chat-console 0.2.9__py3-none-any.whl → 0.2.99__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.
- app/__init__.py +1 -1
- app/api/anthropic.py +163 -26
- app/api/base.py +45 -2
- app/api/ollama.py +202 -43
- app/api/openai.py +53 -4
- app/config.py +53 -7
- app/main.py +512 -103
- app/ui/chat_interface.py +40 -20
- app/ui/model_browser.py +405 -45
- app/ui/model_selector.py +77 -19
- app/utils.py +359 -85
- {chat_console-0.2.9.dist-info → chat_console-0.2.99.dist-info}/METADATA +1 -1
- chat_console-0.2.99.dist-info/RECORD +24 -0
- chat_console-0.2.9.dist-info/RECORD +0 -24
- {chat_console-0.2.9.dist-info → chat_console-0.2.99.dist-info}/WHEEL +0 -0
- {chat_console-0.2.9.dist-info → chat_console-0.2.99.dist-info}/entry_points.txt +0 -0
- {chat_console-0.2.9.dist-info → chat_console-0.2.99.dist-info}/licenses/LICENSE +0 -0
- {chat_console-0.2.9.dist-info → chat_console-0.2.99.dist-info}/top_level.txt +0 -0
app/ui/model_selector.py
CHANGED
@@ -7,6 +7,7 @@ from textual.widget import Widget
|
|
7
7
|
from textual.message import Message
|
8
8
|
|
9
9
|
from ..config import CONFIG
|
10
|
+
from ..utils import resolve_model_id # Import the resolve_model_id function
|
10
11
|
from ..api.ollama import OllamaClient
|
11
12
|
from .chat_interface import ChatInterface
|
12
13
|
|
@@ -58,7 +59,10 @@ class ModelSelector(Container):
|
|
58
59
|
class ModelSelected(Message):
|
59
60
|
"""Event sent when a model is selected"""
|
60
61
|
def __init__(self, model_id: str):
|
61
|
-
|
62
|
+
# Always resolve the model ID before sending it to the main app
|
63
|
+
# This ensures short names like "claude-3.7-sonnet" are converted to full IDs
|
64
|
+
self.model_id = resolve_model_id(model_id)
|
65
|
+
logger.info(f"ModelSelected: Original ID '{model_id}' resolved to '{self.model_id}'")
|
62
66
|
super().__init__()
|
63
67
|
|
64
68
|
def __init__(
|
@@ -68,7 +72,10 @@ class ModelSelector(Container):
|
|
68
72
|
id: Optional[str] = None
|
69
73
|
):
|
70
74
|
super().__init__(name=name, id=id)
|
71
|
-
|
75
|
+
# Resolve the model ID during initialization
|
76
|
+
original_id = selected_model or CONFIG["default_model"]
|
77
|
+
self.selected_model = resolve_model_id(original_id)
|
78
|
+
logger.info(f"ModelSelector.__init__: Original ID '{original_id}' resolved to '{self.selected_model}'")
|
72
79
|
# Handle custom models not in CONFIG
|
73
80
|
if self.selected_model in CONFIG["available_models"]:
|
74
81
|
self.selected_provider = CONFIG["available_models"][self.selected_model]["provider"]
|
@@ -220,12 +227,48 @@ class ModelSelector(Container):
|
|
220
227
|
model_options = await self._get_model_options(self.selected_provider)
|
221
228
|
model_select.set_options(model_options)
|
222
229
|
# Select first model of new provider
|
223
|
-
if model_options:
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
230
|
+
if model_options and len(model_options) > 0:
|
231
|
+
# Check if model_options is properly structured as a list of tuples
|
232
|
+
try:
|
233
|
+
# Get the first non-custom model if available
|
234
|
+
first_model = None
|
235
|
+
for model_option in model_options:
|
236
|
+
if isinstance(model_option, tuple) and len(model_option) >= 2 and model_option[1] != "custom":
|
237
|
+
first_model = model_option
|
238
|
+
break
|
239
|
+
|
240
|
+
# If no non-custom models, use the first model
|
241
|
+
if not first_model and isinstance(model_options[0], tuple) and len(model_options[0]) >= 2:
|
242
|
+
first_model = model_options[0]
|
243
|
+
|
244
|
+
# Set the model if we found one
|
245
|
+
if first_model and len(first_model) >= 2:
|
246
|
+
# Resolve the model ID before storing and sending
|
247
|
+
original_id = first_model[1]
|
248
|
+
resolved_id = resolve_model_id(original_id)
|
249
|
+
logger.info(f"on_select_changed (provider): Original ID '{original_id}' resolved to '{resolved_id}'")
|
250
|
+
self.selected_model = resolved_id
|
251
|
+
model_select.value = resolved_id
|
252
|
+
model_select.remove_class("hide")
|
253
|
+
self.query_one("#custom-model-input").add_class("hide")
|
254
|
+
self.post_message(self.ModelSelected(resolved_id))
|
255
|
+
else:
|
256
|
+
# Fall back to custom if no valid model found
|
257
|
+
self.selected_model = "custom"
|
258
|
+
model_select.value = "custom"
|
259
|
+
model_select.add_class("hide")
|
260
|
+
custom_input = self.query_one("#custom-model-input")
|
261
|
+
custom_input.remove_class("hide")
|
262
|
+
custom_input.focus()
|
263
|
+
except (IndexError, TypeError) as e:
|
264
|
+
logger.error(f"Error selecting first model: {e}")
|
265
|
+
# Fall back to custom
|
266
|
+
self.selected_model = "custom"
|
267
|
+
model_select.value = "custom"
|
268
|
+
model_select.add_class("hide")
|
269
|
+
custom_input = self.query_one("#custom-model-input")
|
270
|
+
custom_input.remove_class("hide")
|
271
|
+
custom_input.focus()
|
229
272
|
|
230
273
|
elif event.select.id == "model-select":
|
231
274
|
if event.value == "custom":
|
@@ -241,28 +284,43 @@ class ModelSelector(Container):
|
|
241
284
|
custom_input = self.query_one("#custom-model-input")
|
242
285
|
model_select.remove_class("hide")
|
243
286
|
custom_input.add_class("hide")
|
244
|
-
|
245
|
-
|
287
|
+
# Resolve the model ID before storing and sending
|
288
|
+
resolved_id = resolve_model_id(event.value)
|
289
|
+
logger.info(f"on_select_changed: Original ID '{event.value}' resolved to '{resolved_id}'")
|
290
|
+
self.selected_model = resolved_id
|
291
|
+
self.post_message(self.ModelSelected(resolved_id))
|
246
292
|
|
247
293
|
def on_input_changed(self, event: Input.Changed) -> None:
|
248
294
|
"""Handle custom model input changes"""
|
249
295
|
if event.input.id == "custom-model-input":
|
250
296
|
value = event.value.strip()
|
251
297
|
if value: # Only update if there's actual content
|
252
|
-
|
253
|
-
|
298
|
+
# Resolve the model ID before storing and sending
|
299
|
+
resolved_id = resolve_model_id(value)
|
300
|
+
logger.info(f"on_input_changed: Original ID '{value}' resolved to '{resolved_id}'")
|
301
|
+
self.selected_model = resolved_id
|
302
|
+
self.post_message(self.ModelSelected(resolved_id))
|
254
303
|
|
255
304
|
def get_selected_model(self) -> str:
|
256
|
-
"""Get the current selected model ID"""
|
257
|
-
|
305
|
+
"""Get the current selected model ID, ensuring it's properly resolved"""
|
306
|
+
resolved_id = resolve_model_id(self.selected_model)
|
307
|
+
logger.info(f"get_selected_model: Original ID '{self.selected_model}' resolved to '{resolved_id}'")
|
308
|
+
return resolved_id
|
258
309
|
|
259
310
|
def set_selected_model(self, model_id: str) -> None:
|
260
|
-
"""Set the selected model"""
|
261
|
-
|
262
|
-
|
311
|
+
"""Set the selected model, ensuring it's properly resolved"""
|
312
|
+
# First resolve the model ID to ensure we're using the full ID
|
313
|
+
resolved_id = resolve_model_id(model_id)
|
314
|
+
logger.info(f"set_selected_model: Original ID '{model_id}' resolved to '{resolved_id}'")
|
315
|
+
|
316
|
+
# Store the resolved ID
|
317
|
+
self.selected_model = resolved_id
|
318
|
+
|
319
|
+
# Update the UI based on whether this is a known model or custom
|
320
|
+
if resolved_id in CONFIG["available_models"]:
|
263
321
|
select = self.query_one("#model-select", Select)
|
264
322
|
custom_input = self.query_one("#custom-model-input")
|
265
|
-
select.value =
|
323
|
+
select.value = resolved_id
|
266
324
|
select.remove_class("hide")
|
267
325
|
custom_input.add_class("hide")
|
268
326
|
else:
|
@@ -270,7 +328,7 @@ class ModelSelector(Container):
|
|
270
328
|
custom_input = self.query_one("#custom-model-input")
|
271
329
|
select.value = "custom"
|
272
330
|
select.add_class("hide")
|
273
|
-
custom_input.value =
|
331
|
+
custom_input.value = resolved_id
|
274
332
|
custom_input.remove_class("hide")
|
275
333
|
|
276
334
|
class StyleSelector(Container):
|