fluxflow-cli 3.19.1 โ†’ 3.19.2

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/ARCHITECTURE.md CHANGED
@@ -1,3 +1,6 @@
1
+ ##### **THIS DOCUMENTATION FILE IS OUTDATED & NO LONGER MAINTAINED. TO SEE LATEST ARCHITECTURAL DOCUMENTATION & CHANGES VISIT: [FluxFlow Architecture Documentation](https://fluxflow-cli.onrender.com/architecture/)**
2
+ ##### [Changelog](https://fluxflow-cli.onrender.com/changelog.html)
3
+
1
4
  # ๐Ÿ›๏ธ Architecture & Design
2
5
 
3
6
  Flux Flow is built on a modern, reactive stack that brings web-like development paradigms to the terminal. It utilizes a custom agentic loop for reasoning and a unique dual-model system for background processing.
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  ๐Ÿ“– **[Official Documentation](https://fluxflow-cli.onrender.com/)**
13
13
 
14
- **Flux Flow** is not just another CLIโ€”it's a high-speed, sassy, and goal-oriented CLI AI Agent powered by the latest Gemini/Gemma frontier models. Designed for developers who demand a premium UI/UX while managing complex file-system tasks, web research, and autonomous workflows.
14
+ **Flux Flow** is not just another CLIโ€”it's a high-speed, sassy, and goal-oriented CLI AI Agent powered by multi-provider frontier models (Google Gemini, DeepSeek, OpenRouter, and more). Designed for developers who demand a premium UI/UX while managing complex file-system tasks, web research, and autonomous workflows.
15
15
 
16
16
  ---
17
17
 
package/TOOLS.md CHANGED
@@ -1,3 +1,6 @@
1
+ ##### **THIS DOCUMENTATION FILE IS OUTDATED & NO LONGER MAINTAINED. TO SEE LATEST TOOLS DOCUMENTATION & AVAILABILITY VISIT: [FluxFlow Tools Documentation](https://fluxflow-cli.onrender.com/tools/)**
2
+ ##### [Changelog](https://fluxflow-cli.onrender.com/changelog.html)
3
+
1
4
  # ๐Ÿงฐ Agent Tools & Capabilities
2
5
 
3
6
  Flux Flow provides a robust set of tools that allow the AI to interact with the file system, execute code, and search the web. The availability of these tools depends on the active operating mode.
package/UI_FEATURES.md CHANGED
@@ -1,3 +1,6 @@
1
+ ##### **THIS DOCUMENTATION FILE IS OUTDATED & NO LONGER MAINTAINED. TO SEE LATEST UI FEATURES & CHANGES VISIT: [FluxFlow Documentation](https://fluxflow-cli.onrender.com/)**
2
+ ##### [Changelog](https://fluxflow-cli.onrender.com/changelog.html)
3
+
1
4
  # ๐ŸŽฎ User Interface & Interaction Features
2
5
 
3
6
  Flux Flow is designed to be a high-performance terminal application. Beyond basic chat, it includes a variety of advanced UI features and human-in-the-loop controls to keep you in command of the agent.
@@ -88,4 +91,4 @@ Flux Flow is a "Self-Healing" agent. It actively monitors its own environment to
88
91
 
89
92
  - **Startup Integrity Check**: On launch, Flux performs a "Heartbeat Check" on its internal engines.
90
93
  - **Automatic Recovery**: If a dependency is missing, you will see a `๐Ÿ”ง [SYSTEM] Initializing...` message. Flux will autonomously download and configure the required binaries using `pnpm` or `npx` fallbacks, keeping you informed every step of the way.
91
- - **Silent Maintenance**: Once the engine is ready, you'll receive a `โœ… [SYSTEM] All dependencies installed successfully.` confirmation.
94
+ - **Silent Maintenance**: Once the engine is ready, you'll receive a `โœ… [SYSTEM] All dependencies installed successfully.` confirmation.
package/dist/fluxflow.js CHANGED
@@ -6977,7 +6977,8 @@ TOOL RULES:
6977
6977
  ${mode === "Flux" ? `- JSON ESCAPE ALL LITERAL ESCAPE SEQUENCES IN TOOL ARGUMENTS
6978
6978
  - SAME file, MULTIPLE edits? ONE PatchFile (\u226415 blocks) \u2190 PRIORITY
6979
6979
  - Tool denied? Ask for guidance \u2190 MANDATORY
6980
- - Need text or huge files? SearchKeyword > Full Read
6980
+ - Need text or HUGE file? SearchKeyword > Full Read
6981
+ - MUST AVOID UNNECESSARY LARGE-FILE CHUNK READS
6981
6982
  ` : ""}
6982
6983
  - COMMUNICATION WITH USER -
6983
6984
  - [tool:functions.Ask(question="...", optionA="title::description", ...MAX4)]. Ambiguity: MUST for path divergence, security risk. Ask, don't finish/guess. Keep titles short
@@ -9863,7 +9864,7 @@ ${projectContextBlock}${isMemoryEnabled ? `
9863
9864
  -- MEMORY RULES --
9864
9865
  - Subtly Personalize with RELEVENT CONTEXTUAL MEMORIES. Auto Saves
9865
9866
  ` : ""}
9866
- -- SECURITY RULES --
9867
+ -- SECURITY POLICIES --
9867
9868
  - Sensitive files? Ask before Read${isSystemDir ? "\n- PROTECTED DIRECTORY" : ""}
9868
9869
 
9869
9870
  -- CHAT FORMATTING --
@@ -15372,34 +15373,51 @@ var init_ai = __esm({
15372
15373
  for (const line of lines) {
15373
15374
  const cleanLine = line.trim();
15374
15375
  if (!cleanLine || !cleanLine.startsWith("data: ")) continue;
15375
- if (cleanLine === "data: [DONE]") break;
15376
- try {
15377
- const json = JSON.parse(cleanLine.substring(6));
15378
- const delta = json.choices?.[0]?.delta;
15379
- const usage = json.usage;
15380
- if (usage) {
15381
- latestUsageMetadata = {
15382
- totalTokenCount: usage.total_tokens || usage.prompt_tokens + usage.completion_tokens,
15383
- promptTokenCount: usage.prompt_tokens || 0,
15384
- candidatesTokenCount: usage.completion_tokens || 0,
15385
- cachedContentTokenCount: usage.prompt_tokens_details?.cached_tokens || 0,
15386
- thoughtsTokenCount: usage.completion_tokens_details?.reasoning_tokens || 0
15387
- };
15388
- hasNewData = true;
15389
- }
15390
- if (delta) {
15391
- const thought = delta.reasoning_content || null;
15392
- if (thought) {
15393
- pendingParts.push({ text: thought, thought: true });
15394
- hasNewData = true;
15376
+ let isDone = false;
15377
+ if (cleanLine === "data: [DONE]") {
15378
+ isDone = true;
15379
+ } else {
15380
+ try {
15381
+ const json = JSON.parse(cleanLine.substring(6));
15382
+ const delta = json.choices?.[0]?.delta;
15383
+ const usage = json.usage;
15384
+ if (json.choices?.[0]?.finish_reason) {
15385
+ isDone = true;
15395
15386
  }
15396
- if (delta.content) {
15397
- pendingParts.push({ text: delta.content });
15387
+ if (usage) {
15388
+ latestUsageMetadata = {
15389
+ totalTokenCount: usage.total_tokens || usage.prompt_tokens + usage.completion_tokens,
15390
+ promptTokenCount: usage.prompt_tokens || 0,
15391
+ candidatesTokenCount: usage.completion_tokens || 0,
15392
+ cachedContentTokenCount: usage.prompt_tokens_details?.cached_tokens || 0,
15393
+ thoughtsTokenCount: usage.completion_tokens_details?.reasoning_tokens || 0
15394
+ };
15398
15395
  hasNewData = true;
15399
15396
  }
15397
+ if (delta) {
15398
+ const thought = delta.reasoning_content || null;
15399
+ if (thought) {
15400
+ pendingParts.push({ text: thought, thought: true });
15401
+ hasNewData = true;
15402
+ }
15403
+ if (delta.content) {
15404
+ pendingParts.push({ text: delta.content });
15405
+ hasNewData = true;
15406
+ }
15407
+ }
15408
+ } catch (e) {
15400
15409
  }
15401
- } catch (e) {
15402
15410
  }
15411
+ if ((isDone || Date.now() - lastFlushTime >= 150) && hasNewData) {
15412
+ yield {
15413
+ candidates: pendingParts.length > 0 ? [{ content: { parts: [...pendingParts] } }] : [],
15414
+ usageMetadata: latestUsageMetadata
15415
+ };
15416
+ pendingParts = [];
15417
+ lastFlushTime = Date.now();
15418
+ hasNewData = false;
15419
+ }
15420
+ if (isDone) break;
15403
15421
  }
15404
15422
  if (Date.now() - lastFlushTime >= 150 && hasNewData) {
15405
15423
  yield {
@@ -15497,33 +15515,50 @@ var init_ai = __esm({
15497
15515
  for (const line of lines) {
15498
15516
  const cleanLine = line.trim();
15499
15517
  if (!cleanLine || !cleanLine.startsWith("data: ")) continue;
15500
- if (cleanLine === "data: [DONE]") break;
15501
- try {
15502
- const json = JSON.parse(cleanLine.substring(6));
15503
- const delta = json.choices?.[0]?.delta;
15504
- const usage = json.usage;
15505
- if (usage) {
15506
- latestUsageMetadata = {
15507
- totalTokenCount: usage.total_tokens || (usage.prompt_tokens || 0) + (usage.completion_tokens || 0),
15508
- promptTokenCount: usage.prompt_tokens || 0,
15509
- candidatesTokenCount: usage.completion_tokens || 0,
15510
- cachedContentTokenCount: usage.prompt_tokens_details?.cached_tokens || 0,
15511
- thoughtsTokenCount: 0
15512
- };
15513
- hasNewData = true;
15514
- }
15515
- if (delta) {
15516
- if (delta.thinking) {
15517
- pendingParts.push({ text: delta.thinking, thought: true });
15518
- hasNewData = true;
15518
+ let isDone = false;
15519
+ if (cleanLine === "data: [DONE]") {
15520
+ isDone = true;
15521
+ } else {
15522
+ try {
15523
+ const json = JSON.parse(cleanLine.substring(6));
15524
+ const delta = json.choices?.[0]?.delta;
15525
+ const usage = json.usage;
15526
+ if (json.choices?.[0]?.finish_reason) {
15527
+ isDone = true;
15519
15528
  }
15520
- if (delta.content) {
15521
- pendingParts.push({ text: delta.content });
15529
+ if (usage) {
15530
+ latestUsageMetadata = {
15531
+ totalTokenCount: usage.total_tokens || (usage.prompt_tokens || 0) + (usage.completion_tokens || 0),
15532
+ promptTokenCount: usage.prompt_tokens || 0,
15533
+ candidatesTokenCount: usage.completion_tokens || 0,
15534
+ cachedContentTokenCount: usage.prompt_tokens_details?.cached_tokens || 0,
15535
+ thoughtsTokenCount: 0
15536
+ };
15522
15537
  hasNewData = true;
15523
15538
  }
15539
+ if (delta) {
15540
+ if (delta.thinking) {
15541
+ pendingParts.push({ text: delta.thinking, thought: true });
15542
+ hasNewData = true;
15543
+ }
15544
+ if (delta.content) {
15545
+ pendingParts.push({ text: delta.content });
15546
+ hasNewData = true;
15547
+ }
15548
+ }
15549
+ } catch (e) {
15524
15550
  }
15525
- } catch (e) {
15526
15551
  }
15552
+ if ((isDone || Date.now() - lastFlushTime >= 150) && hasNewData) {
15553
+ yield {
15554
+ candidates: pendingParts.length > 0 ? [{ content: { parts: [...pendingParts] } }] : [],
15555
+ usageMetadata: latestUsageMetadata
15556
+ };
15557
+ pendingParts = [];
15558
+ lastFlushTime = Date.now();
15559
+ hasNewData = false;
15560
+ }
15561
+ if (isDone) break;
15527
15562
  }
15528
15563
  if (Date.now() - lastFlushTime >= 150 && hasNewData) {
15529
15564
  yield {
@@ -15716,9 +15751,14 @@ var init_ai = __esm({
15716
15751
  buffer += decoder.decode(value, { stream: true });
15717
15752
  const lines = buffer.split("\n");
15718
15753
  buffer = lines.pop();
15754
+ let isDone = false;
15719
15755
  for (const line of lines) {
15720
15756
  const trimmed = line.trim();
15721
- if (!trimmed || trimmed === "data: [DONE]") continue;
15757
+ if (!trimmed) continue;
15758
+ if (trimmed === "data: [DONE]") {
15759
+ isDone = true;
15760
+ break;
15761
+ }
15722
15762
  if (trimmed.startsWith("data: ")) {
15723
15763
  let json;
15724
15764
  try {
@@ -15729,6 +15769,9 @@ var init_ai = __esm({
15729
15769
  if (json.error) {
15730
15770
  throw new Error(`NVIDIA Stream Error: ${json.error.message || JSON.stringify(json.error)}`);
15731
15771
  }
15772
+ if (json.choices?.[0]?.finish_reason) {
15773
+ isDone = true;
15774
+ }
15732
15775
  try {
15733
15776
  const usage = json.usage;
15734
15777
  if (usage) {
@@ -15755,7 +15798,7 @@ var init_ai = __esm({
15755
15798
  }
15756
15799
  }
15757
15800
  }
15758
- if (Date.now() - lastFlushTime >= 350 && hasNewData) {
15801
+ if ((isDone || Date.now() - lastFlushTime >= 350) && hasNewData) {
15759
15802
  yield {
15760
15803
  candidates: pendingParts.length > 0 ? [{ content: { parts: [...pendingParts] } }] : [],
15761
15804
  usageMetadata: latestUsageMetadata
@@ -15765,6 +15808,7 @@ var init_ai = __esm({
15765
15808
  lastFlushTime = Date.now();
15766
15809
  hasNewData = false;
15767
15810
  }
15811
+ if (isDone) break;
15768
15812
  }
15769
15813
  break;
15770
15814
  } catch (error) {
@@ -15982,43 +16026,51 @@ var init_ai = __esm({
15982
16026
  for (const line of lines) {
15983
16027
  const cleanLine = line.trim();
15984
16028
  if (!cleanLine || !cleanLine.startsWith("data: ")) continue;
15985
- if (cleanLine === "data: [DONE]") break;
15986
- try {
15987
- const json = JSON.parse(cleanLine.substring(6));
15988
- const delta = json.choices?.[0]?.delta;
15989
- const usage = json.usage;
15990
- if (usage) {
15991
- latestUsageMetadata = {
15992
- totalTokenCount: usage.total_tokens || (usage.prompt_tokens || 0) + (usage.completion_tokens || 0),
15993
- promptTokenCount: usage.prompt_tokens || 0,
15994
- candidatesTokenCount: usage.completion_tokens || 0,
15995
- cachedContentTokenCount: usage.prompt_tokens_details?.cached_tokens || usage.prompt_tokens_details?.cache_read_input_tokens || usage.cache_read_input_tokens || 0,
15996
- thoughtsTokenCount: usage.completion_tokens_details?.reasoning_tokens || 0
15997
- };
15998
- hasNewData = true;
15999
- }
16000
- if (delta) {
16001
- const thought = delta.reasoning || (delta.reasoning_details ? delta.reasoning_details.map((d) => d.text).join("") : null);
16002
- if (thought) {
16003
- pendingParts.push({ text: thought, thought: true });
16004
- hasNewData = true;
16029
+ let isDone = false;
16030
+ if (cleanLine === "data: [DONE]") {
16031
+ isDone = true;
16032
+ } else {
16033
+ try {
16034
+ const json = JSON.parse(cleanLine.substring(6));
16035
+ const delta = json.choices?.[0]?.delta;
16036
+ const usage = json.usage;
16037
+ if (json.choices?.[0]?.finish_reason) {
16038
+ isDone = true;
16005
16039
  }
16006
- if (delta.content) {
16007
- pendingParts.push({ text: delta.content });
16040
+ if (usage) {
16041
+ latestUsageMetadata = {
16042
+ totalTokenCount: usage.total_tokens || (usage.prompt_tokens || 0) + (usage.completion_tokens || 0),
16043
+ promptTokenCount: usage.prompt_tokens || 0,
16044
+ candidatesTokenCount: usage.completion_tokens || 0,
16045
+ cachedContentTokenCount: usage.prompt_tokens_details?.cached_tokens || usage.prompt_tokens_details?.cache_read_input_tokens || usage.cache_read_input_tokens || 0,
16046
+ thoughtsTokenCount: usage.completion_tokens_details?.reasoning_tokens || 0
16047
+ };
16008
16048
  hasNewData = true;
16009
16049
  }
16050
+ if (delta) {
16051
+ const thought = delta.reasoning || (delta.reasoning_details ? delta.reasoning_details.map((d) => d.text).join("") : null);
16052
+ if (thought) {
16053
+ pendingParts.push({ text: thought, thought: true });
16054
+ hasNewData = true;
16055
+ }
16056
+ if (delta.content) {
16057
+ pendingParts.push({ text: delta.content });
16058
+ hasNewData = true;
16059
+ }
16060
+ }
16061
+ } catch (e) {
16010
16062
  }
16011
- } catch (e) {
16012
16063
  }
16013
- }
16014
- if (Date.now() - lastFlushTime >= 150 && hasNewData) {
16015
- yield {
16016
- candidates: pendingParts.length > 0 ? [{ content: { parts: [...pendingParts] } }] : [],
16017
- usageMetadata: latestUsageMetadata
16018
- };
16019
- pendingParts = [];
16020
- lastFlushTime = Date.now();
16021
- hasNewData = false;
16064
+ if ((isDone || Date.now() - lastFlushTime >= 150) && hasNewData) {
16065
+ yield {
16066
+ candidates: pendingParts.length > 0 ? [{ content: { parts: [...pendingParts] } }] : [],
16067
+ usageMetadata: latestUsageMetadata
16068
+ };
16069
+ pendingParts = [];
16070
+ lastFlushTime = Date.now();
16071
+ hasNewData = false;
16072
+ }
16073
+ if (isDone) break;
16022
16074
  }
16023
16075
  }
16024
16076
  };
@@ -16091,18 +16143,24 @@ var init_ai = __esm({
16091
16143
  hasNewData = true;
16092
16144
  }
16093
16145
  if (chunk.done) {
16094
- const evalNs = chunk.prompt_eval_duration || 0;
16095
- const isCached = evalNs > 0 && evalNs < 75e6;
16146
+ let cachedCount = chunk.prompt_cached_count || 0;
16147
+ if (!cachedCount && chunk.prompt_eval_count) {
16148
+ const evalNs = chunk.prompt_eval_duration || 0;
16149
+ if (evalNs > 0 && evalNs < 75e6) {
16150
+ cachedCount = chunk.prompt_eval_count;
16151
+ }
16152
+ }
16096
16153
  latestUsageMetadata = {
16097
16154
  totalTokenCount: (chunk.prompt_eval_count || 0) + (chunk.eval_count || 0),
16098
16155
  promptTokenCount: chunk.prompt_eval_count || 0,
16099
16156
  candidatesTokenCount: chunk.eval_count || 0,
16100
- cachedContentTokenCount: chunk.prompt_eval_count && isCached ? chunk.prompt_eval_count : 0,
16157
+ cachedContentTokenCount: cachedCount,
16101
16158
  thoughtsTokenCount: 0
16159
+ // Note: Ollama does not natively return a separate sub-count for thoughts yet
16102
16160
  };
16103
16161
  hasNewData = true;
16104
16162
  }
16105
- if (Date.now() - lastFlushTime >= 150 && hasNewData) {
16163
+ if (chunk.done || Date.now() - lastFlushTime >= 150 && hasNewData) {
16106
16164
  yield {
16107
16165
  candidates: pendingParts.length > 0 ? [{ content: { parts: [...pendingParts] } }] : [],
16108
16166
  usageMetadata: latestUsageMetadata
@@ -17850,7 +17908,7 @@ ${combinedNudge}`;
17850
17908
  if (!text || !text.includes("[tool:")) return text;
17851
17909
  const THINK_OPEN_PH = "___THINK_OPEN_TAG___";
17852
17910
  const THINK_CLOSE_PH = "___THINK_CLOSE_TAG___";
17853
- text = text.replaceAll("<think>", THINK_OPEN_PH).replaceAll("</think>", THINK_CLOSE_PH);
17911
+ text = text.replace("<think>", THINK_OPEN_PH).replace("</think>", THINK_CLOSE_PH);
17854
17912
  text = text.replace(/<(\w+)(?:[^>]*)>\s*([\s\S]*?\[tool:[^\]]*\][\s\S]*?)\s*<\/\1>/gi, (match2, tagName, innerContent) => {
17855
17913
  if (innerContent && innerContent.includes("[tool:")) return innerContent.trim();
17856
17914
  return match2;
@@ -19933,6 +19991,7 @@ Error Log can be found in ${path26.join(LOGS_DIR, "agent", "error.log")}`);
19933
19991
  if (lower === "openrouter") return "OpenRouter";
19934
19992
  if (lower === "nvidia") return "NVIDIA";
19935
19993
  if (lower === "mistral") return "Mistral";
19994
+ if (lower === "ollama") return "Ollama";
19936
19995
  return null;
19937
19996
  };
19938
19997
  const envSubagentProvider = normalizeProvider(envSubagentProviderRaw);
@@ -19997,6 +20056,7 @@ TOOL RULES:
19997
20056
  - JSON ESCAPE ALL LITERAL ESCAPE SEQUENCES IN TOOL ARGUMENTS
19998
20057
  - SAME file, MULTIPLE edits? ONE PatchFile (\u226415 blocks) \u2190 PRIORITY
19999
20058
  - Need text or huge files? SearchKeyword > Full Read
20059
+ - MUST AVOID UNNECESSARY LARGE-FILE CHUNK READS
20000
20060
  - Restricted Shell Access, No Deletion
20001
20061
  - ONLY valid tools and syntax defined below are allowed
20002
20062
 
@@ -21439,7 +21499,7 @@ function App({ args = [] }) {
21439
21499
  }
21440
21500
  const envModel = process.env.SUBAGENT_MODEL ? process.env.SUBAGENT_MODEL.trim() : null;
21441
21501
  const envProviderRaw = process.env.SUBAGENT_PROVIDER ? process.env.SUBAGENT_PROVIDER.trim() : null;
21442
- const ALL_PROVIDERS = ["Google", "DeepSeek", "OpenRouter", "NVIDIA", "Mistral"];
21502
+ const ALL_PROVIDERS = ["Google", "DeepSeek", "OpenRouter", "NVIDIA", "Mistral", "Ollama"];
21443
21503
  const normalizeProvider = (pStr) => {
21444
21504
  if (!pStr) return null;
21445
21505
  const lower = pStr.toLowerCase();
@@ -21448,6 +21508,7 @@ function App({ args = [] }) {
21448
21508
  if (lower === "openrouter") return "OpenRouter";
21449
21509
  if (lower === "nvidia") return "NVIDIA";
21450
21510
  if (lower === "mistral") return "Mistral";
21511
+ if (lower === "ollama") return "Ollama";
21451
21512
  return null;
21452
21513
  };
21453
21514
  const envProvider = normalizeProvider(envProviderRaw);
package/model_config.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": 0,
2
+ "version": 1,
3
3
  "release": 20260806,
4
4
  "fallbacks": {
5
5
  "janitor_default": "gemini-3.1-flash-lite",
@@ -42,6 +42,21 @@
42
42
  "multimodal": false,
43
43
  "desc": "Cost Saving (Text Only) [EXPERIMENTAL]"
44
44
  },
45
+ {
46
+ "cmd": "ministral-3b-2512",
47
+ "multimodal": false,
48
+ "desc": "Cost Saving (Text Only) [EXPERIMENTAL]"
49
+ },
50
+ {
51
+ "cmd": "ministral-8b-2512",
52
+ "multimodal": false,
53
+ "desc": "Cost Saving (Text Only) [EXPERIMENTAL]"
54
+ },
55
+ {
56
+ "cmd": "ministral-14b-2512",
57
+ "multimodal": false,
58
+ "desc": "Cost Saving (Text Only) [EXPERIMENTAL]"
59
+ },
45
60
  {
46
61
  "cmd": "mistral-small-2506",
47
62
  "multimodal": false,
@@ -53,10 +68,15 @@
53
68
  "desc": "Devstral Coding (Text Only) [EXPERIMENTAL]"
54
69
  },
55
70
  {
56
- "cmd": "mistral-medium-2505",
71
+ "cmd": "mistral-medium-2508",
57
72
  "multimodal": true,
58
73
  "desc": "Mistral Medium (Multimodal)"
59
74
  },
75
+ {
76
+ "cmd": "mistral-large-2512",
77
+ "multimodal": true,
78
+ "desc": "Mistral Large (Multimodal)"
79
+ },
60
80
  {
61
81
  "cmd": "labs-leanstral-1-5-1",
62
82
  "multimodal": false,
@@ -73,6 +93,21 @@
73
93
  "multimodal": false,
74
94
  "desc": "Cost Saving (Text Only) [EXPERIMENTAL]"
75
95
  },
96
+ {
97
+ "cmd": "ministral-3b-2512",
98
+ "multimodal": false,
99
+ "desc": "Cost Saving (Text Only) [EXPERIMENTAL]"
100
+ },
101
+ {
102
+ "cmd": "ministral-8b-2512",
103
+ "multimodal": false,
104
+ "desc": "Cost Saving (Text Only) [EXPERIMENTAL]"
105
+ },
106
+ {
107
+ "cmd": "ministral-14b-2512",
108
+ "multimodal": false,
109
+ "desc": "Cost Saving (Text Only) [EXPERIMENTAL]"
110
+ },
76
111
  {
77
112
  "cmd": "mistral-small-2506",
78
113
  "multimodal": false,
@@ -84,10 +119,15 @@
84
119
  "desc": "Devstral Coding (Text Only) [EXPERIMENTAL]"
85
120
  },
86
121
  {
87
- "cmd": "mistral-medium-2505",
122
+ "cmd": "mistral-medium-2508",
88
123
  "multimodal": true,
89
124
  "desc": "Mistral Medium (Multimodal)"
90
125
  },
126
+ {
127
+ "cmd": "mistral-large-2512",
128
+ "multimodal": true,
129
+ "desc": "Mistral Large (Multimodal)"
130
+ },
91
131
  {
92
132
  "cmd": "labs-leanstral-1-5-1",
93
133
  "multimodal": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "3.19.1",
3
+ "version": "3.19.2",
4
4
  "date": "2026-08-06",
5
5
  "description": "A High-Fidelity Agentic CLI with Sub-Agents for the Flux Era.",
6
6
  "keywords": [