@juspay/neurolink 12.39.1 → 12.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +2 -2
  2. package/README.md +1 -1
  3. package/dist/auth/middleware/AuthMiddleware.d.ts +1 -1
  4. package/dist/browser/neurolink.min.js +423 -422
  5. package/dist/constants/enums.d.ts +237 -0
  6. package/dist/constants/enums.js +257 -0
  7. package/dist/neurolink.js +46 -21
  8. package/dist/processors/media/VideoProcessor.d.ts +17 -0
  9. package/dist/processors/media/VideoProcessor.js +119 -0
  10. package/dist/providers/catalog/ai21.json +142 -0
  11. package/dist/providers/catalog/aionlabs.json +144 -0
  12. package/dist/providers/catalog/atlas-cloud.json +203 -0
  13. package/dist/providers/catalog/avian-io.json +227 -0
  14. package/dist/providers/catalog/crusoe.json +229 -0
  15. package/dist/providers/catalog/index.generated.d.ts +1 -1
  16. package/dist/providers/catalog/index.generated.js +60 -0
  17. package/dist/providers/catalog/minimax.json +200 -0
  18. package/dist/providers/catalog/moonshot-ai.json +135 -0
  19. package/dist/providers/catalog/nebius.json +165 -0
  20. package/dist/providers/catalog/prime-intellect.json +217 -0
  21. package/dist/providers/catalog/scaleway.json +177 -0
  22. package/dist/providers/catalog/siliconflow.json +242 -0
  23. package/dist/providers/catalog/stepfun.json +155 -0
  24. package/dist/providers/catalog/subconscious.json +93 -0
  25. package/dist/providers/catalog/tinfoil.json +155 -0
  26. package/dist/providers/catalog/umans-ai.json +174 -0
  27. package/dist/providers/catalog/venice-ai.json +208 -0
  28. package/dist/providers/catalog/vultr-inference.json +220 -0
  29. package/dist/providers/catalog/wafer.json +165 -0
  30. package/dist/providers/catalog/wandb-inference.json +249 -0
  31. package/dist/providers/catalog/z-ai.json +255 -0
  32. package/dist/types/providerCatalog.generated.d.ts +2 -2
  33. package/dist/types/providers.d.ts +80 -0
  34. package/docs-site/static/search-index.json +227 -3
  35. package/package.json +3 -2
@@ -22,15 +22,20 @@ export var AIProviderName;
22
22
  AIProviderName["LLAMACPP"] = "llamacpp";
23
23
  // ── BEGIN GENERATED(provider-members): provider catalog (pnpm run codegen:catalog) ──
24
24
  AIProviderName["ABOVE_DEV"] = "above-dev";
25
+ AIProviderName["AI21"] = "ai21";
25
26
  AIProviderName["AIAND"] = "aiand";
27
+ AIProviderName["AIONLABS"] = "aionlabs";
26
28
  AIProviderName["AMBIENT"] = "ambient";
27
29
  AIProviderName["API_ROUTE"] = "api-route";
30
+ AIProviderName["ATLAS_CLOUD"] = "atlas-cloud";
31
+ AIProviderName["AVIAN_IO"] = "avian-io";
28
32
  AIProviderName["BASETEN"] = "baseten";
29
33
  AIProviderName["BEE_HEOSSI"] = "bee-heossi";
30
34
  AIProviderName["CEREBRAS"] = "cerebras";
31
35
  AIProviderName["CHARM_HYPER"] = "charm-hyper";
32
36
  AIProviderName["CHUTES"] = "chutes";
33
37
  AIProviderName["CLOUDFLARE"] = "cloudflare";
38
+ AIProviderName["CRUSOE"] = "crusoe";
34
39
  AIProviderName["DEEPINFRA"] = "deepinfra";
35
40
  AIProviderName["DEEPSEEK"] = "deepseek";
36
41
  AIProviderName["EMPIRIOLABS"] = "empiriolabs";
@@ -48,20 +53,35 @@ export var AIProviderName;
48
53
  AIProviderName["LILAC"] = "lilac";
49
54
  AIProviderName["LLMTECH"] = "llmtech";
50
55
  AIProviderName["MANCER"] = "mancer";
56
+ AIProviderName["MINIMAX"] = "minimax";
51
57
  AIProviderName["MISTRAL"] = "mistral";
52
58
  AIProviderName["MOARK"] = "moark";
59
+ AIProviderName["MOONSHOT_AI"] = "moonshot-ai";
53
60
  AIProviderName["MORPH"] = "morph";
61
+ AIProviderName["NEBIUS"] = "nebius";
54
62
  AIProviderName["NEURALWATT"] = "neuralwatt";
55
63
  AIProviderName["NOVITA"] = "novita";
56
64
  AIProviderName["OVHCLOUD"] = "ovhcloud";
57
65
  AIProviderName["PARETO_INFERENCE"] = "pareto-inference";
58
66
  AIProviderName["PERPLEXITY"] = "perplexity";
67
+ AIProviderName["PRIME_INTELLECT"] = "prime-intellect";
59
68
  AIProviderName["SAMBANOVA"] = "sambanova";
60
69
  AIProviderName["SARVAM"] = "sarvam";
70
+ AIProviderName["SCALEWAY"] = "scaleway";
71
+ AIProviderName["SILICONFLOW"] = "siliconflow";
72
+ AIProviderName["STEPFUN"] = "stepfun";
73
+ AIProviderName["SUBCONSCIOUS"] = "subconscious";
61
74
  AIProviderName["SYNTHETIC"] = "synthetic";
75
+ AIProviderName["TINFOIL"] = "tinfoil";
62
76
  AIProviderName["TOGETHER_AI"] = "together-ai";
77
+ AIProviderName["UMANS_AI"] = "umans-ai";
63
78
  AIProviderName["UPSTAGE"] = "upstage";
79
+ AIProviderName["VENICE_AI"] = "venice-ai";
80
+ AIProviderName["VULTR_INFERENCE"] = "vultr-inference";
81
+ AIProviderName["WAFER"] = "wafer";
82
+ AIProviderName["WANDB_INFERENCE"] = "wandb-inference";
64
83
  AIProviderName["XAI"] = "xai";
84
+ AIProviderName["Z_AI"] = "z-ai";
65
85
  // ── END GENERATED(provider-members) ──
66
86
  AIProviderName["COHERE"] = "cohere";
67
87
  AIProviderName["REPLICATE"] = "replicate";
@@ -1048,6 +1068,15 @@ export var AboveDevModels;
1048
1068
  AboveDevModels["MIMO_V2_6_FLASH"] = "mimo-v2.6-flash";
1049
1069
  AboveDevModels["MIMO_V2_6_PRO_ULTRASPEED"] = "mimo-v2.6-pro-ultraspeed";
1050
1070
  })(AboveDevModels || (AboveDevModels = {}));
1071
+ export var Ai21Models;
1072
+ (function (Ai21Models) {
1073
+ Ai21Models["JAMBA_LARGE"] = "jamba-large";
1074
+ Ai21Models["JAMBA_MINI"] = "jamba-mini";
1075
+ Ai21Models["JAMBA_LARGE_1_7_2025_07"] = "jamba-large-1.7-2025-07";
1076
+ Ai21Models["JAMBA_MINI_2_2026_01"] = "jamba-mini-2-2026-01";
1077
+ Ai21Models["JAMBA_LARGE_1_7"] = "jamba-large-1.7";
1078
+ Ai21Models["JAMBA_MINI_2"] = "jamba-mini-2";
1079
+ })(Ai21Models || (Ai21Models = {}));
1051
1080
  export var AiandModels;
1052
1081
  (function (AiandModels) {
1053
1082
  AiandModels["OPENAI_GPT_OSS_120B"] = "openai/gpt-oss-120b";
@@ -1062,6 +1091,15 @@ export var AiandModels;
1062
1091
  AiandModels["MOTIF_TECHNOLOGIES_MOTIF_3"] = "motif-technologies/motif-3";
1063
1092
  AiandModels["GOOGLE_GEMMA_4_31B_IT"] = "google/gemma-4-31b-it";
1064
1093
  })(AiandModels || (AiandModels = {}));
1094
+ export var AionlabsModels;
1095
+ (function (AionlabsModels) {
1096
+ AionlabsModels["AION_LABS_AION_3_5"] = "aion-labs/aion-3.5";
1097
+ AionlabsModels["AION_LABS_AION_3_5_MINI"] = "aion-labs/aion-3.5-mini";
1098
+ AionlabsModels["AION_LABS_AION_3_0"] = "aion-labs/aion-3.0";
1099
+ AionlabsModels["AION_LABS_AION_3_0_MINI"] = "aion-labs/aion-3.0-mini";
1100
+ AionlabsModels["AION_LABS_AION_2_0"] = "aion-labs/aion-2.0";
1101
+ AionlabsModels["AION_LABS_AION_RP_LLAMA_3_1_8B"] = "aion-labs/aion-rp-llama-3.1-8b";
1102
+ })(AionlabsModels || (AionlabsModels = {}));
1065
1103
  export var AmbientModels;
1066
1104
  (function (AmbientModels) {
1067
1105
  AmbientModels["AMBIENT_LARGE"] = "ambient/large";
@@ -1080,6 +1118,34 @@ export var ApiRouteModels;
1080
1118
  ApiRouteModels["KIMI_K2_7_CODE"] = "kimi-k2.7-code";
1081
1119
  ApiRouteModels["GLM_5_3_FLASH"] = "glm-5.3-flash";
1082
1120
  })(ApiRouteModels || (ApiRouteModels = {}));
1121
+ export var AtlasCloudModels;
1122
+ (function (AtlasCloudModels) {
1123
+ AtlasCloudModels["DEEPSEEK_AI_DEEPSEEK_V3_2"] = "deepseek-ai/deepseek-v3.2";
1124
+ AtlasCloudModels["DEEPSEEK_AI_DEEPSEEK_V4_FLASH"] = "deepseek-ai/deepseek-v4-flash";
1125
+ AtlasCloudModels["ZAI_ORG_GLM_5_3"] = "zai-org/glm-5.3";
1126
+ AtlasCloudModels["QWEN_QWEN3_235B_A22B_INSTRUCT_2507"] = "Qwen/Qwen3-235B-A22B-Instruct-2507";
1127
+ AtlasCloudModels["DEEPSEEK_AI_DEEPSEEK_V4_PRO"] = "deepseek-ai/deepseek-v4-pro";
1128
+ AtlasCloudModels["ZAI_ORG_GLM_5_1"] = "zai-org/glm-5.1";
1129
+ AtlasCloudModels["MINIMAXAI_MINIMAX_M2_7"] = "minimaxai/minimax-m2.7";
1130
+ AtlasCloudModels["MOONSHOTAI_KIMI_K2_6"] = "moonshotai/kimi-k2.6";
1131
+ AtlasCloudModels["QWEN_QWEN3_5_397B_A17B"] = "qwen/qwen3.5-397b-a17b";
1132
+ AtlasCloudModels["QWEN_QWEN3_5_27B"] = "qwen/qwen3.5-27b";
1133
+ })(AtlasCloudModels || (AtlasCloudModels = {}));
1134
+ export var AvianIoModels;
1135
+ (function (AvianIoModels) {
1136
+ AvianIoModels["DEEPSEEK_DEEPSEEK_V4_PRO_0813"] = "deepseek/deepseek-v4-pro-0813";
1137
+ AvianIoModels["DEEPSEEK_DEEPSEEK_V4_FLASH"] = "deepseek/deepseek-v4-flash";
1138
+ AvianIoModels["DEEPSEEK_DEEPSEEK_V3_2"] = "deepseek/deepseek-v3.2";
1139
+ AvianIoModels["Z_AI_GLM_5_2"] = "z-ai/glm-5.2";
1140
+ AvianIoModels["DEEPSEEK_DEEPSEEK_V4_PRO"] = "deepseek/deepseek-v4-pro";
1141
+ AvianIoModels["MINIMAX_MINIMAX_M2_5"] = "minimax/minimax-m2.5";
1142
+ AvianIoModels["Z_AI_GLM_5"] = "z-ai/glm-5";
1143
+ AvianIoModels["Z_AI_GLM_5_1"] = "z-ai/glm-5.1";
1144
+ AvianIoModels["MOONSHOTAI_KIMI_K2_5"] = "moonshotai/kimi-k2.5";
1145
+ AvianIoModels["MOONSHOTAI_KIMI_K2_6"] = "moonshotai/kimi-k2.6";
1146
+ AvianIoModels["XIAOMI_MIMO_V2_6_FLASH"] = "xiaomi/mimo-v2.6-flash";
1147
+ AvianIoModels["XIAOMI_MIMO_V2_6_PRO"] = "xiaomi/mimo-v2.6-pro";
1148
+ })(AvianIoModels || (AvianIoModels = {}));
1083
1149
  export var BasetenModels;
1084
1150
  (function (BasetenModels) {
1085
1151
  BasetenModels["OPENAI_GPT_OSS_120B"] = "openai/gpt-oss-120b";
@@ -1173,6 +1239,21 @@ export var CloudflareModels;
1173
1239
  CloudflareModels["QWEN_1P5_14B_CHAT_AWQ"] = "@cf/qwen/qwen1.5-14b-chat-awq";
1174
1240
  CloudflareModels["GEMMA_2B_IT_LORA"] = "@cf/google/gemma-2b-it-lora";
1175
1241
  })(CloudflareModels || (CloudflareModels = {}));
1242
+ export var CrusoeModels;
1243
+ (function (CrusoeModels) {
1244
+ CrusoeModels["DEEPSEEK_AI_DEEPSEEK_V4_FLASH"] = "deepseek-ai/DeepSeek-V4-Flash";
1245
+ CrusoeModels["DEEPSEEK_AI_DEEPSEEK_V4_PRO"] = "deepseek-ai/DeepSeek-V4-Pro";
1246
+ CrusoeModels["OPENAI_GPT_OSS_120B"] = "openai/gpt-oss-120b";
1247
+ CrusoeModels["ZAI_GLM_5_3"] = "zai/GLM-5.3";
1248
+ CrusoeModels["MOONSHOTAI_KIMI_K2_6"] = "moonshotai/Kimi-K2.6";
1249
+ CrusoeModels["GOOGLE_GEMMA_4_31B_IT"] = "google/gemma-4-31b-it";
1250
+ CrusoeModels["NVIDIA_NEMOTRON_3_NANO_30B_A3B"] = "nvidia/Nemotron-3-Nano-30B-A3B";
1251
+ CrusoeModels["NVIDIA_NEMOTRON_3_SUPER_120B_A12B"] = "nvidia/Nemotron-3-Super-120B-A12B";
1252
+ CrusoeModels["NVIDIA_NEMOTRON_3_NANO_OMNI_REASONING_30B_A3B"] = "nvidia/Nemotron-3-Nano-Omni-Reasoning-30B-A3B";
1253
+ CrusoeModels["NVIDIA_NEMOTRON_3_5_LIGHTNING_30B_A3B"] = "nvidia/nemotron-3.5-lightning-30b-a3b";
1254
+ CrusoeModels["QWEN_QWEN3_8_27B"] = "qwen/Qwen3.8-27B";
1255
+ CrusoeModels["ZAI_GLM_5_3_FLASH"] = "zai/GLM-5.3-Flash";
1256
+ })(CrusoeModels || (CrusoeModels = {}));
1176
1257
  export var DeepinfraModels;
1177
1258
  (function (DeepinfraModels) {
1178
1259
  DeepinfraModels["DEEPSEEK_AI_DEEPSEEK_V4_FLASH_0731"] = "deepseek-ai/DeepSeek-V4-Flash-0731";
@@ -1412,6 +1493,18 @@ export var MancerModels;
1412
1493
  MancerModels["WEAVER_ALPHA"] = "weaver-alpha";
1413
1494
  MancerModels["DANS_PE_1_3_24B"] = "dans-pe-1.3-24b";
1414
1495
  })(MancerModels || (MancerModels = {}));
1496
+ export var MinimaxModels;
1497
+ (function (MinimaxModels) {
1498
+ MinimaxModels["MINIMAX_M3"] = "MiniMax-M3";
1499
+ MinimaxModels["MINIMAX_M3_1_FLASH_PREVIEW"] = "MiniMax-M3.1-Flash-Preview";
1500
+ MinimaxModels["MINIMAX_M2_7"] = "MiniMax-M2.7";
1501
+ MinimaxModels["MINIMAX_M2_7_HIGHSPEED"] = "MiniMax-M2.7-highspeed";
1502
+ MinimaxModels["MINIMAX_M2_5"] = "MiniMax-M2.5";
1503
+ MinimaxModels["MINIMAX_M2_5_HIGHSPEED"] = "MiniMax-M2.5-highspeed";
1504
+ MinimaxModels["MINIMAX_M2_1"] = "MiniMax-M2.1";
1505
+ MinimaxModels["MINIMAX_M2_1_HIGHSPEED"] = "MiniMax-M2.1-highspeed";
1506
+ MinimaxModels["MINIMAX_M2"] = "MiniMax-M2";
1507
+ })(MinimaxModels || (MinimaxModels = {}));
1415
1508
  export var MistralModels;
1416
1509
  (function (MistralModels) {
1417
1510
  MistralModels["MISTRAL_LARGE_LATEST"] = "mistral-large-latest";
@@ -1456,11 +1549,28 @@ export var MoarkModels;
1456
1549
  MoarkModels["KIMI_K3"] = "kimi-k3";
1457
1550
  MoarkModels["DEEPSEEK_V4_PRO_0813"] = "DeepSeek-V4-Pro-0813";
1458
1551
  })(MoarkModels || (MoarkModels = {}));
1552
+ export var MoonshotAiModels;
1553
+ (function (MoonshotAiModels) {
1554
+ MoonshotAiModels["KIMI_K3"] = "kimi-k3";
1555
+ MoonshotAiModels["KIMI_K2_7_CODE"] = "kimi-k2.7-code";
1556
+ MoonshotAiModels["KIMI_K2_7_CODE_HIGHSPEED"] = "kimi-k2.7-code-highspeed";
1557
+ MoonshotAiModels["KIMI_K2_6"] = "kimi-k2.6";
1558
+ })(MoonshotAiModels || (MoonshotAiModels = {}));
1459
1559
  export var MorphModels;
1460
1560
  (function (MorphModels) {
1461
1561
  MorphModels["MORPH_V3_LARGE"] = "morph-v3-large";
1462
1562
  MorphModels["MORPH_V3_FAST"] = "morph-v3-fast";
1463
1563
  })(MorphModels || (MorphModels = {}));
1564
+ export var NebiusModels;
1565
+ (function (NebiusModels) {
1566
+ NebiusModels["QWEN_QWEN3_235B_A22B_INSTRUCT_2507"] = "Qwen/Qwen3-235B-A22B-Instruct-2507";
1567
+ NebiusModels["DEEPSEEK_AI_DEEPSEEK_V4_FLASH_0731"] = "deepseek-ai/DeepSeek-V4-Flash-0731";
1568
+ NebiusModels["OPENAI_GPT_OSS_120B"] = "openai/gpt-oss-120b";
1569
+ NebiusModels["QWEN_QWEN3_30B_A3B_INSTRUCT_2507"] = "Qwen/Qwen3-30B-A3B-Instruct-2507";
1570
+ NebiusModels["NOUSRESEARCH_HERMES_4_405B"] = "NousResearch/Hermes-4-405B";
1571
+ NebiusModels["NVIDIA_NEMOTRON_3_5_LIGHTNING"] = "nvidia/Nemotron-3_5-Lightning";
1572
+ NebiusModels["OPENBMB_MINICPM_V_4_5"] = "openbmb/MiniCPM-V-4_5";
1573
+ })(NebiusModels || (NebiusModels = {}));
1464
1574
  export var NeuralwattModels;
1465
1575
  (function (NeuralwattModels) {
1466
1576
  NeuralwattModels["GLM_5_3"] = "glm-5.3";
@@ -1509,6 +1619,21 @@ export var PerplexityModels;
1509
1619
  PerplexityModels["SONAR_REASONING_PRO"] = "sonar-reasoning-pro";
1510
1620
  PerplexityModels["SONAR_DEEP_RESEARCH"] = "sonar-deep-research";
1511
1621
  })(PerplexityModels || (PerplexityModels = {}));
1622
+ export var PrimeIntellectModels;
1623
+ (function (PrimeIntellectModels) {
1624
+ PrimeIntellectModels["OPENAI_GPT_4_1_MINI"] = "openai/gpt-4.1-mini";
1625
+ PrimeIntellectModels["OPENAI_GPT_4_1"] = "openai/gpt-4.1";
1626
+ PrimeIntellectModels["ANTHROPIC_CLAUDE_SONNET_4_5"] = "anthropic/claude-sonnet-4.5";
1627
+ PrimeIntellectModels["META_LLAMA_LLAMA_3_3_70B_INSTRUCT"] = "meta-llama/llama-3.3-70b-instruct";
1628
+ PrimeIntellectModels["GOOGLE_GEMINI_2_5_FLASH"] = "google/gemini-2.5-flash";
1629
+ PrimeIntellectModels["QWEN_QWEN3_235B_A22B_INSTRUCT_2507"] = "Qwen/Qwen3-235B-A22B-Instruct-2507";
1630
+ PrimeIntellectModels["Z_AI_GLM_5_3"] = "z-ai/glm-5.3";
1631
+ PrimeIntellectModels["OPENAI_GPT_5_4_MINI"] = "openai/gpt-5.4-mini";
1632
+ PrimeIntellectModels["OPENAI_GPT_OSS_120B"] = "openai/gpt-oss-120b";
1633
+ PrimeIntellectModels["DEEPSEEK_DEEPSEEK_V4_FLASH"] = "deepseek/deepseek-v4-flash";
1634
+ PrimeIntellectModels["ANTHROPIC_CLAUDE_HAIKU_4_5"] = "anthropic/claude-haiku-4.5";
1635
+ PrimeIntellectModels["QWEN_QWEN3_5_122B_A10B"] = "Qwen/Qwen3.5-122B-A10B";
1636
+ })(PrimeIntellectModels || (PrimeIntellectModels = {}));
1512
1637
  export var SambanovaModels;
1513
1638
  (function (SambanovaModels) {
1514
1639
  SambanovaModels["META_LLAMA_3_3_70B_INSTRUCT"] = "Meta-Llama-3.3-70B-Instruct";
@@ -1524,6 +1649,49 @@ export var SarvamModels;
1524
1649
  SarvamModels["SARVAM_105B"] = "sarvam-105b";
1525
1650
  SarvamModels["SARVAM_105B_CONVERSATIONS"] = "sarvam-105b-conversations";
1526
1651
  })(SarvamModels || (SarvamModels = {}));
1652
+ export var ScalewayModels;
1653
+ (function (ScalewayModels) {
1654
+ ScalewayModels["MISTRAL_SMALL_3_2_24B_INSTRUCT_2506"] = "mistral-small-3.2-24b-instruct-2506";
1655
+ ScalewayModels["LLAMA_3_3_70B_INSTRUCT"] = "llama-3.3-70b-instruct";
1656
+ ScalewayModels["QWEN3_235B_A22B_INSTRUCT_2507"] = "qwen3-235b-a22b-instruct-2507";
1657
+ ScalewayModels["GEMMA_4_26B_A4B_IT"] = "gemma-4-26b-a4b-it";
1658
+ ScalewayModels["QWEN3_6_35B_A3B"] = "qwen3.6-35b-a3b";
1659
+ ScalewayModels["QWEN3_8_27B"] = "qwen3.8-27b";
1660
+ ScalewayModels["QWEN3_5_397B_A17B"] = "qwen3.5-397b-a17b";
1661
+ ScalewayModels["DEEPSEEK_V4_FLASH_0731"] = "deepseek-v4-flash-0731";
1662
+ ScalewayModels["GLM_5_2"] = "glm-5.2";
1663
+ ScalewayModels["MISTRAL_MEDIUM_3_5_128B"] = "mistral-medium-3.5-128b";
1664
+ ScalewayModels["GPT_OSS_120B"] = "gpt-oss-120b";
1665
+ })(ScalewayModels || (ScalewayModels = {}));
1666
+ export var SiliconflowModels;
1667
+ (function (SiliconflowModels) {
1668
+ SiliconflowModels["DEEPSEEK_AI_DEEPSEEK_V4_PRO"] = "deepseek-ai/DeepSeek-V4-Pro";
1669
+ SiliconflowModels["DEEPSEEK_AI_DEEPSEEK_V4_FLASH"] = "deepseek-ai/DeepSeek-V4-Flash";
1670
+ SiliconflowModels["DEEPSEEK_AI_DEEPSEEK_V3_2"] = "deepseek-ai/DeepSeek-V3.2";
1671
+ SiliconflowModels["ZAI_ORG_GLM_5_1"] = "zai-org/GLM-5.1";
1672
+ SiliconflowModels["ZAI_ORG_GLM_5"] = "zai-org/GLM-5";
1673
+ SiliconflowModels["MOONSHOTAI_KIMI_K2_6"] = "moonshotai/Kimi-K2.6";
1674
+ SiliconflowModels["MOONSHOTAI_KIMI_K2_5"] = "moonshotai/Kimi-K2.5";
1675
+ SiliconflowModels["QWEN_QWEN3_6_27B"] = "Qwen/Qwen3.6-27B";
1676
+ SiliconflowModels["QWEN_QWEN3_6_35B_A3B"] = "Qwen/Qwen3.6-35B-A3B";
1677
+ SiliconflowModels["QWEN_QWEN3_32B"] = "Qwen/Qwen3-32B";
1678
+ SiliconflowModels["QWEN_QWEN3_VL_32B_INSTRUCT"] = "Qwen/Qwen3-VL-32B-Instruct";
1679
+ SiliconflowModels["GOOGLE_GEMMA_4_31B_IT"] = "google/gemma-4-31B-it";
1680
+ })(SiliconflowModels || (SiliconflowModels = {}));
1681
+ export var StepfunModels;
1682
+ (function (StepfunModels) {
1683
+ StepfunModels["STEP_5_PREVIEW"] = "step-5-preview";
1684
+ StepfunModels["STEP_3_7_FLASH"] = "step-3.7-flash";
1685
+ StepfunModels["STEP_3_5_FLASH"] = "step-3.5-flash";
1686
+ StepfunModels["STEP_3_5_FLASH_2603"] = "step-3.5-flash-2603";
1687
+ StepfunModels["STEP_1O_TURBO_VISION"] = "step-1o-turbo-vision";
1688
+ })(StepfunModels || (StepfunModels = {}));
1689
+ export var SubconsciousModels;
1690
+ (function (SubconsciousModels) {
1691
+ SubconsciousModels["SUBCONSCIOUS_GLM_5_3_MARATHON"] = "subconscious/glm-5.3-marathon";
1692
+ SubconsciousModels["SUBCONSCIOUS_DEEPSEEK_V4_1_FLASH_MARATHON"] = "subconscious/deepseek-v4.1-flash-marathon";
1693
+ SubconsciousModels["SUBCONSCIOUS_TIM_QWEN3_6_27B"] = "subconscious/tim-qwen3.6-27b";
1694
+ })(SubconsciousModels || (SubconsciousModels = {}));
1527
1695
  export var SyntheticModels;
1528
1696
  (function (SyntheticModels) {
1529
1697
  SyntheticModels["SYN_LARGE_TEXT"] = "syn:large:text";
@@ -1538,6 +1706,16 @@ export var SyntheticModels;
1538
1706
  SyntheticModels["HF_QWEN_QWEN3_8_27B"] = "hf:Qwen/Qwen3.8-27B";
1539
1707
  SyntheticModels["HF_ZAI_ORG_GLM_4_7_FLASH"] = "hf:zai-org/GLM-4.7-Flash";
1540
1708
  })(SyntheticModels || (SyntheticModels = {}));
1709
+ export var TinfoilModels;
1710
+ (function (TinfoilModels) {
1711
+ TinfoilModels["KIMI_K3"] = "kimi-k3";
1712
+ TinfoilModels["GPT_OSS_120B"] = "gpt-oss-120b";
1713
+ TinfoilModels["GEMMA4_31B"] = "gemma4-31b";
1714
+ TinfoilModels["LLAMA3_3_70B"] = "llama3-3-70b";
1715
+ TinfoilModels["GLM_5_3"] = "glm-5-3";
1716
+ TinfoilModels["GLM_5_3_FLASH"] = "glm-5-3-flash";
1717
+ TinfoilModels["DEEPSEEK_V4_1_FLASH"] = "deepseek-v4-1-flash";
1718
+ })(TinfoilModels || (TinfoilModels = {}));
1541
1719
  export var TogetherAIModels;
1542
1720
  (function (TogetherAIModels) {
1543
1721
  TogetherAIModels["LLAMA_3_3_70B_INSTRUCT_TURBO"] = "meta-llama/Llama-3.3-70B-Instruct-Turbo";
@@ -1553,6 +1731,16 @@ export var TogetherAIModels;
1553
1731
  TogetherAIModels["GEMMA_2_27B_IT"] = "google/gemma-2-27b-it";
1554
1732
  TogetherAIModels["WIZARDLM_2_8X22B"] = "microsoft/WizardLM-2-8x22B";
1555
1733
  })(TogetherAIModels || (TogetherAIModels = {}));
1734
+ export var UmansAiModels;
1735
+ (function (UmansAiModels) {
1736
+ UmansAiModels["UMANS_CODER"] = "umans-coder";
1737
+ UmansAiModels["UMANS_GLM_5_3"] = "umans-glm-5.3";
1738
+ UmansAiModels["UMANS_DEEPSEEK_V4_FLASH_0731"] = "umans-deepseek-v4-flash-0731";
1739
+ UmansAiModels["UMANS_KIMI_K3"] = "umans-kimi-k3";
1740
+ UmansAiModels["UMANS_GLM_5_3_FLASH"] = "umans-glm-5.3-flash";
1741
+ UmansAiModels["UMANS_DEEPSEEK_V4_1_FLASH"] = "umans-deepseek-v4.1-flash";
1742
+ UmansAiModels["UMANS_FLASH"] = "umans-flash";
1743
+ })(UmansAiModels || (UmansAiModels = {}));
1556
1744
  export var UpstageModels;
1557
1745
  (function (UpstageModels) {
1558
1746
  UpstageModels["SOLAR_PRO4"] = "solar-pro4";
@@ -1566,6 +1754,60 @@ export var UpstageModels;
1566
1754
  UpstageModels["SYN_PRO"] = "syn-pro";
1567
1755
  UpstageModels["SYN_PRO_251021"] = "syn-pro-251021";
1568
1756
  })(UpstageModels || (UpstageModels = {}));
1757
+ export var VeniceAiModels;
1758
+ (function (VeniceAiModels) {
1759
+ VeniceAiModels["ZAI_ORG_GLM_5_2"] = "zai-org-glm-5-2";
1760
+ VeniceAiModels["ZAI_ORG_GLM_5"] = "zai-org-glm-5";
1761
+ VeniceAiModels["ZAI_ORG_GLM_5_1"] = "zai-org-glm-5-1";
1762
+ VeniceAiModels["DEEPSEEK_V4_PRO_0813"] = "deepseek-v4-pro-0813";
1763
+ VeniceAiModels["KIMI_K3"] = "kimi-k3";
1764
+ VeniceAiModels["KIMI_K2_6"] = "kimi-k2-6";
1765
+ VeniceAiModels["QWEN3_VL_235B_A22B"] = "qwen3-vl-235b-a22b";
1766
+ VeniceAiModels["VENICE_UNCENSORED_1_2"] = "venice-uncensored-1-2";
1767
+ VeniceAiModels["GROK_4_7"] = "grok-4-7";
1768
+ VeniceAiModels["CLAUDE_OPUS_4_8"] = "claude-opus-4-8";
1769
+ })(VeniceAiModels || (VeniceAiModels = {}));
1770
+ export var VultrInferenceModels;
1771
+ (function (VultrInferenceModels) {
1772
+ VultrInferenceModels["GLM_5_2"] = "glm-5.2";
1773
+ VultrInferenceModels["DEEPSEEK_V4_1_FLASH"] = "deepseek-v4.1-flash";
1774
+ VultrInferenceModels["QWEN3_8_FLASH_NEXT"] = "qwen3.8-flash-next";
1775
+ VultrInferenceModels["MIMO_V2_6_FLASH_RL"] = "mimo-v2.6-flash-rl";
1776
+ VultrInferenceModels["DEEPSEEK_V4_FLASH_0731"] = "deepseek-v4-flash-0731";
1777
+ VultrInferenceModels["GLM_5_3"] = "glm-5.3";
1778
+ VultrInferenceModels["GLM_5_3_FLASH"] = "glm-5.3-flash";
1779
+ VultrInferenceModels["GLM_5_X_MENTHOL"] = "glm-5.x-menthol";
1780
+ VultrInferenceModels["LAGUNA_S_2_1"] = "laguna-s-2.1";
1781
+ VultrInferenceModels["MIMO_V2_6_PRO_RL"] = "mimo-v2.6-pro-rl";
1782
+ VultrInferenceModels["MINIMAX_M3"] = "minimax-m3";
1783
+ VultrInferenceModels["MUSE_GLIMMER_30B"] = "muse-glimmer-30b";
1784
+ })(VultrInferenceModels || (VultrInferenceModels = {}));
1785
+ export var WaferModels;
1786
+ (function (WaferModels) {
1787
+ WaferModels["GLM_5_3"] = "GLM-5.3";
1788
+ WaferModels["DEEPSEEK_V4_PRO"] = "DeepSeek-V4-Pro";
1789
+ WaferModels["KIMI_K3"] = "Kimi-K3";
1790
+ WaferModels["GLM_5_2"] = "GLM-5.2";
1791
+ WaferModels["QWEN3_8_27B"] = "Qwen3.8-27B";
1792
+ WaferModels["GLM_5_3_FLASH"] = "GLM-5.3-Flash";
1793
+ WaferModels["DEEPSEEK_V4_1_FLASH"] = "DeepSeek-V4.1-Flash";
1794
+ WaferModels["DEEPSEEK_V4_FLASH_0731_FAST"] = "DeepSeek-V4-Flash-0731-Fast";
1795
+ })(WaferModels || (WaferModels = {}));
1796
+ export var WandbInferenceModels;
1797
+ (function (WandbInferenceModels) {
1798
+ WandbInferenceModels["OPENAI_GPT_OSS_120B"] = "openai/gpt-oss-120b";
1799
+ WandbInferenceModels["DEEPSEEK_AI_DEEPSEEK_V4_FLASH_0731"] = "deepseek-ai/DeepSeek-V4-Flash-0731";
1800
+ WandbInferenceModels["META_LLAMA_LLAMA_3_3_70B_INSTRUCT"] = "meta-llama/Llama-3.3-70B-Instruct";
1801
+ WandbInferenceModels["OPENAI_GPT_OSS_20B"] = "openai/gpt-oss-20b";
1802
+ WandbInferenceModels["META_LLAMA_LLAMA_3_1_8B_INSTRUCT"] = "meta-llama/Llama-3.1-8B-Instruct";
1803
+ WandbInferenceModels["ZAI_ORG_GLM_5_2"] = "zai-org/GLM-5.2";
1804
+ WandbInferenceModels["DEEPSEEK_AI_DEEPSEEK_V4_PRO_0813"] = "deepseek-ai/DeepSeek-V4-Pro-0813";
1805
+ WandbInferenceModels["GOOGLE_GEMMA_4_26B_A4B_IT"] = "google/gemma-4-26B-A4B-it";
1806
+ WandbInferenceModels["QWEN_QWEN3_8_27B"] = "Qwen/Qwen3.8-27B";
1807
+ WandbInferenceModels["MOONSHOTAI_KIMI_K2_6"] = "moonshotai/Kimi-K2.6";
1808
+ WandbInferenceModels["DEEPSEEK_AI_DEEPSEEK_V4_1_FLASH"] = "deepseek-ai/DeepSeek-V4.1-Flash";
1809
+ WandbInferenceModels["IBM_GRANITE_GRANITE_4_2_8B"] = "ibm-granite/granite-4.2-8b";
1810
+ })(WandbInferenceModels || (WandbInferenceModels = {}));
1569
1811
  export var XaiModels;
1570
1812
  (function (XaiModels) {
1571
1813
  XaiModels["GROK_4_7"] = "grok-4.7";
@@ -1578,6 +1820,21 @@ export var XaiModels;
1578
1820
  XaiModels["GROK_2_VISION_LATEST"] = "grok-2-vision-latest";
1579
1821
  XaiModels["GROK_BETA"] = "grok-beta";
1580
1822
  })(XaiModels || (XaiModels = {}));
1823
+ export var ZAiModels;
1824
+ (function (ZAiModels) {
1825
+ ZAiModels["GLM_5_3"] = "glm-5.3";
1826
+ ZAiModels["GLM_5_3_FLASH"] = "glm-5.3-flash";
1827
+ ZAiModels["GLM_5_3_FLASHX"] = "glm-5.3-flashx";
1828
+ ZAiModels["GLM_5_2"] = "glm-5.2";
1829
+ ZAiModels["GLM_5_1"] = "glm-5.1";
1830
+ ZAiModels["GLM_5"] = "glm-5";
1831
+ ZAiModels["GLM_4_7"] = "glm-4.7";
1832
+ ZAiModels["GLM_4_6"] = "glm-4.6";
1833
+ ZAiModels["GLM_4_5"] = "glm-4.5";
1834
+ ZAiModels["GLM_4_5_AIR"] = "glm-4.5-air";
1835
+ ZAiModels["GLM_4_7_FLASHX"] = "glm-4.7-flashx";
1836
+ ZAiModels["GLM_4_7_FLASH"] = "glm-4.7-flash";
1837
+ })(ZAiModels || (ZAiModels = {}));
1581
1838
  // ── END GENERATED(models-enums) ──
1582
1839
  /**
1583
1840
  * TypeSafe decision models. Hand-written: TypeSafe is a Tier-3 provider, so
package/dist/neurolink.js CHANGED
@@ -7851,11 +7851,33 @@ Current user's request: ${currentInput}`;
7851
7851
  },
7852
7852
  });
7853
7853
  ttsMetadataSink?.(streamTtsMetadata);
7854
+ // E1b: do NOT snapshot mcpStreamOutcome.toolCalls/toolResults here.
7855
+ // For a provider whose tool loop runs in the background (native Vertex
7856
+ // Claude — see the `allToolCalls`-backed getter in
7857
+ // googleVertex/client.ts), toolCalls/toolResults are live getters that
7858
+ // are still empty at this instant: `createMCPStream` has only just
7859
+ // kicked the loop off, and it fills in as the caller drains
7860
+ // `incrementalStream` below. Reading the getter now and storing the
7861
+ // returned VALUE freezes that empty snapshot forever, because a
7862
+ // property assignment is not a live binding — previously only the
7863
+ // cross-provider fallback branch (handleStreamFallback) ever
7864
+ // reassigned it, so every other path returned an empty array even
7865
+ // after the caller had fully drained a stream with real tool calls.
7866
+ // `streamState.toolCalls`/`toolResults` now start undefined and are
7867
+ // set only by that fallback branch; every read goes through
7868
+ // `currentToolCalls`/`currentToolResults`, which fall through to
7869
+ // `mcpStreamOutcome`'s own (possibly still-live) getter so a read
7870
+ // after the stream completes sees the real, current value. Providers
7871
+ // that populate toolCalls eagerly (a plain array, not a getter) are
7872
+ // unaffected — `mcpStreamOutcome.toolCalls` already holds their final
7873
+ // value the first time it's read.
7854
7874
  const streamState = {
7855
7875
  finishReason: mcpStreamOutcome.finishReason ?? "stop",
7856
- toolCalls: mcpStreamOutcome.toolCalls ?? [],
7857
- toolResults: mcpStreamOutcome.toolResults ?? [],
7876
+ toolCalls: undefined,
7877
+ toolResults: undefined,
7858
7878
  };
7879
+ const currentToolCalls = () => streamState.toolCalls ?? mcpStreamOutcome.toolCalls ?? [];
7880
+ const currentToolResults = () => streamState.toolResults ?? mcpStreamOutcome.toolResults ?? [];
7859
7881
  streamSpan.setAttribute(ATTR.NL_PROVIDER, providerName || "unknown");
7860
7882
  let accumulatedContent = "";
7861
7883
  let chunkCount = 0;
@@ -7942,8 +7964,8 @@ Current user's request: ${currentInput}`;
7942
7964
  !cappedByCallerBudget &&
7943
7965
  !metadata.fallbackAttempted &&
7944
7966
  !enhancedOptions.disableInternalFallback &&
7945
- streamState.toolCalls.length === 0 &&
7946
- streamState.toolResults.length === 0) {
7967
+ currentToolCalls().length === 0 &&
7968
+ currentToolResults().length === 0) {
7947
7969
  const fallbackStream = self.handleStreamFallback(metadata, streamState, originalPrompt, enhancedOptions, providerName, (content) => {
7948
7970
  accumulatedContent += content;
7949
7971
  });
@@ -8073,7 +8095,7 @@ Current user's request: ${currentInput}`;
8073
8095
  provider: finalProvider,
8074
8096
  model: finalModel,
8075
8097
  responseTime: Date.now() - streamStartTime,
8076
- toolsUsed: streamState.toolCalls?.map((t) => t.toolName),
8098
+ toolsUsed: currentToolCalls().map((t) => t.toolName),
8077
8099
  timestamp: Date.now(),
8078
8100
  result: {
8079
8101
  content: accumulatedContent,
@@ -8152,29 +8174,32 @@ Current user's request: ${currentInput}`;
8152
8174
  const streamResult = await this.processStreamResult(processedStream, enhancedOptions, factoryResult);
8153
8175
  streamResult.finishReason =
8154
8176
  streamState.finishReason || streamResult.finishReason;
8155
- // Unresolved #1819 review comment: a top-level cross-provider fallback
8156
- // (handleStreamFallback, inside `processedStream` above) only
8157
- // reassigns `streamState.toolCalls`/`toolResults` once the caller
8158
- // starts draining the stream — strictly AFTER this point, since
8159
- // `processedStream` is a lazy async generator and the
8160
- // `processStreamResult` call above resolves without pulling a single
8161
- // chunk. A plain value copy here (`streamResult.toolCalls =
8162
- // streamState.toolCalls`) would freeze whatever streamState held at
8163
- // THIS instant — the primary attempt's (usually empty) arrays —
8164
- // because a property assignment is not a live binding. Define live
8165
- // getters instead so every later read reflects streamState's current
8166
- // value, mirroring the pattern #1819 already used to keep
8167
- // finishReason/usage/model live via getters over streamState/
8168
- // mcpStreamOutcome.
8177
+ // #1819 / E1b: a top-level cross-provider fallback (handleStreamFallback,
8178
+ // inside `processedStream` above) only reassigns
8179
+ // `streamState.toolCalls`/`toolResults` once the caller starts draining
8180
+ // the stream — strictly AFTER this point, since `processedStream` is a
8181
+ // lazy async generator and the `processStreamResult` call above
8182
+ // resolves without pulling a single chunk. A plain value copy here
8183
+ // (`streamResult.toolCalls = streamState.toolCalls`) would freeze
8184
+ // whatever streamState held at THIS instant — always undefined this
8185
+ // early — because a property assignment is not a live binding. Define
8186
+ // live getters instead, routed through `currentToolCalls`/
8187
+ // `currentToolResults` (see their definition above) so every later
8188
+ // read reflects the fallback override once set, and otherwise falls
8189
+ // through live to `mcpStreamOutcome`'s own getter — which is what
8190
+ // fixes a background-tool-loop provider (native Vertex Claude)
8191
+ // reporting empty toolCalls: that getter is only populated by the time
8192
+ // the caller has finished draining the stream, and this getter is read
8193
+ // after that, not frozen before it.
8169
8194
  Object.defineProperty(streamResult, "toolCalls", {
8170
8195
  enumerable: true,
8171
8196
  configurable: true,
8172
- get: () => streamState.toolCalls,
8197
+ get: () => currentToolCalls(),
8173
8198
  });
8174
8199
  Object.defineProperty(streamResult, "toolResults", {
8175
8200
  enumerable: true,
8176
8201
  configurable: true,
8177
- get: () => streamState.toolResults,
8202
+ get: () => currentToolResults(),
8178
8203
  });
8179
8204
  if (!streamResult.usage) {
8180
8205
  streamResult.usage = mcpStreamOutcome.usage;
@@ -129,6 +129,23 @@ export declare class VideoProcessor extends BaseFileProcessor<ProcessedVideo> {
129
129
  * Falls back to ffprobe if mediabunny fails or doesn't support the format.
130
130
  */
131
131
  private probeVideoWithMediabunny;
132
+ /**
133
+ * Read metadata from the ffmpeg binary itself, for hosts that have ffmpeg
134
+ * but no ffprobe (mediabunny cannot read AVI, FLV or WMV, and ffprobe was the
135
+ * only other reader).
136
+ *
137
+ * ffmpeg prints the input's streams to stderr before it opens the output, so
138
+ * a zero-length run to the null muxer is enough to read them.
139
+ */
140
+ private probeVideoWithFfmpeg;
141
+ /**
142
+ * Parse the input section of an ffmpeg banner: `Duration:`, `bitrate:` and
143
+ * one `Stream #…: Video|Audio|Subtitle:` line per stream. Returns undefined
144
+ * when there is no positive duration, since frames cannot be timed without it.
145
+ */
146
+ private parseFfmpegInputReport;
147
+ /** ffmpeg names a layout ("mono", "stereo", "5.1(side)") or counts ("6 channels"). */
148
+ private channelCountFromLayout;
132
149
  /**
133
150
  * Build a structured metadata object from ffprobe data.
134
151
  *
@@ -445,6 +445,20 @@ export class VideoProcessor extends BaseFileProcessor {
445
445
  metadata = this.buildMetadata(probeResult.data, buffer.length);
446
446
  }
447
447
  }
448
+ if (!metadata) {
449
+ // ffmpeg-static ships ffmpeg only, so a host that relies on it has
450
+ // no ffprobe. Without a duration no frame timestamps can be chosen.
451
+ const ffmpegProbe = await this.probeVideoWithFfmpeg(tempVideoPath);
452
+ if (ffmpegProbe.success && ffmpegProbe.data) {
453
+ metadata = { ...ffmpegProbe.data, fileSize: buffer.length };
454
+ }
455
+ else {
456
+ // Nothing downstream reports this: an empty duration selects no
457
+ // frames, the request still succeeds, and the model is simply
458
+ // told nothing about the video.
459
+ logger.warn(`[NEUROLINK] No metadata could be read for ${filename} (mediabunny, ffprobe and ffmpeg all failed), so no keyframes will be extracted: ${ffmpegProbe.error}`);
460
+ }
461
+ }
448
462
  if (!metadata) {
449
463
  metadata = {
450
464
  duration: 0,
@@ -636,6 +650,111 @@ export class VideoProcessor extends BaseFileProcessor {
636
650
  input?.dispose();
637
651
  }
638
652
  }
653
+ /**
654
+ * Read metadata from the ffmpeg binary itself, for hosts that have ffmpeg
655
+ * but no ffprobe (mediabunny cannot read AVI, FLV or WMV, and ffprobe was the
656
+ * only other reader).
657
+ *
658
+ * ffmpeg prints the input's streams to stderr before it opens the output, so
659
+ * a zero-length run to the null muxer is enough to read them.
660
+ */
661
+ async probeVideoWithFfmpeg(filePath) {
662
+ let report;
663
+ try {
664
+ const { stderr } = await runFfmpeg(["-hide_banner", "-i", filePath, "-t", "0", "-f", "null", "-"], { timeoutMs: VIDEO_CONFIG.FFPROBE_TIMEOUT_MS });
665
+ report = stderr;
666
+ }
667
+ catch (error) {
668
+ // A non-zero exit still carries the stream report when the failure came
669
+ // after the input was opened.
670
+ const stderr = error.stderr;
671
+ if (typeof stderr !== "string") {
672
+ return {
673
+ success: false,
674
+ error: `ffmpeg probe failed: ${error instanceof Error ? error.message : String(error)}`,
675
+ };
676
+ }
677
+ report = stderr;
678
+ }
679
+ const data = this.parseFfmpegInputReport(report);
680
+ return data
681
+ ? { success: true, data }
682
+ : { success: false, error: "ffmpeg reported no duration" };
683
+ }
684
+ /**
685
+ * Parse the input section of an ffmpeg banner: `Duration:`, `bitrate:` and
686
+ * one `Stream #…: Video|Audio|Subtitle:` line per stream. Returns undefined
687
+ * when there is no positive duration, since frames cannot be timed without it.
688
+ */
689
+ parseFfmpegInputReport(report) {
690
+ const lines = report.split(/\r?\n/);
691
+ const outputStart = lines.findIndex((line) => line.startsWith("Output #"));
692
+ const inputLines = outputStart === -1 ? lines : lines.slice(0, outputStart);
693
+ const inputText = inputLines.join("\n");
694
+ const durationMatch = /Duration:\s*(\d+):(\d{2}):(\d{2}(?:\.\d+)?)/.exec(inputText);
695
+ if (!durationMatch) {
696
+ return undefined;
697
+ }
698
+ const duration = Number(durationMatch[1]) * 3600 +
699
+ Number(durationMatch[2]) * 60 +
700
+ Number(durationMatch[3]);
701
+ if (!(duration > 0)) {
702
+ return undefined;
703
+ }
704
+ const streams = inputLines.flatMap((line) => {
705
+ const match = /^\s*Stream #\d+:\d+(?:\[[^\]]*\])?(?:\([^)]*\))?:\s*(Video|Audio|Subtitle):\s*(.*)$/.exec(line);
706
+ return match ? [{ kind: match[1], details: match[2] }] : [];
707
+ });
708
+ const video = streams.find((stream) => stream.kind === "Video" && !stream.details.includes("attached pic"));
709
+ const audio = streams.find((stream) => stream.kind === "Audio");
710
+ const size = video
711
+ ? /(?:^|[\s,])(\d{2,5})x(\d{2,5})(?=[\s,[]|$)/.exec(video.details)
712
+ : null;
713
+ const frameRate = video
714
+ ? /,\s*(\d+(?:\.\d+)?)\s*(?:fps|tbr)/.exec(video.details)
715
+ : null;
716
+ const bitrate = /bitrate:\s*(\d+)\s*kb\/s/.exec(inputText);
717
+ const sampleRate = audio ? /(\d+)\s*Hz/.exec(audio.details) : null;
718
+ const layout = audio ? /Hz,\s*([^,]+)/.exec(audio.details) : null;
719
+ return {
720
+ duration,
721
+ durationFormatted: this.formatDuration(duration),
722
+ width: size ? Number(size[1]) : 0,
723
+ height: size ? Number(size[2]) : 0,
724
+ codec: video
725
+ ? (/^([^\s,(]+)/.exec(video.details)?.[1] ?? "unknown")
726
+ : "unknown",
727
+ fps: frameRate ? Number(frameRate[1]) : 0,
728
+ bitrate: bitrate ? Number(bitrate[1]) * 1000 : 0,
729
+ audioCodec: audio ? /^([^\s,(]+)/.exec(audio.details)?.[1] : undefined,
730
+ audioChannels: layout
731
+ ? this.channelCountFromLayout(layout[1])
732
+ : undefined,
733
+ audioSampleRate: sampleRate ? Number(sampleRate[1]) : undefined,
734
+ subtitleTracks: streams.filter((stream) => stream.kind === "Subtitle")
735
+ .length,
736
+ fileSize: 0,
737
+ };
738
+ }
739
+ /** ffmpeg names a layout ("mono", "stereo", "5.1(side)") or counts ("6 channels"). */
740
+ channelCountFromLayout(layout) {
741
+ const named = new Map([
742
+ ["mono", 1],
743
+ ["stereo", 2],
744
+ ["quad", 4],
745
+ ]);
746
+ const trimmed = layout.trim();
747
+ const namedCount = named.get(trimmed);
748
+ if (namedCount !== undefined) {
749
+ return namedCount;
750
+ }
751
+ const counted = /^(\d+) channels?/.exec(trimmed);
752
+ if (counted) {
753
+ return Number(counted[1]);
754
+ }
755
+ const dotted = /^(\d+)\.(\d)/.exec(trimmed);
756
+ return dotted ? Number(dotted[1]) + Number(dotted[2]) : undefined;
757
+ }
639
758
  /**
640
759
  * Build a structured metadata object from ffprobe data.
641
760
  *