@everworker/oneringai 0.4.5 → 0.4.7

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/dist/index.js CHANGED
@@ -21,6 +21,7 @@ import process2 from 'process';
21
21
  import { PassThrough } from 'stream';
22
22
  import * as fs17 from 'fs/promises';
23
23
  import { stat, readFile, mkdir, writeFile, readdir } from 'fs/promises';
24
+ import { EventEmitter as EventEmitter$1 } from 'events';
24
25
  import * as simpleIcons from 'simple-icons';
25
26
  import { exec, spawn } from 'child_process';
26
27
  import { promisify } from 'util';
@@ -12599,18 +12600,30 @@ function isVendor(value) {
12599
12600
  // src/domain/entities/Model.ts
12600
12601
  var LLM_MODELS = {
12601
12602
  [Vendor.OpenAI]: {
12603
+ // GPT-5.3 Series
12604
+ GPT_5_3_CODEX: "gpt-5.3-codex",
12605
+ GPT_5_3_CHAT: "gpt-5.3-chat-latest",
12602
12606
  // GPT-5.2 Series (Current Flagship)
12603
12607
  GPT_5_2: "gpt-5.2",
12604
12608
  GPT_5_2_PRO: "gpt-5.2-pro",
12609
+ GPT_5_2_CODEX: "gpt-5.2-codex",
12610
+ GPT_5_2_CHAT: "gpt-5.2-chat-latest",
12611
+ // GPT-5.1 Series
12612
+ GPT_5_1: "gpt-5.1",
12613
+ GPT_5_1_CODEX: "gpt-5.1-codex",
12614
+ GPT_5_1_CODEX_MAX: "gpt-5.1-codex-max",
12615
+ GPT_5_1_CODEX_MINI: "gpt-5.1-codex-mini",
12616
+ GPT_5_1_CHAT: "gpt-5.1-chat-latest",
12605
12617
  // GPT-5 Series
12606
12618
  GPT_5: "gpt-5",
12607
12619
  GPT_5_MINI: "gpt-5-mini",
12608
12620
  GPT_5_NANO: "gpt-5-nano",
12621
+ GPT_5_CHAT: "gpt-5-chat-latest",
12609
12622
  // GPT-4.1 Series
12610
12623
  GPT_4_1: "gpt-4.1",
12611
12624
  GPT_4_1_MINI: "gpt-4.1-mini",
12612
12625
  GPT_4_1_NANO: "gpt-4.1-nano",
12613
- // GPT-4o Series (Legacy, Audio Capable)
12626
+ // GPT-4o Series (Legacy)
12614
12627
  GPT_4O: "gpt-4o",
12615
12628
  GPT_4O_MINI: "gpt-4o-mini",
12616
12629
  // Reasoning Models (o-series)
@@ -12618,18 +12631,26 @@ var LLM_MODELS = {
12618
12631
  O1: "o1"
12619
12632
  },
12620
12633
  [Vendor.Anthropic]: {
12621
- // Claude 4.5 Series (Current)
12634
+ // Claude 4.6 Series (Current)
12635
+ CLAUDE_OPUS_4_6: "claude-opus-4-6",
12636
+ CLAUDE_SONNET_4_6: "claude-sonnet-4-6",
12637
+ // Claude 4.5 Series
12622
12638
  CLAUDE_OPUS_4_5: "claude-opus-4-5-20251101",
12623
12639
  CLAUDE_SONNET_4_5: "claude-sonnet-4-5-20250929",
12624
12640
  CLAUDE_HAIKU_4_5: "claude-haiku-4-5-20251001",
12625
12641
  // Claude 4.x Legacy
12626
12642
  CLAUDE_OPUS_4_1: "claude-opus-4-1-20250805",
12643
+ CLAUDE_OPUS_4: "claude-opus-4-20250514",
12627
12644
  CLAUDE_SONNET_4: "claude-sonnet-4-20250514",
12628
12645
  CLAUDE_SONNET_3_7: "claude-3-7-sonnet-20250219",
12629
- // Claude 3.x Legacy
12646
+ // Claude 3.x Legacy (Deprecated)
12630
12647
  CLAUDE_HAIKU_3: "claude-3-haiku-20240307"
12631
12648
  },
12632
12649
  [Vendor.Google]: {
12650
+ // Gemini 3.1 Series (Preview)
12651
+ GEMINI_3_1_PRO_PREVIEW: "gemini-3.1-pro-preview",
12652
+ GEMINI_3_1_FLASH_LITE_PREVIEW: "gemini-3.1-flash-lite-preview",
12653
+ GEMINI_3_1_FLASH_IMAGE_PREVIEW: "gemini-3.1-flash-image-preview",
12633
12654
  // Gemini 3 Series (Preview)
12634
12655
  GEMINI_3_FLASH_PREVIEW: "gemini-3-flash-preview",
12635
12656
  GEMINI_3_PRO_PREVIEW: "gemini-3-pro-preview",
@@ -12661,12 +12682,91 @@ var MODEL_REGISTRY = {
12661
12682
  // ============================================================================
12662
12683
  // OpenAI Models (Verified from platform.openai.com)
12663
12684
  // ============================================================================
12685
+ // GPT-5.3 Series
12686
+ "gpt-5.3-codex": {
12687
+ name: "gpt-5.3-codex",
12688
+ provider: Vendor.OpenAI,
12689
+ description: "Latest codex model for coding and agentic tasks. Reasoning.effort: low, medium, high, xhigh",
12690
+ isActive: true,
12691
+ releaseDate: "2026-02-01",
12692
+ knowledgeCutoff: "2025-08-31",
12693
+ features: {
12694
+ reasoning: true,
12695
+ streaming: true,
12696
+ structuredOutput: true,
12697
+ functionCalling: true,
12698
+ fineTuning: false,
12699
+ predictedOutputs: false,
12700
+ realtime: false,
12701
+ vision: true,
12702
+ audio: false,
12703
+ video: false,
12704
+ batchAPI: true,
12705
+ promptCaching: true,
12706
+ parameters: {
12707
+ temperature: false,
12708
+ topP: false,
12709
+ frequencyPenalty: false,
12710
+ presencePenalty: false
12711
+ },
12712
+ input: {
12713
+ tokens: 4e5,
12714
+ text: true,
12715
+ image: true,
12716
+ cpm: 1.75,
12717
+ cpmCached: 0.175
12718
+ },
12719
+ output: {
12720
+ tokens: 128e3,
12721
+ text: true,
12722
+ cpm: 14
12723
+ }
12724
+ }
12725
+ },
12726
+ "gpt-5.3-chat-latest": {
12727
+ name: "gpt-5.3-chat-latest",
12728
+ provider: Vendor.OpenAI,
12729
+ description: "Latest GPT-5.3 chat model for general-purpose use",
12730
+ isActive: true,
12731
+ releaseDate: "2026-02-01",
12732
+ knowledgeCutoff: "2025-08-31",
12733
+ features: {
12734
+ reasoning: false,
12735
+ streaming: true,
12736
+ structuredOutput: true,
12737
+ functionCalling: true,
12738
+ fineTuning: false,
12739
+ predictedOutputs: false,
12740
+ realtime: false,
12741
+ vision: true,
12742
+ audio: false,
12743
+ video: false,
12744
+ batchAPI: true,
12745
+ promptCaching: true,
12746
+ parameters: {
12747
+ temperature: false
12748
+ },
12749
+ input: {
12750
+ tokens: 128e3,
12751
+ text: true,
12752
+ image: true,
12753
+ cpm: 1.75,
12754
+ cpmCached: 0.175
12755
+ },
12756
+ output: {
12757
+ tokens: 16e3,
12758
+ text: true,
12759
+ cpm: 14
12760
+ }
12761
+ }
12762
+ },
12664
12763
  // GPT-5.2 Series (Current Flagship)
12665
12764
  "gpt-5.2": {
12666
12765
  name: "gpt-5.2",
12667
12766
  provider: Vendor.OpenAI,
12668
12767
  description: "Flagship model for coding and agentic tasks. Reasoning.effort: none, low, medium, high, xhigh",
12669
12768
  isActive: true,
12769
+ preferred: true,
12670
12770
  releaseDate: "2025-12-01",
12671
12771
  knowledgeCutoff: "2025-08-31",
12672
12772
  features: {
@@ -12692,7 +12792,8 @@ var MODEL_REGISTRY = {
12692
12792
  tokens: 4e5,
12693
12793
  text: true,
12694
12794
  image: true,
12695
- cpm: 1.75
12795
+ cpm: 1.75,
12796
+ cpmCached: 0.175
12696
12797
  },
12697
12798
  output: {
12698
12799
  tokens: 128e3,
@@ -12711,7 +12812,7 @@ var MODEL_REGISTRY = {
12711
12812
  features: {
12712
12813
  reasoning: true,
12713
12814
  streaming: true,
12714
- structuredOutput: true,
12815
+ structuredOutput: false,
12715
12816
  functionCalling: true,
12716
12817
  fineTuning: false,
12717
12818
  predictedOutputs: false,
@@ -12740,6 +12841,276 @@ var MODEL_REGISTRY = {
12740
12841
  }
12741
12842
  }
12742
12843
  },
12844
+ "gpt-5.2-codex": {
12845
+ name: "gpt-5.2-codex",
12846
+ provider: Vendor.OpenAI,
12847
+ description: "GPT-5.2 codex for coding and agentic tasks. Reasoning.effort: low, medium, high, xhigh",
12848
+ isActive: true,
12849
+ preferred: true,
12850
+ releaseDate: "2025-12-01",
12851
+ knowledgeCutoff: "2025-08-31",
12852
+ features: {
12853
+ reasoning: true,
12854
+ streaming: true,
12855
+ structuredOutput: true,
12856
+ functionCalling: true,
12857
+ fineTuning: false,
12858
+ predictedOutputs: false,
12859
+ realtime: false,
12860
+ vision: true,
12861
+ audio: false,
12862
+ video: false,
12863
+ batchAPI: true,
12864
+ promptCaching: true,
12865
+ parameters: {
12866
+ temperature: false,
12867
+ topP: false,
12868
+ frequencyPenalty: false,
12869
+ presencePenalty: false
12870
+ },
12871
+ input: {
12872
+ tokens: 4e5,
12873
+ text: true,
12874
+ image: true,
12875
+ cpm: 1.75,
12876
+ cpmCached: 0.175
12877
+ },
12878
+ output: {
12879
+ tokens: 128e3,
12880
+ text: true,
12881
+ cpm: 14
12882
+ }
12883
+ }
12884
+ },
12885
+ "gpt-5.2-chat-latest": {
12886
+ name: "gpt-5.2-chat-latest",
12887
+ provider: Vendor.OpenAI,
12888
+ description: "GPT-5.2 chat model for general-purpose use",
12889
+ isActive: true,
12890
+ releaseDate: "2025-12-01",
12891
+ knowledgeCutoff: "2025-08-31",
12892
+ features: {
12893
+ reasoning: false,
12894
+ streaming: true,
12895
+ structuredOutput: true,
12896
+ functionCalling: true,
12897
+ fineTuning: false,
12898
+ predictedOutputs: false,
12899
+ realtime: false,
12900
+ vision: true,
12901
+ audio: false,
12902
+ video: false,
12903
+ batchAPI: true,
12904
+ promptCaching: true,
12905
+ input: {
12906
+ tokens: 128e3,
12907
+ text: true,
12908
+ image: true,
12909
+ cpm: 1.75,
12910
+ cpmCached: 0.175
12911
+ },
12912
+ output: {
12913
+ tokens: 16e3,
12914
+ text: true,
12915
+ cpm: 14
12916
+ }
12917
+ }
12918
+ },
12919
+ // GPT-5.1 Series
12920
+ "gpt-5.1": {
12921
+ name: "gpt-5.1",
12922
+ provider: Vendor.OpenAI,
12923
+ description: "Intelligent reasoning model for coding and agentic tasks. Reasoning.effort: none, low, medium, high",
12924
+ isActive: true,
12925
+ releaseDate: "2025-10-01",
12926
+ knowledgeCutoff: "2024-09-30",
12927
+ features: {
12928
+ reasoning: true,
12929
+ streaming: true,
12930
+ structuredOutput: true,
12931
+ functionCalling: true,
12932
+ fineTuning: false,
12933
+ predictedOutputs: false,
12934
+ realtime: false,
12935
+ vision: true,
12936
+ audio: false,
12937
+ video: false,
12938
+ batchAPI: true,
12939
+ promptCaching: true,
12940
+ parameters: {
12941
+ temperature: false,
12942
+ topP: false,
12943
+ frequencyPenalty: false,
12944
+ presencePenalty: false
12945
+ },
12946
+ input: {
12947
+ tokens: 4e5,
12948
+ text: true,
12949
+ image: true,
12950
+ cpm: 1.25,
12951
+ cpmCached: 0.125
12952
+ },
12953
+ output: {
12954
+ tokens: 128e3,
12955
+ text: true,
12956
+ cpm: 10
12957
+ }
12958
+ }
12959
+ },
12960
+ "gpt-5.1-codex": {
12961
+ name: "gpt-5.1-codex",
12962
+ provider: Vendor.OpenAI,
12963
+ description: "GPT-5.1 codex for coding and agentic tasks with reasoning",
12964
+ isActive: true,
12965
+ releaseDate: "2025-10-01",
12966
+ knowledgeCutoff: "2024-09-30",
12967
+ features: {
12968
+ reasoning: true,
12969
+ streaming: true,
12970
+ structuredOutput: true,
12971
+ functionCalling: true,
12972
+ fineTuning: false,
12973
+ predictedOutputs: false,
12974
+ realtime: false,
12975
+ vision: true,
12976
+ audio: false,
12977
+ video: false,
12978
+ batchAPI: true,
12979
+ promptCaching: true,
12980
+ parameters: {
12981
+ temperature: false,
12982
+ topP: false,
12983
+ frequencyPenalty: false,
12984
+ presencePenalty: false
12985
+ },
12986
+ input: {
12987
+ tokens: 4e5,
12988
+ text: true,
12989
+ image: true,
12990
+ cpm: 1.25,
12991
+ cpmCached: 0.125
12992
+ },
12993
+ output: {
12994
+ tokens: 128e3,
12995
+ text: true,
12996
+ cpm: 10
12997
+ }
12998
+ }
12999
+ },
13000
+ "gpt-5.1-codex-max": {
13001
+ name: "gpt-5.1-codex-max",
13002
+ provider: Vendor.OpenAI,
13003
+ description: "GPT-5.1 codex max for maximum reasoning depth on coding tasks",
13004
+ isActive: true,
13005
+ releaseDate: "2025-10-01",
13006
+ knowledgeCutoff: "2024-09-30",
13007
+ features: {
13008
+ reasoning: true,
13009
+ streaming: true,
13010
+ structuredOutput: true,
13011
+ functionCalling: true,
13012
+ fineTuning: false,
13013
+ predictedOutputs: false,
13014
+ realtime: false,
13015
+ vision: true,
13016
+ audio: false,
13017
+ video: false,
13018
+ batchAPI: true,
13019
+ promptCaching: true,
13020
+ parameters: {
13021
+ temperature: false,
13022
+ topP: false,
13023
+ frequencyPenalty: false,
13024
+ presencePenalty: false
13025
+ },
13026
+ input: {
13027
+ tokens: 4e5,
13028
+ text: true,
13029
+ image: true,
13030
+ cpm: 1.25,
13031
+ cpmCached: 0.125
13032
+ },
13033
+ output: {
13034
+ tokens: 128e3,
13035
+ text: true,
13036
+ cpm: 10
13037
+ }
13038
+ }
13039
+ },
13040
+ "gpt-5.1-codex-mini": {
13041
+ name: "gpt-5.1-codex-mini",
13042
+ provider: Vendor.OpenAI,
13043
+ description: "GPT-5.1 codex mini for cost-efficient coding tasks",
13044
+ isActive: true,
13045
+ releaseDate: "2025-10-01",
13046
+ knowledgeCutoff: "2024-09-30",
13047
+ features: {
13048
+ reasoning: true,
13049
+ streaming: true,
13050
+ structuredOutput: true,
13051
+ functionCalling: true,
13052
+ fineTuning: false,
13053
+ predictedOutputs: false,
13054
+ realtime: false,
13055
+ vision: true,
13056
+ audio: false,
13057
+ video: false,
13058
+ batchAPI: true,
13059
+ promptCaching: true,
13060
+ parameters: {
13061
+ temperature: false,
13062
+ topP: false,
13063
+ frequencyPenalty: false,
13064
+ presencePenalty: false
13065
+ },
13066
+ input: {
13067
+ tokens: 4e5,
13068
+ text: true,
13069
+ image: true,
13070
+ cpm: 0.25,
13071
+ cpmCached: 0.025
13072
+ },
13073
+ output: {
13074
+ tokens: 128e3,
13075
+ text: true,
13076
+ cpm: 2
13077
+ }
13078
+ }
13079
+ },
13080
+ "gpt-5.1-chat-latest": {
13081
+ name: "gpt-5.1-chat-latest",
13082
+ provider: Vendor.OpenAI,
13083
+ description: "GPT-5.1 chat model for general-purpose use",
13084
+ isActive: true,
13085
+ releaseDate: "2025-10-01",
13086
+ knowledgeCutoff: "2024-09-30",
13087
+ features: {
13088
+ reasoning: false,
13089
+ streaming: true,
13090
+ structuredOutput: true,
13091
+ functionCalling: true,
13092
+ fineTuning: false,
13093
+ predictedOutputs: false,
13094
+ realtime: false,
13095
+ vision: true,
13096
+ audio: false,
13097
+ video: false,
13098
+ batchAPI: true,
13099
+ promptCaching: true,
13100
+ input: {
13101
+ tokens: 128e3,
13102
+ text: true,
13103
+ image: true,
13104
+ cpm: 1.25,
13105
+ cpmCached: 0.125
13106
+ },
13107
+ output: {
13108
+ tokens: 16e3,
13109
+ text: true,
13110
+ cpm: 10
13111
+ }
13112
+ }
13113
+ },
12743
13114
  // GPT-5 Series
12744
13115
  "gpt-5": {
12745
13116
  name: "gpt-5",
@@ -12771,7 +13142,8 @@ var MODEL_REGISTRY = {
12771
13142
  tokens: 4e5,
12772
13143
  text: true,
12773
13144
  image: true,
12774
- cpm: 1.25
13145
+ cpm: 1.25,
13146
+ cpmCached: 0.125
12775
13147
  },
12776
13148
  output: {
12777
13149
  tokens: 128e3,
@@ -12810,7 +13182,8 @@ var MODEL_REGISTRY = {
12810
13182
  tokens: 4e5,
12811
13183
  text: true,
12812
13184
  image: true,
12813
- cpm: 0.25
13185
+ cpm: 0.25,
13186
+ cpmCached: 0.025
12814
13187
  },
12815
13188
  output: {
12816
13189
  tokens: 128e3,
@@ -12849,7 +13222,8 @@ var MODEL_REGISTRY = {
12849
13222
  tokens: 4e5,
12850
13223
  text: true,
12851
13224
  image: true,
12852
- cpm: 0.05
13225
+ cpm: 0.05,
13226
+ cpmCached: 5e-3
12853
13227
  },
12854
13228
  output: {
12855
13229
  tokens: 128e3,
@@ -12858,6 +13232,40 @@ var MODEL_REGISTRY = {
12858
13232
  }
12859
13233
  }
12860
13234
  },
13235
+ "gpt-5-chat-latest": {
13236
+ name: "gpt-5-chat-latest",
13237
+ provider: Vendor.OpenAI,
13238
+ description: "GPT-5 chat model for general-purpose use",
13239
+ isActive: true,
13240
+ releaseDate: "2025-08-01",
13241
+ knowledgeCutoff: "2024-09-30",
13242
+ features: {
13243
+ reasoning: false,
13244
+ streaming: true,
13245
+ structuredOutput: true,
13246
+ functionCalling: true,
13247
+ fineTuning: false,
13248
+ predictedOutputs: false,
13249
+ realtime: false,
13250
+ vision: true,
13251
+ audio: false,
13252
+ video: false,
13253
+ batchAPI: true,
13254
+ promptCaching: true,
13255
+ input: {
13256
+ tokens: 128e3,
13257
+ text: true,
13258
+ image: true,
13259
+ cpm: 1.25,
13260
+ cpmCached: 0.125
13261
+ },
13262
+ output: {
13263
+ tokens: 16e3,
13264
+ text: true,
13265
+ cpm: 10
13266
+ }
13267
+ }
13268
+ },
12861
13269
  // GPT-4.1 Series
12862
13270
  "gpt-4.1": {
12863
13271
  name: "gpt-4.1",
@@ -12865,7 +13273,7 @@ var MODEL_REGISTRY = {
12865
13273
  description: "GPT-4.1 specialized for coding with 1M token context window",
12866
13274
  isActive: true,
12867
13275
  releaseDate: "2025-04-14",
12868
- knowledgeCutoff: "2025-04-01",
13276
+ knowledgeCutoff: "2024-06-01",
12869
13277
  features: {
12870
13278
  reasoning: false,
12871
13279
  streaming: true,
@@ -12883,7 +13291,8 @@ var MODEL_REGISTRY = {
12883
13291
  tokens: 1e6,
12884
13292
  text: true,
12885
13293
  image: true,
12886
- cpm: 2
13294
+ cpm: 2,
13295
+ cpmCached: 0.5
12887
13296
  },
12888
13297
  output: {
12889
13298
  tokens: 32768,
@@ -12898,7 +13307,7 @@ var MODEL_REGISTRY = {
12898
13307
  description: "Efficient GPT-4.1 model, beats GPT-4o in many benchmarks at 83% lower cost",
12899
13308
  isActive: true,
12900
13309
  releaseDate: "2025-04-14",
12901
- knowledgeCutoff: "2025-04-01",
13310
+ knowledgeCutoff: "2024-06-01",
12902
13311
  features: {
12903
13312
  reasoning: false,
12904
13313
  streaming: true,
@@ -12916,7 +13325,8 @@ var MODEL_REGISTRY = {
12916
13325
  tokens: 1e6,
12917
13326
  text: true,
12918
13327
  image: true,
12919
- cpm: 0.4
13328
+ cpm: 0.4,
13329
+ cpmCached: 0.1
12920
13330
  },
12921
13331
  output: {
12922
13332
  tokens: 16384,
@@ -12931,7 +13341,7 @@ var MODEL_REGISTRY = {
12931
13341
  description: "Fastest and cheapest model with 1M context. 80.1% MMLU, ideal for classification/autocompletion",
12932
13342
  isActive: true,
12933
13343
  releaseDate: "2025-04-14",
12934
- knowledgeCutoff: "2025-04-01",
13344
+ knowledgeCutoff: "2024-06-01",
12935
13345
  features: {
12936
13346
  reasoning: false,
12937
13347
  streaming: true,
@@ -12949,7 +13359,8 @@ var MODEL_REGISTRY = {
12949
13359
  tokens: 1e6,
12950
13360
  text: true,
12951
13361
  image: true,
12952
- cpm: 0.1
13362
+ cpm: 0.1,
13363
+ cpmCached: 0.025
12953
13364
  },
12954
13365
  output: {
12955
13366
  tokens: 16384,
@@ -12958,14 +13369,14 @@ var MODEL_REGISTRY = {
12958
13369
  }
12959
13370
  }
12960
13371
  },
12961
- // GPT-4o Series (Legacy, Audio Capable)
13372
+ // GPT-4o Series (Legacy)
12962
13373
  "gpt-4o": {
12963
13374
  name: "gpt-4o",
12964
13375
  provider: Vendor.OpenAI,
12965
- description: "Versatile omni model with audio support. Legacy but still available",
13376
+ description: "Versatile omni model. Legacy but still available",
12966
13377
  isActive: true,
12967
13378
  releaseDate: "2024-05-13",
12968
- knowledgeCutoff: "2024-04-01",
13379
+ knowledgeCutoff: "2023-10-01",
12969
13380
  features: {
12970
13381
  reasoning: false,
12971
13382
  streaming: true,
@@ -12975,7 +13386,7 @@ var MODEL_REGISTRY = {
12975
13386
  predictedOutputs: true,
12976
13387
  realtime: true,
12977
13388
  vision: true,
12978
- audio: true,
13389
+ audio: false,
12979
13390
  video: false,
12980
13391
  batchAPI: true,
12981
13392
  promptCaching: true,
@@ -12983,13 +13394,12 @@ var MODEL_REGISTRY = {
12983
13394
  tokens: 128e3,
12984
13395
  text: true,
12985
13396
  image: true,
12986
- audio: true,
12987
- cpm: 2.5
13397
+ cpm: 2.5,
13398
+ cpmCached: 1.25
12988
13399
  },
12989
13400
  output: {
12990
13401
  tokens: 16384,
12991
13402
  text: true,
12992
- audio: true,
12993
13403
  cpm: 10
12994
13404
  }
12995
13405
  }
@@ -12997,10 +13407,10 @@ var MODEL_REGISTRY = {
12997
13407
  "gpt-4o-mini": {
12998
13408
  name: "gpt-4o-mini",
12999
13409
  provider: Vendor.OpenAI,
13000
- description: "Fast, affordable omni model with audio support",
13410
+ description: "Fast, affordable omni model",
13001
13411
  isActive: true,
13002
13412
  releaseDate: "2024-07-18",
13003
- knowledgeCutoff: "2024-04-01",
13413
+ knowledgeCutoff: "2023-10-01",
13004
13414
  features: {
13005
13415
  reasoning: false,
13006
13416
  streaming: true,
@@ -13010,7 +13420,7 @@ var MODEL_REGISTRY = {
13010
13420
  predictedOutputs: false,
13011
13421
  realtime: true,
13012
13422
  vision: true,
13013
- audio: true,
13423
+ audio: false,
13014
13424
  video: false,
13015
13425
  batchAPI: true,
13016
13426
  promptCaching: true,
@@ -13018,13 +13428,12 @@ var MODEL_REGISTRY = {
13018
13428
  tokens: 128e3,
13019
13429
  text: true,
13020
13430
  image: true,
13021
- audio: true,
13022
- cpm: 0.15
13431
+ cpm: 0.15,
13432
+ cpmCached: 0.075
13023
13433
  },
13024
13434
  output: {
13025
13435
  tokens: 16384,
13026
13436
  text: true,
13027
- audio: true,
13028
13437
  cpm: 0.6
13029
13438
  }
13030
13439
  }
@@ -13036,7 +13445,7 @@ var MODEL_REGISTRY = {
13036
13445
  description: "Fast reasoning model tailored for coding, math, and science",
13037
13446
  isActive: true,
13038
13447
  releaseDate: "2025-01-31",
13039
- knowledgeCutoff: "2024-10-01",
13448
+ knowledgeCutoff: "2023-10-01",
13040
13449
  features: {
13041
13450
  reasoning: true,
13042
13451
  streaming: true,
@@ -13045,11 +13454,11 @@ var MODEL_REGISTRY = {
13045
13454
  fineTuning: false,
13046
13455
  predictedOutputs: false,
13047
13456
  realtime: false,
13048
- vision: true,
13457
+ vision: false,
13049
13458
  audio: false,
13050
13459
  video: false,
13051
13460
  batchAPI: true,
13052
- promptCaching: false,
13461
+ promptCaching: true,
13053
13462
  parameters: {
13054
13463
  temperature: false,
13055
13464
  topP: false,
@@ -13059,8 +13468,8 @@ var MODEL_REGISTRY = {
13059
13468
  input: {
13060
13469
  tokens: 2e5,
13061
13470
  text: true,
13062
- image: true,
13063
- cpm: 1.1
13471
+ cpm: 1.1,
13472
+ cpmCached: 0.55
13064
13473
  },
13065
13474
  output: {
13066
13475
  tokens: 1e5,
@@ -13075,7 +13484,7 @@ var MODEL_REGISTRY = {
13075
13484
  description: "Advanced reasoning model for complex problems",
13076
13485
  isActive: true,
13077
13486
  releaseDate: "2024-12-17",
13078
- knowledgeCutoff: "2024-10-01",
13487
+ knowledgeCutoff: "2023-10-01",
13079
13488
  features: {
13080
13489
  reasoning: true,
13081
13490
  streaming: true,
@@ -13088,7 +13497,7 @@ var MODEL_REGISTRY = {
13088
13497
  audio: false,
13089
13498
  video: false,
13090
13499
  batchAPI: true,
13091
- promptCaching: false,
13500
+ promptCaching: true,
13092
13501
  parameters: {
13093
13502
  temperature: false,
13094
13503
  topP: false,
@@ -13099,7 +13508,8 @@ var MODEL_REGISTRY = {
13099
13508
  tokens: 2e5,
13100
13509
  text: true,
13101
13510
  image: true,
13102
- cpm: 15
13511
+ cpm: 15,
13512
+ cpmCached: 7.5
13103
13513
  },
13104
13514
  output: {
13105
13515
  tokens: 1e5,
@@ -13109,13 +13519,88 @@ var MODEL_REGISTRY = {
13109
13519
  }
13110
13520
  },
13111
13521
  // ============================================================================
13112
- // Anthropic Models (Verified from platform.claude.com)
13522
+ // Anthropic Models (Verified from platform.claude.com - March 2026)
13113
13523
  // ============================================================================
13114
- // Claude 4.5 Series (Current)
13524
+ // Claude 4.6 Series (Current)
13525
+ "claude-opus-4-6": {
13526
+ name: "claude-opus-4-6",
13527
+ provider: Vendor.Anthropic,
13528
+ description: "The most intelligent model for building agents and coding. 128K output, adaptive thinking",
13529
+ isActive: true,
13530
+ preferred: true,
13531
+ releaseDate: "2026-02-01",
13532
+ knowledgeCutoff: "2025-05-01",
13533
+ features: {
13534
+ reasoning: false,
13535
+ streaming: true,
13536
+ structuredOutput: true,
13537
+ functionCalling: true,
13538
+ fineTuning: false,
13539
+ predictedOutputs: false,
13540
+ realtime: false,
13541
+ vision: true,
13542
+ audio: false,
13543
+ video: false,
13544
+ extendedThinking: true,
13545
+ batchAPI: true,
13546
+ promptCaching: true,
13547
+ input: {
13548
+ tokens: 2e5,
13549
+ // 1M with beta header
13550
+ text: true,
13551
+ image: true,
13552
+ cpm: 5,
13553
+ cpmCached: 0.5
13554
+ },
13555
+ output: {
13556
+ tokens: 128e3,
13557
+ text: true,
13558
+ cpm: 25
13559
+ }
13560
+ }
13561
+ },
13562
+ "claude-sonnet-4-6": {
13563
+ name: "claude-sonnet-4-6",
13564
+ provider: Vendor.Anthropic,
13565
+ description: "Best combination of speed and intelligence. Adaptive thinking, 1M context beta",
13566
+ isActive: true,
13567
+ preferred: true,
13568
+ releaseDate: "2026-02-01",
13569
+ knowledgeCutoff: "2025-08-01",
13570
+ features: {
13571
+ reasoning: false,
13572
+ streaming: true,
13573
+ structuredOutput: true,
13574
+ functionCalling: true,
13575
+ fineTuning: false,
13576
+ predictedOutputs: false,
13577
+ realtime: false,
13578
+ vision: true,
13579
+ audio: false,
13580
+ video: false,
13581
+ extendedThinking: true,
13582
+ batchAPI: true,
13583
+ promptCaching: true,
13584
+ input: {
13585
+ tokens: 2e5,
13586
+ // 1M with beta header
13587
+ text: true,
13588
+ image: true,
13589
+ cpm: 3,
13590
+ cpmCached: 0.3
13591
+ },
13592
+ output: {
13593
+ tokens: 64e3,
13594
+ text: true,
13595
+ cpm: 15
13596
+ }
13597
+ }
13598
+ },
13599
+ // Claude 4.5 Series
13115
13600
  "claude-opus-4-5-20251101": {
13116
13601
  name: "claude-opus-4-5-20251101",
13117
13602
  provider: Vendor.Anthropic,
13118
- description: "Premium model combining maximum intelligence with practical performance",
13603
+ description: "Legacy Opus 4.5. Premium model combining maximum intelligence with practical performance",
13119
13604
  isActive: true,
13120
13605
  releaseDate: "2025-11-01",
13121
13606
  knowledgeCutoff: "2025-05-01",
@@ -13150,7 +13635,7 @@ var MODEL_REGISTRY = {
13150
13635
  "claude-sonnet-4-5-20250929": {
13151
13636
  name: "claude-sonnet-4-5-20250929",
13152
13637
  provider: Vendor.Anthropic,
13153
- description: "Smart model for complex agents and coding. Best balance of intelligence, speed, cost",
13638
+ description: "Legacy Sonnet 4.5. Smart model for complex agents and coding",
13154
13639
  isActive: true,
13155
13640
  releaseDate: "2025-09-29",
13156
13641
  knowledgeCutoff: "2025-01-01",
@@ -13170,6 +13655,7 @@ var MODEL_REGISTRY = {
13170
13655
  promptCaching: true,
13171
13656
  input: {
13172
13657
  tokens: 2e5,
13658
+ // 1M with beta header
13173
13659
  text: true,
13174
13660
  image: true,
13175
13661
  cpm: 3,
@@ -13253,10 +13739,45 @@ var MODEL_REGISTRY = {
13253
13739
  }
13254
13740
  }
13255
13741
  },
13742
+ "claude-opus-4-20250514": {
13743
+ name: "claude-opus-4-20250514",
13744
+ provider: Vendor.Anthropic,
13745
+ description: "Legacy Opus 4. Agentic tasks and reasoning",
13746
+ isActive: true,
13747
+ releaseDate: "2025-05-14",
13748
+ knowledgeCutoff: "2025-01-01",
13749
+ features: {
13750
+ reasoning: false,
13751
+ streaming: true,
13752
+ structuredOutput: true,
13753
+ functionCalling: true,
13754
+ fineTuning: false,
13755
+ predictedOutputs: false,
13756
+ realtime: false,
13757
+ vision: true,
13758
+ audio: false,
13759
+ video: false,
13760
+ extendedThinking: true,
13761
+ batchAPI: true,
13762
+ promptCaching: true,
13763
+ input: {
13764
+ tokens: 2e5,
13765
+ text: true,
13766
+ image: true,
13767
+ cpm: 15,
13768
+ cpmCached: 1.5
13769
+ },
13770
+ output: {
13771
+ tokens: 32e3,
13772
+ text: true,
13773
+ cpm: 75
13774
+ }
13775
+ }
13776
+ },
13256
13777
  "claude-sonnet-4-20250514": {
13257
13778
  name: "claude-sonnet-4-20250514",
13258
13779
  provider: Vendor.Anthropic,
13259
- description: "Legacy Sonnet 4. Default for most users, supports 1M context beta",
13780
+ description: "Legacy Sonnet 4. Supports 1M context beta",
13260
13781
  isActive: true,
13261
13782
  releaseDate: "2025-05-14",
13262
13783
  knowledgeCutoff: "2025-01-01",
@@ -13292,7 +13813,7 @@ var MODEL_REGISTRY = {
13292
13813
  "claude-3-7-sonnet-20250219": {
13293
13814
  name: "claude-3-7-sonnet-20250219",
13294
13815
  provider: Vendor.Anthropic,
13295
- description: "Claude 3.7 Sonnet with extended thinking, supports 128K output beta",
13816
+ description: "Deprecated. Claude 3.7 Sonnet with extended thinking",
13296
13817
  isActive: true,
13297
13818
  releaseDate: "2025-02-19",
13298
13819
  knowledgeCutoff: "2024-10-01",
@@ -13319,17 +13840,16 @@ var MODEL_REGISTRY = {
13319
13840
  },
13320
13841
  output: {
13321
13842
  tokens: 64e3,
13322
- // 128K with beta header
13323
13843
  text: true,
13324
13844
  cpm: 15
13325
13845
  }
13326
13846
  }
13327
13847
  },
13328
- // Claude 3.x Legacy
13848
+ // Claude 3.x Legacy (Deprecated - retiring April 19, 2026)
13329
13849
  "claude-3-haiku-20240307": {
13330
13850
  name: "claude-3-haiku-20240307",
13331
13851
  provider: Vendor.Anthropic,
13332
- description: "Fast legacy model. Recommend migrating to Haiku 4.5",
13852
+ description: "Deprecated. Retiring April 19, 2026. Migrate to Haiku 4.5",
13333
13853
  isActive: true,
13334
13854
  releaseDate: "2024-03-07",
13335
13855
  knowledgeCutoff: "2023-08-01",
@@ -13362,16 +13882,124 @@ var MODEL_REGISTRY = {
13362
13882
  }
13363
13883
  },
13364
13884
  // ============================================================================
13365
- // Google Models (Verified from ai.google.dev)
13885
+ // Google Models (Verified from ai.google.dev - March 2026)
13366
13886
  // ============================================================================
13887
+ // Gemini 3.1 Series (Preview)
13888
+ "gemini-3.1-pro-preview": {
13889
+ name: "gemini-3.1-pro-preview",
13890
+ provider: Vendor.Google,
13891
+ description: "Advanced intelligence with powerful agentic and coding capabilities. Replaces gemini-3-pro-preview",
13892
+ isActive: true,
13893
+ preferred: true,
13894
+ releaseDate: "2026-02-01",
13895
+ knowledgeCutoff: "2025-01-01",
13896
+ features: {
13897
+ reasoning: true,
13898
+ streaming: true,
13899
+ structuredOutput: true,
13900
+ functionCalling: true,
13901
+ fineTuning: false,
13902
+ predictedOutputs: false,
13903
+ realtime: false,
13904
+ vision: true,
13905
+ audio: true,
13906
+ video: true,
13907
+ batchAPI: true,
13908
+ promptCaching: true,
13909
+ input: {
13910
+ tokens: 1048576,
13911
+ text: true,
13912
+ image: true,
13913
+ audio: true,
13914
+ video: true,
13915
+ cpm: 2,
13916
+ cpmCached: 0.2
13917
+ },
13918
+ output: {
13919
+ tokens: 65536,
13920
+ text: true,
13921
+ cpm: 12
13922
+ }
13923
+ }
13924
+ },
13925
+ "gemini-3.1-flash-lite-preview": {
13926
+ name: "gemini-3.1-flash-lite-preview",
13927
+ provider: Vendor.Google,
13928
+ description: "High performance, budget-friendly for high-volume agentic tasks and data extraction",
13929
+ isActive: true,
13930
+ releaseDate: "2026-03-01",
13931
+ knowledgeCutoff: "2025-01-01",
13932
+ features: {
13933
+ reasoning: true,
13934
+ streaming: true,
13935
+ structuredOutput: true,
13936
+ functionCalling: true,
13937
+ fineTuning: false,
13938
+ predictedOutputs: false,
13939
+ realtime: false,
13940
+ vision: true,
13941
+ audio: true,
13942
+ video: true,
13943
+ batchAPI: true,
13944
+ promptCaching: true,
13945
+ input: {
13946
+ tokens: 1048576,
13947
+ text: true,
13948
+ image: true,
13949
+ audio: true,
13950
+ video: true,
13951
+ cpm: 0.25
13952
+ },
13953
+ output: {
13954
+ tokens: 65536,
13955
+ text: true,
13956
+ cpm: 1.5
13957
+ }
13958
+ }
13959
+ },
13960
+ "gemini-3.1-flash-image-preview": {
13961
+ name: "gemini-3.1-flash-image-preview",
13962
+ provider: Vendor.Google,
13963
+ description: "High-efficiency image generation with up to 4K output, search grounding support",
13964
+ isActive: true,
13965
+ releaseDate: "2026-02-01",
13966
+ knowledgeCutoff: "2025-01-01",
13967
+ features: {
13968
+ reasoning: true,
13969
+ streaming: true,
13970
+ structuredOutput: false,
13971
+ functionCalling: false,
13972
+ fineTuning: false,
13973
+ predictedOutputs: false,
13974
+ realtime: false,
13975
+ vision: true,
13976
+ audio: false,
13977
+ video: false,
13978
+ batchAPI: true,
13979
+ promptCaching: false,
13980
+ input: {
13981
+ tokens: 131072,
13982
+ text: true,
13983
+ image: true,
13984
+ cpm: 0.25
13985
+ },
13986
+ output: {
13987
+ tokens: 32768,
13988
+ text: true,
13989
+ image: true,
13990
+ cpm: 1.5
13991
+ }
13992
+ }
13993
+ },
13367
13994
  // Gemini 3 Series (Preview)
13368
13995
  "gemini-3-flash-preview": {
13369
13996
  name: "gemini-3-flash-preview",
13370
13997
  provider: Vendor.Google,
13371
- description: "Pro-grade reasoning with Flash-level latency and efficiency",
13998
+ description: "Most powerful agentic and coding model with frontier-class reasoning",
13372
13999
  isActive: true,
13373
- releaseDate: "2025-11-18",
13374
- knowledgeCutoff: "2025-08-01",
14000
+ preferred: true,
14001
+ releaseDate: "2025-12-01",
14002
+ knowledgeCutoff: "2025-01-01",
13375
14003
  features: {
13376
14004
  reasoning: true,
13377
14005
  streaming: true,
@@ -13386,27 +14014,28 @@ var MODEL_REGISTRY = {
13386
14014
  batchAPI: true,
13387
14015
  promptCaching: true,
13388
14016
  input: {
13389
- tokens: 1e6,
14017
+ tokens: 1048576,
13390
14018
  text: true,
13391
14019
  image: true,
13392
14020
  audio: true,
13393
14021
  video: true,
13394
- cpm: 0.15
14022
+ cpm: 0.5,
14023
+ cpmCached: 0.05
13395
14024
  },
13396
14025
  output: {
13397
14026
  tokens: 65536,
13398
14027
  text: true,
13399
- cpm: 0.6
14028
+ cpm: 3
13400
14029
  }
13401
14030
  }
13402
14031
  },
13403
14032
  "gemini-3-pro-preview": {
13404
14033
  name: "gemini-3-pro-preview",
13405
14034
  provider: Vendor.Google,
13406
- description: "Most advanced reasoning Gemini model for complex tasks",
14035
+ description: "Deprecated. Shutting down March 9, 2026. Migrate to gemini-3.1-pro-preview",
13407
14036
  isActive: true,
13408
14037
  releaseDate: "2025-11-18",
13409
- knowledgeCutoff: "2025-08-01",
14038
+ knowledgeCutoff: "2025-01-01",
13410
14039
  features: {
13411
14040
  reasoning: true,
13412
14041
  streaming: true,
@@ -13421,7 +14050,7 @@ var MODEL_REGISTRY = {
13421
14050
  batchAPI: true,
13422
14051
  promptCaching: true,
13423
14052
  input: {
13424
- tokens: 1e6,
14053
+ tokens: 1048576,
13425
14054
  text: true,
13426
14055
  image: true,
13427
14056
  audio: true,
@@ -13438,14 +14067,14 @@ var MODEL_REGISTRY = {
13438
14067
  "gemini-3-pro-image-preview": {
13439
14068
  name: "gemini-3-pro-image-preview",
13440
14069
  provider: Vendor.Google,
13441
- description: "Highest quality image generation model",
14070
+ description: "Professional-grade image generation and editing with reasoning",
13442
14071
  isActive: true,
13443
14072
  releaseDate: "2025-11-18",
13444
- knowledgeCutoff: "2025-08-01",
14073
+ knowledgeCutoff: "2025-01-01",
13445
14074
  features: {
13446
14075
  reasoning: true,
13447
14076
  streaming: true,
13448
- structuredOutput: false,
14077
+ structuredOutput: true,
13449
14078
  functionCalling: false,
13450
14079
  fineTuning: false,
13451
14080
  predictedOutputs: false,
@@ -13454,15 +14083,15 @@ var MODEL_REGISTRY = {
13454
14083
  audio: false,
13455
14084
  video: false,
13456
14085
  batchAPI: true,
13457
- promptCaching: true,
14086
+ promptCaching: false,
13458
14087
  input: {
13459
- tokens: 1e6,
14088
+ tokens: 65536,
13460
14089
  text: true,
13461
14090
  image: true,
13462
14091
  cpm: 1.25
13463
14092
  },
13464
14093
  output: {
13465
- tokens: 65536,
14094
+ tokens: 32768,
13466
14095
  text: true,
13467
14096
  image: true,
13468
14097
  cpm: 10
@@ -13473,7 +14102,7 @@ var MODEL_REGISTRY = {
13473
14102
  "gemini-2.5-pro": {
13474
14103
  name: "gemini-2.5-pro",
13475
14104
  provider: Vendor.Google,
13476
- description: "Advanced multimodal model built for deep reasoning and agents",
14105
+ description: "Most advanced model for complex tasks with deep reasoning and coding",
13477
14106
  isActive: true,
13478
14107
  releaseDate: "2025-03-01",
13479
14108
  knowledgeCutoff: "2025-01-01",
@@ -13491,12 +14120,13 @@ var MODEL_REGISTRY = {
13491
14120
  batchAPI: true,
13492
14121
  promptCaching: true,
13493
14122
  input: {
13494
- tokens: 1e6,
14123
+ tokens: 1048576,
13495
14124
  text: true,
13496
14125
  image: true,
13497
14126
  audio: true,
13498
14127
  video: true,
13499
- cpm: 1.25
14128
+ cpm: 1.25,
14129
+ cpmCached: 0.125
13500
14130
  },
13501
14131
  output: {
13502
14132
  tokens: 65536,
@@ -13508,7 +14138,7 @@ var MODEL_REGISTRY = {
13508
14138
  "gemini-2.5-flash": {
13509
14139
  name: "gemini-2.5-flash",
13510
14140
  provider: Vendor.Google,
13511
- description: "Fast, cost-effective model with excellent reasoning",
14141
+ description: "Best price-performance for low-latency, high-volume tasks with reasoning",
13512
14142
  isActive: true,
13513
14143
  releaseDate: "2025-06-17",
13514
14144
  knowledgeCutoff: "2025-01-01",
@@ -13526,24 +14156,25 @@ var MODEL_REGISTRY = {
13526
14156
  batchAPI: true,
13527
14157
  promptCaching: true,
13528
14158
  input: {
13529
- tokens: 1e6,
14159
+ tokens: 1048576,
13530
14160
  text: true,
13531
14161
  image: true,
13532
14162
  audio: true,
13533
14163
  video: true,
13534
- cpm: 0.15
14164
+ cpm: 0.3,
14165
+ cpmCached: 0.03
13535
14166
  },
13536
14167
  output: {
13537
14168
  tokens: 65536,
13538
14169
  text: true,
13539
- cpm: 0.6
14170
+ cpm: 2.5
13540
14171
  }
13541
14172
  }
13542
14173
  },
13543
14174
  "gemini-2.5-flash-lite": {
13544
14175
  name: "gemini-2.5-flash-lite",
13545
14176
  provider: Vendor.Google,
13546
- description: "Lowest latency for high-volume tasks, summarization, classification",
14177
+ description: "Fastest and most budget-friendly multimodal model in the 2.5 family",
13547
14178
  isActive: true,
13548
14179
  releaseDate: "2025-06-17",
13549
14180
  knowledgeCutoff: "2025-01-01",
@@ -13561,31 +14192,31 @@ var MODEL_REGISTRY = {
13561
14192
  batchAPI: true,
13562
14193
  promptCaching: true,
13563
14194
  input: {
13564
- tokens: 1e6,
14195
+ tokens: 1048576,
13565
14196
  text: true,
13566
14197
  image: true,
13567
14198
  audio: true,
13568
14199
  video: true,
13569
- cpm: 0.075
14200
+ cpm: 0.1
13570
14201
  },
13571
14202
  output: {
13572
14203
  tokens: 65536,
13573
14204
  text: true,
13574
- cpm: 0.3
14205
+ cpm: 0.4
13575
14206
  }
13576
14207
  }
13577
14208
  },
13578
14209
  "gemini-2.5-flash-image": {
13579
14210
  name: "gemini-2.5-flash-image",
13580
14211
  provider: Vendor.Google,
13581
- description: "Image generation and editing model",
14212
+ description: "Fast native image generation and editing (Nano Banana)",
13582
14213
  isActive: true,
13583
- releaseDate: "2025-09-01",
13584
- knowledgeCutoff: "2025-01-01",
14214
+ releaseDate: "2025-10-01",
14215
+ knowledgeCutoff: "2025-06-01",
13585
14216
  features: {
13586
- reasoning: true,
14217
+ reasoning: false,
13587
14218
  streaming: true,
13588
- structuredOutput: false,
14219
+ structuredOutput: true,
13589
14220
  functionCalling: false,
13590
14221
  fineTuning: false,
13591
14222
  predictedOutputs: false,
@@ -13596,13 +14227,13 @@ var MODEL_REGISTRY = {
13596
14227
  batchAPI: true,
13597
14228
  promptCaching: true,
13598
14229
  input: {
13599
- tokens: 1e6,
14230
+ tokens: 65536,
13600
14231
  text: true,
13601
14232
  image: true,
13602
14233
  cpm: 0.15
13603
14234
  },
13604
14235
  output: {
13605
- tokens: 65536,
14236
+ tokens: 32768,
13606
14237
  text: true,
13607
14238
  image: true,
13608
14239
  cpm: 0.6
@@ -13610,7 +14241,7 @@ var MODEL_REGISTRY = {
13610
14241
  }
13611
14242
  },
13612
14243
  // ============================================================================
13613
- // xAI Grok Models (Verified from docs.x.ai - January 2026)
14244
+ // xAI Grok Models (Verified from docs.x.ai - March 2026)
13614
14245
  // ============================================================================
13615
14246
  // Grok 4.1 Series (2M context, fast)
13616
14247
  "grok-4-1-fast-reasoning": {
@@ -13631,13 +14262,14 @@ var MODEL_REGISTRY = {
13631
14262
  vision: true,
13632
14263
  audio: false,
13633
14264
  video: false,
13634
- batchAPI: false,
13635
- promptCaching: false,
14265
+ batchAPI: true,
14266
+ promptCaching: true,
13636
14267
  input: {
13637
14268
  tokens: 2e6,
13638
14269
  text: true,
13639
14270
  image: true,
13640
- cpm: 0.2
14271
+ cpm: 0.2,
14272
+ cpmCached: 0.05
13641
14273
  },
13642
14274
  output: {
13643
14275
  tokens: 65536,
@@ -13664,13 +14296,14 @@ var MODEL_REGISTRY = {
13664
14296
  vision: true,
13665
14297
  audio: false,
13666
14298
  video: false,
13667
- batchAPI: false,
13668
- promptCaching: false,
14299
+ batchAPI: true,
14300
+ promptCaching: true,
13669
14301
  input: {
13670
14302
  tokens: 2e6,
13671
14303
  text: true,
13672
14304
  image: true,
13673
- cpm: 0.2
14305
+ cpm: 0.2,
14306
+ cpmCached: 0.05
13674
14307
  },
13675
14308
  output: {
13676
14309
  tokens: 65536,
@@ -13698,12 +14331,13 @@ var MODEL_REGISTRY = {
13698
14331
  vision: false,
13699
14332
  audio: false,
13700
14333
  video: false,
13701
- batchAPI: false,
13702
- promptCaching: false,
14334
+ batchAPI: true,
14335
+ promptCaching: true,
13703
14336
  input: {
13704
14337
  tokens: 256e3,
13705
14338
  text: true,
13706
- cpm: 0.2
14339
+ cpm: 0.2,
14340
+ cpmCached: 0.02
13707
14341
  },
13708
14342
  output: {
13709
14343
  tokens: 32768,
@@ -13716,7 +14350,7 @@ var MODEL_REGISTRY = {
13716
14350
  "grok-4-fast-reasoning": {
13717
14351
  name: "grok-4-fast-reasoning",
13718
14352
  provider: Vendor.Grok,
13719
- description: "Fast Grok 4 with reasoning capabilities, 2M context window",
14353
+ description: "Fast Grok 4 with reasoning capabilities, 2M context window, vision support",
13720
14354
  isActive: true,
13721
14355
  releaseDate: "2025-09-01",
13722
14356
  knowledgeCutoff: "2024-11-01",
@@ -13728,15 +14362,17 @@ var MODEL_REGISTRY = {
13728
14362
  fineTuning: false,
13729
14363
  predictedOutputs: false,
13730
14364
  realtime: false,
13731
- vision: false,
14365
+ vision: true,
13732
14366
  audio: false,
13733
14367
  video: false,
13734
- batchAPI: false,
13735
- promptCaching: false,
14368
+ batchAPI: true,
14369
+ promptCaching: true,
13736
14370
  input: {
13737
14371
  tokens: 2e6,
13738
14372
  text: true,
13739
- cpm: 0.2
14373
+ image: true,
14374
+ cpm: 0.2,
14375
+ cpmCached: 0.05
13740
14376
  },
13741
14377
  output: {
13742
14378
  tokens: 65536,
@@ -13763,13 +14399,14 @@ var MODEL_REGISTRY = {
13763
14399
  vision: true,
13764
14400
  audio: false,
13765
14401
  video: false,
13766
- batchAPI: false,
13767
- promptCaching: false,
14402
+ batchAPI: true,
14403
+ promptCaching: true,
13768
14404
  input: {
13769
14405
  tokens: 2e6,
13770
14406
  text: true,
13771
14407
  image: true,
13772
- cpm: 0.2
14408
+ cpm: 0.2,
14409
+ cpmCached: 0.05
13773
14410
  },
13774
14411
  output: {
13775
14412
  tokens: 65536,
@@ -13781,12 +14418,12 @@ var MODEL_REGISTRY = {
13781
14418
  "grok-4-0709": {
13782
14419
  name: "grok-4-0709",
13783
14420
  provider: Vendor.Grok,
13784
- description: "Grok 4 flagship model (July 2025 release), 256K context, vision support",
14421
+ description: "Grok 4 flagship model (July 2025 release), 256K context, vision support, reasoning",
13785
14422
  isActive: true,
13786
14423
  releaseDate: "2025-07-09",
13787
14424
  knowledgeCutoff: "2024-11-01",
13788
14425
  features: {
13789
- reasoning: false,
14426
+ reasoning: true,
13790
14427
  streaming: true,
13791
14428
  structuredOutput: true,
13792
14429
  functionCalling: true,
@@ -13796,13 +14433,14 @@ var MODEL_REGISTRY = {
13796
14433
  vision: true,
13797
14434
  audio: false,
13798
14435
  video: false,
13799
- batchAPI: false,
13800
- promptCaching: false,
14436
+ batchAPI: true,
14437
+ promptCaching: true,
13801
14438
  input: {
13802
14439
  tokens: 256e3,
13803
14440
  text: true,
13804
14441
  image: true,
13805
- cpm: 3
14442
+ cpm: 3,
14443
+ cpmCached: 0.75
13806
14444
  },
13807
14445
  output: {
13808
14446
  tokens: 32768,
@@ -13815,12 +14453,12 @@ var MODEL_REGISTRY = {
13815
14453
  "grok-3-mini": {
13816
14454
  name: "grok-3-mini",
13817
14455
  provider: Vendor.Grok,
13818
- description: "Lightweight, cost-efficient model for simpler tasks, 131K context",
14456
+ description: "Lightweight, cost-efficient model with reasoning, 131K context",
13819
14457
  isActive: true,
13820
14458
  releaseDate: "2025-06-01",
13821
14459
  knowledgeCutoff: "2024-11-01",
13822
14460
  features: {
13823
- reasoning: false,
14461
+ reasoning: true,
13824
14462
  streaming: true,
13825
14463
  structuredOutput: true,
13826
14464
  functionCalling: true,
@@ -13830,12 +14468,13 @@ var MODEL_REGISTRY = {
13830
14468
  vision: false,
13831
14469
  audio: false,
13832
14470
  video: false,
13833
- batchAPI: false,
13834
- promptCaching: false,
14471
+ batchAPI: true,
14472
+ promptCaching: true,
13835
14473
  input: {
13836
14474
  tokens: 131072,
13837
14475
  text: true,
13838
- cpm: 0.3
14476
+ cpm: 0.3,
14477
+ cpmCached: 0.07
13839
14478
  },
13840
14479
  output: {
13841
14480
  tokens: 32768,
@@ -13862,12 +14501,13 @@ var MODEL_REGISTRY = {
13862
14501
  vision: false,
13863
14502
  audio: false,
13864
14503
  video: false,
13865
- batchAPI: false,
13866
- promptCaching: false,
14504
+ batchAPI: true,
14505
+ promptCaching: true,
13867
14506
  input: {
13868
14507
  tokens: 131072,
13869
14508
  text: true,
13870
- cpm: 3
14509
+ cpm: 3,
14510
+ cpmCached: 0.75
13871
14511
  },
13872
14512
  output: {
13873
14513
  tokens: 32768,
@@ -13876,11 +14516,11 @@ var MODEL_REGISTRY = {
13876
14516
  }
13877
14517
  }
13878
14518
  },
13879
- // Grok 2 Series (Vision)
14519
+ // Grok 2 Series (Legacy - not in current docs)
13880
14520
  "grok-2-vision-1212": {
13881
14521
  name: "grok-2-vision-1212",
13882
14522
  provider: Vendor.Grok,
13883
- description: "Vision-capable model for image understanding, 32K context",
14523
+ description: "Legacy vision model for image understanding, 32K context. Not in current xAI docs",
13884
14524
  isActive: true,
13885
14525
  releaseDate: "2024-12-12",
13886
14526
  knowledgeCutoff: "2024-11-01",
@@ -17026,27 +17666,6 @@ ${formatValue(entry.value)}`).join("\n\n")
17026
17666
  // src/core/context-nextgen/plugins/ToolCatalogPluginNextGen.ts
17027
17667
  init_Logger();
17028
17668
  var DEFAULT_MAX_LOADED = 10;
17029
- var TOOL_CATALOG_INSTRUCTIONS = `## Tool Catalog
17030
-
17031
- You have access to a dynamic tool catalog. Not all tools are loaded at once \u2014 use these metatools to discover and load what you need:
17032
-
17033
- **tool_catalog_search** \u2014 Browse available tool categories and search for specific tools.
17034
- - No params \u2192 list all available categories with descriptions
17035
- - \`category\` \u2192 list tools in that category
17036
- - \`query\` \u2192 keyword search across categories and tools
17037
-
17038
- **tool_catalog_load** \u2014 Load a category's tools so you can use them.
17039
- - Tools become available immediately after loading.
17040
- - If you need tools from a category, load it first.
17041
-
17042
- **tool_catalog_unload** \u2014 Unload a category to free token budget.
17043
- - Unloaded tools are no longer sent to you.
17044
- - Use when you're done with a category.
17045
-
17046
- **Best practices:**
17047
- - Search first to find the right category before loading.
17048
- - Unload categories you no longer need to keep context lean.
17049
- - Categories marked [LOADED] are already available.`;
17050
17669
  var catalogSearchDefinition = {
17051
17670
  type: "function",
17052
17671
  function: {
@@ -17105,6 +17724,8 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17105
17724
  name = "tool_catalog";
17106
17725
  /** category name → array of tool names that were loaded */
17107
17726
  _loadedCategories = /* @__PURE__ */ new Map();
17727
+ /** Categories that cannot be unloaded */
17728
+ _pinnedCategories = /* @__PURE__ */ new Set();
17108
17729
  /** Reference to the ToolManager for registering/disabling tools */
17109
17730
  _toolManager = null;
17110
17731
  /** Cached connector categories — discovered once in setToolManager() */
@@ -17120,12 +17741,17 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17120
17741
  maxLoadedCategories: DEFAULT_MAX_LOADED,
17121
17742
  ...config
17122
17743
  };
17744
+ if (this._config.pinned?.length) {
17745
+ for (const cat of this._config.pinned) {
17746
+ this._pinnedCategories.add(cat);
17747
+ }
17748
+ }
17123
17749
  }
17124
17750
  // ========================================================================
17125
17751
  // Plugin Interface
17126
17752
  // ========================================================================
17127
17753
  getInstructions() {
17128
- return TOOL_CATALOG_INSTRUCTIONS;
17754
+ return this.buildInstructions();
17129
17755
  }
17130
17756
  async getContent() {
17131
17757
  const categories = this.getAllowedCategories();
@@ -17136,15 +17762,15 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17136
17762
  if (loaded.length > 0) {
17137
17763
  lines.push(`**Loaded:** ${loaded.join(", ")}`);
17138
17764
  }
17139
- lines.push(`**Available categories:** ${categories.length}`);
17765
+ lines.push(`**Available categories:** ${categories.length + this.getConnectorCategories().length}`);
17140
17766
  for (const cat of categories) {
17141
17767
  const tools = ToolCatalogRegistry.getToolsInCategory(cat.name);
17142
- const marker = this._loadedCategories.has(cat.name) ? " [LOADED]" : "";
17143
- lines.push(`- **${cat.displayName}** (${tools.length} tools)${marker}: ${cat.description}`);
17768
+ const markers = this.getCategoryMarkers(cat.name);
17769
+ lines.push(`- **${cat.displayName}** (${tools.length} tools)${markers}: ${cat.description}`);
17144
17770
  }
17145
17771
  for (const cc of this.getConnectorCategories()) {
17146
- const marker = this._loadedCategories.has(cc.name) ? " [LOADED]" : "";
17147
- lines.push(`- **${cc.displayName}** (${cc.toolCount} tools)${marker}: ${cc.description}`);
17772
+ const markers = this.getCategoryMarkers(cc.name);
17773
+ lines.push(`- **${cc.displayName}** (${cc.toolCount} tools)${markers}: ${cc.description}`);
17148
17774
  }
17149
17775
  const content = lines.join("\n");
17150
17776
  this.updateTokenCache(this.estimator.estimateTokens(content));
@@ -17155,7 +17781,8 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17155
17781
  loadedCategories: Array.from(this._loadedCategories.entries()).map(([name, tools]) => ({
17156
17782
  category: name,
17157
17783
  toolCount: tools.length,
17158
- tools
17784
+ tools,
17785
+ pinned: this._pinnedCategories.has(name)
17159
17786
  }))
17160
17787
  };
17161
17788
  }
@@ -17182,11 +17809,14 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17182
17809
  return [searchTool, loadTool, unloadTool];
17183
17810
  }
17184
17811
  isCompactable() {
17185
- return this._loadedCategories.size > 0;
17812
+ for (const category of this._loadedCategories.keys()) {
17813
+ if (!this._pinnedCategories.has(category)) return true;
17814
+ }
17815
+ return false;
17186
17816
  }
17187
17817
  async compact(targetTokensToFree) {
17188
17818
  if (!this._toolManager || this._loadedCategories.size === 0) return 0;
17189
- const categoriesByLastUsed = this.getCategoriesSortedByLastUsed();
17819
+ const categoriesByLastUsed = this.getCategoriesSortedByLastUsed().filter((cat) => !this._pinnedCategories.has(cat));
17190
17820
  let freed = 0;
17191
17821
  for (const category of categoriesByLastUsed) {
17192
17822
  if (freed >= targetTokensToFree) break;
@@ -17227,6 +17857,7 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17227
17857
  }
17228
17858
  destroy() {
17229
17859
  this._loadedCategories.clear();
17860
+ this._pinnedCategories.clear();
17230
17861
  this._toolManager = null;
17231
17862
  this._connectorCategories = null;
17232
17863
  this._destroyed = true;
@@ -17240,11 +17871,20 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17240
17871
  setToolManager(tm) {
17241
17872
  this._toolManager = tm;
17242
17873
  this._connectorCategories = ToolCatalogRegistry.discoverConnectorCategories({
17243
- scope: this._config.categoryScope,
17244
17874
  identities: this._config.identities
17245
17875
  });
17876
+ for (const category of this._pinnedCategories) {
17877
+ const result = this.executeLoad(category);
17878
+ if (result.error) {
17879
+ logger.warn(
17880
+ { category, error: result.error },
17881
+ `[ToolCatalogPlugin] Failed to load pinned category '${category}'`
17882
+ );
17883
+ }
17884
+ }
17246
17885
  if (this._config.autoLoadCategories?.length) {
17247
17886
  for (const category of this._config.autoLoadCategories) {
17887
+ if (this._pinnedCategories.has(category)) continue;
17248
17888
  const result = this.executeLoad(category);
17249
17889
  if (result.error) {
17250
17890
  logger.warn(
@@ -17259,6 +17899,10 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17259
17899
  get loadedCategories() {
17260
17900
  return Array.from(this._loadedCategories.keys());
17261
17901
  }
17902
+ /** Get set of pinned category names */
17903
+ get pinnedCategories() {
17904
+ return this._pinnedCategories;
17905
+ }
17262
17906
  // ========================================================================
17263
17907
  // Metatool Implementations
17264
17908
  // ========================================================================
@@ -17279,6 +17923,7 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17279
17923
  return {
17280
17924
  category,
17281
17925
  loaded,
17926
+ pinned: this._pinnedCategories.has(category),
17282
17927
  tools: tools.map((t) => ({
17283
17928
  name: t.name,
17284
17929
  displayName: t.displayName,
@@ -17300,7 +17945,8 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17300
17945
  displayName: cat.displayName,
17301
17946
  description: cat.description,
17302
17947
  toolCount: tools.length,
17303
- loaded: this._loadedCategories.has(cat.name)
17948
+ loaded: this._loadedCategories.has(cat.name),
17949
+ pinned: this._pinnedCategories.has(cat.name)
17304
17950
  });
17305
17951
  }
17306
17952
  for (const cc of connectorCats) {
@@ -17309,7 +17955,8 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17309
17955
  displayName: cc.displayName,
17310
17956
  description: cc.description,
17311
17957
  toolCount: cc.toolCount,
17312
- loaded: this._loadedCategories.has(cc.name)
17958
+ loaded: this._loadedCategories.has(cc.name),
17959
+ pinned: this._pinnedCategories.has(cc.name)
17313
17960
  });
17314
17961
  }
17315
17962
  return { categories: result };
@@ -17319,20 +17966,28 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17319
17966
  if (!this._toolManager) {
17320
17967
  return { error: "ToolManager not connected. Plugin not properly initialized." };
17321
17968
  }
17322
- if (!ToolCatalogRegistry.isCategoryAllowed(category, this._config.categoryScope)) {
17323
- return { error: `Category '${category}' is not available for this agent.` };
17969
+ const isConnector = ToolCatalogRegistry.parseConnectorCategory(category) !== null;
17970
+ if (isConnector) {
17971
+ const allowed = this.getConnectorCategories().some((cc) => cc.name === category);
17972
+ if (!allowed) {
17973
+ return { error: `Category '${category}' is not available for this agent.` };
17974
+ }
17975
+ } else {
17976
+ if (!ToolCatalogRegistry.isCategoryAllowed(category, this._config.categoryScope)) {
17977
+ return { error: `Category '${category}' is not available for this agent.` };
17978
+ }
17324
17979
  }
17325
17980
  if (this._loadedCategories.has(category)) {
17326
17981
  const toolNames2 = this._loadedCategories.get(category);
17327
17982
  return { loaded: toolNames2.length, tools: toolNames2, alreadyLoaded: true };
17328
17983
  }
17329
- if (this._loadedCategories.size >= this._config.maxLoadedCategories) {
17984
+ const nonPinnedLoaded = this._loadedCategories.size - this._pinnedCategories.size;
17985
+ if (!this._pinnedCategories.has(category) && nonPinnedLoaded >= this._config.maxLoadedCategories) {
17330
17986
  return {
17331
17987
  error: `Maximum loaded categories (${this._config.maxLoadedCategories}) reached. Unload a category first.`,
17332
17988
  loaded: Array.from(this._loadedCategories.keys())
17333
17989
  };
17334
17990
  }
17335
- const isConnector = ToolCatalogRegistry.parseConnectorCategory(category) !== null;
17336
17991
  let tools;
17337
17992
  if (isConnector) {
17338
17993
  tools = ToolCatalogRegistry.resolveConnectorCategoryTools(category);
@@ -17369,6 +18024,9 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17369
18024
  if (!this._toolManager) {
17370
18025
  return { error: "ToolManager not connected." };
17371
18026
  }
18027
+ if (this._pinnedCategories.has(category)) {
18028
+ return { error: `Category '${category}' is pinned and cannot be unloaded.` };
18029
+ }
17372
18030
  const toolNames = this._loadedCategories.get(category);
17373
18031
  if (!toolNames) {
17374
18032
  return { unloaded: 0, message: `Category '${category}' is not loaded.` };
@@ -17394,6 +18052,61 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17394
18052
  getConnectorCategories() {
17395
18053
  return this._connectorCategories ?? [];
17396
18054
  }
18055
+ /**
18056
+ * Build status markers for a category (e.g., " [PINNED]", " [LOADED]", " [PINNED] [LOADED]")
18057
+ */
18058
+ getCategoryMarkers(name) {
18059
+ const parts = [];
18060
+ if (this._pinnedCategories.has(name)) parts.push("[PINNED]");
18061
+ if (this._loadedCategories.has(name)) parts.push("[LOADED]");
18062
+ return parts.length > 0 ? " " + parts.join(" ") : "";
18063
+ }
18064
+ /**
18065
+ * Build dynamic instructions that include the list of available categories.
18066
+ */
18067
+ buildInstructions() {
18068
+ const lines = [];
18069
+ lines.push("## Tool Catalog");
18070
+ lines.push("");
18071
+ lines.push("Your core tools (memory, context, instructions, etc.) are always available.");
18072
+ lines.push("Additional tool categories can be loaded on demand from the catalog below.");
18073
+ lines.push("");
18074
+ lines.push("**tool_catalog_search** \u2014 Browse available tool categories and search for specific tools.");
18075
+ lines.push(" - No params \u2192 list all available categories with descriptions");
18076
+ lines.push(" - `category` \u2192 list tools in that category");
18077
+ lines.push(" - `query` \u2192 keyword search across categories and tools");
18078
+ lines.push("");
18079
+ lines.push("**tool_catalog_load** \u2014 Load a category's tools so you can use them.");
18080
+ lines.push(" - Tools become available immediately after loading.");
18081
+ lines.push(" - If you need tools from a category, load it first.");
18082
+ lines.push("");
18083
+ lines.push("**tool_catalog_unload** \u2014 Unload a category to free token budget.");
18084
+ lines.push(" - Unloaded tools are no longer sent to you.");
18085
+ lines.push(" - Use when you're done with a category.");
18086
+ lines.push(" - Pinned categories cannot be unloaded.");
18087
+ lines.push("");
18088
+ const builtIn = this.getAllowedCategories();
18089
+ const connectors = this.getConnectorCategories();
18090
+ if (builtIn.length > 0 || connectors.length > 0) {
18091
+ lines.push("**Available categories:**");
18092
+ for (const cat of builtIn) {
18093
+ const tools = ToolCatalogRegistry.getToolsInCategory(cat.name);
18094
+ const pinned = this._pinnedCategories.has(cat.name) ? " [PINNED]" : "";
18095
+ lines.push(`- ${cat.name} (${tools.length} tools)${pinned}: ${cat.description}`);
18096
+ }
18097
+ for (const cc of connectors) {
18098
+ const pinned = this._pinnedCategories.has(cc.name) ? " [PINNED]" : "";
18099
+ lines.push(`- ${cc.name} (${cc.toolCount} tools)${pinned}: ${cc.description}`);
18100
+ }
18101
+ lines.push("");
18102
+ }
18103
+ lines.push("**Best practices:**");
18104
+ lines.push("- Search first to find the right category before loading.");
18105
+ lines.push("- Unload categories you no longer need to keep context lean.");
18106
+ lines.push("- Categories marked [LOADED] are already available.");
18107
+ lines.push("- Categories marked [PINNED] are always available and cannot be unloaded.");
18108
+ return lines.join("\n");
18109
+ }
17397
18110
  keywordSearch(query) {
17398
18111
  const lq = query.toLowerCase();
17399
18112
  const results = [];
@@ -17431,12 +18144,17 @@ var ToolCatalogPluginNextGen = class extends BasePluginNextGen {
17431
18144
  return { query, results, totalMatches: results.length };
17432
18145
  }
17433
18146
  searchConnectorCategory(category) {
18147
+ const allowed = this.getConnectorCategories().some((cc) => cc.name === category);
18148
+ if (!allowed) {
18149
+ return { error: `Category '${category}' is not available for this agent.` };
18150
+ }
17434
18151
  const connectorName = ToolCatalogRegistry.parseConnectorCategory(category);
17435
18152
  const tools = ToolCatalogRegistry.resolveConnectorCategoryTools(category);
17436
18153
  const loaded = this._loadedCategories.has(category);
17437
18154
  return {
17438
18155
  category,
17439
18156
  loaded,
18157
+ pinned: this._pinnedCategories.has(category),
17440
18158
  connectorName,
17441
18159
  tools: tools.map((t) => ({
17442
18160
  name: t.name,
@@ -20185,6 +20903,9 @@ var StreamEventType = /* @__PURE__ */ ((StreamEventType2) => {
20185
20903
  StreamEventType2["REASONING_DONE"] = "response.reasoning.done";
20186
20904
  StreamEventType2["RESPONSE_COMPLETE"] = "response.complete";
20187
20905
  StreamEventType2["ERROR"] = "response.error";
20906
+ StreamEventType2["AUDIO_CHUNK_READY"] = "response.audio_chunk.ready";
20907
+ StreamEventType2["AUDIO_CHUNK_ERROR"] = "response.audio_chunk.error";
20908
+ StreamEventType2["AUDIO_STREAM_COMPLETE"] = "response.audio_stream.complete";
20188
20909
  return StreamEventType2;
20189
20910
  })(StreamEventType || {});
20190
20911
  function isStreamEvent(event, type) {
@@ -20214,6 +20935,15 @@ function isResponseComplete(event) {
20214
20935
  function isErrorEvent(event) {
20215
20936
  return event.type === "response.error" /* ERROR */;
20216
20937
  }
20938
+ function isAudioChunkReady(event) {
20939
+ return event.type === "response.audio_chunk.ready" /* AUDIO_CHUNK_READY */;
20940
+ }
20941
+ function isAudioChunkError(event) {
20942
+ return event.type === "response.audio_chunk.error" /* AUDIO_CHUNK_ERROR */;
20943
+ }
20944
+ function isAudioStreamComplete(event) {
20945
+ return event.type === "response.audio_stream.complete" /* AUDIO_STREAM_COMPLETE */;
20946
+ }
20217
20947
 
20218
20948
  // src/infrastructure/providers/openai/OpenAIResponsesStreamConverter.ts
20219
20949
  var OpenAIResponsesStreamConverter = class {
@@ -20523,9 +21253,17 @@ var OpenAITextProvider = class extends BaseTextProvider {
20523
21253
  ...options.metadata && { metadata: options.metadata }
20524
21254
  };
20525
21255
  this.applyReasoningConfig(params, options);
21256
+ console.log(
21257
+ `[OpenAITextProvider] generate: calling OpenAI API (model=${options.model}, tools=${params.tools?.length ?? 0})`
21258
+ );
21259
+ const genStartTime = Date.now();
20526
21260
  const response = await this.client.responses.create(params);
21261
+ console.log(
21262
+ `[OpenAITextProvider] generate: response received (${Date.now() - genStartTime}ms)`
21263
+ );
20527
21264
  return this.converter.convertResponse(response);
20528
21265
  } catch (error) {
21266
+ console.error(`[OpenAITextProvider] generate error (model=${options.model}):`, error.message || error);
20529
21267
  this.handleError(error, options.model);
20530
21268
  throw error;
20531
21269
  }
@@ -20565,9 +21303,27 @@ var OpenAITextProvider = class extends BaseTextProvider {
20565
21303
  stream: true
20566
21304
  };
20567
21305
  this.applyReasoningConfig(params, options);
21306
+ console.log(
21307
+ `[OpenAITextProvider] streamGenerate: calling OpenAI API (model=${options.model}, tools=${params.tools?.length ?? 0})`
21308
+ );
21309
+ const streamStartTime = Date.now();
20568
21310
  const stream = await this.client.responses.create(params);
20569
- yield* this.streamConverter.convertStream(stream);
21311
+ console.log(
21312
+ `[OpenAITextProvider] streamGenerate: OpenAI stream opened (${Date.now() - streamStartTime}ms)`
21313
+ );
21314
+ let chunkCount = 0;
21315
+ for await (const event of this.streamConverter.convertStream(stream)) {
21316
+ chunkCount++;
21317
+ yield event;
21318
+ }
21319
+ console.log(
21320
+ `[OpenAITextProvider] streamGenerate: stream complete (${chunkCount} events, ${Date.now() - streamStartTime}ms total)`
21321
+ );
20570
21322
  } catch (error) {
21323
+ console.error(
21324
+ `[OpenAITextProvider] streamGenerate error (model=${options.model}):`,
21325
+ error.message || error
21326
+ );
20571
21327
  this.handleError(error, options.model);
20572
21328
  throw error;
20573
21329
  }
@@ -21573,12 +22329,20 @@ var AnthropicTextProvider = class extends BaseTextProvider {
21573
22329
  return this.executeWithCircuitBreaker(async () => {
21574
22330
  try {
21575
22331
  const anthropicRequest = this.converter.convertRequest(options);
22332
+ console.log(
22333
+ `[AnthropicTextProvider] generate: calling Anthropic API (model=${options.model}, messages=${anthropicRequest.messages?.length ?? 0}, tools=${anthropicRequest.tools?.length ?? 0})`
22334
+ );
22335
+ const genStartTime = Date.now();
21576
22336
  const anthropicResponse = await this.client.messages.create({
21577
22337
  ...anthropicRequest,
21578
22338
  stream: false
21579
22339
  });
22340
+ console.log(
22341
+ `[AnthropicTextProvider] generate: response received (${Date.now() - genStartTime}ms)`
22342
+ );
21580
22343
  return this.converter.convertResponse(anthropicResponse);
21581
22344
  } catch (error) {
22345
+ console.error(`[AnthropicTextProvider] generate error (model=${options.model}):`, error.message || error);
21582
22346
  this.handleError(error, options.model);
21583
22347
  throw error;
21584
22348
  }
@@ -21590,13 +22354,31 @@ var AnthropicTextProvider = class extends BaseTextProvider {
21590
22354
  async *streamGenerate(options) {
21591
22355
  try {
21592
22356
  const anthropicRequest = this.converter.convertRequest(options);
22357
+ console.log(
22358
+ `[AnthropicTextProvider] streamGenerate: calling Anthropic API (model=${options.model}, messages=${anthropicRequest.messages?.length ?? 0}, tools=${anthropicRequest.tools?.length ?? 0})`
22359
+ );
22360
+ const streamStartTime = Date.now();
21593
22361
  const stream = await this.client.messages.create({
21594
22362
  ...anthropicRequest,
21595
22363
  stream: true
21596
22364
  });
22365
+ console.log(
22366
+ `[AnthropicTextProvider] streamGenerate: Anthropic stream opened (${Date.now() - streamStartTime}ms)`
22367
+ );
21597
22368
  this.streamConverter.reset();
21598
- yield* this.streamConverter.convertStream(stream, options.model);
22369
+ let chunkCount = 0;
22370
+ for await (const event of this.streamConverter.convertStream(stream, options.model)) {
22371
+ chunkCount++;
22372
+ yield event;
22373
+ }
22374
+ console.log(
22375
+ `[AnthropicTextProvider] streamGenerate: stream complete (${chunkCount} events, ${Date.now() - streamStartTime}ms total)`
22376
+ );
21599
22377
  } catch (error) {
22378
+ console.error(
22379
+ `[AnthropicTextProvider] streamGenerate error (model=${options.model}):`,
22380
+ error.message || error
22381
+ );
21600
22382
  this.handleError(error, options.model);
21601
22383
  throw error;
21602
22384
  } finally {
@@ -22390,6 +23172,10 @@ var GoogleTextProvider = class extends BaseTextProvider {
22390
23172
  // First message only
22391
23173
  }, null, 2));
22392
23174
  }
23175
+ console.log(
23176
+ `[GoogleTextProvider] generate: calling Google API (model=${options.model}, contents=${googleRequest.contents?.length ?? 0} messages, tools=${googleRequest.tools?.[0]?.functionDeclarations?.length ?? 0} tools)`
23177
+ );
23178
+ const genStartTime = Date.now();
22393
23179
  const result = await this.client.models.generateContent({
22394
23180
  model: options.model,
22395
23181
  contents: googleRequest.contents,
@@ -22400,6 +23186,9 @@ var GoogleTextProvider = class extends BaseTextProvider {
22400
23186
  ...googleRequest.generationConfig
22401
23187
  }
22402
23188
  });
23189
+ console.log(
23190
+ `[GoogleTextProvider] generate: response received (${Date.now() - genStartTime}ms)`
23191
+ );
22403
23192
  if (process.env.DEBUG_GOOGLE) {
22404
23193
  console.error("[DEBUG] Google Response:", JSON.stringify({
22405
23194
  candidates: result.candidates?.map((c) => ({
@@ -22418,6 +23207,7 @@ var GoogleTextProvider = class extends BaseTextProvider {
22418
23207
  }
22419
23208
  return response;
22420
23209
  } catch (error) {
23210
+ console.error(`[GoogleTextProvider] generate error (model=${options.model}):`, error.message || error);
22421
23211
  this.converter.clearMappings();
22422
23212
  this.handleError(error, options.model);
22423
23213
  throw error;
@@ -22430,6 +23220,10 @@ var GoogleTextProvider = class extends BaseTextProvider {
22430
23220
  async *streamGenerate(options) {
22431
23221
  try {
22432
23222
  const googleRequest = await this.converter.convertRequest(options);
23223
+ console.log(
23224
+ `[GoogleTextProvider] streamGenerate: calling Google API (model=${options.model}, contents=${googleRequest.contents?.length ?? 0} messages, tools=${googleRequest.tools?.[0]?.functionDeclarations?.length ?? 0} tools)`
23225
+ );
23226
+ const streamStartTime = Date.now();
22433
23227
  const stream = await this.client.models.generateContentStream({
22434
23228
  model: options.model,
22435
23229
  contents: googleRequest.contents,
@@ -22440,13 +23234,27 @@ var GoogleTextProvider = class extends BaseTextProvider {
22440
23234
  ...googleRequest.generationConfig
22441
23235
  }
22442
23236
  });
23237
+ console.log(
23238
+ `[GoogleTextProvider] streamGenerate: Google stream opened (${Date.now() - streamStartTime}ms)`
23239
+ );
22443
23240
  this.streamConverter.reset();
22444
- yield* this.streamConverter.convertStream(stream, options.model);
23241
+ let chunkCount = 0;
23242
+ for await (const event of this.streamConverter.convertStream(stream, options.model)) {
23243
+ chunkCount++;
23244
+ yield event;
23245
+ }
23246
+ console.log(
23247
+ `[GoogleTextProvider] streamGenerate: stream complete (${chunkCount} events, ${Date.now() - streamStartTime}ms total)`
23248
+ );
22445
23249
  if (!this.streamConverter.hasToolCalls()) {
22446
23250
  this.converter.clearMappings();
22447
23251
  this.streamConverter.clear();
22448
23252
  }
22449
23253
  } catch (error) {
23254
+ console.error(
23255
+ `[GoogleTextProvider] streamGenerate error (model=${options.model}):`,
23256
+ error.message || error
23257
+ );
22450
23258
  this.converter.clearMappings();
22451
23259
  this.streamConverter.clear();
22452
23260
  this.handleError(error, options.model);
@@ -22533,6 +23341,10 @@ var VertexAITextProvider = class extends BaseTextProvider {
22533
23341
  async generate(options) {
22534
23342
  try {
22535
23343
  const googleRequest = await this.converter.convertRequest(options);
23344
+ console.log(
23345
+ `[VertexAITextProvider] generate: calling Vertex AI (model=${options.model}, contents=${googleRequest.contents?.length ?? 0} messages, tools=${googleRequest.tools?.[0]?.functionDeclarations?.length ?? 0} tools)`
23346
+ );
23347
+ const genStartTime = Date.now();
22536
23348
  const result = await this.client.models.generateContent({
22537
23349
  model: options.model,
22538
23350
  contents: googleRequest.contents,
@@ -22543,8 +23355,12 @@ var VertexAITextProvider = class extends BaseTextProvider {
22543
23355
  ...googleRequest.generationConfig
22544
23356
  }
22545
23357
  });
23358
+ console.log(
23359
+ `[VertexAITextProvider] generate: response received (${Date.now() - genStartTime}ms)`
23360
+ );
22546
23361
  return this.converter.convertResponse(result);
22547
23362
  } catch (error) {
23363
+ console.error(`[VertexAITextProvider] generate error (model=${options.model}):`, error.message || error);
22548
23364
  this.handleError(error, options.model);
22549
23365
  throw error;
22550
23366
  }
@@ -22555,6 +23371,10 @@ var VertexAITextProvider = class extends BaseTextProvider {
22555
23371
  async *streamGenerate(options) {
22556
23372
  try {
22557
23373
  const googleRequest = await this.converter.convertRequest(options);
23374
+ console.log(
23375
+ `[VertexAITextProvider] streamGenerate: calling Vertex AI (model=${options.model}, contents=${googleRequest.contents?.length ?? 0} messages, tools=${googleRequest.tools?.[0]?.functionDeclarations?.length ?? 0} tools)`
23376
+ );
23377
+ const streamStartTime = Date.now();
22558
23378
  const stream = await this.client.models.generateContentStream({
22559
23379
  model: options.model,
22560
23380
  contents: googleRequest.contents,
@@ -22565,9 +23385,23 @@ var VertexAITextProvider = class extends BaseTextProvider {
22565
23385
  ...googleRequest.generationConfig
22566
23386
  }
22567
23387
  });
23388
+ console.log(
23389
+ `[VertexAITextProvider] streamGenerate: Vertex AI stream opened (${Date.now() - streamStartTime}ms)`
23390
+ );
22568
23391
  const streamConverter = new GoogleStreamConverter();
22569
- yield* streamConverter.convertStream(stream, options.model);
23392
+ let chunkCount = 0;
23393
+ for await (const event of streamConverter.convertStream(stream, options.model)) {
23394
+ chunkCount++;
23395
+ yield event;
23396
+ }
23397
+ console.log(
23398
+ `[VertexAITextProvider] streamGenerate: stream complete (${chunkCount} events, ${Date.now() - streamStartTime}ms total)`
23399
+ );
22570
23400
  } catch (error) {
23401
+ console.error(
23402
+ `[VertexAITextProvider] streamGenerate error (model=${options.model}):`,
23403
+ error.message || error
23404
+ );
22571
23405
  this.handleError(error, options.model);
22572
23406
  throw error;
22573
23407
  }
@@ -24508,6 +25342,20 @@ var Agent = class _Agent extends BaseAgent {
24508
25342
  timestamp: /* @__PURE__ */ new Date(),
24509
25343
  duration: totalDuration
24510
25344
  });
25345
+ const hasTextOutput = response.output_text?.trim() || response.output?.some(
25346
+ (item) => "content" in item && Array.isArray(item.content) && item.content.some((c) => c.type === "output_text" /* OUTPUT_TEXT */ && c.text?.trim())
25347
+ );
25348
+ if (!hasTextOutput) {
25349
+ console.warn(
25350
+ `[Agent] WARNING: ${methodName} completed with zero text output (executionId=${executionId}, iterations=${this.executionContext?.metrics.iterationCount ?? "?"}, tokens=${response.usage?.total_tokens ?? 0})`
25351
+ );
25352
+ this.emit("execution:empty_output", {
25353
+ executionId,
25354
+ timestamp: /* @__PURE__ */ new Date(),
25355
+ duration: totalDuration,
25356
+ usage: response.usage
25357
+ });
25358
+ }
24511
25359
  const duration = Date.now() - startTime;
24512
25360
  this._logger.info({ duration }, `Agent ${methodName} completed`);
24513
25361
  metrics.timing(`agent.${methodName}.duration`, duration, { model: this.model, connector: this.connector.name });
@@ -24562,6 +25410,17 @@ var Agent = class _Agent extends BaseAgent {
24562
25410
  }
24563
25411
  const iterationStartTime = Date.now();
24564
25412
  const prepared = await this._agentContext.prepare();
25413
+ const b1 = prepared.budget;
25414
+ const bd1 = b1.breakdown;
25415
+ const bp1 = [
25416
+ `sysPrompt=${bd1.systemPrompt}`,
25417
+ `PI=${bd1.persistentInstructions}`,
25418
+ bd1.pluginInstructions ? `pluginInstr=${bd1.pluginInstructions}` : "",
25419
+ ...Object.entries(bd1.pluginContents || {}).map(([k, v]) => `plugin:${k}=${v}`)
25420
+ ].filter(Boolean).join(" ");
25421
+ console.log(
25422
+ `[Agent] [Context] iteration=${iteration} tokens: ${b1.totalUsed}/${b1.maxTokens} (${b1.utilizationPercent.toFixed(1)}%) tools=${b1.toolsTokens} conversation=${b1.conversationTokens} system=${b1.systemMessageTokens} input=${b1.currentInputTokens}` + (bp1 ? ` | ${bp1}` : "") + (prepared.compacted ? ` COMPACTED: ${prepared.compactionLog.join("; ")}` : "")
25423
+ );
24565
25424
  const response = await this.generateWithHooks(prepared.input, iteration, executionId);
24566
25425
  const toolCalls = this.extractToolCalls(response.output);
24567
25426
  this._agentContext.addAssistantResponse(response.output);
@@ -24676,13 +25535,23 @@ var Agent = class _Agent extends BaseAgent {
24676
25535
  * Build placeholder response for streaming finalization
24677
25536
  */
24678
25537
  _buildPlaceholderResponse(executionId, startTime, streamState) {
25538
+ const outputText = streamState.getAllText();
25539
+ const output = [];
25540
+ if (outputText && outputText.trim()) {
25541
+ output.push({
25542
+ type: "message",
25543
+ role: "assistant" /* ASSISTANT */,
25544
+ content: [{ type: "output_text" /* OUTPUT_TEXT */, text: outputText }]
25545
+ });
25546
+ }
24679
25547
  return {
24680
25548
  id: executionId,
24681
25549
  object: "response",
24682
25550
  created_at: Math.floor(startTime / 1e3),
24683
25551
  status: "completed",
24684
25552
  model: this.model,
24685
- output: [],
25553
+ output,
25554
+ output_text: outputText || void 0,
24686
25555
  usage: streamState.usage
24687
25556
  };
24688
25557
  }
@@ -24702,6 +25571,17 @@ var Agent = class _Agent extends BaseAgent {
24702
25571
  break;
24703
25572
  }
24704
25573
  const prepared = await this._agentContext.prepare();
25574
+ const b2 = prepared.budget;
25575
+ const bd2 = b2.breakdown;
25576
+ const bp2 = [
25577
+ `sysPrompt=${bd2.systemPrompt}`,
25578
+ `PI=${bd2.persistentInstructions}`,
25579
+ bd2.pluginInstructions ? `pluginInstr=${bd2.pluginInstructions}` : "",
25580
+ ...Object.entries(bd2.pluginContents || {}).map(([k, v]) => `plugin:${k}=${v}`)
25581
+ ].filter(Boolean).join(" ");
25582
+ console.log(
25583
+ `[Agent] [Context] iteration=${iteration} tokens: ${b2.totalUsed}/${b2.maxTokens} (${b2.utilizationPercent.toFixed(1)}%) tools=${b2.toolsTokens} conversation=${b2.conversationTokens} system=${b2.systemMessageTokens} input=${b2.currentInputTokens}` + (bp2 ? ` | ${bp2}` : "") + (prepared.compacted ? ` COMPACTED: ${prepared.compactionLog.join("; ")}` : "")
25584
+ );
24705
25585
  const iterationStreamState = new StreamState(executionId, this.model);
24706
25586
  const toolCallsMap = /* @__PURE__ */ new Map();
24707
25587
  yield* this.streamGenerateWithHooks(
@@ -33371,6 +34251,56 @@ var OpenAITTSProvider = class extends BaseMediaProvider {
33371
34251
  { model: options.model, voice: options.voice }
33372
34252
  );
33373
34253
  }
34254
+ /**
34255
+ * Check if streaming is supported for the given format
34256
+ */
34257
+ supportsStreaming(format) {
34258
+ if (!format) return true;
34259
+ return ["pcm", "wav", "mp3", "opus", "aac", "flac"].includes(format);
34260
+ }
34261
+ /**
34262
+ * Stream TTS audio chunks as they arrive from the API
34263
+ */
34264
+ async *synthesizeStream(options) {
34265
+ const format = this.mapFormat(options.format);
34266
+ const requestParams = {
34267
+ model: options.model,
34268
+ input: options.input,
34269
+ voice: options.voice,
34270
+ response_format: format,
34271
+ speed: options.speed
34272
+ };
34273
+ if (options.vendorOptions?.instructions) {
34274
+ requestParams.instructions = options.vendorOptions.instructions;
34275
+ }
34276
+ this.logOperationStart("tts.synthesizeStream", {
34277
+ model: options.model,
34278
+ voice: options.voice,
34279
+ inputLength: options.input.length,
34280
+ format
34281
+ });
34282
+ try {
34283
+ const response = await this.client.audio.speech.create(requestParams);
34284
+ const body = response.body;
34285
+ if (!body) {
34286
+ throw new Error("No response body from OpenAI TTS API");
34287
+ }
34288
+ let totalBytes = 0;
34289
+ for await (const chunk of body) {
34290
+ const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
34291
+ totalBytes += buf.length;
34292
+ yield { audio: buf, isFinal: false };
34293
+ }
34294
+ yield { audio: Buffer.alloc(0), isFinal: true };
34295
+ this.logOperationComplete("tts.synthesizeStream", {
34296
+ model: options.model,
34297
+ totalBytes
34298
+ });
34299
+ } catch (error) {
34300
+ this.handleError(error);
34301
+ throw error;
34302
+ }
34303
+ }
33374
34304
  /**
33375
34305
  * List available voices (returns static list for OpenAI)
33376
34306
  */
@@ -33972,13 +34902,13 @@ var TTS_MODEL_REGISTRY = {
33972
34902
  name: "gemini-2.5-flash-preview-tts",
33973
34903
  displayName: "Gemini 2.5 Flash TTS",
33974
34904
  provider: Vendor.Google,
33975
- description: "Google Gemini 2.5 Flash TTS - optimized for low latency",
34905
+ description: "Google Gemini 2.5 Flash TTS - optimized for low latency, 30 voices, 70+ languages",
33976
34906
  isActive: true,
33977
34907
  releaseDate: "2025-01-01",
33978
34908
  sources: {
33979
34909
  documentation: "https://ai.google.dev/gemini-api/docs/speech-generation",
33980
34910
  pricing: "https://ai.google.dev/pricing",
33981
- lastVerified: "2026-01-25"
34911
+ lastVerified: "2026-03-04"
33982
34912
  },
33983
34913
  capabilities: {
33984
34914
  voices: GEMINI_VOICES,
@@ -33997,20 +34927,27 @@ var TTS_MODEL_REGISTRY = {
33997
34927
  wordTimestamps: false
33998
34928
  },
33999
34929
  limits: { maxInputLength: 32e3 }
34000
- // 32k tokens
34930
+ // 32k token context window
34931
+ },
34932
+ pricing: {
34933
+ perMInputTokens: 0.5,
34934
+ // $0.50 per 1M input tokens
34935
+ perMOutputTokens: 10,
34936
+ // $10.00 per 1M output tokens
34937
+ currency: "USD"
34001
34938
  }
34002
34939
  },
34003
34940
  "gemini-2.5-pro-preview-tts": {
34004
34941
  name: "gemini-2.5-pro-preview-tts",
34005
34942
  displayName: "Gemini 2.5 Pro TTS",
34006
34943
  provider: Vendor.Google,
34007
- description: "Google Gemini 2.5 Pro TTS - optimized for quality",
34944
+ description: "Google Gemini 2.5 Pro TTS - optimized for quality, 30 voices, 70+ languages",
34008
34945
  isActive: true,
34009
34946
  releaseDate: "2025-01-01",
34010
34947
  sources: {
34011
34948
  documentation: "https://ai.google.dev/gemini-api/docs/speech-generation",
34012
34949
  pricing: "https://ai.google.dev/pricing",
34013
- lastVerified: "2026-01-25"
34950
+ lastVerified: "2026-03-04"
34014
34951
  },
34015
34952
  capabilities: {
34016
34953
  voices: GEMINI_VOICES,
@@ -34029,7 +34966,14 @@ var TTS_MODEL_REGISTRY = {
34029
34966
  wordTimestamps: false
34030
34967
  },
34031
34968
  limits: { maxInputLength: 32e3 }
34032
- // 32k tokens
34969
+ // 32k token context window
34970
+ },
34971
+ pricing: {
34972
+ perMInputTokens: 1,
34973
+ // $1.00 per 1M input tokens
34974
+ perMOutputTokens: 20,
34975
+ // $20.00 per 1M output tokens
34976
+ currency: "USD"
34033
34977
  }
34034
34978
  }
34035
34979
  };
@@ -34042,10 +34986,18 @@ function getTTSModelsWithFeature(feature) {
34042
34986
  (model) => model.isActive && model.capabilities.features[feature]
34043
34987
  );
34044
34988
  }
34045
- function calculateTTSCost(modelName, characterCount) {
34989
+ function calculateTTSCost(modelName, characterCount, options) {
34046
34990
  const model = getTTSModelInfo(modelName);
34047
34991
  if (!model?.pricing) return null;
34048
- return characterCount / 1e3 * model.pricing.per1kCharacters;
34992
+ if (model.pricing.per1kCharacters) {
34993
+ return characterCount / 1e3 * model.pricing.per1kCharacters;
34994
+ }
34995
+ if (model.pricing.perMInputTokens && options?.inputTokens != null) {
34996
+ const inputCost = options.inputTokens / 1e6 * model.pricing.perMInputTokens;
34997
+ const outputCost = options.outputTokens ? options.outputTokens / 1e6 * (model.pricing.perMOutputTokens ?? 0) : 0;
34998
+ return inputCost + outputCost;
34999
+ }
35000
+ return null;
34049
35001
  }
34050
35002
  var TextToSpeech = class _TextToSpeech {
34051
35003
  provider;
@@ -34091,6 +35043,35 @@ var TextToSpeech = class _TextToSpeech {
34091
35043
  const response = await this.synthesize(text, options);
34092
35044
  await fs17.writeFile(filePath, response.audio);
34093
35045
  }
35046
+ // ======================== Streaming Methods ========================
35047
+ /**
35048
+ * Check if the underlying provider supports streaming TTS
35049
+ */
35050
+ supportsStreaming(format) {
35051
+ const provider = this.provider;
35052
+ return typeof provider.supportsStreaming === "function" && provider.supportsStreaming(format);
35053
+ }
35054
+ /**
35055
+ * Stream TTS audio chunks as they arrive from the API.
35056
+ * Falls back to buffered synthesis yielding a single chunk if provider doesn't support streaming.
35057
+ */
35058
+ async *synthesizeStream(text, options) {
35059
+ const fullOptions = {
35060
+ model: this.config.model ?? this.getDefaultModel(),
35061
+ input: text,
35062
+ voice: options?.voice ?? this.config.voice ?? this.getDefaultVoice(),
35063
+ format: options?.format ?? this.config.format,
35064
+ speed: options?.speed ?? this.config.speed,
35065
+ vendorOptions: options?.vendorOptions
35066
+ };
35067
+ const provider = this.provider;
35068
+ if (typeof provider.synthesizeStream === "function" && provider.supportsStreaming?.(fullOptions.format)) {
35069
+ yield* provider.synthesizeStream(fullOptions);
35070
+ } else {
35071
+ const response = await this.provider.synthesize(fullOptions);
35072
+ yield { audio: response.audio, isFinal: true };
35073
+ }
35074
+ }
34094
35075
  // ======================== Introspection Methods ========================
34095
35076
  /**
34096
35077
  * Get model information for current or specified model
@@ -35491,7 +36472,13 @@ var IMAGE_MODELS = {
35491
36472
  /** Imagen 4.0 Ultra: Highest quality */
35492
36473
  IMAGEN_4_ULTRA: "imagen-4.0-ultra-generate-001",
35493
36474
  /** Imagen 4.0 Fast: Optimized for speed */
35494
- IMAGEN_4_FAST: "imagen-4.0-fast-generate-001"
36475
+ IMAGEN_4_FAST: "imagen-4.0-fast-generate-001",
36476
+ /** Nano Banana 2: Gemini 3.1 Flash native image gen with 4K support */
36477
+ GEMINI_3_1_FLASH_IMAGE: "gemini-3.1-flash-image-preview",
36478
+ /** Nano Banana Pro: Gemini 3 Pro professional design engine with reasoning */
36479
+ GEMINI_3_PRO_IMAGE: "gemini-3-pro-image-preview",
36480
+ /** Nano Banana: Gemini 2.5 Flash native image gen/editing */
36481
+ GEMINI_2_5_FLASH_IMAGE: "gemini-2.5-flash-image"
35495
36482
  },
35496
36483
  [Vendor.Grok]: {
35497
36484
  /** Grok Imagine Image: xAI image generation with editing support */
@@ -35675,7 +36662,7 @@ var IMAGE_MODEL_REGISTRY = {
35675
36662
  sources: {
35676
36663
  documentation: "https://ai.google.dev/gemini-api/docs/imagen",
35677
36664
  pricing: "https://ai.google.dev/pricing",
35678
- lastVerified: "2026-01-25"
36665
+ lastVerified: "2026-03-04"
35679
36666
  },
35680
36667
  capabilities: {
35681
36668
  sizes: ["1024x1024"],
@@ -35786,7 +36773,7 @@ var IMAGE_MODEL_REGISTRY = {
35786
36773
  sources: {
35787
36774
  documentation: "https://ai.google.dev/gemini-api/docs/imagen",
35788
36775
  pricing: "https://ai.google.dev/pricing",
35789
- lastVerified: "2026-01-25"
36776
+ lastVerified: "2026-03-04"
35790
36777
  },
35791
36778
  capabilities: {
35792
36779
  sizes: ["1024x1024"],
@@ -35883,7 +36870,8 @@ var IMAGE_MODEL_REGISTRY = {
35883
36870
  }
35884
36871
  },
35885
36872
  pricing: {
35886
- perImage: 0.08,
36873
+ perImage: 0.06,
36874
+ // Updated per official pricing page (was $0.08)
35887
36875
  currency: "USD"
35888
36876
  }
35889
36877
  },
@@ -35897,7 +36885,7 @@ var IMAGE_MODEL_REGISTRY = {
35897
36885
  sources: {
35898
36886
  documentation: "https://ai.google.dev/gemini-api/docs/imagen",
35899
36887
  pricing: "https://ai.google.dev/pricing",
35900
- lastVerified: "2026-01-25"
36888
+ lastVerified: "2026-03-04"
35901
36889
  },
35902
36890
  capabilities: {
35903
36891
  sizes: ["1024x1024"],
@@ -35998,6 +36986,141 @@ var IMAGE_MODEL_REGISTRY = {
35998
36986
  currency: "USD"
35999
36987
  }
36000
36988
  },
36989
+ // ======================== Google Nano Banana (Gemini Native Image) ========================
36990
+ "gemini-3.1-flash-image-preview": {
36991
+ name: "gemini-3.1-flash-image-preview",
36992
+ displayName: "Nano Banana 2 (Gemini 3.1 Flash Image)",
36993
+ provider: Vendor.Google,
36994
+ description: "High-efficiency native image generation and editing with 4K support and thinking capabilities",
36995
+ isActive: true,
36996
+ releaseDate: "2026-02-01",
36997
+ sources: {
36998
+ documentation: "https://ai.google.dev/gemini-api/docs/models/gemini-3.1-flash-image-preview",
36999
+ pricing: "https://ai.google.dev/pricing",
37000
+ lastVerified: "2026-03-04"
37001
+ },
37002
+ capabilities: {
37003
+ sizes: ["512x512", "1024x1024", "1536x1536", "auto"],
37004
+ aspectRatios: ["1:1", "1:4", "4:1", "1:8", "8:1"],
37005
+ maxImagesPerRequest: 4,
37006
+ outputFormats: ["png", "jpeg"],
37007
+ features: {
37008
+ generation: true,
37009
+ editing: true,
37010
+ variations: false,
37011
+ styleControl: false,
37012
+ qualityControl: true,
37013
+ // Multiple resolution tiers: 0.5K, 1K, 2K, 4K
37014
+ transparency: false,
37015
+ promptRevision: false
37016
+ },
37017
+ limits: { maxPromptLength: 131072 },
37018
+ // 131K input tokens
37019
+ vendorOptions: {
37020
+ outputImageResolution: {
37021
+ type: "enum",
37022
+ label: "Resolution",
37023
+ description: "Output image resolution tier",
37024
+ enum: ["0.5K", "1K", "2K", "4K"],
37025
+ default: "1K",
37026
+ controlType: "select"
37027
+ }
37028
+ }
37029
+ },
37030
+ pricing: {
37031
+ // Per-image, varies by resolution: $0.045 (512px), $0.067 (1K), $0.101 (2K), $0.151 (4K)
37032
+ perImageStandard: 0.067,
37033
+ // 1K default
37034
+ perImageHD: 0.151,
37035
+ // 4K
37036
+ currency: "USD"
37037
+ }
37038
+ },
37039
+ "gemini-3-pro-image-preview": {
37040
+ name: "gemini-3-pro-image-preview",
37041
+ displayName: "Nano Banana Pro (Gemini 3 Pro Image)",
37042
+ provider: Vendor.Google,
37043
+ description: "Professional design engine with reasoning for studio-quality 4K visuals, complex layouts, and precise text rendering",
37044
+ isActive: true,
37045
+ releaseDate: "2025-11-01",
37046
+ sources: {
37047
+ documentation: "https://ai.google.dev/gemini-api/docs/models/gemini-3-pro-image-preview",
37048
+ pricing: "https://ai.google.dev/pricing",
37049
+ lastVerified: "2026-03-04"
37050
+ },
37051
+ capabilities: {
37052
+ sizes: ["1024x1024", "auto"],
37053
+ aspectRatios: ["1:1", "3:4", "4:3", "9:16", "16:9"],
37054
+ maxImagesPerRequest: 4,
37055
+ outputFormats: ["png", "jpeg"],
37056
+ features: {
37057
+ generation: true,
37058
+ editing: true,
37059
+ variations: false,
37060
+ styleControl: true,
37061
+ // Reasoning-driven design
37062
+ qualityControl: true,
37063
+ // 1K, 2K, 4K tiers
37064
+ transparency: false,
37065
+ promptRevision: false
37066
+ },
37067
+ limits: { maxPromptLength: 65536 },
37068
+ // 65K input tokens
37069
+ vendorOptions: {
37070
+ outputImageResolution: {
37071
+ type: "enum",
37072
+ label: "Resolution",
37073
+ description: "Output image resolution tier",
37074
+ enum: ["1K", "2K", "4K"],
37075
+ default: "1K",
37076
+ controlType: "select"
37077
+ }
37078
+ }
37079
+ },
37080
+ pricing: {
37081
+ // $0.134 per 1K/2K image, $0.24 per 4K image
37082
+ perImageStandard: 0.134,
37083
+ // 1K/2K
37084
+ perImageHD: 0.24,
37085
+ // 4K
37086
+ currency: "USD"
37087
+ }
37088
+ },
37089
+ "gemini-2.5-flash-image": {
37090
+ name: "gemini-2.5-flash-image",
37091
+ displayName: "Nano Banana (Gemini 2.5 Flash Image)",
37092
+ provider: Vendor.Google,
37093
+ description: "Native image generation and editing designed for fast, creative workflows",
37094
+ isActive: true,
37095
+ releaseDate: "2025-10-01",
37096
+ sources: {
37097
+ documentation: "https://ai.google.dev/gemini-api/docs/models/gemini-2.5-flash-image",
37098
+ pricing: "https://ai.google.dev/pricing",
37099
+ lastVerified: "2026-03-04"
37100
+ },
37101
+ capabilities: {
37102
+ sizes: ["1024x1024", "auto"],
37103
+ aspectRatios: ["1:1", "3:4", "4:3", "9:16", "16:9"],
37104
+ maxImagesPerRequest: 4,
37105
+ outputFormats: ["png", "jpeg"],
37106
+ features: {
37107
+ generation: true,
37108
+ editing: true,
37109
+ variations: false,
37110
+ styleControl: false,
37111
+ qualityControl: false,
37112
+ transparency: false,
37113
+ promptRevision: false
37114
+ },
37115
+ limits: { maxPromptLength: 65536 }
37116
+ // 65K input tokens
37117
+ },
37118
+ pricing: {
37119
+ perImage: 0.039,
37120
+ // $0.039 per image
37121
+ currency: "USD"
37122
+ }
37123
+ },
36001
37124
  // ======================== xAI Grok ========================
36002
37125
  "grok-imagine-image": {
36003
37126
  name: "grok-imagine-image",
@@ -36009,11 +37132,11 @@ var IMAGE_MODEL_REGISTRY = {
36009
37132
  sources: {
36010
37133
  documentation: "https://docs.x.ai/docs/guides/image-generation",
36011
37134
  pricing: "https://docs.x.ai/docs/models",
36012
- lastVerified: "2026-02-01"
37135
+ lastVerified: "2026-03-04"
36013
37136
  },
36014
37137
  capabilities: {
36015
37138
  sizes: ["1024x1024"],
36016
- aspectRatios: ["1:1", "4:3", "3:4", "16:9", "9:16", "3:2", "2:3"],
37139
+ aspectRatios: ["1:1", "4:3", "3:4", "16:9", "9:16", "3:2", "2:3", "2:1", "1:2"],
36017
37140
  maxImagesPerRequest: 10,
36018
37141
  outputFormats: ["png", "jpeg"],
36019
37142
  features: {
@@ -37269,9 +38392,9 @@ var OPENAI_SOURCES = {
37269
38392
  lastVerified: "2026-01-25"
37270
38393
  };
37271
38394
  var GOOGLE_SOURCES = {
37272
- documentation: "https://docs.cloud.google.com/vertex-ai/generative-ai/docs/video/overview",
37273
- apiReference: "https://docs.cloud.google.com/vertex-ai/generative-ai/docs/model-reference/veo-video-generation",
37274
- lastVerified: "2026-01-25"
38395
+ documentation: "https://ai.google.dev/gemini-api/docs/video",
38396
+ apiReference: "https://ai.google.dev/gemini-api/docs/models/veo",
38397
+ lastVerified: "2026-03-04"
37275
38398
  };
37276
38399
  var GROK_SOURCES = {
37277
38400
  documentation: "https://docs.x.ai/docs/guides/video-generations",
@@ -37345,14 +38468,16 @@ var VIDEO_MODEL_REGISTRY = {
37345
38468
  sources: GOOGLE_SOURCES,
37346
38469
  capabilities: {
37347
38470
  durations: [5, 6, 7, 8],
37348
- resolutions: [],
37349
- // Veo 2.0 uses aspectRatio only, no resolution control
38471
+ resolutions: ["720p"],
38472
+ // Veo 2 only supports 720p
37350
38473
  aspectRatios: ["16:9", "9:16"],
37351
38474
  maxFps: 24,
37352
38475
  audio: false,
37353
- imageToVideo: true,
38476
+ imageToVideo: false,
38477
+ // Veo 2 does not support reference images
37354
38478
  videoExtension: false,
37355
38479
  frameControl: true,
38480
+ // First/last frame interpolation supported
37356
38481
  features: {
37357
38482
  upscaling: false,
37358
38483
  styleControl: false,
@@ -37361,7 +38486,8 @@ var VIDEO_MODEL_REGISTRY = {
37361
38486
  }
37362
38487
  },
37363
38488
  pricing: {
37364
- perSecond: 0.03,
38489
+ perSecond: 0.35,
38490
+ // Updated per official pricing page (was $0.03)
37365
38491
  currency: "USD"
37366
38492
  }
37367
38493
  },
@@ -37373,14 +38499,18 @@ var VIDEO_MODEL_REGISTRY = {
37373
38499
  sources: GOOGLE_SOURCES,
37374
38500
  capabilities: {
37375
38501
  durations: [4, 6, 8],
37376
- resolutions: ["720p"],
37377
- // Fast model only supports 720p
38502
+ resolutions: ["720p", "1080p", "4k"],
38503
+ // 1080p/4k require 8s duration
37378
38504
  aspectRatios: ["16:9", "9:16"],
37379
38505
  maxFps: 24,
37380
38506
  audio: true,
38507
+ // Native audio generation
37381
38508
  imageToVideo: true,
37382
- videoExtension: false,
37383
- frameControl: false,
38509
+ // Up to 3 reference images
38510
+ videoExtension: true,
38511
+ // Supported (720p only)
38512
+ frameControl: true,
38513
+ // First/last frame interpolation
37384
38514
  features: {
37385
38515
  upscaling: false,
37386
38516
  styleControl: false,
@@ -37389,7 +38519,8 @@ var VIDEO_MODEL_REGISTRY = {
37389
38519
  }
37390
38520
  },
37391
38521
  pricing: {
37392
- perSecond: 0.75,
38522
+ perSecond: 0.15,
38523
+ // $0.15 for 720p/1080p, $0.35 for 4K
37393
38524
  currency: "USD"
37394
38525
  }
37395
38526
  },
@@ -37406,8 +38537,11 @@ var VIDEO_MODEL_REGISTRY = {
37406
38537
  aspectRatios: ["16:9", "9:16"],
37407
38538
  maxFps: 30,
37408
38539
  audio: true,
38540
+ // Native audio generation
37409
38541
  imageToVideo: true,
38542
+ // Up to 3 reference images
37410
38543
  videoExtension: true,
38544
+ // Supported (720p only)
37411
38545
  frameControl: true,
37412
38546
  features: {
37413
38547
  upscaling: true,
@@ -37417,7 +38551,8 @@ var VIDEO_MODEL_REGISTRY = {
37417
38551
  }
37418
38552
  },
37419
38553
  pricing: {
37420
- perSecond: 0.75,
38554
+ perSecond: 0.4,
38555
+ // $0.40 for 720p/1080p, $0.60 for 4K
37421
38556
  currency: "USD"
37422
38557
  }
37423
38558
  },
@@ -37641,6 +38776,694 @@ var VideoGeneration = class _VideoGeneration {
37641
38776
  }
37642
38777
  };
37643
38778
 
38779
+ // src/capabilities/speech/SentenceSplitter.ts
38780
+ var DEFAULT_ABBREVIATIONS = /* @__PURE__ */ new Set([
38781
+ "dr.",
38782
+ "mr.",
38783
+ "mrs.",
38784
+ "ms.",
38785
+ "prof.",
38786
+ "sr.",
38787
+ "jr.",
38788
+ "st.",
38789
+ "ave.",
38790
+ "blvd.",
38791
+ "rd.",
38792
+ "u.s.",
38793
+ "u.k.",
38794
+ "u.s.a.",
38795
+ "u.n.",
38796
+ "e.g.",
38797
+ "i.e.",
38798
+ "etc.",
38799
+ "vs.",
38800
+ "viz.",
38801
+ "approx.",
38802
+ "dept.",
38803
+ "est.",
38804
+ "inc.",
38805
+ "ltd.",
38806
+ "corp.",
38807
+ "no.",
38808
+ "vol.",
38809
+ "rev.",
38810
+ "gen.",
38811
+ "gov.",
38812
+ "jan.",
38813
+ "feb.",
38814
+ "mar.",
38815
+ "apr.",
38816
+ "jun.",
38817
+ "jul.",
38818
+ "aug.",
38819
+ "sep.",
38820
+ "oct.",
38821
+ "nov.",
38822
+ "dec.",
38823
+ "fig.",
38824
+ "eq.",
38825
+ "ref.",
38826
+ "sec.",
38827
+ "ch.",
38828
+ "min.",
38829
+ "max.",
38830
+ "avg."
38831
+ ]);
38832
+ var DEFAULT_OPTIONS = {
38833
+ minChunkLength: 20,
38834
+ maxChunkLength: 500,
38835
+ skipCodeBlocks: true,
38836
+ stripMarkdown: true,
38837
+ additionalAbbreviations: []
38838
+ };
38839
+ var SentenceChunkingStrategy = class {
38840
+ buffer = "";
38841
+ inCodeBlock = false;
38842
+ codeBlockBuffer = "";
38843
+ options;
38844
+ abbreviations;
38845
+ constructor(options) {
38846
+ this.options = { ...DEFAULT_OPTIONS, ...options };
38847
+ this.abbreviations = /* @__PURE__ */ new Set([
38848
+ ...DEFAULT_ABBREVIATIONS,
38849
+ ...this.options.additionalAbbreviations.map((a) => a.toLowerCase())
38850
+ ]);
38851
+ }
38852
+ feed(delta) {
38853
+ this.buffer += delta;
38854
+ return this.extractChunks();
38855
+ }
38856
+ flush() {
38857
+ if (this.inCodeBlock) {
38858
+ this.codeBlockBuffer = "";
38859
+ this.inCodeBlock = false;
38860
+ }
38861
+ const text = this.cleanForSpeech(this.buffer.trim());
38862
+ this.buffer = "";
38863
+ return text.length > 0 ? text : null;
38864
+ }
38865
+ reset() {
38866
+ this.buffer = "";
38867
+ this.inCodeBlock = false;
38868
+ this.codeBlockBuffer = "";
38869
+ }
38870
+ // ======================== Private Methods ========================
38871
+ extractChunks() {
38872
+ const chunks = [];
38873
+ if (this.options.skipCodeBlocks) {
38874
+ this.processCodeBlocks();
38875
+ }
38876
+ let paragraphIdx = this.buffer.indexOf("\n\n");
38877
+ while (paragraphIdx !== -1) {
38878
+ const chunk = this.buffer.slice(0, paragraphIdx).trim();
38879
+ this.buffer = this.buffer.slice(paragraphIdx + 2);
38880
+ if (chunk.length > 0) {
38881
+ const cleaned = this.cleanForSpeech(chunk);
38882
+ if (cleaned.length > 0) {
38883
+ chunks.push(cleaned);
38884
+ }
38885
+ }
38886
+ paragraphIdx = this.buffer.indexOf("\n\n");
38887
+ }
38888
+ let sentenceEnd = this.findSentenceBoundary();
38889
+ while (sentenceEnd !== -1) {
38890
+ const sentence = this.buffer.slice(0, sentenceEnd).trim();
38891
+ this.buffer = this.buffer.slice(sentenceEnd).trimStart();
38892
+ if (sentence.length > 0) {
38893
+ const cleaned = this.cleanForSpeech(sentence);
38894
+ if (cleaned.length > 0) {
38895
+ chunks.push(cleaned);
38896
+ }
38897
+ }
38898
+ sentenceEnd = this.findSentenceBoundary();
38899
+ }
38900
+ if (this.buffer.length > this.options.maxChunkLength) {
38901
+ const splitChunks = this.splitLongText(this.buffer);
38902
+ this.buffer = splitChunks.pop() ?? "";
38903
+ for (const chunk of splitChunks) {
38904
+ const cleaned = this.cleanForSpeech(chunk.trim());
38905
+ if (cleaned.length > 0) {
38906
+ chunks.push(cleaned);
38907
+ }
38908
+ }
38909
+ }
38910
+ return this.mergeSmallChunks(chunks);
38911
+ }
38912
+ /**
38913
+ * Track and remove fenced code blocks from the buffer.
38914
+ * Text inside code blocks is discarded (not spoken).
38915
+ */
38916
+ processCodeBlocks() {
38917
+ let idx = 0;
38918
+ let result = "";
38919
+ while (idx < this.buffer.length) {
38920
+ if (this.buffer.startsWith("```", idx)) {
38921
+ if (this.inCodeBlock) {
38922
+ this.inCodeBlock = false;
38923
+ this.codeBlockBuffer = "";
38924
+ idx += 3;
38925
+ const newline = this.buffer.indexOf("\n", idx);
38926
+ idx = newline !== -1 ? newline + 1 : this.buffer.length;
38927
+ } else {
38928
+ this.inCodeBlock = true;
38929
+ this.codeBlockBuffer = "";
38930
+ idx += 3;
38931
+ const newline = this.buffer.indexOf("\n", idx);
38932
+ idx = newline !== -1 ? newline + 1 : this.buffer.length;
38933
+ }
38934
+ } else if (this.inCodeBlock) {
38935
+ this.codeBlockBuffer += this.buffer[idx];
38936
+ idx++;
38937
+ } else {
38938
+ result += this.buffer[idx];
38939
+ idx++;
38940
+ }
38941
+ }
38942
+ this.buffer = result;
38943
+ }
38944
+ /**
38945
+ * Find the position right after the next sentence boundary.
38946
+ * Returns -1 if no complete sentence boundary found.
38947
+ */
38948
+ findSentenceBoundary() {
38949
+ const terminators = [".", "?", "!"];
38950
+ for (let i = 0; i < this.buffer.length; i++) {
38951
+ const ch = this.buffer.charAt(i);
38952
+ if (!terminators.includes(ch)) continue;
38953
+ if (i + 1 >= this.buffer.length) return -1;
38954
+ const nextChar = this.buffer[i + 1];
38955
+ if (nextChar !== " " && nextChar !== "\n" && nextChar !== "\r" && nextChar !== " ") {
38956
+ continue;
38957
+ }
38958
+ if (ch === ".") {
38959
+ if (this.isAbbreviation(i)) continue;
38960
+ if (this.isDecimalNumber(i)) continue;
38961
+ if (this.isEllipsis(i)) continue;
38962
+ }
38963
+ const candidate = this.buffer.slice(0, i + 1).trim();
38964
+ if (candidate.length < this.options.minChunkLength) continue;
38965
+ return i + 1;
38966
+ }
38967
+ return -1;
38968
+ }
38969
+ /**
38970
+ * Check if the period at position `pos` is part of a known abbreviation.
38971
+ */
38972
+ isAbbreviation(pos) {
38973
+ let wordStart = pos - 1;
38974
+ while (wordStart >= 0 && this.buffer[wordStart] !== " " && this.buffer[wordStart] !== "\n") {
38975
+ wordStart--;
38976
+ }
38977
+ wordStart++;
38978
+ const word = this.buffer.slice(wordStart, pos + 1).toLowerCase();
38979
+ return this.abbreviations.has(word);
38980
+ }
38981
+ /**
38982
+ * Check if the period at position `pos` is a decimal point.
38983
+ * e.g., 3.14, $1.50
38984
+ */
38985
+ isDecimalNumber(pos) {
38986
+ if (pos === 0 || pos + 1 >= this.buffer.length) return false;
38987
+ const before = this.buffer.charAt(pos - 1);
38988
+ const after = this.buffer.charAt(pos + 1);
38989
+ return /\d/.test(before) && /\d/.test(after);
38990
+ }
38991
+ /**
38992
+ * Check if the period at position `pos` is part of an ellipsis (...).
38993
+ */
38994
+ isEllipsis(pos) {
38995
+ if (pos >= 2 && this.buffer[pos - 1] === "." && this.buffer[pos - 2] === ".") return true;
38996
+ if (pos + 1 < this.buffer.length && this.buffer[pos + 1] === ".") return true;
38997
+ return false;
38998
+ }
38999
+ /**
39000
+ * Split text that exceeds maxChunkLength at clause boundaries.
39001
+ */
39002
+ splitLongText(text) {
39003
+ const max = this.options.maxChunkLength;
39004
+ const chunks = [];
39005
+ let remaining = text;
39006
+ while (remaining.length > max) {
39007
+ let splitPos = -1;
39008
+ const clauseBreaks = [",", ";", ":", " \u2014", " \u2013", " -"];
39009
+ for (const brk of clauseBreaks) {
39010
+ const searchRegion = remaining.slice(0, max);
39011
+ const lastPos = searchRegion.lastIndexOf(brk);
39012
+ if (lastPos > this.options.minChunkLength) {
39013
+ splitPos = lastPos + brk.length;
39014
+ break;
39015
+ }
39016
+ }
39017
+ if (splitPos === -1) {
39018
+ const searchRegion = remaining.slice(0, max);
39019
+ splitPos = searchRegion.lastIndexOf(" ");
39020
+ if (splitPos <= this.options.minChunkLength) {
39021
+ splitPos = max;
39022
+ }
39023
+ }
39024
+ chunks.push(remaining.slice(0, splitPos));
39025
+ remaining = remaining.slice(splitPos);
39026
+ }
39027
+ chunks.push(remaining);
39028
+ return chunks;
39029
+ }
39030
+ /**
39031
+ * Merge chunks that are shorter than minChunkLength with the next chunk.
39032
+ */
39033
+ mergeSmallChunks(chunks) {
39034
+ if (chunks.length <= 1) return chunks;
39035
+ const merged = [];
39036
+ let accumulator = "";
39037
+ for (const chunk of chunks) {
39038
+ if (accumulator.length > 0) {
39039
+ accumulator += " " + chunk;
39040
+ } else {
39041
+ accumulator = chunk;
39042
+ }
39043
+ if (accumulator.length >= this.options.minChunkLength) {
39044
+ merged.push(accumulator);
39045
+ accumulator = "";
39046
+ }
39047
+ }
39048
+ if (accumulator.length > 0) {
39049
+ if (merged.length > 0) {
39050
+ merged[merged.length - 1] += " " + accumulator;
39051
+ } else {
39052
+ merged.push(accumulator);
39053
+ }
39054
+ }
39055
+ return merged;
39056
+ }
39057
+ /**
39058
+ * Strip markdown formatting from text for natural speech.
39059
+ */
39060
+ cleanForSpeech(text) {
39061
+ if (!this.options.stripMarkdown) return text;
39062
+ let cleaned = text;
39063
+ cleaned = cleaned.replace(/`([^`]+)`/g, "$1");
39064
+ cleaned = cleaned.replace(/\*\*([^*]+)\*\*/g, "$1");
39065
+ cleaned = cleaned.replace(/__([^_]+)__/g, "$1");
39066
+ cleaned = cleaned.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, "$1");
39067
+ cleaned = cleaned.replace(/(?<!_)_([^_]+)_(?!_)/g, "$1");
39068
+ cleaned = cleaned.replace(/~~([^~]+)~~/g, "$1");
39069
+ cleaned = cleaned.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
39070
+ cleaned = cleaned.replace(/!\[([^\]]*)\]\([^)]+\)/g, "");
39071
+ cleaned = cleaned.replace(/^#{1,6}\s+/gm, "");
39072
+ cleaned = cleaned.replace(/^[-*+]\s+/gm, "");
39073
+ cleaned = cleaned.replace(/^\d+\.\s+/gm, "");
39074
+ cleaned = cleaned.replace(/^>\s+/gm, "");
39075
+ cleaned = cleaned.replace(/^[-*_]{3,}\s*$/gm, "");
39076
+ cleaned = cleaned.replace(/\n+/g, " ");
39077
+ cleaned = cleaned.replace(/\s{2,}/g, " ");
39078
+ return cleaned.trim();
39079
+ }
39080
+ };
39081
+
39082
+ // src/capabilities/speech/VoiceStream.ts
39083
+ var VoiceStream = class _VoiceStream extends EventEmitter$1 {
39084
+ tts;
39085
+ chunker;
39086
+ format;
39087
+ speed;
39088
+ maxConcurrentTTS;
39089
+ maxQueuedChunks;
39090
+ vendorOptions;
39091
+ streaming;
39092
+ // Pipeline state
39093
+ chunkIndex = 0;
39094
+ totalCharacters = 0;
39095
+ totalDuration = 0;
39096
+ activeJobs = /* @__PURE__ */ new Map();
39097
+ activeTTSCount = 0;
39098
+ interrupted = false;
39099
+ lastResponseId = "";
39100
+ _isDestroyed = false;
39101
+ // Semaphore for TTS concurrency control
39102
+ slotWaiters = [];
39103
+ // Audio event buffer for interleaving with text events
39104
+ audioEventBuffer = [];
39105
+ // Async notification: resolves when new events are pushed to audioEventBuffer
39106
+ bufferNotify = null;
39107
+ // Queue backpressure
39108
+ queueWaiters = [];
39109
+ /**
39110
+ * Create a new VoiceStream instance
39111
+ */
39112
+ static create(config) {
39113
+ return new _VoiceStream(config);
39114
+ }
39115
+ constructor(config) {
39116
+ super();
39117
+ this.tts = TextToSpeech.create({
39118
+ connector: config.ttsConnector,
39119
+ model: config.ttsModel,
39120
+ voice: config.voice
39121
+ });
39122
+ this.chunker = config.chunkingStrategy ?? new SentenceChunkingStrategy(config.chunkingOptions);
39123
+ this.format = config.format ?? "mp3";
39124
+ this.speed = config.speed ?? 1;
39125
+ this.maxConcurrentTTS = config.maxConcurrentTTS ?? 2;
39126
+ this.maxQueuedChunks = config.maxQueuedChunks ?? 5;
39127
+ this.vendorOptions = config.vendorOptions;
39128
+ this.streaming = config.streaming ?? false;
39129
+ }
39130
+ // ======================== Public API ========================
39131
+ /**
39132
+ * Transform an agent text stream into an augmented stream with audio events.
39133
+ * Original text events pass through unchanged; audio events are interleaved.
39134
+ *
39135
+ * The generator yields events in this order:
39136
+ * 1. All original StreamEvents (pass-through)
39137
+ * 2. AudioChunkReady/AudioChunkError events as TTS completes
39138
+ * 3. AudioStreamComplete as the final audio event
39139
+ */
39140
+ async *wrap(textStream) {
39141
+ this.reset();
39142
+ try {
39143
+ for await (const event of textStream) {
39144
+ yield event;
39145
+ if (event.response_id) {
39146
+ this.lastResponseId = event.response_id;
39147
+ }
39148
+ if (event.type === "response.output_text.delta" /* OUTPUT_TEXT_DELTA */ && !this.interrupted) {
39149
+ const completedChunks = this.chunker.feed(event.delta);
39150
+ for (const chunk of completedChunks) {
39151
+ await this.scheduleTTS(chunk);
39152
+ }
39153
+ }
39154
+ if ((event.type === "response.output_text.done" /* OUTPUT_TEXT_DONE */ || event.type === "response.complete" /* RESPONSE_COMPLETE */) && !this.interrupted) {
39155
+ const remaining = this.chunker.flush();
39156
+ if (remaining) {
39157
+ await this.scheduleTTS(remaining);
39158
+ }
39159
+ }
39160
+ yield* this.drainAudioBuffer();
39161
+ }
39162
+ while (this.activeJobs.size > 0 || this.audioEventBuffer.length > 0) {
39163
+ if (this.audioEventBuffer.length === 0) {
39164
+ await Promise.race([
39165
+ this.waitForBufferNotify(),
39166
+ ...Array.from(this.activeJobs.values()).map((j) => j.promise)
39167
+ ]);
39168
+ }
39169
+ yield* this.drainAudioBuffer();
39170
+ }
39171
+ if (this.chunkIndex > 0) {
39172
+ const completeEvent = {
39173
+ type: "response.audio_stream.complete" /* AUDIO_STREAM_COMPLETE */,
39174
+ response_id: this.lastResponseId,
39175
+ total_chunks: this.chunkIndex,
39176
+ total_characters: this.totalCharacters,
39177
+ total_duration_seconds: this.totalDuration > 0 ? this.totalDuration : void 0
39178
+ };
39179
+ yield completeEvent;
39180
+ this.emit("audio:complete", {
39181
+ totalChunks: this.chunkIndex,
39182
+ totalDurationSeconds: this.totalDuration > 0 ? this.totalDuration : void 0
39183
+ });
39184
+ }
39185
+ } finally {
39186
+ this.cleanup();
39187
+ }
39188
+ }
39189
+ /**
39190
+ * Interrupt audio generation. Cancels pending TTS and flushes queue.
39191
+ * Call this when the user sends a new message mid-speech.
39192
+ * Active HTTP requests cannot be cancelled but their results will be discarded.
39193
+ */
39194
+ interrupt() {
39195
+ this.interrupted = true;
39196
+ const pendingCount = this.activeJobs.size;
39197
+ this.activeJobs.clear();
39198
+ this.activeTTSCount = 0;
39199
+ this.audioEventBuffer = [];
39200
+ this.releaseAllWaiters();
39201
+ this.chunker.reset();
39202
+ this.emit("audio:interrupted", { pendingChunks: pendingCount });
39203
+ }
39204
+ /**
39205
+ * Reset state for a new stream. Called automatically by wrap().
39206
+ */
39207
+ reset() {
39208
+ this.chunkIndex = 0;
39209
+ this.totalCharacters = 0;
39210
+ this.totalDuration = 0;
39211
+ this.activeJobs.clear();
39212
+ this.activeTTSCount = 0;
39213
+ this.interrupted = false;
39214
+ this.lastResponseId = "";
39215
+ this.audioEventBuffer = [];
39216
+ this.bufferNotify = null;
39217
+ this.slotWaiters = [];
39218
+ this.queueWaiters = [];
39219
+ this.chunker.reset();
39220
+ }
39221
+ destroy() {
39222
+ this.interrupt();
39223
+ this._isDestroyed = true;
39224
+ this.removeAllListeners();
39225
+ }
39226
+ get isDestroyed() {
39227
+ return this._isDestroyed;
39228
+ }
39229
+ // ======================== Private Methods ========================
39230
+ /**
39231
+ * Schedule a text chunk for TTS synthesis.
39232
+ * Awaits a free queue slot if backpressure is active (lossless).
39233
+ */
39234
+ async scheduleTTS(text) {
39235
+ if (this.interrupted || this._isDestroyed) return;
39236
+ const cleanText = text.trim();
39237
+ if (cleanText.length === 0) return;
39238
+ while (this.activeJobs.size >= this.maxQueuedChunks && !this.interrupted) {
39239
+ await this.waitForQueueSlot();
39240
+ }
39241
+ if (this.interrupted) return;
39242
+ const index = this.chunkIndex++;
39243
+ this.totalCharacters += cleanText.length;
39244
+ const job = {
39245
+ index,
39246
+ text: cleanText,
39247
+ promise: this.executeTTS(index, cleanText)
39248
+ };
39249
+ this.activeJobs.set(index, job);
39250
+ job.promise.finally(() => {
39251
+ this.activeJobs.delete(index);
39252
+ this.releaseQueueWaiter();
39253
+ });
39254
+ }
39255
+ /**
39256
+ * Execute TTS for a single text chunk.
39257
+ * Respects concurrency semaphore.
39258
+ * Branches on streaming mode: yields sub-chunks or a single buffered chunk.
39259
+ */
39260
+ async executeTTS(index, text) {
39261
+ while (this.activeTTSCount >= this.maxConcurrentTTS && !this.interrupted) {
39262
+ await this.waitForTTSSlot();
39263
+ }
39264
+ if (this.interrupted) return;
39265
+ this.activeTTSCount++;
39266
+ try {
39267
+ const ttsStart = Date.now();
39268
+ if (this.streaming && this.tts.supportsStreaming(this.format)) {
39269
+ let subIndex = 0;
39270
+ const streamFormat = this.format === "mp3" ? "pcm" : this.format;
39271
+ const MIN_BUFFER_BYTES = 6e3;
39272
+ const pendingBuffers = [];
39273
+ let pendingSize = 0;
39274
+ const flushPending = () => {
39275
+ if (pendingSize === 0) return;
39276
+ const merged = Buffer.concat(pendingBuffers, pendingSize);
39277
+ pendingBuffers.length = 0;
39278
+ pendingSize = 0;
39279
+ const currentSubIndex = subIndex++;
39280
+ const audioEvent = {
39281
+ type: "response.audio_chunk.ready" /* AUDIO_CHUNK_READY */,
39282
+ response_id: this.lastResponseId,
39283
+ chunk_index: index,
39284
+ sub_index: currentSubIndex,
39285
+ text: currentSubIndex === 0 ? text : "",
39286
+ audio_base64: merged.toString("base64"),
39287
+ format: streamFormat
39288
+ };
39289
+ this.pushAudioEvent(audioEvent);
39290
+ };
39291
+ for await (const chunk of this.tts.synthesizeStream(text, {
39292
+ format: streamFormat,
39293
+ speed: this.speed,
39294
+ vendorOptions: this.vendorOptions
39295
+ })) {
39296
+ if (this.interrupted) return;
39297
+ if (chunk.audio.length > 0) {
39298
+ pendingBuffers.push(chunk.audio);
39299
+ pendingSize += chunk.audio.length;
39300
+ if (pendingSize >= MIN_BUFFER_BYTES) {
39301
+ flushPending();
39302
+ }
39303
+ }
39304
+ if (chunk.isFinal) {
39305
+ break;
39306
+ }
39307
+ }
39308
+ flushPending();
39309
+ console.log(`[VoiceStream] TTS chunk ${index} streamed ${subIndex} sub-chunks in ${Date.now() - ttsStart}ms, text: "${text.slice(0, 40)}..."`);
39310
+ this.emit("audio:ready", { chunkIndex: index, text });
39311
+ } else {
39312
+ const response = await this.tts.synthesize(text, {
39313
+ format: this.format,
39314
+ speed: this.speed,
39315
+ vendorOptions: this.vendorOptions
39316
+ });
39317
+ if (this.interrupted) return;
39318
+ if (response.durationSeconds) {
39319
+ this.totalDuration += response.durationSeconds;
39320
+ }
39321
+ const audioEvent = {
39322
+ type: "response.audio_chunk.ready" /* AUDIO_CHUNK_READY */,
39323
+ response_id: this.lastResponseId,
39324
+ chunk_index: index,
39325
+ text,
39326
+ audio_base64: response.audio.toString("base64"),
39327
+ format: response.format,
39328
+ duration_seconds: response.durationSeconds,
39329
+ characters_used: response.charactersUsed
39330
+ };
39331
+ this.pushAudioEvent(audioEvent);
39332
+ console.log(`[VoiceStream] TTS chunk ${index} ready in ${Date.now() - ttsStart}ms, text: "${text.slice(0, 40)}..."`);
39333
+ this.emit("audio:ready", {
39334
+ chunkIndex: index,
39335
+ text,
39336
+ durationSeconds: response.durationSeconds
39337
+ });
39338
+ }
39339
+ } catch (error) {
39340
+ if (this.interrupted) return;
39341
+ const errorEvent = {
39342
+ type: "response.audio_chunk.error" /* AUDIO_CHUNK_ERROR */,
39343
+ response_id: this.lastResponseId,
39344
+ chunk_index: index,
39345
+ text,
39346
+ error: error.message
39347
+ };
39348
+ this.pushAudioEvent(errorEvent);
39349
+ this.emit("audio:error", {
39350
+ chunkIndex: index,
39351
+ text,
39352
+ error
39353
+ });
39354
+ } finally {
39355
+ this.activeTTSCount--;
39356
+ this.releaseTTSSlot();
39357
+ }
39358
+ }
39359
+ /**
39360
+ * Drain the audio event buffer, yielding all ready events.
39361
+ */
39362
+ *drainAudioBuffer() {
39363
+ while (this.audioEventBuffer.length > 0) {
39364
+ yield this.audioEventBuffer.shift();
39365
+ }
39366
+ }
39367
+ // ======================== Buffer Notification ========================
39368
+ /**
39369
+ * Push an audio event and wake up the consumer in wrap()
39370
+ */
39371
+ pushAudioEvent(event) {
39372
+ this.audioEventBuffer.push(event);
39373
+ if (this.bufferNotify) {
39374
+ this.bufferNotify();
39375
+ this.bufferNotify = null;
39376
+ }
39377
+ }
39378
+ /**
39379
+ * Wait until a new event is pushed to the audio buffer
39380
+ */
39381
+ waitForBufferNotify() {
39382
+ return new Promise((resolve4) => {
39383
+ this.bufferNotify = resolve4;
39384
+ });
39385
+ }
39386
+ // ======================== Semaphore / Backpressure ========================
39387
+ waitForTTSSlot() {
39388
+ return new Promise((resolve4) => {
39389
+ this.slotWaiters.push(resolve4);
39390
+ });
39391
+ }
39392
+ releaseTTSSlot() {
39393
+ const waiter = this.slotWaiters.shift();
39394
+ if (waiter) waiter();
39395
+ }
39396
+ waitForQueueSlot() {
39397
+ return new Promise((resolve4) => {
39398
+ this.queueWaiters.push(resolve4);
39399
+ });
39400
+ }
39401
+ releaseQueueWaiter() {
39402
+ const waiter = this.queueWaiters.shift();
39403
+ if (waiter) waiter();
39404
+ }
39405
+ releaseAllWaiters() {
39406
+ for (const waiter of this.slotWaiters) waiter();
39407
+ this.slotWaiters = [];
39408
+ for (const waiter of this.queueWaiters) waiter();
39409
+ this.queueWaiters = [];
39410
+ if (this.bufferNotify) {
39411
+ this.bufferNotify();
39412
+ this.bufferNotify = null;
39413
+ }
39414
+ }
39415
+ cleanup() {
39416
+ this.releaseAllWaiters();
39417
+ }
39418
+ };
39419
+
39420
+ // src/capabilities/speech/AudioPlaybackQueue.ts
39421
+ var AudioPlaybackQueue = class {
39422
+ buffer = /* @__PURE__ */ new Map();
39423
+ nextPlayIndex = 0;
39424
+ onReady;
39425
+ constructor(onReady) {
39426
+ this.onReady = onReady;
39427
+ }
39428
+ /**
39429
+ * Enqueue an audio chunk event. If it's the next expected chunk,
39430
+ * it (and any subsequent buffered chunks) are immediately delivered
39431
+ * to the callback in order.
39432
+ */
39433
+ enqueue(event) {
39434
+ this.buffer.set(event.chunk_index, event);
39435
+ this.drain();
39436
+ }
39437
+ /**
39438
+ * Reset the queue (e.g., on interruption or new stream).
39439
+ */
39440
+ reset() {
39441
+ this.buffer.clear();
39442
+ this.nextPlayIndex = 0;
39443
+ }
39444
+ /**
39445
+ * Number of chunks currently buffered waiting for earlier chunks.
39446
+ */
39447
+ get pendingCount() {
39448
+ return this.buffer.size;
39449
+ }
39450
+ /**
39451
+ * The next chunk index expected for playback.
39452
+ */
39453
+ get nextExpectedIndex() {
39454
+ return this.nextPlayIndex;
39455
+ }
39456
+ // ======================== Private ========================
39457
+ drain() {
39458
+ while (this.buffer.has(this.nextPlayIndex)) {
39459
+ const event = this.buffer.get(this.nextPlayIndex);
39460
+ this.buffer.delete(this.nextPlayIndex);
39461
+ this.nextPlayIndex++;
39462
+ this.onReady(event);
39463
+ }
39464
+ }
39465
+ };
39466
+
37644
39467
  // src/capabilities/search/SearchProvider.ts
37645
39468
  init_Connector();
37646
39469
 
@@ -42320,6 +44143,14 @@ var SERVICE_DEFINITIONS = [
42320
44143
  baseURL: "https://aws.amazon.com",
42321
44144
  docsURL: "https://docs.aws.amazon.com/"
42322
44145
  },
44146
+ {
44147
+ id: "cloudflare",
44148
+ name: "Cloudflare",
44149
+ category: "cloud",
44150
+ urlPattern: /api\.cloudflare\.com/i,
44151
+ baseURL: "https://api.cloudflare.com/client/v4",
44152
+ docsURL: "https://developers.cloudflare.com/api/"
44153
+ },
42323
44154
  // ============ Storage ============
42324
44155
  {
42325
44156
  id: "dropbox",
@@ -42363,6 +44194,14 @@ var SERVICE_DEFINITIONS = [
42363
44194
  baseURL: "https://api.postmarkapp.com",
42364
44195
  docsURL: "https://postmarkapp.com/developer"
42365
44196
  },
44197
+ {
44198
+ id: "mailgun",
44199
+ name: "Mailgun",
44200
+ category: "email",
44201
+ urlPattern: /api\.mailgun\.net|api\.eu\.mailgun\.net/i,
44202
+ baseURL: "https://api.mailgun.net/v3",
44203
+ docsURL: "https://documentation.mailgun.com/docs/mailgun/api-reference/"
44204
+ },
42366
44205
  // ============ Monitoring & Observability ============
42367
44206
  {
42368
44207
  id: "datadog",
@@ -45102,6 +46941,43 @@ var awsTemplate = {
45102
46941
  ]
45103
46942
  };
45104
46943
 
46944
+ // src/connectors/vendors/templates/cloudflare.ts
46945
+ var cloudflareTemplate = {
46946
+ id: "cloudflare",
46947
+ name: "Cloudflare",
46948
+ serviceType: "cloudflare",
46949
+ baseURL: "https://api.cloudflare.com/client/v4",
46950
+ docsURL: "https://developers.cloudflare.com/api/",
46951
+ credentialsSetupURL: "https://dash.cloudflare.com/profile/api-tokens",
46952
+ category: "cloud",
46953
+ notes: "API Tokens (recommended) are scoped and more secure. Global API Key requires email and has full account access.",
46954
+ authTemplates: [
46955
+ {
46956
+ id: "api-token",
46957
+ name: "API Token",
46958
+ type: "api_key",
46959
+ description: "Scoped API token (recommended). Create at dash.cloudflare.com > My Profile > API Tokens",
46960
+ requiredFields: ["apiKey"],
46961
+ defaults: {
46962
+ type: "api_key",
46963
+ headerName: "Authorization",
46964
+ headerPrefix: "Bearer"
46965
+ }
46966
+ },
46967
+ {
46968
+ id: "global-api-key",
46969
+ name: "Global API Key",
46970
+ type: "api_key",
46971
+ description: "Legacy global API key + email. Has full account access. Prefer API Tokens for least-privilege access",
46972
+ requiredFields: ["apiKey", "username"],
46973
+ defaults: {
46974
+ type: "api_key",
46975
+ headerName: "X-Auth-Key"
46976
+ }
46977
+ }
46978
+ ]
46979
+ };
46980
+
45105
46981
  // src/connectors/vendors/templates/dropbox.ts
45106
46982
  var dropboxTemplate = {
45107
46983
  id: "dropbox",
@@ -45290,6 +47166,30 @@ var postmarkTemplate = {
45290
47166
  }
45291
47167
  ]
45292
47168
  };
47169
+ var mailgunTemplate = {
47170
+ id: "mailgun",
47171
+ name: "Mailgun",
47172
+ serviceType: "mailgun",
47173
+ baseURL: "https://api.mailgun.net/v3",
47174
+ docsURL: "https://documentation.mailgun.com/docs/mailgun/api-reference/",
47175
+ credentialsSetupURL: "https://app.mailgun.com/settings/api_security",
47176
+ category: "email",
47177
+ notes: "EU region uses api.eu.mailgun.net. Most endpoints require /v3/<domain> in the path.",
47178
+ authTemplates: [
47179
+ {
47180
+ id: "api-key",
47181
+ name: "API Key",
47182
+ type: "api_key",
47183
+ description: "Private API key for full account access. Find at Settings > API Security",
47184
+ requiredFields: ["apiKey"],
47185
+ defaults: {
47186
+ type: "api_key",
47187
+ headerName: "Authorization",
47188
+ headerPrefix: "Basic"
47189
+ }
47190
+ }
47191
+ ]
47192
+ };
45293
47193
 
45294
47194
  // src/connectors/vendors/templates/monitoring.ts
45295
47195
  var datadogTemplate = {
@@ -45738,6 +47638,7 @@ var allVendorTemplates = [
45738
47638
  rampTemplate,
45739
47639
  // Cloud
45740
47640
  awsTemplate,
47641
+ cloudflareTemplate,
45741
47642
  // Storage
45742
47643
  dropboxTemplate,
45743
47644
  boxTemplate,
@@ -45745,6 +47646,7 @@ var allVendorTemplates = [
45745
47646
  sendgridTemplate,
45746
47647
  mailchimpTemplate,
45747
47648
  postmarkTemplate,
47649
+ mailgunTemplate,
45748
47650
  // Monitoring
45749
47651
  datadogTemplate,
45750
47652
  pagerdutyTemplate,
@@ -49102,7 +51004,8 @@ SANDBOX API:
49102
51004
  4. connectors.get(name) \u2014 Connector info: { displayName, description, baseURL, serviceType }
49103
51005
 
49104
51006
  VARIABLES:
49105
- \u2022 input \u2014 data passed via the "input" parameter (default: {})
51007
+ \u2022 input \u2014 data passed via the "input" parameter (default: {}). Always a parsed object/array, never a string.
51008
+ CRITICAL: You MUST pass actual data values directly. Template placeholders ({{results}}, {{param.name}}, etc.) are NOT supported and will be passed as literal strings. If you need data from a previous tool call, include the actual returned data in the input object.
49106
51009
  \u2022 output \u2014 SET THIS to return your result to the caller
49107
51010
 
49108
51011
  GLOBALS: console.log/error/warn, JSON, Math, Date, Buffer, Promise, Array, Object, String, Number, Boolean, setTimeout, setInterval, URL, URLSearchParams, RegExp, Map, Set, Error, TextEncoder, TextDecoder
@@ -49125,7 +51028,8 @@ const resp = await authenticatedFetch('/chat.postMessage', {
49125
51028
  }, 'slack');
49126
51029
  output = await resp.json();
49127
51030
  ${accountIdExamples}
49128
- // Data processing (no API needed)
51031
+ // Data processing \u2014 pass actual data via the input parameter, NOT template references
51032
+ // e.g. call with: { "code": "...", "input": { "data": [{"score": 0.9}, {"score": 0.5}] } }
49129
51033
  const items = input.data;
49130
51034
  output = items.filter(i => i.score > 0.8).sort((a, b) => b.score - a.score);
49131
51035
 
@@ -49149,7 +51053,7 @@ function createExecuteJavaScriptTool(options) {
49149
51053
  description: 'JavaScript code to execute. Set the "output" variable with your result. Code is auto-wrapped in async IIFE \u2014 you can use await directly. For explicit async control, wrap in (async () => { ... })().'
49150
51054
  },
49151
51055
  input: {
49152
- description: 'Optional data available as the "input" variable in your code. Can be any JSON value.'
51056
+ description: 'Optional data available as the "input" variable in your code. IMPORTANT: Pass actual data directly as a JSON object/array. Template placeholders like {{results}} or {{param.name}} are NOT supported here and will be passed as literal strings. You must include the actual data values inline. Correct: "input": {"deals": [{"id":"1"}, ...]}. Wrong: "input": {"deals": "{{results}}"}.'
49153
51057
  },
49154
51058
  timeout: {
49155
51059
  type: "number",
@@ -49172,9 +51076,19 @@ function createExecuteJavaScriptTool(options) {
49172
51076
  try {
49173
51077
  const timeout = Math.min(Math.max(args.timeout || defaultTimeout, 0), maxTimeout);
49174
51078
  const registry = context?.connectorRegistry ?? Connector.asRegistry();
51079
+ let resolvedInput = args.input;
51080
+ if (typeof resolvedInput === "string") {
51081
+ const trimmed = resolvedInput.trim();
51082
+ if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
51083
+ try {
51084
+ resolvedInput = JSON.parse(trimmed);
51085
+ } catch {
51086
+ }
51087
+ }
51088
+ }
49175
51089
  const result = await executeInVM(
49176
51090
  args.code,
49177
- args.input,
51091
+ resolvedInput,
49178
51092
  timeout,
49179
51093
  logs,
49180
51094
  context?.userId,
@@ -54584,6 +56498,6 @@ var EventEmitterTrigger = class {
54584
56498
  }
54585
56499
  };
54586
56500
 
54587
- export { AGENT_DEFINITION_FORMAT_VERSION, AIError, APPROVAL_STATE_VERSION, Agent, AgentContextNextGen, ApproximateTokenEstimator, BaseMediaProvider, BasePluginNextGen, BaseProvider, BaseTextProvider, BraveProvider, CONNECTOR_CONFIG_VERSION, CONTEXT_SESSION_FORMAT_VERSION, CUSTOM_TOOL_DEFINITION_VERSION, CheckpointManager, CircuitBreaker, CircuitOpenError, Connector, ConnectorConfigStore, ConnectorTools, ConsoleMetrics, ContentType, ContextOverflowError, DEFAULT_ALLOWLIST, DEFAULT_BACKOFF_CONFIG, DEFAULT_BASE_DELAY_MS, DEFAULT_CHECKPOINT_STRATEGY, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_CONFIG2 as DEFAULT_CONFIG, DEFAULT_CONNECTOR_TIMEOUT, DEFAULT_CONTEXT_CONFIG, DEFAULT_DESKTOP_CONFIG, DEFAULT_FEATURES, DEFAULT_FILESYSTEM_CONFIG, DEFAULT_HISTORY_MANAGER_CONFIG, DEFAULT_MAX_DELAY_MS, DEFAULT_MAX_RETRIES, DEFAULT_MEMORY_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_RATE_LIMITER_CONFIG, DEFAULT_RETRYABLE_STATUSES, DEFAULT_SHELL_CONFIG, DESKTOP_TOOL_NAMES, DefaultCompactionStrategy, DependencyCycleError, DocumentReader, ErrorHandler, EventEmitterTrigger, ExecutionContext, ExternalDependencyHandler, FileAgentDefinitionStorage, FileConnectorStorage, FileContextStorage, FileCustomToolStorage, FileMediaStorage as FileMediaOutputHandler, FileMediaStorage, FilePersistentInstructionsStorage, FileRoutineDefinitionStorage, FileStorage, FileUserInfoStorage, FormatDetector, FrameworkLogger, HookManager, IMAGE_MODELS, IMAGE_MODEL_REGISTRY, ImageGeneration, InContextMemoryPluginNextGen, InMemoryAgentStateStorage, InMemoryHistoryStorage, InMemoryMetrics, InMemoryPlanStorage, InMemoryStorage, InvalidConfigError, InvalidToolArgumentsError, LLM_MODELS, LoggingPlugin, MCPClient, MCPConnectionError, MCPError, MCPProtocolError, MCPRegistry, MCPResourceError, MCPTimeoutError, MCPToolError, MEMORY_PRIORITY_VALUES, MODEL_REGISTRY, MemoryConnectorStorage, MemoryEvictionCompactor, MemoryStorage, MessageBuilder, MessageRole, ModelNotSupportedError, NoOpMetrics, NutTreeDriver, OAuthManager, ParallelTasksError, PersistentInstructionsPluginNextGen, PlanningAgent, ProviderAuthError, ProviderConfigAgent, ProviderContextLengthError, ProviderError, ProviderErrorMapper, ProviderNotFoundError, ProviderRateLimitError, ROUTINE_KEYS, RapidAPIProvider, RateLimitError, SERVICE_DEFINITIONS, SERVICE_INFO, SERVICE_URL_PATTERNS, SIMPLE_ICONS_CDN, STT_MODELS, STT_MODEL_REGISTRY, ScopedConnectorRegistry, ScrapeProvider, SearchProvider, SerperProvider, Services, SimpleScheduler, SpeechToText, StorageRegistry, StrategyRegistry, StreamEventType, StreamHelpers, StreamState, SummarizeCompactor, TERMINAL_TASK_STATUSES, TTS_MODELS, TTS_MODEL_REGISTRY, TaskTimeoutError, TaskValidationError, TavilyProvider, TextToSpeech, TokenBucketRateLimiter, ToolCallState, ToolCatalogPluginNextGen, ToolCatalogRegistry, ToolExecutionError, ToolExecutionPipeline, ToolManager, ToolNotFoundError, ToolPermissionManager, ToolRegistry, ToolTimeoutError, TruncateCompactor, UserInfoPluginNextGen, VENDORS, VENDOR_ICON_MAP, VIDEO_MODELS, VIDEO_MODEL_REGISTRY, Vendor, VideoGeneration, WorkingMemory, WorkingMemoryPluginNextGen, addJitter, allVendorTemplates, assertNotDestroyed, authenticatedFetch, backoffSequence, backoffWait, bash, buildAuthConfig, buildEndpointWithQuery, buildQueryString, calculateBackoff, calculateCost, calculateEntrySize, calculateImageCost, calculateSTTCost, calculateTTSCost, calculateVideoCost, canTaskExecute, createAgentStorage, createAuthenticatedFetch, createBashTool, createConnectorFromTemplate, createCreatePRTool, createCustomToolDelete, createCustomToolDraft, createCustomToolList, createCustomToolLoad, createCustomToolMetaTools, createCustomToolSave, createCustomToolTest, createDesktopGetCursorTool, createDesktopGetScreenSizeTool, createDesktopKeyboardKeyTool, createDesktopKeyboardTypeTool, createDesktopMouseClickTool, createDesktopMouseDragTool, createDesktopMouseMoveTool, createDesktopMouseScrollTool, createDesktopScreenshotTool, createDesktopWindowFocusTool, createDesktopWindowListTool, createDraftEmailTool, createEditFileTool, createEditMeetingTool, createEstimator, createExecuteJavaScriptTool, createExecutionRecorder, createFileAgentDefinitionStorage, createFileContextStorage, createFileCustomToolStorage, createFileMediaStorage, createFileRoutineDefinitionStorage, createFindMeetingSlotsTool, createGetMeetingTranscriptTool, createGetPRTool, createGitHubReadFileTool, createGlobTool, createGrepTool, createImageGenerationTool, createImageProvider, createListDirectoryTool, createMeetingTool, createMessageWithImages, createMetricsCollector, createMicrosoftListFilesTool, createMicrosoftReadFileTool, createMicrosoftSearchFilesTool, createPRCommentsTool, createPRFilesTool, createPlan, createProvider, createReadFileTool, createRoutineDefinition, createRoutineExecution, createRoutineExecutionRecord, createSearchCodeTool, createSearchFilesTool, createSendEmailTool, createSpeechToTextTool, createTask, createTaskSnapshots, createTextMessage, createTextToSpeechTool, createVideoProvider, createVideoTools, createWriteFileTool, customToolDelete, customToolDraft, customToolList, customToolLoad, customToolSave, customToolTest, defaultDescribeCall, desktopGetCursor, desktopGetScreenSize, desktopKeyboardKey, desktopKeyboardType, desktopMouseClick, desktopMouseDrag, desktopMouseMove, desktopMouseScroll, desktopScreenshot, desktopTools, desktopWindowFocus, desktopWindowList, detectDependencyCycle, detectServiceFromURL, developerTools, documentToContent, editFile, encodeSharingUrl, evaluateCondition, executeRoutine, extractJSON, extractJSONField, extractNumber, findConnectorByServiceTypes, forPlan, forTasks, formatAttendees, formatFileSize, formatPluginDisplayName, formatRecipients, generateEncryptionKey, generateSimplePlan, generateWebAPITool, getActiveImageModels, getActiveModels, getActiveSTTModels, getActiveTTSModels, getActiveVideoModels, getAllBuiltInTools, getAllServiceIds, getAllVendorLogos, getAllVendorTemplates, getBackgroundOutput, getConnectorTools, getCredentialsSetupURL, getDesktopDriver, getDocsURL, getDrivePrefix, getImageModelInfo, getImageModelsByVendor, getImageModelsWithFeature, getMediaOutputHandler, getMediaStorage, getModelInfo, getModelsByVendor, getNextExecutableTasks, getRegisteredScrapeProviders, getRoutineProgress, getSTTModelInfo, getSTTModelsByVendor, getSTTModelsWithFeature, getServiceDefinition, getServiceInfo, getServicesByCategory, getTTSModelInfo, getTTSModelsByVendor, getTTSModelsWithFeature, getTaskDependencies, getToolByName, getToolCallDescription, getToolCategories, getToolRegistry, getToolsByCategory, getToolsRequiringConnector, getUserPathPrefix, getVendorAuthTemplate, getVendorColor, getVendorDefaultBaseURL, getVendorInfo, getVendorLogo, getVendorLogoCdnUrl, getVendorLogoSvg, getVendorTemplate, getVideoModelInfo, getVideoModelsByVendor, getVideoModelsWithAudio, getVideoModelsWithFeature, glob, globalErrorHandler, grep, hasClipboardImage, hasVendorLogo, hydrateCustomTool, isBlockedCommand, isErrorEvent, isExcludedExtension, isKnownService, isMicrosoftFileUrl, isOutputTextDelta, isReasoningDelta, isReasoningDone, isResponseComplete, isSimpleScope, isStreamEvent, isTaskAwareScope, isTaskBlocked, isTeamsMeetingUrl, isTerminalMemoryStatus, isTerminalStatus, isToolCallArgumentsDelta, isToolCallArgumentsDone, isToolCallStart, isVendor, isWebUrl, killBackgroundProcess, listConnectorsByServiceTypes, listDirectory, listVendorIds, listVendors, listVendorsByAuthType, listVendorsByCategory, listVendorsWithLogos, logger, mergeTextPieces, metrics, microsoftFetch, normalizeEmails, parseKeyCombo, parseRepository, readClipboardImage, readDocumentAsContent, readFile5 as readFile, registerScrapeProvider, resetDefaultDriver, resolveConnector, resolveDependencies, resolveFileEndpoints, resolveFlowSource, resolveMaxContextTokens, resolveMeetingId, resolveModelCapabilities, resolveRepository, resolveTemplates, retryWithBackoff, sanitizeToolName, scopeEquals, scopeMatches, setMediaOutputHandler, setMediaStorage, setMetricsCollector, simpleTokenEstimator, toConnectorOptions, toolRegistry, tools_exports as tools, updateTaskStatus, validatePath, writeFile5 as writeFile };
56501
+ export { AGENT_DEFINITION_FORMAT_VERSION, AIError, APPROVAL_STATE_VERSION, Agent, AgentContextNextGen, ApproximateTokenEstimator, AudioPlaybackQueue, BaseMediaProvider, BasePluginNextGen, BaseProvider, BaseTextProvider, BraveProvider, CONNECTOR_CONFIG_VERSION, CONTEXT_SESSION_FORMAT_VERSION, CUSTOM_TOOL_DEFINITION_VERSION, CheckpointManager, CircuitBreaker, CircuitOpenError, Connector, ConnectorConfigStore, ConnectorTools, ConsoleMetrics, ContentType, ContextOverflowError, DEFAULT_ALLOWLIST, DEFAULT_BACKOFF_CONFIG, DEFAULT_BASE_DELAY_MS, DEFAULT_CHECKPOINT_STRATEGY, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_CONFIG2 as DEFAULT_CONFIG, DEFAULT_CONNECTOR_TIMEOUT, DEFAULT_CONTEXT_CONFIG, DEFAULT_DESKTOP_CONFIG, DEFAULT_FEATURES, DEFAULT_FILESYSTEM_CONFIG, DEFAULT_HISTORY_MANAGER_CONFIG, DEFAULT_MAX_DELAY_MS, DEFAULT_MAX_RETRIES, DEFAULT_MEMORY_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_RATE_LIMITER_CONFIG, DEFAULT_RETRYABLE_STATUSES, DEFAULT_SHELL_CONFIG, DESKTOP_TOOL_NAMES, DefaultCompactionStrategy, DependencyCycleError, DocumentReader, ErrorHandler, EventEmitterTrigger, ExecutionContext, ExternalDependencyHandler, FileAgentDefinitionStorage, FileConnectorStorage, FileContextStorage, FileCustomToolStorage, FileMediaStorage as FileMediaOutputHandler, FileMediaStorage, FilePersistentInstructionsStorage, FileRoutineDefinitionStorage, FileStorage, FileUserInfoStorage, FormatDetector, FrameworkLogger, HookManager, IMAGE_MODELS, IMAGE_MODEL_REGISTRY, ImageGeneration, InContextMemoryPluginNextGen, InMemoryAgentStateStorage, InMemoryHistoryStorage, InMemoryMetrics, InMemoryPlanStorage, InMemoryStorage, InvalidConfigError, InvalidToolArgumentsError, LLM_MODELS, LoggingPlugin, MCPClient, MCPConnectionError, MCPError, MCPProtocolError, MCPRegistry, MCPResourceError, MCPTimeoutError, MCPToolError, MEMORY_PRIORITY_VALUES, MODEL_REGISTRY, MemoryConnectorStorage, MemoryEvictionCompactor, MemoryStorage, MessageBuilder, MessageRole, ModelNotSupportedError, NoOpMetrics, NutTreeDriver, OAuthManager, ParallelTasksError, PersistentInstructionsPluginNextGen, PlanningAgent, ProviderAuthError, ProviderConfigAgent, ProviderContextLengthError, ProviderError, ProviderErrorMapper, ProviderNotFoundError, ProviderRateLimitError, ROUTINE_KEYS, RapidAPIProvider, RateLimitError, SERVICE_DEFINITIONS, SERVICE_INFO, SERVICE_URL_PATTERNS, SIMPLE_ICONS_CDN, STT_MODELS, STT_MODEL_REGISTRY, ScopedConnectorRegistry, ScrapeProvider, SearchProvider, SentenceChunkingStrategy, SerperProvider, Services, SimpleScheduler, SpeechToText, StorageRegistry, StrategyRegistry, StreamEventType, StreamHelpers, StreamState, SummarizeCompactor, TERMINAL_TASK_STATUSES, TTS_MODELS, TTS_MODEL_REGISTRY, TaskTimeoutError, TaskValidationError, TavilyProvider, TextToSpeech, TokenBucketRateLimiter, ToolCallState, ToolCatalogPluginNextGen, ToolCatalogRegistry, ToolExecutionError, ToolExecutionPipeline, ToolManager, ToolNotFoundError, ToolPermissionManager, ToolRegistry, ToolTimeoutError, TruncateCompactor, UserInfoPluginNextGen, VENDORS, VENDOR_ICON_MAP, VIDEO_MODELS, VIDEO_MODEL_REGISTRY, Vendor, VideoGeneration, VoiceStream, WorkingMemory, WorkingMemoryPluginNextGen, addJitter, allVendorTemplates, assertNotDestroyed, authenticatedFetch, backoffSequence, backoffWait, bash, buildAuthConfig, buildEndpointWithQuery, buildQueryString, calculateBackoff, calculateCost, calculateEntrySize, calculateImageCost, calculateSTTCost, calculateTTSCost, calculateVideoCost, canTaskExecute, createAgentStorage, createAuthenticatedFetch, createBashTool, createConnectorFromTemplate, createCreatePRTool, createCustomToolDelete, createCustomToolDraft, createCustomToolList, createCustomToolLoad, createCustomToolMetaTools, createCustomToolSave, createCustomToolTest, createDesktopGetCursorTool, createDesktopGetScreenSizeTool, createDesktopKeyboardKeyTool, createDesktopKeyboardTypeTool, createDesktopMouseClickTool, createDesktopMouseDragTool, createDesktopMouseMoveTool, createDesktopMouseScrollTool, createDesktopScreenshotTool, createDesktopWindowFocusTool, createDesktopWindowListTool, createDraftEmailTool, createEditFileTool, createEditMeetingTool, createEstimator, createExecuteJavaScriptTool, createExecutionRecorder, createFileAgentDefinitionStorage, createFileContextStorage, createFileCustomToolStorage, createFileMediaStorage, createFileRoutineDefinitionStorage, createFindMeetingSlotsTool, createGetMeetingTranscriptTool, createGetPRTool, createGitHubReadFileTool, createGlobTool, createGrepTool, createImageGenerationTool, createImageProvider, createListDirectoryTool, createMeetingTool, createMessageWithImages, createMetricsCollector, createMicrosoftListFilesTool, createMicrosoftReadFileTool, createMicrosoftSearchFilesTool, createPRCommentsTool, createPRFilesTool, createPlan, createProvider, createReadFileTool, createRoutineDefinition, createRoutineExecution, createRoutineExecutionRecord, createSearchCodeTool, createSearchFilesTool, createSendEmailTool, createSpeechToTextTool, createTask, createTaskSnapshots, createTextMessage, createTextToSpeechTool, createVideoProvider, createVideoTools, createWriteFileTool, customToolDelete, customToolDraft, customToolList, customToolLoad, customToolSave, customToolTest, defaultDescribeCall, desktopGetCursor, desktopGetScreenSize, desktopKeyboardKey, desktopKeyboardType, desktopMouseClick, desktopMouseDrag, desktopMouseMove, desktopMouseScroll, desktopScreenshot, desktopTools, desktopWindowFocus, desktopWindowList, detectDependencyCycle, detectServiceFromURL, developerTools, documentToContent, editFile, encodeSharingUrl, evaluateCondition, executeRoutine, extractJSON, extractJSONField, extractNumber, findConnectorByServiceTypes, forPlan, forTasks, formatAttendees, formatFileSize, formatPluginDisplayName, formatRecipients, generateEncryptionKey, generateSimplePlan, generateWebAPITool, getActiveImageModels, getActiveModels, getActiveSTTModels, getActiveTTSModels, getActiveVideoModels, getAllBuiltInTools, getAllServiceIds, getAllVendorLogos, getAllVendorTemplates, getBackgroundOutput, getConnectorTools, getCredentialsSetupURL, getDesktopDriver, getDocsURL, getDrivePrefix, getImageModelInfo, getImageModelsByVendor, getImageModelsWithFeature, getMediaOutputHandler, getMediaStorage, getModelInfo, getModelsByVendor, getNextExecutableTasks, getRegisteredScrapeProviders, getRoutineProgress, getSTTModelInfo, getSTTModelsByVendor, getSTTModelsWithFeature, getServiceDefinition, getServiceInfo, getServicesByCategory, getTTSModelInfo, getTTSModelsByVendor, getTTSModelsWithFeature, getTaskDependencies, getToolByName, getToolCallDescription, getToolCategories, getToolRegistry, getToolsByCategory, getToolsRequiringConnector, getUserPathPrefix, getVendorAuthTemplate, getVendorColor, getVendorDefaultBaseURL, getVendorInfo, getVendorLogo, getVendorLogoCdnUrl, getVendorLogoSvg, getVendorTemplate, getVideoModelInfo, getVideoModelsByVendor, getVideoModelsWithAudio, getVideoModelsWithFeature, glob, globalErrorHandler, grep, hasClipboardImage, hasVendorLogo, hydrateCustomTool, isAudioChunkError, isAudioChunkReady, isAudioStreamComplete, isBlockedCommand, isErrorEvent, isExcludedExtension, isKnownService, isMicrosoftFileUrl, isOutputTextDelta, isReasoningDelta, isReasoningDone, isResponseComplete, isSimpleScope, isStreamEvent, isTaskAwareScope, isTaskBlocked, isTeamsMeetingUrl, isTerminalMemoryStatus, isTerminalStatus, isToolCallArgumentsDelta, isToolCallArgumentsDone, isToolCallStart, isVendor, isWebUrl, killBackgroundProcess, listConnectorsByServiceTypes, listDirectory, listVendorIds, listVendors, listVendorsByAuthType, listVendorsByCategory, listVendorsWithLogos, logger, mergeTextPieces, metrics, microsoftFetch, normalizeEmails, parseKeyCombo, parseRepository, readClipboardImage, readDocumentAsContent, readFile5 as readFile, registerScrapeProvider, resetDefaultDriver, resolveConnector, resolveDependencies, resolveFileEndpoints, resolveFlowSource, resolveMaxContextTokens, resolveMeetingId, resolveModelCapabilities, resolveRepository, resolveTemplates, retryWithBackoff, sanitizeToolName, scopeEquals, scopeMatches, setMediaOutputHandler, setMediaStorage, setMetricsCollector, simpleTokenEstimator, toConnectorOptions, toolRegistry, tools_exports as tools, updateTaskStatus, validatePath, writeFile5 as writeFile };
54588
56502
  //# sourceMappingURL=index.js.map
54589
56503
  //# sourceMappingURL=index.js.map