code-puppy 0.0.323__tar.gz → 0.0.325__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.323 → code_puppy-0.0.325}/PKG-INFO +1 -1
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/base_agent.py +58 -15
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/add_model_menu.py +11 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/models.json +2 -2
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/__init__.py +12 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/pyproject.toml +1 -1
- {code_puppy-0.0.323 → code_puppy-0.0.325}/.gitignore +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/LICENSE +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/README.md +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/__main__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_c_reviewer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_code_puppy.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_code_reviewer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_cpp_reviewer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_creator_agent.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_golang_reviewer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_javascript_reviewer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_manager.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_planning.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_python_programmer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_python_reviewer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_qa_expert.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_qa_kitten.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_security_auditor.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/agent_typescript_reviewer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/json_agent.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/agents/prompt_reviewer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/callbacks.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/chatgpt_codex_client.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/claude_cache_client.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/cli_runner.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/attachments.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/autosave_menu.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/colors_menu.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/command_handler.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/command_registry.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/config_commands.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/core_commands.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/diff_menu.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/file_path_completion.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/load_context_completion.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/add_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/base.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/edit_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/handler.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/help_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/install_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/install_menu.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/list_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/logs_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/remove_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/restart_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/search_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/start_all_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/start_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/status_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/stop_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/test_command.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/utils.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp_completion.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/model_picker_completion.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/model_settings_menu.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/motd.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/pin_command_completion.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/session_commands.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/utils.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/config.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/error_logging.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/gemini_code_assist.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/http_utils.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/keymap.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/main.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/async_lifecycle.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/blocking_startup.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/captured_stdio_server.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/circuit_breaker.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/config_wizard.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/dashboard.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/error_isolation.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/examples/retry_example.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/health_monitor.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/managed_server.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/manager.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/mcp_logs.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/registry.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/retry_manager.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/server_registry_catalog.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/status_tracker.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/mcp_/system_tools.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/bus.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/commands.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/markdown_patches.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/message_queue.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/messages.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/queue_console.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/renderers.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/rich_renderer.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/spinner/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/spinner/console_spinner.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/messaging/spinner/spinner_base.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/model_factory.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/model_utils.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/models_dev_api.json +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/models_dev_parser.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/chatgpt_oauth/config.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/chatgpt_oauth/utils.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/claude_code_oauth/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/claude_code_oauth/config.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/claude_code_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/claude_code_oauth/utils.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/customizable_commands/register_callbacks.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/example_custom_command/README.md +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/file_permission_handler/register_callbacks.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/oauth_puppy_html.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/shell_safety/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/shell_safety/agent_shell_safety.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/shell_safety/command_cache.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/shell_safety/register_callbacks.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/prompts/codex_system_prompt.md +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/pydantic_patches.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/reopenable_async_client.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/round_robin_model.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/session_storage.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/status_display.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/summarization_agent.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/terminal_utils.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/agent_tools.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/browser/__init__.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/browser/browser_control.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/browser/browser_interactions.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/browser/browser_locators.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/browser/browser_navigation.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/browser/browser_screenshot.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/browser/browser_scripts.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/browser/browser_workflows.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/browser/camoufox_manager.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/browser/vqa_agent.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/command_runner.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/common.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/file_modifications.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/file_operations.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/tools/tools_content.py +0 -0
- {code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/version_checker.py +0 -0
|
@@ -1340,15 +1340,19 @@ class BaseAgent(ABC):
|
|
|
1340
1340
|
) -> None:
|
|
1341
1341
|
"""Handle streaming events from the agent run.
|
|
1342
1342
|
|
|
1343
|
-
This method processes streaming events and emits TextPart
|
|
1344
|
-
content with styled banners as they stream in.
|
|
1343
|
+
This method processes streaming events and emits TextPart, ThinkingPart,
|
|
1344
|
+
and ToolCallPart content with styled banners/tokens as they stream in.
|
|
1345
1345
|
|
|
1346
1346
|
Args:
|
|
1347
1347
|
ctx: The run context.
|
|
1348
1348
|
events: Async iterable of streaming events (PartStartEvent, PartDeltaEvent, etc.).
|
|
1349
1349
|
"""
|
|
1350
1350
|
from pydantic_ai import PartDeltaEvent, PartStartEvent
|
|
1351
|
-
from pydantic_ai.messages import
|
|
1351
|
+
from pydantic_ai.messages import (
|
|
1352
|
+
TextPartDelta,
|
|
1353
|
+
ThinkingPartDelta,
|
|
1354
|
+
ToolCallPartDelta,
|
|
1355
|
+
)
|
|
1352
1356
|
from rich.console import Console
|
|
1353
1357
|
from rich.markdown import Markdown
|
|
1354
1358
|
from rich.markup import escape
|
|
@@ -1364,15 +1368,16 @@ class BaseAgent(ABC):
|
|
|
1364
1368
|
# Fallback if console not set (shouldn't happen in normal use)
|
|
1365
1369
|
console = Console()
|
|
1366
1370
|
|
|
1367
|
-
# Track which part indices we're currently streaming (for Text/Thinking parts)
|
|
1371
|
+
# Track which part indices we're currently streaming (for Text/Thinking/Tool parts)
|
|
1368
1372
|
streaming_parts: set[int] = set()
|
|
1369
1373
|
thinking_parts: set[int] = (
|
|
1370
1374
|
set()
|
|
1371
1375
|
) # Track which parts are thinking (for dim style)
|
|
1372
1376
|
text_parts: set[int] = set() # Track which parts are text
|
|
1377
|
+
tool_parts: set[int] = set() # Track which parts are tool calls
|
|
1373
1378
|
banner_printed: set[int] = set() # Track if banner was already printed
|
|
1374
1379
|
text_buffer: dict[int, list[str]] = {} # Buffer text for final markdown render
|
|
1375
|
-
token_count: dict[int, int] = {} # Track token count per text part
|
|
1380
|
+
token_count: dict[int, int] = {} # Track token count per text/tool part
|
|
1376
1381
|
did_stream_anything = False # Track if we streamed any content
|
|
1377
1382
|
|
|
1378
1383
|
def _print_thinking_banner() -> None:
|
|
@@ -1442,7 +1447,16 @@ class BaseAgent(ABC):
|
|
|
1442
1447
|
# Buffer initial content if present
|
|
1443
1448
|
if part.content and part.content.strip():
|
|
1444
1449
|
text_buffer[event.index].append(part.content)
|
|
1445
|
-
|
|
1450
|
+
# Use len(content) / 3 for token estimation (more accurate than chunk counting)
|
|
1451
|
+
token_count[event.index] += len(part.content) // 3
|
|
1452
|
+
elif isinstance(part, ToolCallPart):
|
|
1453
|
+
streaming_parts.add(event.index)
|
|
1454
|
+
tool_parts.add(event.index)
|
|
1455
|
+
token_count[event.index] = 0 # Initialize token counter
|
|
1456
|
+
# Track tool name for display
|
|
1457
|
+
banner_printed.add(
|
|
1458
|
+
event.index
|
|
1459
|
+
) # Use banner_printed to track if we've shown tool info
|
|
1446
1460
|
|
|
1447
1461
|
# PartDeltaEvent - stream the content as it arrives
|
|
1448
1462
|
elif isinstance(event, PartDeltaEvent):
|
|
@@ -1460,7 +1474,10 @@ class BaseAgent(ABC):
|
|
|
1460
1474
|
banner_printed.add(event.index)
|
|
1461
1475
|
# Accumulate text for final markdown render
|
|
1462
1476
|
text_buffer[event.index].append(delta.content_delta)
|
|
1463
|
-
|
|
1477
|
+
# Use len(content) / 3 for token estimation
|
|
1478
|
+
token_count[event.index] += (
|
|
1479
|
+
len(delta.content_delta) // 3
|
|
1480
|
+
)
|
|
1464
1481
|
# Update token counter in place (single line)
|
|
1465
1482
|
count = token_count[event.index]
|
|
1466
1483
|
sys.stdout.write(
|
|
@@ -1474,14 +1491,32 @@ class BaseAgent(ABC):
|
|
|
1474
1491
|
banner_printed.add(event.index)
|
|
1475
1492
|
escaped = escape(delta.content_delta)
|
|
1476
1493
|
console.print(f"[dim]{escaped}[/dim]", end="")
|
|
1494
|
+
elif isinstance(delta, ToolCallPartDelta):
|
|
1495
|
+
import sys
|
|
1496
|
+
|
|
1497
|
+
# For tool calls, show token counter (use string repr for estimation)
|
|
1498
|
+
token_count[event.index] += len(str(delta)) // 3
|
|
1499
|
+
# Get tool name if available
|
|
1500
|
+
tool_name = getattr(delta, "tool_name_delta", "")
|
|
1501
|
+
count = token_count[event.index]
|
|
1502
|
+
# Display with tool wrench icon and tool name
|
|
1503
|
+
if tool_name:
|
|
1504
|
+
sys.stdout.write(
|
|
1505
|
+
f"\r\x1b[K 🔧 Calling {tool_name}... {count} tokens"
|
|
1506
|
+
)
|
|
1507
|
+
else:
|
|
1508
|
+
sys.stdout.write(
|
|
1509
|
+
f"\r\x1b[K 🔧 Calling tool... {count} tokens"
|
|
1510
|
+
)
|
|
1511
|
+
sys.stdout.flush()
|
|
1477
1512
|
|
|
1478
1513
|
# PartEndEvent - finish the streaming with a newline
|
|
1479
1514
|
elif isinstance(event, PartEndEvent):
|
|
1480
1515
|
if event.index in streaming_parts:
|
|
1516
|
+
import sys
|
|
1517
|
+
|
|
1481
1518
|
# For text parts, clear counter line and render markdown
|
|
1482
1519
|
if event.index in text_parts:
|
|
1483
|
-
import sys
|
|
1484
|
-
|
|
1485
1520
|
# Clear the token counter line
|
|
1486
1521
|
sys.stdout.write("\r\x1b[K")
|
|
1487
1522
|
sys.stdout.flush()
|
|
@@ -1494,24 +1529,31 @@ class BaseAgent(ABC):
|
|
|
1494
1529
|
except Exception:
|
|
1495
1530
|
pass
|
|
1496
1531
|
del text_buffer[event.index]
|
|
1497
|
-
|
|
1498
|
-
|
|
1532
|
+
# For tool parts, clear the token counter line
|
|
1533
|
+
elif event.index in tool_parts:
|
|
1534
|
+
# Clear the token counter line
|
|
1535
|
+
sys.stdout.write("\r\x1b[K")
|
|
1536
|
+
sys.stdout.flush()
|
|
1499
1537
|
# For thinking parts, just print newline
|
|
1500
1538
|
elif event.index in banner_printed:
|
|
1501
1539
|
console.print() # Final newline after streaming
|
|
1540
|
+
|
|
1541
|
+
# Clean up token count
|
|
1542
|
+
token_count.pop(event.index, None)
|
|
1502
1543
|
# Clean up all tracking sets
|
|
1503
1544
|
streaming_parts.discard(event.index)
|
|
1504
1545
|
thinking_parts.discard(event.index)
|
|
1505
1546
|
text_parts.discard(event.index)
|
|
1547
|
+
tool_parts.discard(event.index)
|
|
1506
1548
|
banner_printed.discard(event.index)
|
|
1507
1549
|
|
|
1508
|
-
# Resume spinner if next part is NOT text/thinking (avoid race condition)
|
|
1509
|
-
# If next part is
|
|
1550
|
+
# Resume spinner if next part is NOT text/thinking/tool (avoid race condition)
|
|
1551
|
+
# If next part is None or handled differently, it's safe to resume
|
|
1510
1552
|
# Note: spinner itself handles blank line before appearing
|
|
1511
1553
|
from code_puppy.messaging.spinner import resume_all_spinners
|
|
1512
1554
|
|
|
1513
1555
|
next_kind = getattr(event, "next_part_kind", None)
|
|
1514
|
-
if next_kind not in ("text", "thinking"):
|
|
1556
|
+
if next_kind not in ("text", "thinking", "tool-call"):
|
|
1515
1557
|
resume_all_spinners()
|
|
1516
1558
|
|
|
1517
1559
|
# Spinner is resumed in PartEndEvent when appropriate (based on next_part_kind)
|
|
@@ -1910,9 +1952,10 @@ class BaseAgent(ABC):
|
|
|
1910
1952
|
def graceful_sigint_handler(_sig, _frame):
|
|
1911
1953
|
# When using keyboard-based cancel, SIGINT should be a no-op
|
|
1912
1954
|
# (just show a hint to user about the configured cancel key)
|
|
1913
|
-
from code_puppy.keymap import get_cancel_agent_display_name
|
|
1914
1955
|
import sys
|
|
1915
1956
|
|
|
1957
|
+
from code_puppy.keymap import get_cancel_agent_display_name
|
|
1958
|
+
|
|
1916
1959
|
cancel_key = get_cancel_agent_display_name()
|
|
1917
1960
|
if sys.platform == "win32":
|
|
1918
1961
|
# On Windows, we use keyboard listener, so SIGINT might still fire
|
|
@@ -571,6 +571,7 @@ class AddModelMenu:
|
|
|
571
571
|
"cerebras": "cerebras",
|
|
572
572
|
"cohere": "custom_openai",
|
|
573
573
|
"perplexity": "custom_openai",
|
|
574
|
+
"minimax": "custom_anthropic",
|
|
574
575
|
}
|
|
575
576
|
|
|
576
577
|
# Determine the model type
|
|
@@ -600,6 +601,16 @@ class AddModelMenu:
|
|
|
600
601
|
api_key_env = f"${provider.env[0]}" if provider.env else "$API_KEY"
|
|
601
602
|
config["custom_endpoint"] = {"url": api_url, "api_key": api_key_env}
|
|
602
603
|
|
|
604
|
+
# Special handling for minimax: uses custom_anthropic but needs custom_endpoint
|
|
605
|
+
# and the URL needs /v1 stripped (comes as https://api.minimax.io/anthropic/v1)
|
|
606
|
+
if provider.id == "minimax" and provider.api:
|
|
607
|
+
api_url = provider.api
|
|
608
|
+
# Strip /v1 suffix if present
|
|
609
|
+
if api_url.endswith("/v1"):
|
|
610
|
+
api_url = api_url[:-3]
|
|
611
|
+
api_key_env = f"${provider.env[0]}" if provider.env else "$API_KEY"
|
|
612
|
+
config["custom_endpoint"] = {"url": api_url, "api_key": api_key_env}
|
|
613
|
+
|
|
603
614
|
# Add context length if available
|
|
604
615
|
if model.context_length and model.context_length > 0:
|
|
605
616
|
config["context_length"] = model.context_length
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"context_length": 200000,
|
|
10
10
|
"supported_settings": ["temperature", "seed"]
|
|
11
11
|
},
|
|
12
|
-
"synthetic-MiniMax-M2": {
|
|
12
|
+
"synthetic-MiniMax-M2.1": {
|
|
13
13
|
"type": "custom_openai",
|
|
14
|
-
"name": "hf:MiniMaxAI/MiniMax-M2",
|
|
14
|
+
"name": "hf:MiniMaxAI/MiniMax-M2.1",
|
|
15
15
|
"custom_endpoint": {
|
|
16
16
|
"url": "https://api.synthetic.new/openai/v1/",
|
|
17
17
|
"api_key": "$SYN_API_KEY"
|
|
@@ -18,6 +18,9 @@ def _load_builtin_plugins(plugins_dir: Path) -> list[str]:
|
|
|
18
18
|
|
|
19
19
|
Returns list of successfully loaded plugin names.
|
|
20
20
|
"""
|
|
21
|
+
# Import safety permission check for shell_safety plugin
|
|
22
|
+
from code_puppy.config import get_safety_permission_level
|
|
23
|
+
|
|
21
24
|
loaded = []
|
|
22
25
|
|
|
23
26
|
for item in plugins_dir.iterdir():
|
|
@@ -26,6 +29,15 @@ def _load_builtin_plugins(plugins_dir: Path) -> list[str]:
|
|
|
26
29
|
callbacks_file = item / "register_callbacks.py"
|
|
27
30
|
|
|
28
31
|
if callbacks_file.exists():
|
|
32
|
+
# Skip shell_safety plugin unless safety_permission_level is "low" or "none"
|
|
33
|
+
if plugin_name == "shell_safety":
|
|
34
|
+
safety_level = get_safety_permission_level()
|
|
35
|
+
if safety_level not in ("none", "low"):
|
|
36
|
+
logger.debug(
|
|
37
|
+
f"Skipping shell_safety plugin - safety_permission_level is '{safety_level}' (needs 'low' or 'none')"
|
|
38
|
+
)
|
|
39
|
+
continue
|
|
40
|
+
|
|
29
41
|
try:
|
|
30
42
|
module_name = f"code_puppy.plugins.{plugin_name}.register_callbacks"
|
|
31
43
|
importlib.import_module(module_name)
|
|
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.323 → code_puppy-0.0.325}/code_puppy/command_line/load_context_completion.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/catalog_server_installer.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/mcp/custom_server_installer.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
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/command_line/model_picker_completion.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/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
|
|
File without changes
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py
RENAMED
|
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.323 → code_puppy-0.0.325}/code_puppy/plugins/claude_code_oauth/register_callbacks.py
RENAMED
|
File without changes
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/claude_code_oauth/test_plugin.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/customizable_commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/example_custom_command/README.md
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/file_permission_handler/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/shell_safety/agent_shell_safety.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.323 → code_puppy-0.0.325}/code_puppy/plugins/shell_safety/register_callbacks.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
|