code-puppy 0.0.157__tar.gz → 0.0.159__tar.gz
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.
- {code_puppy-0.0.157 → code_puppy-0.0.159}/PKG-INFO +1 -1
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/command_handler.py +7 -8
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/config.py +15 -8
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/messaging/queue_console.py +3 -2
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/model_factory.py +29 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/models.json +0 -6
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/components/chat_view.py +38 -21
- {code_puppy-0.0.157 → code_puppy-0.0.159}/pyproject.toml +1 -1
- {code_puppy-0.0.157 → code_puppy-0.0.159}/.gitignore +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/LICENSE +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/README.md +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/__main__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/agent.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/agents/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/agents/agent_code_puppy.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/agents/agent_creator_agent.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/agents/agent_manager.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/agents/agent_orchestrator.json +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/agents/base_agent.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/agents/json_agent.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/agents/runtime_manager.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/callbacks.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/file_path_completion.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/load_context_completion.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/add_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/base.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/handler.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/help_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/install_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/list_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/logs_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/remove_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/restart_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/search_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/start_all_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/start_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/status_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/stop_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/test_command.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/utils.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/meta_command_handler.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/model_picker_completion.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/motd.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/utils.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/http_utils.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/main.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/async_lifecycle.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/blocking_startup.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/captured_stdio_server.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/circuit_breaker.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/config_wizard.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/dashboard.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/error_isolation.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/examples/retry_example.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/health_monitor.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/managed_server.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/manager.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/registry.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/retry_manager.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/server_registry_catalog.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/status_tracker.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/mcp/system_tools.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/message_history_processor.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/messaging/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/messaging/message_queue.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/messaging/renderers.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/messaging/spinner/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/messaging/spinner/console_spinner.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/messaging/spinner/spinner_base.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/messaging/spinner/textual_spinner.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/plugins/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/reopenable_async_client.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/round_robin_model.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/state_management.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/status_display.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/summarization_agent.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tools/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tools/agent_tools.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tools/command_runner.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tools/common.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tools/file_modifications.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tools/file_operations.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tools/tools_content.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/app.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/components/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/components/command_history_modal.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/components/copy_button.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/components/custom_widgets.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/components/human_input_modal.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/components/input_area.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/components/sidebar.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/components/status_bar.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/messages.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/models/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/models/chat_message.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/models/command_history.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/models/enums.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/screens/__init__.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/screens/help.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/screens/mcp_install_wizard.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/screens/settings.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/screens/tools.py +0 -0
- {code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/version_checker.py +0 -0
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
|
|
3
|
-
from code_puppy.command_line.model_picker_completion import
|
|
4
|
-
load_model_names,
|
|
5
|
-
update_model_in_input,
|
|
6
|
-
)
|
|
3
|
+
from code_puppy.command_line.model_picker_completion import update_model_in_input
|
|
7
4
|
from code_puppy.command_line.motd import print_motd
|
|
8
5
|
from code_puppy.command_line.utils import make_directory_table
|
|
9
6
|
from code_puppy.config import get_config_keys
|
|
@@ -60,7 +57,7 @@ def get_commands_help():
|
|
|
60
57
|
)
|
|
61
58
|
help_lines.append(
|
|
62
59
|
Text("/compact", style="cyan")
|
|
63
|
-
+ Text(" Summarize and compact current chat history")
|
|
60
|
+
+ Text(" Summarize and compact current chat history (uses compaction_strategy config)")
|
|
64
61
|
)
|
|
65
62
|
help_lines.append(
|
|
66
63
|
Text("/dump_context", style="cyan")
|
|
@@ -137,18 +134,18 @@ def handle_command(command: str):
|
|
|
137
134
|
|
|
138
135
|
before_tokens = sum(estimate_tokens_for_message(m) for m in history)
|
|
139
136
|
compaction_strategy = get_compaction_strategy()
|
|
137
|
+
protected_tokens = get_protected_token_count()
|
|
140
138
|
emit_info(
|
|
141
139
|
f"🤔 Compacting {len(history)} messages using {compaction_strategy} strategy... (~{before_tokens} tokens)"
|
|
142
140
|
)
|
|
143
141
|
|
|
144
142
|
if compaction_strategy == "truncation":
|
|
145
|
-
protected_tokens = get_protected_token_count()
|
|
146
143
|
compacted = truncation(history, protected_tokens)
|
|
147
144
|
summarized_messages = [] # No summarization in truncation mode
|
|
148
145
|
else:
|
|
149
146
|
# Default to summarization
|
|
150
147
|
compacted, summarized_messages = summarize_messages(
|
|
151
|
-
history, with_protection=
|
|
148
|
+
history, with_protection=True
|
|
152
149
|
)
|
|
153
150
|
|
|
154
151
|
if not compacted:
|
|
@@ -372,6 +369,9 @@ def handle_command(command: str):
|
|
|
372
369
|
# Convert /model to /m for internal processing
|
|
373
370
|
model_command = command.replace("/model", "/m", 1)
|
|
374
371
|
|
|
372
|
+
# If no model matched, show available models
|
|
373
|
+
from code_puppy.command_line.model_picker_completion import load_model_names
|
|
374
|
+
|
|
375
375
|
new_input = update_model_in_input(model_command)
|
|
376
376
|
if new_input is not None:
|
|
377
377
|
from code_puppy.agents.runtime_manager import get_runtime_agent_manager
|
|
@@ -383,7 +383,6 @@ def handle_command(command: str):
|
|
|
383
383
|
manager.reload_agent()
|
|
384
384
|
emit_success(f"Active model set and loaded: {model}")
|
|
385
385
|
return True
|
|
386
|
-
# If no model matched, show available models
|
|
387
386
|
model_names = load_model_names()
|
|
388
387
|
emit_warning("Usage: /model <model-name> or /m <model-name>")
|
|
389
388
|
emit_warning(f"Available models: {', '.join(model_names)}")
|
|
@@ -110,6 +110,8 @@ def get_config_keys():
|
|
|
110
110
|
"yolo_mode",
|
|
111
111
|
"model",
|
|
112
112
|
"compaction_strategy",
|
|
113
|
+
"protected_token_count",
|
|
114
|
+
"compaction_threshold",
|
|
113
115
|
"message_limit",
|
|
114
116
|
"allow_recursion",
|
|
115
117
|
]
|
|
@@ -162,7 +164,7 @@ _default_model_cache = None
|
|
|
162
164
|
def _default_model_from_models_json():
|
|
163
165
|
"""Attempt to load the first model name from models.json.
|
|
164
166
|
|
|
165
|
-
Falls back to the hard-coded default (``
|
|
167
|
+
Falls back to the hard-coded default (``gpt-5``) if the file
|
|
166
168
|
cannot be read for any reason or is empty.
|
|
167
169
|
"""
|
|
168
170
|
global _default_model_cache
|
|
@@ -176,11 +178,17 @@ def _default_model_from_models_json():
|
|
|
176
178
|
from code_puppy.model_factory import ModelFactory
|
|
177
179
|
|
|
178
180
|
models_config = ModelFactory.load_config()
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
181
|
+
if models_config:
|
|
182
|
+
# Get the first key from the models config
|
|
183
|
+
first_key = next(iter(models_config))
|
|
184
|
+
_default_model_cache = first_key
|
|
185
|
+
return first_key
|
|
186
|
+
else:
|
|
187
|
+
# If models_config is empty, fall back to gpt-5
|
|
188
|
+
_default_model_cache = "gpt-5"
|
|
189
|
+
return "gpt-5"
|
|
182
190
|
except Exception:
|
|
183
|
-
# Any problem (network, file missing, empty dict, etc.) => fall back
|
|
191
|
+
# Any problem (network, file missing, empty dict, etc.) => fall back to gpt-5
|
|
184
192
|
_default_model_cache = "gpt-5"
|
|
185
193
|
return "gpt-5"
|
|
186
194
|
|
|
@@ -196,8 +204,7 @@ def _validate_model_exists(model_name: str) -> bool:
|
|
|
196
204
|
try:
|
|
197
205
|
from code_puppy.model_factory import ModelFactory
|
|
198
206
|
|
|
199
|
-
|
|
200
|
-
models_config = ModelFactory.load_config(models_config_path)
|
|
207
|
+
models_config = ModelFactory.load_config()
|
|
201
208
|
exists = model_name in models_config
|
|
202
209
|
|
|
203
210
|
# Cache the result
|
|
@@ -485,4 +492,4 @@ def save_command_to_history(command: str):
|
|
|
485
492
|
error_msg = (
|
|
486
493
|
f"❌ An unexpected error occurred while saving command history: {str(e)}"
|
|
487
494
|
)
|
|
488
|
-
direct_console.print(f"[bold red]{error_msg}[/bold red]")
|
|
495
|
+
direct_console.print(f"[bold red]{error_msg}[/bold red]")
|
|
@@ -58,9 +58,10 @@ class QueueConsole:
|
|
|
58
58
|
from rich.console import Console
|
|
59
59
|
|
|
60
60
|
string_io = StringIO()
|
|
61
|
-
# Use markup=
|
|
61
|
+
# Use markup=True to properly process rich styling
|
|
62
|
+
# Use a reasonable width to prevent wrapping issues
|
|
62
63
|
temp_console = Console(
|
|
63
|
-
file=string_io, width=80, legacy_windows=False, markup=
|
|
64
|
+
file=string_io, width=80, legacy_windows=False, markup=True
|
|
64
65
|
)
|
|
65
66
|
temp_console.print(v)
|
|
66
67
|
processed_values.append(string_io.getvalue().rstrip("\n"))
|
|
@@ -14,6 +14,7 @@ from pydantic_ai.providers.anthropic import AnthropicProvider
|
|
|
14
14
|
from pydantic_ai.providers.google_gla import GoogleGLAProvider
|
|
15
15
|
from pydantic_ai.providers.openai import OpenAIProvider
|
|
16
16
|
from pydantic_ai.providers.cerebras import CerebrasProvider
|
|
17
|
+
from pydantic_ai.providers.openrouter import OpenRouterProvider
|
|
17
18
|
|
|
18
19
|
from . import callbacks
|
|
19
20
|
from .config import EXTRA_MODELS_FILE
|
|
@@ -248,6 +249,34 @@ class ModelFactory:
|
|
|
248
249
|
setattr(model, "provider", provider)
|
|
249
250
|
return model
|
|
250
251
|
|
|
252
|
+
elif model_type == "openrouter":
|
|
253
|
+
# Get API key from config, which can be an environment variable reference or raw value
|
|
254
|
+
api_key_config = model_config.get("api_key")
|
|
255
|
+
api_key = None
|
|
256
|
+
|
|
257
|
+
if api_key_config:
|
|
258
|
+
if api_key_config.startswith("$"):
|
|
259
|
+
# It's an environment variable reference
|
|
260
|
+
env_var_name = api_key_config[1:] # Remove the $ prefix
|
|
261
|
+
api_key = os.environ.get(env_var_name)
|
|
262
|
+
if api_key is None:
|
|
263
|
+
raise ValueError(
|
|
264
|
+
f"OpenRouter API key environment variable '{env_var_name}' not found or is empty. "
|
|
265
|
+
f"Please set the environment variable: export {env_var_name}=your_value"
|
|
266
|
+
)
|
|
267
|
+
else:
|
|
268
|
+
# It's a raw API key value
|
|
269
|
+
api_key = api_key_config
|
|
270
|
+
else:
|
|
271
|
+
# No API key in config, try to get it from the default environment variable
|
|
272
|
+
api_key = os.environ.get("OPENROUTER_API_KEY")
|
|
273
|
+
|
|
274
|
+
provider = OpenRouterProvider(api_key=api_key)
|
|
275
|
+
|
|
276
|
+
model = OpenAIChatModel(model_name=model_config["name"], provider=provider)
|
|
277
|
+
setattr(model, "provider", provider)
|
|
278
|
+
return model
|
|
279
|
+
|
|
251
280
|
elif model_type == "round_robin":
|
|
252
281
|
# Get the list of model names to use in the round-robin
|
|
253
282
|
model_names = model_config.get("models")
|
|
@@ -87,12 +87,6 @@
|
|
|
87
87
|
},
|
|
88
88
|
"context_length": 64000
|
|
89
89
|
},
|
|
90
|
-
"openrouter": {
|
|
91
|
-
"type": "openrouter",
|
|
92
|
-
"name": "meta-llama/llama-4-maverick:free",
|
|
93
|
-
"api_key": "$OPENROUTER_API_KEY",
|
|
94
|
-
"context_length": 131072
|
|
95
|
-
},
|
|
96
90
|
"azure-gpt-4.1": {
|
|
97
91
|
"type": "azure_openai",
|
|
98
92
|
"name": "gpt-4.1",
|
|
@@ -261,8 +261,35 @@ class ChatView(VerticalScroll):
|
|
|
261
261
|
else:
|
|
262
262
|
separator = "\n"
|
|
263
263
|
|
|
264
|
-
#
|
|
265
|
-
last_message.content
|
|
264
|
+
# Handle content concatenation carefully to preserve Rich objects
|
|
265
|
+
if hasattr(last_message.content, "__rich_console__") or hasattr(message.content, "__rich_console__"):
|
|
266
|
+
# If either content is a Rich object, convert both to text and concatenate
|
|
267
|
+
from io import StringIO
|
|
268
|
+
from rich.console import Console
|
|
269
|
+
|
|
270
|
+
# Convert existing content to string
|
|
271
|
+
if hasattr(last_message.content, "__rich_console__"):
|
|
272
|
+
string_io = StringIO()
|
|
273
|
+
temp_console = Console(file=string_io, width=80, legacy_windows=False, markup=False)
|
|
274
|
+
temp_console.print(last_message.content)
|
|
275
|
+
existing_content = string_io.getvalue().rstrip("\n")
|
|
276
|
+
else:
|
|
277
|
+
existing_content = str(last_message.content)
|
|
278
|
+
|
|
279
|
+
# Convert new content to string
|
|
280
|
+
if hasattr(message.content, "__rich_console__"):
|
|
281
|
+
string_io = StringIO()
|
|
282
|
+
temp_console = Console(file=string_io, width=80, legacy_windows=False, markup=False)
|
|
283
|
+
temp_console.print(message.content)
|
|
284
|
+
new_content = string_io.getvalue().rstrip("\n")
|
|
285
|
+
else:
|
|
286
|
+
new_content = str(message.content)
|
|
287
|
+
|
|
288
|
+
# Combine as plain text
|
|
289
|
+
last_message.content = existing_content + separator + new_content
|
|
290
|
+
else:
|
|
291
|
+
# Both are strings, safe to concatenate
|
|
292
|
+
last_message.content += separator + message.content
|
|
266
293
|
|
|
267
294
|
# Update the widget based on message type
|
|
268
295
|
if last_message.type == MessageType.AGENT_RESPONSE:
|
|
@@ -282,25 +309,15 @@ class ChatView(VerticalScroll):
|
|
|
282
309
|
copy_button.update_text_to_copy(last_message.content)
|
|
283
310
|
else:
|
|
284
311
|
# Handle other message types
|
|
285
|
-
content
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
)
|
|
295
|
-
):
|
|
296
|
-
# Treat as literal text
|
|
297
|
-
last_widget.update(Text(content))
|
|
298
|
-
else:
|
|
299
|
-
# Try to render markup
|
|
300
|
-
try:
|
|
301
|
-
last_widget.update(Text.from_markup(content))
|
|
302
|
-
except Exception:
|
|
303
|
-
last_widget.update(Text(content))
|
|
312
|
+
# After the content concatenation above, content is always a string
|
|
313
|
+
# Try to parse markup when safe to do so
|
|
314
|
+
try:
|
|
315
|
+
# Try to parse as markup first - this handles rich styling correctly
|
|
316
|
+
last_widget.update(Text.from_markup(last_message.content))
|
|
317
|
+
except Exception:
|
|
318
|
+
# If markup parsing fails, fall back to plain text
|
|
319
|
+
# This handles cases where content contains literal square brackets
|
|
320
|
+
last_widget.update(Text(last_message.content))
|
|
304
321
|
|
|
305
322
|
# Add the new message to our tracking lists
|
|
306
323
|
self.messages.append(message)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/load_context_completion.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/model_picker_completion.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/command_line/prompt_toolkit_completion.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.157 → code_puppy-0.0.159}/code_puppy/tui/components/command_history_modal.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|