janito 2.18.0__py3-none-any.whl → 2.19.1__py3-none-any.whl

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.
@@ -27,9 +27,23 @@ def handle_list_models(args, provider_instance):
27
27
  if models and isinstance(models[0], dict):
28
28
  _print_models_table(models, provider_name)
29
29
  else:
30
- print(f"Supported models for provider '{provider_name}':")
30
+ # Fallback for simple string model lists
31
+ from rich.table import Table
32
+ from janito.cli.console import shared_console
33
+
34
+ table = Table(title=f"Supported models for provider '{provider_name}'")
35
+ table.add_column("Model Name", style="cyan")
36
+
31
37
  for m in models:
32
- print(f"- {m}")
38
+ table.add_row(str(m))
39
+
40
+ import sys
41
+ if sys.stdout.isatty():
42
+ shared_console.print(table)
43
+ else:
44
+ print(f"Supported models for provider '{provider_name}':")
45
+ for m in models:
46
+ print(f"- {m}")
33
47
  except Exception as e:
34
48
  print(f"Error listing models for provider '{provider_name}': {e}")
35
49
  return
@@ -3,8 +3,13 @@ CLI Command: List supported LLM providers
3
3
  """
4
4
 
5
5
  from janito.provider_registry import list_providers
6
+ from janito.cli.cli_commands.ping_providers import handle_ping_providers
6
7
 
7
8
 
8
9
  def handle_list_providers(args=None):
9
- list_providers()
10
+ # Check if ping flag is set
11
+ if args and getattr(args, 'ping', False):
12
+ handle_ping_providers(args)
13
+ else:
14
+ list_providers()
10
15
  return
@@ -5,59 +5,94 @@ Utilities for model-related CLI output
5
5
 
6
6
  def _print_models_table(models, provider_name):
7
7
  from rich.table import Table
8
- from rich.console import Console
8
+ from janito.cli.console import shared_console
9
9
 
10
- headers = [
11
- "name",
12
- "open",
13
- "context",
14
- "max_input",
15
- "max_cot",
16
- "max_response",
17
- "thinking_supported",
18
- "driver",
19
- ]
20
- display_headers = [
21
- "Model Name",
22
- "Vendor",
23
- "context",
24
- "max_input",
25
- "max_cot",
26
- "max_response",
27
- "Thinking",
28
- "Driver",
29
- ]
30
10
  table = Table(title=f"Supported models for provider '{provider_name}'")
31
- _add_table_columns(table, display_headers)
32
- num_fields = {"context", "max_input", "max_cot", "max_response"}
11
+ table.add_column("Model Name", style="cyan")
12
+ table.add_column("Vendor", style="yellow", justify="center")
13
+ table.add_column("Context", style="magenta", justify="center")
14
+ table.add_column("Max Input", style="green", justify="center")
15
+ table.add_column("CoT", style="blue", justify="center")
16
+ table.add_column("Max Response", style="red", justify="center")
17
+ table.add_column("Thinking", style="bright_black", justify="center")
18
+ table.add_column("Driver", style="white")
19
+
20
+ # Get default model for this provider
21
+ from janito.providers.registry import LLMProviderRegistry
22
+ try:
23
+ provider_class = LLMProviderRegistry.get(provider_name)
24
+ default_model = getattr(provider_class, "DEFAULT_MODEL", None)
25
+ except:
26
+ default_model = None
27
+
33
28
  for m in models:
34
- row = [str(m.get("name", ""))]
35
- row.extend(_build_model_row(m, headers, num_fields))
36
- table.add_row(*row)
37
- import sys
29
+ name = str(m.get("name", ""))
30
+
31
+ # Highlight default model with different color
32
+ if name == default_model:
33
+ name = f"[bold green]⭐ {name}[/bold green]"
34
+
35
+ vendor = "Open" if m.get("open") is True or m.get("open") == "Open" else "Locked"
36
+
37
+ context = _format_context(m.get("context", ""))
38
+ max_input = _format_k(m.get("max_input", ""))
39
+ max_cot = _format_k(m.get("max_cot", ""))
40
+ max_response = _format_k(m.get("max_response", ""))
41
+
42
+ # Determine thinking indicators
43
+ thinking_supported = m.get("thinking_supported") is True or m.get("thinking_supported") == "True"
44
+ cot_value = m.get("max_cot", "")
45
+
46
+ thinking_icon = "📖" if thinking_supported and m.get("thinking", False) else ""
47
+ # Only show CoT value if it's a valid number and thinking is supported
48
+ cot_display = ""
49
+ if thinking_supported and cot_value and str(cot_value).lower() != "n/a":
50
+ cot_display = _format_k(cot_value)
51
+
52
+ driver = _format_driver(m.get("driver", ""))
53
+
54
+ table.add_row(name, vendor, context, max_input, cot_display, max_response, thinking_icon, driver)
38
55
 
56
+ import sys
39
57
  if sys.stdout.isatty():
40
- from rich.console import Console
41
-
42
- Console().print(table)
58
+ shared_console.print(table)
43
59
  else:
44
60
  # ASCII-friendly fallback table when output is redirected
45
61
  print(f"Supported models for provider '{provider_name}'")
46
- headers_fallback = [h for h in display_headers]
47
- print(" | ".join(headers_fallback))
62
+ print("Model Name | Vendor | Context | Max Input | CoT | Max Response | Thinking | Driver")
63
+
64
+ # Get default model for fallback
65
+ from janito.providers.registry import LLMProviderRegistry
66
+ try:
67
+ provider_class = LLMProviderRegistry.get(provider_name)
68
+ default_model = getattr(provider_class, "DEFAULT_MODEL", None)
69
+ except:
70
+ default_model = None
71
+
48
72
  for m in models:
49
- row = [str(m.get("name", ""))]
50
- row.extend(_build_model_row(m, headers, num_fields))
51
- print(" | ".join(row))
52
-
53
-
54
- def _add_table_columns(table, display_headers):
55
- for i, h in enumerate(display_headers):
56
- justify = "right" if i == 0 else "center"
57
- table.add_column(h, style="bold", justify=justify)
73
+ name = str(m.get("name", ""))
74
+ if name == default_model:
75
+ name = f" {name} (default)"
76
+
77
+ vendor = "Open" if m.get("open") is True or m.get("open") == "Open" else "Locked"
78
+ context = _format_context(m.get("context", ""))
79
+ max_input = _format_k(m.get("max_input", ""))
80
+ max_cot = _format_k(m.get("max_cot", ""))
81
+ max_response = _format_k(m.get("max_response", ""))
82
+ thinking_supported = m.get("thinking_supported") is True or m.get("thinking_supported") == "True"
83
+ cot_value = m.get("max_cot", "")
84
+
85
+ thinking = "Y" if thinking_supported and m.get("thinking", False) else ""
86
+ cot_display = ""
87
+ if thinking_supported and cot_value and str(cot_value).lower() != "n/a":
88
+ cot_display = _format_k(cot_value)
89
+
90
+ driver = _format_driver(m.get("driver", ""))
91
+ print(f"{name} | {vendor} | {context} | {max_input} | {cot_display} | {max_response} | {thinking} | {driver}")
58
92
 
59
93
 
60
94
  def _format_k(val):
95
+ """Format numeric values with k suffix for thousands."""
61
96
  try:
62
97
  n = int(val)
63
98
  if n >= 1000:
@@ -67,31 +102,16 @@ def _format_k(val):
67
102
  return str(val)
68
103
 
69
104
 
70
- def _build_model_row(m, headers, num_fields):
71
- def format_driver(val):
72
- if isinstance(val, (list, tuple)):
73
- return ", ".join(val)
74
- val_str = str(val)
75
- return val_str.removesuffix("ModelDriver").strip()
105
+ def _format_context(val):
106
+ """Format context field which might be a single value or range."""
107
+ if isinstance(val, (list, tuple)) and len(val) == 2:
108
+ return f"{_format_k(val[0])} / {_format_k(val[1])}"
109
+ return _format_k(val)
110
+
76
111
 
77
- row = []
78
- for h in headers[1:]:
79
- v = m.get(h, "")
80
- if h in num_fields and v not in ("", "N/A"):
81
- if (
82
- h in ("context", "max_input")
83
- and isinstance(v, (list, tuple))
84
- and len(v) == 2
85
- ):
86
- row.append(f"{_format_k(v[0])} / {_format_k(v[1])}")
87
- else:
88
- row.append(_format_k(v))
89
- elif h == "open":
90
- row.append("Open" if v is True or v == "Open" else "Locked")
91
- elif h == "thinking_supported":
92
- row.append("📖" if v is True or v == "True" else "")
93
- elif h == "driver":
94
- row.append(format_driver(v))
95
- else:
96
- row.append(str(v))
97
- return row
112
+ def _format_driver(val):
113
+ """Format driver name by removing ModelDriver suffix."""
114
+ if isinstance(val, (list, tuple)):
115
+ return ", ".join(val)
116
+ val_str = str(val)
117
+ return val_str.removesuffix("ModelDriver").strip()
@@ -0,0 +1,55 @@
1
+ from janito.provider_registry import list_providers
2
+ from janito.providers.registry import LLMProviderRegistry
3
+ from janito.cli.console import shared_console
4
+ from rich.table import Table
5
+ from rich.progress import Progress, SpinnerColumn, TextColumn
6
+ import asyncio
7
+ import time
8
+
9
+
10
+ def handle_ping_providers(args):
11
+ """Ping/test connectivity for all providers."""
12
+ try:
13
+ # Get all providers
14
+ providers = list_providers()
15
+
16
+ # Create table for results
17
+ table = Table(title="Provider Connectivity Test")
18
+ table.add_column("Provider", style="cyan")
19
+ table.add_column("Status", style="magenta")
20
+ table.add_column("Time", style="green")
21
+ table.add_column("Details", style="yellow")
22
+
23
+ # Test each provider
24
+ for provider_name in providers:
25
+ start_time = time.time()
26
+ try:
27
+ # Get provider class
28
+ provider_class = LLMProviderRegistry.get(provider_name)
29
+ provider = provider_class()
30
+
31
+ # Test the provider (simplified - just check if we can instantiate and get models)
32
+ models = provider.get_models()
33
+ if models:
34
+ status = "✓ Connected"
35
+ details = f"{len(models)} models available"
36
+ else:
37
+ status = "⚠ No models"
38
+ details = "Provider reachable but no models returned"
39
+
40
+ except Exception as e:
41
+ status = "✗ Failed"
42
+ details = str(e)
43
+
44
+ end_time = time.time()
45
+ elapsed = f"{(end_time - start_time)*1000:.0f}ms"
46
+
47
+ table.add_row(provider_name, status, elapsed, details)
48
+
49
+ # Print results
50
+ shared_console.print(table)
51
+
52
+ except Exception as e:
53
+ print(f"Error testing provider connectivity: {e}")
54
+
55
+ return
janito/cli/main_cli.py CHANGED
@@ -124,6 +124,10 @@ definition = [
124
124
  ["--list-providers"],
125
125
  {"action": "store_true", "help": "List supported LLM providers"},
126
126
  ),
127
+ (
128
+ ["--ping"],
129
+ {"action": "store_true", "help": "Ping/test connectivity for all providers (use with --list-providers)"},
130
+ ),
127
131
  (
128
132
  ["--list-drivers"],
129
133
  {
@@ -238,6 +242,19 @@ GETTER_KEYS = [
238
242
  "list_drivers",
239
243
  "region_info",
240
244
  "list_providers_region",
245
+ "ping",
246
+ ]
247
+ GETTER_KEYS = [
248
+ "show_config",
249
+ "list_providers",
250
+ "list_profiles",
251
+ "list_models",
252
+ "list_tools",
253
+ "list_config",
254
+ "list_drivers",
255
+ "region_info",
256
+ "list_providers_region",
257
+ "ping",
241
258
  ]
242
259
 
243
260
 
@@ -361,6 +378,7 @@ class JanitoCLI:
361
378
  or self.args.show_config
362
379
  or self.args.list_config
363
380
  or self.args.list_drivers
381
+ or self.args.ping
364
382
  ):
365
383
  self._maybe_print_verbose_provider_model()
366
384
  handle_getter(self.args)
janito/i18n/it.py ADDED
@@ -0,0 +1,46 @@
1
+ # pragma: allowlist secret
2
+ translations = {
3
+ "36107ed78ab25f6fb12ad8ce13018cd1ce6735d1": "Avvio del server web...",
4
+ "70a0d194687568a47aa617fd85036ace1e69a982": "Vuoi davvero uscire? (s/n): ",
5
+ "5c9ebcbbd7632ecb328bd52958b17158afaa32c6": "F12 = Azione Rapida (segue l'azione raccomandata)",
6
+ "fe21121e2934234b68d19b2757532117d440c1e3": "Chiave API non trovata. Si prega di configurare 'api_key' nel file di configurazione.",
7
+ "c9e3759b1756eba35b381ce2b72cd659e132b01f": "Ciao, {name}!",
8
+ "ca1fee2f55baabdc2e4b0e9529c89ee024e62079": "Nessun prompt fornito nei messaggi",
9
+ "f7449d23d0c500ae2a0b31e04f92b47a4d8ae845": "max_tokens deve essere un intero, ricevuto: {resolved_max_tokens!r}",
10
+ "70a9ed8edb6da12e208431a31aa16ba54419b26f": "Risposta non valida/malformed da OpenAI (tentativo {attempt}/{max_retries}). Riprovo tra {wait_time} secondi...",
11
+ "a873085e3b06184fb5d27e842f97b06b6190976d": "Numero massimo di tentativi per risposta non valida raggiunto. Generazione errore.",
12
+ "66a34568bbe846bb1bde3619eb4d6dfa10211104": "L'API non supporta l'uso degli strumenti.",
13
+ "09b81476b75586da4116b83f8be70d77b174cec3": "Limite di richieste API OpenAI (429) (tentativo {attempt}/{max_retries}): {e}. Riprovo tra {wait_time} secondi...",
14
+ "5717a35dd2a1533fb7e15edc8c9329cb69f3410b": "Errore server API OpenAI (tentativo {attempt}/{max_retries}): {e}. Riprovo tra {wait_time} secondi...",
15
+ "02e760ba15ed863176c1290ac8a9b923963103cd": "Errore client API OpenAI {status_code}: {e}. Nessun nuovo tentativo.",
16
+ "2e52b0bbc8f16226b70e3e20f95c9245d2bcdb47": "Errore API OpenAI (tentativo {attempt}/{max_retries}): {e}. Riprovo tra {wait_time} secondi...",
17
+ "012cc970e039fdd79c452fc676202c814ffc76ae": "Numero massimo di tentativi per errore API OpenAI raggiunto. Generazione errore.",
18
+ "d0438e45667d31e0022b2497b5901cd4300f084b": "QueuedMessageHandler.handle_message si aspetta un dizionario con 'type' e 'message', ricevuto {msg_type}: {msg!r}",
19
+ "9d3460187ffa19c7c8a4020157072b1087e1bd2f": "[QueuedMessageHandler] {msg_type}: {msg}",
20
+ "3813833343430e8afa8fce33385c5e39fb24dd60": "[QueuedMessageHandler] {msg_type}: {message}",
21
+ "0be9a22226e16a40797010d23a0f581542dca40e": "[ToolExecutor] {tool_name} chiamato con argomenti: {args}",
22
+ "42c68edcb25442f518b1af77c6a2ddc07461aae0": "[ToolExecutor] Motivo chiamata: {tool_call_reason}",
23
+ "002ff598115d84595ffeee6219cb5c03d3a1d4a6": "Domanda",
24
+ "35747d13dcd91e8e8790c7f767d5ed764f541b9e": "procedi",
25
+ "33dde3a1afbc418768a69fa53168d9b0638fe1aa": "avanti",
26
+ "eee0bbba4ff92adbeb038a77df0466d660f15716": "continua",
27
+ "edee9402d198b04ac77dcf5dc9cc3dac44573782": "prossimo",
28
+ "8fdb7e2fa84f4faf0d9b92f466df424ec47a165b": "ok",
29
+ "5f8f924671cda79b5205a6bf1b776f347c4a7a07": "Opzioni di configurazione disponibili:\n",
30
+ "cef780a309cd234750764d42697882c24168ddab": "{key:15} {desc} (predefinito: {default})",
31
+ "68c2cc7f0ceaa3e499ecb4db331feb4debbbcc23": "Modello",
32
+ "c3f104d1365744b538bfde9f4adb6a6df4b80355": "Funzione",
33
+ "99a0efc6cfd85d8ff2732a6718140f822cb90472": "Stile",
34
+ "f1702b4686278becffc88baabe6f4b7a8355532c": "Messaggi",
35
+ "c38c6c1f3a2743f8626703abb302e403d20ff81c": "Token",
36
+ "a817d7eb8e0f1dab755ab5203a082e5c3c094fce": "Prompt",
37
+ "2ff255684a2277f806fcebf3fe338ed27857f350": "Completamento",
38
+ "b25928c69902557b0ef0a628490a3a1768d7b82f": "Totale",
39
+ "76e63d65c883ed50df40ac3aeef0c2d6a1c4ad60": "Azione Rapida",
40
+ "5397e0583f14f6c88de06b1ef28f460a1fb5b0ae": "Sì",
41
+ "816c52fd2bdd94a63cd0944823a6c0aa9384c103": "No",
42
+ "c47ae15370cfe1ed2781eedc1dc2547d12d9e972": "Aiuto",
43
+ "cc3dbd47e1cf9003a55d3366b3adbcd72275e525": "Nuovo Task",
44
+ "efa5a8b84e1afe65c81ecfce28c398c48f19ddc2": "Benvenuto su Janito{version_str}! Modalità chat attiva. Digita /exit per uscire.",
45
+ "b314d6e1460f86e0f21abc5aceb7935a2a0667e8": "Benvenuto su Janito{version_str} in modalità [white on magenta]VANILLA[/white on magenta]! Strumenti, prompt di sistema e temperatura sono disattivati, a meno che non siano sovrascritti.",
46
+ }
janito/llm/model.py CHANGED
@@ -10,6 +10,7 @@ class LLMModelInfo:
10
10
  max_cot: Any = "N/A"
11
11
  max_response: Any = "N/A"
12
12
  thinking_supported: Any = "N/A"
13
+ thinking: bool = False
13
14
  default_temp: float = 0.2
14
15
  open: Optional[Any] = None
15
16
  category: Optional[str] = None
@@ -39,7 +39,17 @@ class ProviderRegistry:
39
39
  if len(info) == 4 and info[3]:
40
40
  continue # skip providers flagged as not implemented
41
41
  rows.append(info[:3])
42
- rows.sort(key=self._maintainer_sort_key)
42
+
43
+ # Group providers by openness (open-source first, then proprietary)
44
+ open_providers = {'cerebras', 'deepseek', 'alibaba', 'moonshotai', 'zai'}
45
+
46
+ def sort_key(row):
47
+ provider_name = row[0]
48
+ is_open = provider_name in open_providers
49
+ # Sort open providers alphabetically first, then proprietary alphabetically
50
+ return (not is_open, provider_name)
51
+
52
+ rows.sort(key=sort_key)
43
53
  return rows
44
54
 
45
55
  def _add_rows_to_table(self, table, rows):
@@ -7,6 +7,9 @@ MODEL_SPECS = {
7
7
  max_response=8192,
8
8
  category="Alibaba Qwen Turbo Model (OpenAI-compatible)",
9
9
  driver="OpenAIModelDriver",
10
+ thinking_supported=True,
11
+ thinking=False,
12
+ max_cot=8192,
10
13
  ),
11
14
  "qwen-plus": LLMModelInfo(
12
15
  name="qwen-plus",
@@ -14,6 +17,9 @@ MODEL_SPECS = {
14
17
  max_response=8192,
15
18
  category="Alibaba Qwen Plus Model (OpenAI-compatible)",
16
19
  driver="OpenAIModelDriver",
20
+ thinking_supported=True,
21
+ thinking=False,
22
+ max_cot=8192,
17
23
  ),
18
24
  "qwen-max": LLMModelInfo(
19
25
  name="qwen-max",
@@ -21,6 +27,9 @@ MODEL_SPECS = {
21
27
  max_response=8192,
22
28
  category="Alibaba Qwen Max Model (OpenAI-compatible)",
23
29
  driver="OpenAIModelDriver",
30
+ thinking_supported=True,
31
+ thinking=False,
32
+ max_cot=8192,
24
33
  ),
25
34
 
26
35
  "qwen3-coder-plus": LLMModelInfo(
@@ -29,6 +38,9 @@ MODEL_SPECS = {
29
38
  max_response=65536,
30
39
  category="Alibaba Qwen3 Coder Plus Model (OpenAI-compatible)",
31
40
  driver="OpenAIModelDriver",
41
+ thinking_supported=True,
42
+ thinking=False,
43
+ max_cot=65536,
32
44
  ),
33
45
  "qwen3-coder-480b-a35b-instruct": LLMModelInfo(
34
46
  name="qwen3-coder-480b-a35b-instruct",
@@ -36,5 +48,50 @@ MODEL_SPECS = {
36
48
  max_response=65536,
37
49
  category="Alibaba Qwen3 Coder 480B A35B Instruct Model (OpenAI-compatible)",
38
50
  driver="OpenAIModelDriver",
51
+ thinking_supported=True,
52
+ thinking=False,
53
+ max_cot=65536,
54
+ ),
55
+
56
+ # Qwen3 1M context models (July 2025 update)
57
+ "qwen3-235b-a22b-thinking-2507": LLMModelInfo(
58
+ name="qwen3-235b-a22b-thinking-2507",
59
+ context=131072, # Supports up to 1M with special config
60
+ max_response=32768,
61
+ category="Alibaba Qwen3 235B A22B Thinking Model (OpenAI-compatible)",
62
+ driver="OpenAIModelDriver",
63
+ thinking=True,
64
+ thinking_supported=True,
65
+ max_cot=32768,
66
+ ),
67
+ "qwen3-235b-a22b-instruct-2507": LLMModelInfo(
68
+ name="qwen3-235b-a22b-instruct-2507",
69
+ context=129024, # Supports up to 1M with special config
70
+ max_response=32768,
71
+ category="Alibaba Qwen3 235B A22B Instruct Model (OpenAI-compatible)",
72
+ driver="OpenAIModelDriver",
73
+ thinking_supported=True,
74
+ thinking=False,
75
+ max_cot=32768,
76
+ ),
77
+ "qwen3-30b-a3b-thinking-2507": LLMModelInfo(
78
+ name="qwen3-30b-a3b-thinking-2507",
79
+ context=126976, # Supports up to 1M with special config
80
+ max_response=32768,
81
+ category="Alibaba Qwen3 30B A3B Thinking Model (OpenAI-compatible)",
82
+ driver="OpenAIModelDriver",
83
+ thinking=True,
84
+ thinking_supported=True,
85
+ max_cot=32768,
86
+ ),
87
+ "qwen3-30b-a3b-instruct-2507": LLMModelInfo(
88
+ name="qwen3-30b-a3b-instruct-2507",
89
+ context=129024, # Supports up to 1M with special config
90
+ max_response=32768,
91
+ category="Alibaba Qwen3 30B A3B Instruct Model (OpenAI-compatible)",
92
+ driver="OpenAIModelDriver",
93
+ thinking_supported=True,
94
+ thinking=False,
95
+ max_cot=32768,
39
96
  ),
40
97
  }
@@ -17,7 +17,7 @@ class AlibabaProvider(LLMProvider):
17
17
  NAME = "alibaba"
18
18
  MAINTAINER = "João Pinto <janito@ikignosis.org>"
19
19
  MODEL_SPECS = MODEL_SPECS
20
- DEFAULT_MODEL = "qwen3-coder-plus" # 128k context, coding-focused model
20
+ DEFAULT_MODEL = "qwen3-235b-a22b-instruct-2507" # 129k context, general-purpose model
21
21
 
22
22
  def __init__(
23
23
  self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None
janito/report_events.py CHANGED
@@ -14,6 +14,7 @@ class ReportSubtype(Enum):
14
14
  PROGRESS = "progress"
15
15
 
16
16
 
17
+
17
18
  class ReportAction(Enum):
18
19
  READ = "READ"
19
20
  CREATE = "CREATE"
@@ -39,17 +39,11 @@ class RunPowershellCommandTool(ToolBase):
39
39
  ReportAction.EXECUTE,
40
40
  )
41
41
  if require_confirmation:
42
- confirmed = self.ask_user_confirmation(
43
- tr(
44
- "About to run PowerShell command: {command}\nContinue?",
45
- command=command,
46
- )
42
+ self.report_warning(
43
+ tr("⚠️ Confirmation requested, but no handler (auto-confirmed)."),
44
+ ReportAction.USER_INPUT
47
45
  )
48
- if not confirmed:
49
- self.report_warning(
50
- tr("⚠️ Execution cancelled by user."), ReportAction.EXECUTE
51
- )
52
- return False
46
+ return True # Auto-confirm for now
53
47
  return True
54
48
 
55
49
  def _launch_process(self, shell_exe, command_with_encoding):
@@ -143,10 +137,7 @@ class RunPowershellCommandTool(ToolBase):
143
137
  tr("🖥️ Running PowerShell command: {command} ...\n", command=command),
144
138
  ReportAction.EXECUTE,
145
139
  )
146
- if not self._confirm_and_warn(
147
- command, require_confirmation, requires_user_input
148
- ):
149
- return tr("❌ Command execution cancelled by user.")
140
+ self._confirm_and_warn(command, require_confirmation, requires_user_input)
150
141
  from janito.platform_discovery import PlatformDiscovery
151
142
 
152
143
  pd = PlatformDiscovery()
janito/tools/tool_base.py CHANGED
@@ -112,3 +112,5 @@ class ToolBase:
112
112
 
113
113
  def run(self, *args, **kwargs):
114
114
  raise NotImplementedError("Subclasses must implement the run method.")
115
+
116
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janito
3
- Version: 2.18.0
3
+ Version: 2.19.1
4
4
  Summary: A new Python package called janito.
5
5
  Author-email: João Pinto <janito@ikignosis.org>
6
6
  Project-URL: Homepage, https://github.com/ikignosis/janito
@@ -16,8 +16,8 @@ janito/perf_singleton.py,sha256=g1h0Sdf4ydzegeEpJlMhQt4H0GQZ2hryXrdYOTL-b30,113
16
16
  janito/performance_collector.py,sha256=RYu4av16Trj3RljJZ8-2Gbn1KlGdJUosrcVFYtwviNI,6285
17
17
  janito/platform_discovery.py,sha256=JN3kC7hkxdvuj-AyrJTlbbDJjtNHke3fdlZDqGi_uz0,4621
18
18
  janito/provider_config.py,sha256=acn2FEgWsEIyi2AxZiuCLoP2rXDd-nXcP5VB4CZHaeE,3189
19
- janito/provider_registry.py,sha256=l0jJZ74KIebOSYXPiy7uqH8d48pckR_WTyAO4iQF98o,6571
20
- janito/report_events.py,sha256=q4OR_jTZNfcqaQF_fzTjgqo6_VlUIxSGWfhpT4nJWcw,938
19
+ janito/provider_registry.py,sha256=Qh2ujKjaa5HZmr7YOHxUy983jSDaCD-AXaZFBVC85XY,7001
20
+ janito/report_events.py,sha256=m72U9TQfbQfKcCDT8O4nYhVI6IFfQQG1ZXQa3Vhq0y4,940
21
21
  janito/shell.bak.zip,sha256=hznHbmgfkAkjuQDJ3w73XPQh05yrtUZQxLmtGbanbYU,22
22
22
  janito/utils.py,sha256=eXSsMgM69YyzahgCNrJQLcEbB8ssLI1MQqaa20ONxbE,376
23
23
  janito/agent/setup_agent.py,sha256=HQU_h1P8VXiOVURjQ4SwvO-R3rujs6xUcPvrNniRDok,11618
@@ -28,7 +28,7 @@ janito/cli/__init__.py,sha256=xaPDOrWphBbCR63Xpcx_yfpXSJIlCaaICc4j2qpWqrM,194
28
28
  janito/cli/config.py,sha256=HkZ14701HzIqrvaNyDcDhGlVHfpX_uHlLp2rHmhRm_k,872
29
29
  janito/cli/console.py,sha256=gJolqzWL7jEPLxeuH-CwBDRFpXt976KdZOEAB2tdBDs,64
30
30
  janito/cli/main.py,sha256=s5odou0txf8pzTf1ADk2yV7T5m8B6cejJ81e7iu776U,312
31
- janito/cli/main_cli.py,sha256=21XPZ5Kp4ye2kEzkhcBtWe60Pe7XYAtzlZOf5RHNDuU,15280
31
+ janito/cli/main_cli.py,sha256=aLkWYT3qG4AmGGx7RXkLJACgVhurhpwFrz6_0rwpQCQ,15703
32
32
  janito/cli/prompt_core.py,sha256=F68J4Xl6jZMYFN4oBBYZFj15Jp-HTYoLub4bw2XpNRU,11648
33
33
  janito/cli/prompt_handler.py,sha256=SnPTlL64noeAMGlI08VBDD5IDD8jlVMIYA4-fS8zVLg,215
34
34
  janito/cli/prompt_setup.py,sha256=1SSvvgS568-3BO_4Sw9A-QF_iLWiIXsNHT0JVqaLwkU,2120
@@ -74,13 +74,14 @@ janito/cli/chat_mode/shell/session/history.py,sha256=tYav6GgjAZkvWhlI_rfG6OArNqW
74
74
  janito/cli/chat_mode/shell/session/manager.py,sha256=MwD9reHsRaly0CyRB-S1JJ0wPKz2g8Xdj2VvlU35Hgc,1001
75
75
  janito/cli/cli_commands/list_config.py,sha256=oiQEGaGPjwjG-PrOcakpNMbbqISTsBEs7rkGH3ceQsI,1179
76
76
  janito/cli/cli_commands/list_drivers.py,sha256=r2ENykUcvf_9XYp6LHd3RvLXGXyVUA6oe_Pr0dyv92I,5124
77
- janito/cli/cli_commands/list_models.py,sha256=_rqHz89GsNLcH0GGkFqPue7ah4ZbN9YHm0lEP30Aa-A,1111
77
+ janito/cli/cli_commands/list_models.py,sha256=DAXH9CT3Q4krJ_NlrXseCGsc4WECYeJSGX6z0ks8_uA,1661
78
78
  janito/cli/cli_commands/list_profiles.py,sha256=9-HV2EbtP2AdubbMoakjbu7Oq4Ss9UDyO7Eb6CC52wI,2681
79
- janito/cli/cli_commands/list_providers.py,sha256=v8OQ8ULnuzNuvgkeKqGXGj69eOiavAlPGhzfR0zavhg,185
79
+ janito/cli/cli_commands/list_providers.py,sha256=3ywm1Ohv7yVqV1E9hB-3Jz8BwzhyCScKxffq6iDI4nA,391
80
80
  janito/cli/cli_commands/list_providers_region.py,sha256=qrMj_gtgEMty8UH0P_O5SgWCVJ9ZKxGUp_GdsE4_EH4,2548
81
81
  janito/cli/cli_commands/list_tools.py,sha256=JFRdlhPeA3BzhJ2PkjIt3u137IJoNc-vYSjUuPlaOXw,3593
82
82
  janito/cli/cli_commands/model_selection.py,sha256=ANWtwC5glZkGMdaNtARDbEG3QmuBUcDLVxzzC5jeBNo,1643
83
- janito/cli/cli_commands/model_utils.py,sha256=U0j2FTpcIBc4eAc40MXz5tyAK3m8lkakpOS2l2bGh4A,2868
83
+ janito/cli/cli_commands/model_utils.py,sha256=PO64PW-TIlWyPY8CzYnI0y5Zp6ukV_NjaSj8CEXflV0,4889
84
+ janito/cli/cli_commands/ping_providers.py,sha256=U3iTETPXDEGr3dqlJqNTPvpkhKo2KfXe_bN2_LGJtx0,2015
84
85
  janito/cli/cli_commands/set_api_key.py,sha256=ZItSuB0HO14UsbyXXCgTKAXS-EUCHfCkntzg3WAAtK0,1048
85
86
  janito/cli/cli_commands/show_config.py,sha256=eYMcuvU-d7mvvuctbQacZFERqcKHEnxaRRjasyj-_lE,2004
86
87
  janito/cli/cli_commands/show_system_prompt.py,sha256=9ZJGW7lIGJ9LX2JZiWVEm4AbaD0qEQO7LF89jPgk52I,5232
@@ -108,6 +109,7 @@ janito/event_bus/event.py,sha256=MtgcBPD7cvCuubiLIyo-BWcsNSO-941HLk6bScHTJtQ,427
108
109
  janito/event_bus/handler.py,sha256=RhBtT1E48VEM2-k8u3HYsESw7VX5qAgiB8ZTJeKXhHc,1322
109
110
  janito/event_bus/queue_bus.py,sha256=l4phun3pxXxi8ZlIq8ChYaiYDVO1PZeXoOzyi3vyu20,1558
110
111
  janito/i18n/__init__.py,sha256=6zCIu6pSQpoMJvIRK9oOD3pkzbNeJik3lFDXse0X6ag,994
112
+ janito/i18n/it.py,sha256=jpWyCrwoZXxHaLEbmYL2B1ouOa854ecdCfpXq4mqroc,4052
111
113
  janito/i18n/messages.py,sha256=fBuwOTFoygyHPkYphm6Y0r1iE8497Z4iryVAmPhMEkg,1851
112
114
  janito/i18n/pt.py,sha256=NlTgpDSftUfFG7FGbs7TK54vQlJVMyaZDHGcWjelwMc,4168
113
115
  janito/llm/README.md,sha256=6GRqCu_a9va5HCB1YqNqbshyWKFyAGlnXugrjom-xj8,1213
@@ -120,14 +122,14 @@ janito/llm/driver_config.py,sha256=OW0ae49EfgKDqaThuDjZBiaN78voNzwiZ6szERMqJos,1
120
122
  janito/llm/driver_config_builder.py,sha256=BvWGx7vaBR5NyvPY1XNAP3lAgo1uf-T25CSsIo2kkCU,1401
121
123
  janito/llm/driver_input.py,sha256=Zq7IO4KdQPUraeIo6XoOaRy1IdQAyYY15RQw4JU30uA,389
122
124
  janito/llm/message_parts.py,sha256=QY_0kDjaxdoErDgKPRPv1dNkkYJuXIBmHWNLiOEKAH4,1365
123
- janito/llm/model.py,sha256=42hjcffZDTuzjAJoVhDcDqwIXm6rUmmi5UwTOYopf5w,1131
125
+ janito/llm/model.py,sha256=EioBkdgn8hJ0iQaKN-0KbXlsrk3YKmwR9IbvoEbdVTE,1159
124
126
  janito/llm/provider.py,sha256=3FbhQPrWBSEoIdIi-5DWIh0DD_CM570EFf1NcuGyGko,7961
125
127
  janito/providers/__init__.py,sha256=wlb8-dfnWRsZclFTT5cbwYqSWFpppChrAxZEgpdBgng,450
126
128
  janito/providers/dashscope.bak.zip,sha256=BwXxRmZreEivvRtmqbr5BR62IFVlNjAf4y6DrF2BVJo,5998
127
129
  janito/providers/registry.py,sha256=Ygwv9eVrTXOKhv0EKxSWQXO5WMHvajWE2Q_Lc3p7dKo,730
128
130
  janito/providers/alibaba/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
- janito/providers/alibaba/model_info.py,sha256=evAW2CZUX9qgRAzDhZTp47ZNj4G1T7W66gkV60Nfan8,1264
130
- janito/providers/alibaba/provider.py,sha256=UVNOdUX4SJln1OS10AY-Zq1THp538yhpEKPqLKyEGKU,4178
131
+ janito/providers/alibaba/model_info.py,sha256=G8TC-SaH96R2EnvVLWb7TjLXAmskeVylDzPho97dSTM,3326
132
+ janito/providers/alibaba/provider.py,sha256=L7oK_TeJn8p_ZaFlls5eb9YF03VrFkR_PLdopVvZQ7w,4192
131
133
  janito/providers/anthropic/model_info.py,sha256=m6pBh0Ia8_xC1KZ7ke_4HeHIFw7nWjnYVItnRpkCSWc,1206
132
134
  janito/providers/anthropic/provider.py,sha256=aGynBxCFc7oTyvGNDUkbutJCKurC_9J4AkReC2LTPYo,3023
133
135
  janito/providers/azure_openai/model_info.py,sha256=TMSqEpQROIIYUGAyulYJ5xGhj7CbLoaKL_JXeLbXaG0,689
@@ -165,7 +167,7 @@ janito/tools/outline_file.bak.zip,sha256=EeI2cBXCwTdWVgJDNiroxKeYlkjwo6NLKeXz3J-
165
167
  janito/tools/path_security.py,sha256=40b0hV0X3449Dht93A04Q3c9AYSsBQsBFy2BjzM83lA,8214
166
168
  janito/tools/permissions.py,sha256=_viTVXyetZC01HjI2s5c3klIJ8-RkWB1ShdOaV__loY,1508
167
169
  janito/tools/permissions_parse.py,sha256=LHadt0bWglm9Q2BbbVVbKePg4oa7QLeRQ-ChQZsE_dI,384
168
- janito/tools/tool_base.py,sha256=TSrXDknqIqOtY3xzuvtsxZ3qwbvmGzUruBiqVzzICfc,3689
170
+ janito/tools/tool_base.py,sha256=6meJZwbsqDIerh84T_C6K9G706wqoSkoR1vnrRk6mvo,3693
169
171
  janito/tools/tool_events.py,sha256=czRtC2TYakAySBZvfHS_Q6_NY_7_krxzAzAL1ggRFWA,1527
170
172
  janito/tools/tool_run_exception.py,sha256=43yWgTaGBGEtRteo6FvTrane6fEVGo9FU1uOdjMRWJE,525
171
173
  janito/tools/tool_use_tracker.py,sha256=IaEmA22D6RuL1xMUCScOMGv0crLPwEJVGmj49cydIaM,2662
@@ -193,7 +195,7 @@ janito/tools/adapters/local/remove_directory.py,sha256=g1wkHcWNgtv3mfuZ4GfvqtKU3
193
195
  janito/tools/adapters/local/remove_file.py,sha256=cSs7EIhEqblnLmwjUKrUq2M8axyT2oTXJqZs5waOAFw,2090
194
196
  janito/tools/adapters/local/replace_text_in_file.py,sha256=zFGWORuaw50ZlEFf3q_s7K25Tt0QXu8yOXDeodY6kcE,10791
195
197
  janito/tools/adapters/local/run_bash_command.py,sha256=iiOz2oBiPcyYG6ySOIS8zOuQ9XpYv6DiUwGiPKciADw,7623
196
- janito/tools/adapters/local/run_powershell_command.py,sha256=wTfIvWo5F3nVuDiNNHv2YzTlra5vQQMz2XYqreFiBVc,9260
198
+ janito/tools/adapters/local/run_powershell_command.py,sha256=p9SNZ2D4CMgbwtCIQ3jwlWWNYXMOPzosdQnkToT8QKI,8961
197
199
  janito/tools/adapters/local/view_file.py,sha256=-6Li0SegDUcUdH9jAulunQZj-Bm4A2MhSVbmtBFXtXQ,7137
198
200
  janito/tools/adapters/local/get_file_outline/__init__.py,sha256=OKV_BHnoD9h-vkcVoW6AHmsuDjjauHPCKNK0nVFl4sU,37
199
201
  janito/tools/adapters/local/get_file_outline/core.py,sha256=L_fS39v5ufLc9BK02tWMiH0nWQcXPAmbmwBNv1s_IhU,4373
@@ -217,9 +219,9 @@ janito/tools/adapters/local/validate_file_syntax/ps1_validator.py,sha256=TeIkPt0
217
219
  janito/tools/adapters/local/validate_file_syntax/python_validator.py,sha256=BfCO_K18qy92m-2ZVvHsbEU5e11OPo1pO9Vz4G4616E,130
218
220
  janito/tools/adapters/local/validate_file_syntax/xml_validator.py,sha256=AijlsP_PgNuC8ZbGsC5vOTt3Jur76otQzkd_7qR0QFY,284
219
221
  janito/tools/adapters/local/validate_file_syntax/yaml_validator.py,sha256=TgyI0HRL6ug_gBcWEm5TGJJuA4E34ZXcIzMpAbv3oJs,155
220
- janito-2.18.0.dist-info/licenses/LICENSE,sha256=GSAKapQH5ZIGWlpQTA7v5YrfECyaxaohUb1vJX-qepw,1090
221
- janito-2.18.0.dist-info/METADATA,sha256=bRfqlaQ-v39RPyYETpzpTi2jSQrd8p4mn4oTjlIwGss,16365
222
- janito-2.18.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
223
- janito-2.18.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
224
- janito-2.18.0.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
225
- janito-2.18.0.dist-info/RECORD,,
222
+ janito-2.19.1.dist-info/licenses/LICENSE,sha256=GSAKapQH5ZIGWlpQTA7v5YrfECyaxaohUb1vJX-qepw,1090
223
+ janito-2.19.1.dist-info/METADATA,sha256=2pmHGTyGGxQ_SEekpmK-xu6oL-_ZRSBjlKdNTEZuW3U,16365
224
+ janito-2.19.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
225
+ janito-2.19.1.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
226
+ janito-2.19.1.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
227
+ janito-2.19.1.dist-info/RECORD,,