newcode 0.2.8__tar.gz → 0.2.9__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.
- {newcode-0.2.8 → newcode-0.2.9}/PKG-INFO +1 -2
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/base_agent.py +38 -145
- {newcode-0.2.8 → newcode-0.2.9}/newcode/cli_runner.py +0 -35
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/config_commands.py +0 -10
- {newcode-0.2.8 → newcode-0.2.9}/newcode/config.py +0 -21
- {newcode-0.2.8 → newcode-0.2.9}/newcode/summarization_agent.py +3 -3
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/agent_tools.py +21 -110
- {newcode-0.2.8 → newcode-0.2.9}/pyproject.toml +1 -2
- {newcode-0.2.8 → newcode-0.2.9}/.gitignore +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/LICENSE +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/README.md +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/__main__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_c_reviewer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_code_agent.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_code_reviewer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_cpp_reviewer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_creator_agent.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_golang_reviewer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_javascript_reviewer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_manager.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_pack_leader.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_planning.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_python_programmer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_python_reviewer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_qa_browser.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_qa_expert.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_security_auditor.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_terminal_qa.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/agent_typescript_reviewer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/event_stream_handler.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/json_agent.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/pack/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/pack/bloodhound.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/pack/husky.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/pack/retriever.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/pack/shepherd.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/pack/terrier.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/pack/watchdog.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/prompt_reviewer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/agents/subagent_stream_handler.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/app.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/main.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/pty_manager.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/routers/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/routers/agents.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/routers/commands.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/routers/config.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/routers/sessions.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/templates/terminal.html +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/api/websocket.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/chatgpt_codex_client.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/claude_cache_client.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/add_model_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/agent_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/attachments.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/autosave_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/clipboard.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/colors_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/command_handler.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/command_registry.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/core_commands.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/diff_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/file_path_completion.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/load_context_completion.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/base.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/catalog_server_installer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/custom_server_form.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/custom_server_installer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/edit_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/handler.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/help_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/install_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/install_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/list_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/logs_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/remove_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/restart_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/search_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/start_all_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/start_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/status_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/stop_all_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/stop_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/test_command.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/utils.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp/wizard_utils.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/mcp_completion.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/model_picker_completion.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/model_settings_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/motd.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/onboarding_slides.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/onboarding_wizard.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/pin_command_completion.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/prompt_toolkit_completion.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/session_commands.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/skills_completion.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/uc_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/utils.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/command_line/wiggum_state.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/error_logging.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/gemini_code_assist.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/gemini_model.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/hook_engine/README.md +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/hook_engine/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/hook_engine/aliases.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/hook_engine/engine.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/hook_engine/executor.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/hook_engine/matcher.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/hook_engine/models.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/hook_engine/registry.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/hook_engine/validator.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/http_utils.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/image_utils.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/keymap.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/main.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/async_lifecycle.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/blocking_startup.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/captured_stdio_server.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/circuit_breaker.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/config_wizard.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/dashboard.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/error_isolation.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/examples/retry_example.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/health_monitor.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/managed_server.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/manager.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/mcp_logs.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/registry.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/retry_manager.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/server_registry_catalog.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/status_tracker.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_/system_tools.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_prompts/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/mcp_prompts/hook_creator.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/bus.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/commands.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/markdown_patches.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/message_queue.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/messages.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/queue_console.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/renderers.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/rich_renderer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/spinner/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/spinner/console_spinner.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/spinner/spinner_base.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/messaging/subagent_console.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/model_factory.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/model_switching.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/model_utils.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/models.json +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/models_dev_api.json +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/models_dev_parser.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/config.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/discovery.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/downloader.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/installer.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/metadata.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/prompt_builder.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/remote_catalog.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/skill_catalog.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/skills_install_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/agent_skills/skills_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/accounts.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/antigravity_model.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/config.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/constants.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/oauth.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/storage.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/test_plugin.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/token.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/transport.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/antigravity_oauth/utils.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/chatgpt_oauth/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/chatgpt_oauth/config.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/chatgpt_oauth/oauth_flow.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/chatgpt_oauth/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/chatgpt_oauth/test_plugin.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/chatgpt_oauth/utils.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_hooks/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_hooks/config.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_hooks/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_oauth/README.md +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_oauth/SETUP.md +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_oauth/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_oauth/config.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_oauth/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_oauth/test_plugin.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/claude_code_oauth/utils.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/customizable_commands/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/customizable_commands/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/example_custom_command/README.md +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/example_custom_command/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/file_permission_handler/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/file_permission_handler/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/frontend_emitter/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/frontend_emitter/emitter.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/frontend_emitter/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/hook_creator/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/hook_creator/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/hook_manager/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/hook_manager/config.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/hook_manager/hooks_menu.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/hook_manager/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/oauth_puppy_html.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/shell_safety/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/shell_safety/agent_shell_safety.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/shell_safety/command_cache.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/shell_safety/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/synthetic_status/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/synthetic_status/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/synthetic_status/status_api.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/universal_constructor/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/universal_constructor/models.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/universal_constructor/register_callbacks.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/universal_constructor/registry.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/plugins/universal_constructor/sandbox.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/prompts/antigravity_system_prompt.md +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/pydantic_patches.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/reopenable_async_client.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/round_robin_model.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/session_storage.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/status_display.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/terminal_utils.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/ask_user_question/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/ask_user_question/constants.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/ask_user_question/demo_tui.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/ask_user_question/handler.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/ask_user_question/models.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/ask_user_question/registration.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/ask_user_question/renderers.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/ask_user_question/terminal_ui.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/ask_user_question/theme.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/ask_user_question/tui_loop.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/__init__.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/browser_control.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/browser_interactions.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/browser_locators.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/browser_manager.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/browser_navigation.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/browser_screenshot.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/browser_scripts.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/browser_workflows.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/chromium_terminal_manager.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/terminal_command_tools.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/terminal_screenshot_tools.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/browser/terminal_tools.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/command_runner.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/common.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/display.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/file_modifications.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/file_operations.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/skills_tools.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/subagent_context.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/tools_content.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/tools/universal_constructor.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/uvx_detection.py +0 -0
- {newcode-0.2.8 → newcode-0.2.9}/newcode/version_checker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: newcode
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.9
|
|
4
4
|
Summary: AI-powered code generation agent platform
|
|
5
5
|
Project-URL: repository, https://github.com/janfeddersen-wq/new_code
|
|
6
6
|
Project-URL: HomePage, https://github.com/janfeddersen-wq/new_code
|
|
@@ -17,7 +17,6 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
17
17
|
Classifier: Topic :: Software Development :: Code Generators
|
|
18
18
|
Requires-Python: <3.14,>=3.11
|
|
19
19
|
Requires-Dist: anthropic==0.79.0
|
|
20
|
-
Requires-Dist: dbos>=2.11.0
|
|
21
20
|
Requires-Dist: fastapi>=0.109.0
|
|
22
21
|
Requires-Dist: httpx[http2]>=0.24.1
|
|
23
22
|
Requires-Dist: json-repair>=0.46.2
|
|
@@ -27,7 +27,6 @@ from typing import (
|
|
|
27
27
|
import mcp
|
|
28
28
|
import pydantic
|
|
29
29
|
import pydantic_ai.models
|
|
30
|
-
from dbos import DBOS, SetWorkflowID
|
|
31
30
|
from pydantic_ai import Agent as PydanticAgent
|
|
32
31
|
from pydantic_ai import (
|
|
33
32
|
BinaryContent,
|
|
@@ -37,7 +36,6 @@ from pydantic_ai import (
|
|
|
37
36
|
UsageLimitExceeded,
|
|
38
37
|
UsageLimits,
|
|
39
38
|
)
|
|
40
|
-
from pydantic_ai.durable_exec.dbos import DBOSAgent
|
|
41
39
|
from pydantic_ai.messages import (
|
|
42
40
|
ModelMessage,
|
|
43
41
|
ModelRequest,
|
|
@@ -67,7 +65,6 @@ from newcode.config import (
|
|
|
67
65
|
get_global_model_name,
|
|
68
66
|
get_message_limit,
|
|
69
67
|
get_protected_token_count,
|
|
70
|
-
get_use_dbos,
|
|
71
68
|
get_value,
|
|
72
69
|
)
|
|
73
70
|
from newcode.error_logging import log_error
|
|
@@ -1423,64 +1420,25 @@ class BaseAgent(ABC):
|
|
|
1423
1420
|
)
|
|
1424
1421
|
|
|
1425
1422
|
self._last_model_name = resolved_model_name
|
|
1426
|
-
# expose for run_with_mcp
|
|
1427
|
-
# Wrap it with DBOS, but handle MCP servers separately to avoid serialization issues
|
|
1428
1423
|
global _reload_count
|
|
1429
1424
|
_reload_count += 1
|
|
1430
|
-
if get_use_dbos():
|
|
1431
|
-
# Don't pass MCP servers to the agent constructor when using DBOS
|
|
1432
|
-
# This prevents the "cannot pickle async_generator object" error
|
|
1433
|
-
# MCP servers will be handled separately in run_with_mcp
|
|
1434
|
-
agent_without_mcp = PydanticAgent(
|
|
1435
|
-
model=model,
|
|
1436
|
-
instructions=instructions,
|
|
1437
|
-
output_type=str,
|
|
1438
|
-
retries=10,
|
|
1439
|
-
toolsets=[], # Don't include MCP servers here
|
|
1440
|
-
history_processors=[self.message_history_accumulator],
|
|
1441
|
-
model_settings=model_settings,
|
|
1442
|
-
)
|
|
1443
|
-
|
|
1444
|
-
# Register regular tools (non-MCP) on the new agent
|
|
1445
|
-
agent_tools = self.get_available_tools()
|
|
1446
|
-
register_tools_for_agent(
|
|
1447
|
-
agent_without_mcp, agent_tools, model_name=resolved_model_name
|
|
1448
|
-
)
|
|
1449
1425
|
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
else:
|
|
1463
|
-
# Normal path without DBOS - include filtered MCP servers in the agent
|
|
1464
|
-
# Re-create agent with filtered MCP servers
|
|
1465
|
-
p_agent = PydanticAgent(
|
|
1466
|
-
model=model,
|
|
1467
|
-
instructions=instructions,
|
|
1468
|
-
output_type=str,
|
|
1469
|
-
retries=10,
|
|
1470
|
-
toolsets=filtered_mcp_servers,
|
|
1471
|
-
history_processors=[self.message_history_accumulator],
|
|
1472
|
-
model_settings=model_settings,
|
|
1473
|
-
)
|
|
1474
|
-
# Register regular tools on the agent
|
|
1475
|
-
agent_tools = self.get_available_tools()
|
|
1476
|
-
register_tools_for_agent(
|
|
1477
|
-
p_agent, agent_tools, model_name=resolved_model_name
|
|
1478
|
-
)
|
|
1426
|
+
p_agent = PydanticAgent(
|
|
1427
|
+
model=model,
|
|
1428
|
+
instructions=instructions,
|
|
1429
|
+
output_type=str,
|
|
1430
|
+
retries=10,
|
|
1431
|
+
toolsets=filtered_mcp_servers,
|
|
1432
|
+
history_processors=[self.message_history_accumulator],
|
|
1433
|
+
model_settings=model_settings,
|
|
1434
|
+
)
|
|
1435
|
+
# Register regular tools on the agent
|
|
1436
|
+
agent_tools = self.get_available_tools()
|
|
1437
|
+
register_tools_for_agent(p_agent, agent_tools, model_name=resolved_model_name)
|
|
1479
1438
|
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
self._mcp_servers = mcp_servers
|
|
1439
|
+
self.pydantic_agent = p_agent
|
|
1440
|
+
self._code_generation_agent = p_agent
|
|
1441
|
+
self._mcp_servers = filtered_mcp_servers
|
|
1484
1442
|
return self._code_generation_agent
|
|
1485
1443
|
|
|
1486
1444
|
def _create_agent_with_output_type(self, output_type: Type[Any]) -> PydanticAgent:
|
|
@@ -1494,7 +1452,7 @@ class BaseAgent(ABC):
|
|
|
1494
1452
|
output_type: The Pydantic model or type for structured output.
|
|
1495
1453
|
|
|
1496
1454
|
Returns:
|
|
1497
|
-
A configured PydanticAgent
|
|
1455
|
+
A configured PydanticAgent with the custom output_type.
|
|
1498
1456
|
"""
|
|
1499
1457
|
from newcode.model_utils import prepare_prompt_for_model
|
|
1500
1458
|
from newcode.tools import register_tools_for_agent
|
|
@@ -1521,45 +1479,21 @@ class BaseAgent(ABC):
|
|
|
1521
1479
|
global _reload_count
|
|
1522
1480
|
_reload_count += 1
|
|
1523
1481
|
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
# Pass event_stream_handler at construction time for streaming output
|
|
1539
|
-
dbos_agent = DBOSAgent(
|
|
1540
|
-
temp_agent,
|
|
1541
|
-
name=f"{self.name}-structured-{_reload_count}",
|
|
1542
|
-
event_stream_handler=event_stream_handler,
|
|
1543
|
-
)
|
|
1544
|
-
return dbos_agent
|
|
1545
|
-
else:
|
|
1546
|
-
temp_agent = PydanticAgent(
|
|
1547
|
-
model=model,
|
|
1548
|
-
instructions=instructions,
|
|
1549
|
-
output_type=output_type,
|
|
1550
|
-
retries=10,
|
|
1551
|
-
toolsets=mcp_servers,
|
|
1552
|
-
history_processors=[self.message_history_accumulator],
|
|
1553
|
-
model_settings=model_settings,
|
|
1554
|
-
)
|
|
1555
|
-
agent_tools = self.get_available_tools()
|
|
1556
|
-
register_tools_for_agent(
|
|
1557
|
-
temp_agent, agent_tools, model_name=resolved_model_name
|
|
1558
|
-
)
|
|
1559
|
-
return temp_agent
|
|
1482
|
+
temp_agent = PydanticAgent(
|
|
1483
|
+
model=model,
|
|
1484
|
+
instructions=instructions,
|
|
1485
|
+
output_type=output_type,
|
|
1486
|
+
retries=10,
|
|
1487
|
+
toolsets=mcp_servers,
|
|
1488
|
+
history_processors=[self.message_history_accumulator],
|
|
1489
|
+
model_settings=model_settings,
|
|
1490
|
+
)
|
|
1491
|
+
agent_tools = self.get_available_tools()
|
|
1492
|
+
register_tools_for_agent(
|
|
1493
|
+
temp_agent, agent_tools, model_name=resolved_model_name
|
|
1494
|
+
)
|
|
1495
|
+
return temp_agent
|
|
1560
1496
|
|
|
1561
|
-
# It's okay to decorate it with DBOS.step even if not using DBOS; the decorator is a no-op in that case.
|
|
1562
|
-
@DBOS.step()
|
|
1563
1497
|
def message_history_accumulator(self, ctx: RunContext, messages: List[Any]):
|
|
1564
1498
|
_message_history = self.get_message_history()
|
|
1565
1499
|
|
|
@@ -1914,51 +1848,14 @@ class BaseAgent(ABC):
|
|
|
1914
1848
|
|
|
1915
1849
|
usage_limits = UsageLimits(request_limit=get_message_limit())
|
|
1916
1850
|
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
pydantic_agent._toolsets = original_toolsets + self._mcp_servers
|
|
1926
|
-
pydantic_agent._toolsets = original_toolsets + self._mcp_servers
|
|
1927
|
-
|
|
1928
|
-
try:
|
|
1929
|
-
# Set the workflow ID for DBOS context so DBOS and the agent ID match
|
|
1930
|
-
with SetWorkflowID(group_id):
|
|
1931
|
-
result_ = await pydantic_agent.run(
|
|
1932
|
-
prompt_payload,
|
|
1933
|
-
message_history=self.get_message_history(),
|
|
1934
|
-
usage_limits=usage_limits,
|
|
1935
|
-
event_stream_handler=event_stream_handler,
|
|
1936
|
-
**kwargs,
|
|
1937
|
-
)
|
|
1938
|
-
return result_
|
|
1939
|
-
finally:
|
|
1940
|
-
# Always restore original toolsets
|
|
1941
|
-
pydantic_agent._toolsets = original_toolsets
|
|
1942
|
-
elif get_use_dbos():
|
|
1943
|
-
with SetWorkflowID(group_id):
|
|
1944
|
-
result_ = await pydantic_agent.run(
|
|
1945
|
-
prompt_payload,
|
|
1946
|
-
message_history=self.get_message_history(),
|
|
1947
|
-
usage_limits=usage_limits,
|
|
1948
|
-
event_stream_handler=event_stream_handler,
|
|
1949
|
-
**kwargs,
|
|
1950
|
-
)
|
|
1951
|
-
return result_
|
|
1952
|
-
else:
|
|
1953
|
-
# Non-DBOS path (MCP servers are already included)
|
|
1954
|
-
result_ = await pydantic_agent.run(
|
|
1955
|
-
prompt_payload,
|
|
1956
|
-
message_history=self.get_message_history(),
|
|
1957
|
-
usage_limits=usage_limits,
|
|
1958
|
-
event_stream_handler=event_stream_handler,
|
|
1959
|
-
**kwargs,
|
|
1960
|
-
)
|
|
1961
|
-
return result_
|
|
1851
|
+
result_ = await pydantic_agent.run(
|
|
1852
|
+
prompt_payload,
|
|
1853
|
+
message_history=self.get_message_history(),
|
|
1854
|
+
usage_limits=usage_limits,
|
|
1855
|
+
event_stream_handler=event_stream_handler,
|
|
1856
|
+
**kwargs,
|
|
1857
|
+
)
|
|
1858
|
+
return result_
|
|
1962
1859
|
except* UsageLimitExceeded as ule:
|
|
1963
1860
|
emit_info(f"Usage limit exceeded: {str(ule)}", group_id=group_id)
|
|
1964
1861
|
emit_info(
|
|
@@ -1974,12 +1871,8 @@ class BaseAgent(ABC):
|
|
|
1974
1871
|
)
|
|
1975
1872
|
except* asyncio.exceptions.CancelledError:
|
|
1976
1873
|
emit_info("Cancelled")
|
|
1977
|
-
if get_use_dbos():
|
|
1978
|
-
await DBOS.cancel_workflow_async(group_id)
|
|
1979
1874
|
except* InterruptedError as ie:
|
|
1980
1875
|
emit_info(f"Interrupted: {str(ie)}")
|
|
1981
|
-
if get_use_dbos():
|
|
1982
|
-
await DBOS.cancel_workflow_async(group_id)
|
|
1983
1876
|
except* Exception as other_error:
|
|
1984
1877
|
|
|
1985
1878
|
def contains_cloudflare_auth_error(exc: Exception) -> bool:
|
|
@@ -12,10 +12,8 @@ import argparse
|
|
|
12
12
|
import asyncio
|
|
13
13
|
import os
|
|
14
14
|
import sys
|
|
15
|
-
import time
|
|
16
15
|
from pathlib import Path
|
|
17
16
|
|
|
18
|
-
from dbos import DBOS, DBOSConfig
|
|
19
17
|
from rich.console import Console
|
|
20
18
|
|
|
21
19
|
from newcode import __version__, callbacks, plugins
|
|
@@ -25,10 +23,8 @@ from newcode.command_line.clipboard import get_clipboard_manager
|
|
|
25
23
|
from newcode.config import (
|
|
26
24
|
AUTOSAVE_DIR,
|
|
27
25
|
COMMAND_HISTORY_FILE,
|
|
28
|
-
DBOS_DATABASE_URL,
|
|
29
26
|
ensure_config_exists,
|
|
30
27
|
finalize_autosave_session,
|
|
31
|
-
get_use_dbos,
|
|
32
28
|
initialize_command_history_file,
|
|
33
29
|
save_command_to_history,
|
|
34
30
|
)
|
|
@@ -271,33 +267,6 @@ async def main():
|
|
|
271
267
|
|
|
272
268
|
await callbacks.on_startup()
|
|
273
269
|
|
|
274
|
-
# Initialize DBOS if not disabled
|
|
275
|
-
if get_use_dbos():
|
|
276
|
-
# Append a Unix timestamp in ms to the version for uniqueness
|
|
277
|
-
dbos_app_version = os.environ.get(
|
|
278
|
-
"DBOS_APP_VERSION", f"{current_version}-{int(time.time() * 1000)}"
|
|
279
|
-
)
|
|
280
|
-
dbos_config: DBOSConfig = {
|
|
281
|
-
"name": "dbos-code-agent",
|
|
282
|
-
"system_database_url": DBOS_DATABASE_URL,
|
|
283
|
-
"run_admin_server": False,
|
|
284
|
-
"conductor_key": os.environ.get(
|
|
285
|
-
"DBOS_CONDUCTOR_KEY"
|
|
286
|
-
), # Optional, if set in env, connect to conductor
|
|
287
|
-
"log_level": os.environ.get(
|
|
288
|
-
"DBOS_LOG_LEVEL", "ERROR"
|
|
289
|
-
), # Default to ERROR level to suppress verbose logs
|
|
290
|
-
"application_version": dbos_app_version, # Match DBOS app version
|
|
291
|
-
}
|
|
292
|
-
try:
|
|
293
|
-
DBOS(config=dbos_config)
|
|
294
|
-
DBOS.launch()
|
|
295
|
-
except Exception as e:
|
|
296
|
-
emit_error(f"Error initializing DBOS: {e}")
|
|
297
|
-
sys.exit(1)
|
|
298
|
-
else:
|
|
299
|
-
pass
|
|
300
|
-
|
|
301
270
|
global shutdown_flag
|
|
302
271
|
shutdown_flag = False
|
|
303
272
|
try:
|
|
@@ -322,8 +291,6 @@ async def main():
|
|
|
322
291
|
if bus_renderer:
|
|
323
292
|
bus_renderer.stop()
|
|
324
293
|
await callbacks.on_shutdown()
|
|
325
|
-
if get_use_dbos():
|
|
326
|
-
DBOS.destroy()
|
|
327
294
|
|
|
328
295
|
|
|
329
296
|
async def interactive_mode(message_renderer, initial_command: str = None) -> None:
|
|
@@ -981,8 +948,6 @@ def main_entry():
|
|
|
981
948
|
asyncio.run(main())
|
|
982
949
|
except KeyboardInterrupt:
|
|
983
950
|
# Normal exit via Ctrl+C – not a crash, so just clean up quietly
|
|
984
|
-
if get_use_dbos():
|
|
985
|
-
DBOS.destroy()
|
|
986
951
|
return 0
|
|
987
952
|
finally:
|
|
988
953
|
# Reset terminal on Unix-like systems (not Windows)
|
|
@@ -42,7 +42,6 @@ def handle_show_command(command: str) -> bool:
|
|
|
42
42
|
get_protected_token_count,
|
|
43
43
|
get_resume_message_count,
|
|
44
44
|
get_temperature,
|
|
45
|
-
get_use_dbos,
|
|
46
45
|
get_yolo_mode,
|
|
47
46
|
)
|
|
48
47
|
from newcode.keymap import (
|
|
@@ -69,7 +68,6 @@ def handle_show_command(command: str) -> bool:
|
|
|
69
68
|
[bold]default_agent:[/bold] [cyan]{default_agent}[/cyan]
|
|
70
69
|
[bold]model:[/bold] [green]{model}[/green]
|
|
71
70
|
[bold]YOLO_MODE:[/bold] {"[red]ON[/red]" if yolo_mode else "[yellow]off[/yellow]"}
|
|
72
|
-
[bold]DBOS:[/bold] {"[green]enabled[/green]" if get_use_dbos() else "[yellow]disabled[/yellow]"} (toggle: /set enable_dbos true|false)
|
|
73
71
|
[bold]auto_save_session:[/bold] {"[green]enabled[/green]" if auto_save else "[yellow]disabled[/yellow]"}
|
|
74
72
|
[bold]protected_tokens:[/bold] [cyan]{protected_tokens:,}[/cyan] recent tokens preserved
|
|
75
73
|
[bold]compaction_threshold:[/bold] [cyan]{compaction_threshold:.1%}[/cyan] context usage triggers compaction
|
|
@@ -211,14 +209,6 @@ def handle_set_command(command: str) -> bool:
|
|
|
211
209
|
)
|
|
212
210
|
return True
|
|
213
211
|
if key:
|
|
214
|
-
# Check if we're toggling DBOS enablement
|
|
215
|
-
if key == "enable_dbos":
|
|
216
|
-
emit_info(
|
|
217
|
-
Text.from_markup(
|
|
218
|
-
"[yellow]⚠️ DBOS configuration changed. Please restart the application for this change to take effect.[/yellow]"
|
|
219
|
-
)
|
|
220
|
-
)
|
|
221
|
-
|
|
222
212
|
# Validate cancel_agent_key before setting
|
|
223
213
|
if key == "cancel_agent_key":
|
|
224
214
|
from newcode.keymap import VALID_CANCEL_KEYS
|
|
@@ -49,7 +49,6 @@ EXTRA_MODELS_FILE = os.path.join(DATA_DIR, "extra_models.json")
|
|
|
49
49
|
AGENTS_DIR = os.path.join(DATA_DIR, "agents")
|
|
50
50
|
SKILLS_DIR = os.path.join(DATA_DIR, "skills")
|
|
51
51
|
CONTEXTS_DIR = os.path.join(DATA_DIR, "contexts")
|
|
52
|
-
_DEFAULT_SQLITE_FILE = os.path.join(DATA_DIR, "dbos_store.sqlite")
|
|
53
52
|
|
|
54
53
|
# OAuth plugin model files (XDG_DATA_HOME)
|
|
55
54
|
GEMINI_MODELS_FILE = os.path.join(DATA_DIR, "gemini_models.json")
|
|
@@ -62,19 +61,6 @@ AUTOSAVE_DIR = os.path.join(CACHE_DIR, "autosaves")
|
|
|
62
61
|
|
|
63
62
|
# State files (XDG_STATE_HOME)
|
|
64
63
|
COMMAND_HISTORY_FILE = os.path.join(STATE_DIR, "command_history.txt")
|
|
65
|
-
DBOS_DATABASE_URL = os.environ.get(
|
|
66
|
-
"DBOS_SYSTEM_DATABASE_URL", f"sqlite:///{_DEFAULT_SQLITE_FILE}"
|
|
67
|
-
)
|
|
68
|
-
# DBOS enable switch is controlled solely via puppy.cfg using key 'enable_dbos'.
|
|
69
|
-
# Default: True (DBOS enabled) unless explicitly disabled.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def get_use_dbos() -> bool:
|
|
73
|
-
"""Return True if DBOS should be used based on 'enable_dbos' (default True)."""
|
|
74
|
-
cfg_val = get_value("enable_dbos")
|
|
75
|
-
if cfg_val is None:
|
|
76
|
-
return True
|
|
77
|
-
return str(cfg_val).strip().lower() in {"1", "true", "yes", "on"}
|
|
78
64
|
|
|
79
65
|
|
|
80
66
|
def get_subagent_verbose() -> bool:
|
|
@@ -288,8 +274,6 @@ def get_config_keys():
|
|
|
288
274
|
"frontend_emitter_max_recent_events",
|
|
289
275
|
"frontend_emitter_queue_size",
|
|
290
276
|
]
|
|
291
|
-
# Add DBOS control key
|
|
292
|
-
default_keys.append("enable_dbos")
|
|
293
277
|
# Add pack agents control key
|
|
294
278
|
default_keys.append("enable_pack_agents")
|
|
295
279
|
# Add universal constructor control key
|
|
@@ -1193,11 +1177,6 @@ def set_http2(enabled: bool) -> None:
|
|
|
1193
1177
|
set_config_value("http2", "true" if enabled else "false")
|
|
1194
1178
|
|
|
1195
1179
|
|
|
1196
|
-
def set_enable_dbos(enabled: bool) -> None:
|
|
1197
|
-
"""Enable DBOS via config (true enables, default false)."""
|
|
1198
|
-
set_config_value("enable_dbos", "true" if enabled else "false")
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
1180
|
def get_message_limit(default: int = 1000) -> int:
|
|
1202
1181
|
"""
|
|
1203
1182
|
Returns the user-configured message/request limit for the agent.
|
|
@@ -82,7 +82,7 @@ def run_summarization_sync(prompt: str, message_history: List) -> List:
|
|
|
82
82
|
"""
|
|
83
83
|
Run the async agent in a dedicated thread with its own event loop.
|
|
84
84
|
Uses run_until_complete instead of asyncio.run to avoid shutting down
|
|
85
|
-
the default executor (which
|
|
85
|
+
the default executor (which can break in the main thread).
|
|
86
86
|
Does NOT touch global event loop state.
|
|
87
87
|
"""
|
|
88
88
|
loop = asyncio.new_event_loop()
|
|
@@ -158,9 +158,9 @@ def reload_summarization_agent():
|
|
|
158
158
|
retries=1, # Fewer retries for summarization
|
|
159
159
|
model_settings=model_settings,
|
|
160
160
|
)
|
|
161
|
-
# NOTE: We intentionally
|
|
161
|
+
# NOTE: We intentionally avoid additional durable wrappers here.
|
|
162
162
|
# Summarization is a simple one-shot call that doesn't need durable execution,
|
|
163
|
-
#
|
|
163
|
+
# because durable wrappers can cause async event loop conflicts with run_sync().
|
|
164
164
|
return agent
|
|
165
165
|
|
|
166
166
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# agent_tools.py
|
|
2
2
|
import asyncio
|
|
3
3
|
import hashlib
|
|
4
|
-
import itertools
|
|
5
4
|
import json
|
|
6
5
|
import pickle
|
|
7
6
|
import re
|
|
@@ -11,7 +10,6 @@ from functools import partial
|
|
|
11
10
|
from pathlib import Path
|
|
12
11
|
from typing import List, Set
|
|
13
12
|
|
|
14
|
-
from dbos import DBOS, SetWorkflowID
|
|
15
13
|
from pydantic import BaseModel
|
|
16
14
|
|
|
17
15
|
# Import Agent from pydantic_ai to create temporary agents for invocation
|
|
@@ -21,7 +19,6 @@ from pydantic_ai.messages import ModelMessage
|
|
|
21
19
|
from newcode.config import (
|
|
22
20
|
DATA_DIR,
|
|
23
21
|
get_message_limit,
|
|
24
|
-
get_use_dbos,
|
|
25
22
|
get_value,
|
|
26
23
|
)
|
|
27
24
|
from newcode.messaging import (
|
|
@@ -40,27 +37,6 @@ from newcode.tools.subagent_context import subagent_context
|
|
|
40
37
|
# Set to track active subagent invocation tasks
|
|
41
38
|
_active_subagent_tasks: Set[asyncio.Task] = set()
|
|
42
39
|
|
|
43
|
-
# Atomic counter for DBOS workflow IDs - ensures uniqueness even in rapid back-to-back calls
|
|
44
|
-
# itertools.count() is thread-safe for next() calls
|
|
45
|
-
_dbos_workflow_counter = itertools.count()
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def _generate_dbos_workflow_id(base_id: str) -> str:
|
|
49
|
-
"""Generate a unique DBOS workflow ID by appending an atomic counter.
|
|
50
|
-
|
|
51
|
-
DBOS requires workflow IDs to be unique across all executions.
|
|
52
|
-
This function ensures uniqueness by combining the base_id with
|
|
53
|
-
an atomically incrementing counter.
|
|
54
|
-
|
|
55
|
-
Args:
|
|
56
|
-
base_id: The base identifier (e.g., group_id from generate_group_id)
|
|
57
|
-
|
|
58
|
-
Returns:
|
|
59
|
-
A unique workflow ID in format: {base_id}-wf-{counter}
|
|
60
|
-
"""
|
|
61
|
-
counter = next(_dbos_workflow_counter)
|
|
62
|
-
return f"{base_id}-wf-{counter}"
|
|
63
|
-
|
|
64
40
|
|
|
65
41
|
def _generate_session_hash_suffix() -> str:
|
|
66
42
|
"""Generate a short SHA1 hash suffix based on current timestamp for uniqueness.
|
|
@@ -495,9 +471,6 @@ def register_invoke_agent(agent):
|
|
|
495
471
|
instructions = prepared.instructions
|
|
496
472
|
prompt = prepared.user_prompt
|
|
497
473
|
|
|
498
|
-
import uuid as _uuid
|
|
499
|
-
|
|
500
|
-
subagent_name = f"temp-invoke-agent-{session_id}-{_uuid.uuid4().hex[:8]}"
|
|
501
474
|
model_settings = make_model_settings(model_name)
|
|
502
475
|
|
|
503
476
|
# Get MCP servers for sub-agents (same as main agent)
|
|
@@ -511,59 +484,24 @@ def register_invoke_agent(agent):
|
|
|
511
484
|
manager = get_mcp_manager()
|
|
512
485
|
mcp_servers = manager.get_servers_for_agent()
|
|
513
486
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
retries=10,
|
|
524
|
-
toolsets=[], # MCP servers added separately for DBOS
|
|
525
|
-
history_processors=[agent_config.message_history_accumulator],
|
|
526
|
-
model_settings=model_settings,
|
|
527
|
-
)
|
|
528
|
-
|
|
529
|
-
# Register the tools that the agent needs
|
|
530
|
-
from newcode.tools import register_tools_for_agent
|
|
531
|
-
|
|
532
|
-
agent_tools = agent_config.get_available_tools()
|
|
533
|
-
register_tools_for_agent(temp_agent, agent_tools, model_name=model_name)
|
|
534
|
-
|
|
535
|
-
# Wrap with DBOS - no streaming for sub-agents
|
|
536
|
-
dbos_agent = DBOSAgent(
|
|
537
|
-
temp_agent,
|
|
538
|
-
name=subagent_name,
|
|
539
|
-
)
|
|
540
|
-
temp_agent = dbos_agent
|
|
541
|
-
|
|
542
|
-
# Store MCP servers to add at runtime
|
|
543
|
-
subagent_mcp_servers = mcp_servers
|
|
544
|
-
else:
|
|
545
|
-
# Non-DBOS path - include MCP servers directly in the agent
|
|
546
|
-
temp_agent = Agent(
|
|
547
|
-
model=model,
|
|
548
|
-
instructions=instructions,
|
|
549
|
-
output_type=str,
|
|
550
|
-
retries=10,
|
|
551
|
-
toolsets=mcp_servers,
|
|
552
|
-
history_processors=[agent_config.message_history_accumulator],
|
|
553
|
-
model_settings=model_settings,
|
|
554
|
-
)
|
|
555
|
-
|
|
556
|
-
# Register the tools that the agent needs
|
|
557
|
-
from newcode.tools import register_tools_for_agent
|
|
487
|
+
temp_agent = Agent(
|
|
488
|
+
model=model,
|
|
489
|
+
instructions=instructions,
|
|
490
|
+
output_type=str,
|
|
491
|
+
retries=10,
|
|
492
|
+
toolsets=mcp_servers,
|
|
493
|
+
history_processors=[agent_config.message_history_accumulator],
|
|
494
|
+
model_settings=model_settings,
|
|
495
|
+
)
|
|
558
496
|
|
|
559
|
-
|
|
560
|
-
|
|
497
|
+
# Register the tools that the agent needs
|
|
498
|
+
from newcode.tools import register_tools_for_agent
|
|
561
499
|
|
|
562
|
-
|
|
500
|
+
agent_tools = agent_config.get_available_tools()
|
|
501
|
+
register_tools_for_agent(temp_agent, agent_tools, model_name=model_name)
|
|
563
502
|
|
|
564
503
|
# Run the temporary agent with the provided prompt as an asyncio task
|
|
565
504
|
# Pass the message_history from the session to continue the conversation
|
|
566
|
-
workflow_id = None # Track for potential cancellation
|
|
567
505
|
|
|
568
506
|
# Always use subagent_stream_handler to silence output and update console manager
|
|
569
507
|
# This ensures all sub-agent output goes through the aggregated dashboard
|
|
@@ -571,47 +509,20 @@ def register_invoke_agent(agent):
|
|
|
571
509
|
|
|
572
510
|
# Wrap the agent run in subagent context for tracking
|
|
573
511
|
with subagent_context(agent_name):
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
if subagent_mcp_servers:
|
|
581
|
-
temp_agent._toolsets = (
|
|
582
|
-
temp_agent._toolsets + subagent_mcp_servers
|
|
583
|
-
)
|
|
584
|
-
|
|
585
|
-
with SetWorkflowID(workflow_id):
|
|
586
|
-
task = asyncio.create_task(
|
|
587
|
-
temp_agent.run(
|
|
588
|
-
prompt,
|
|
589
|
-
message_history=message_history,
|
|
590
|
-
usage_limits=UsageLimits(
|
|
591
|
-
request_limit=get_message_limit()
|
|
592
|
-
),
|
|
593
|
-
event_stream_handler=stream_handler,
|
|
594
|
-
)
|
|
595
|
-
)
|
|
596
|
-
_active_subagent_tasks.add(task)
|
|
597
|
-
else:
|
|
598
|
-
task = asyncio.create_task(
|
|
599
|
-
temp_agent.run(
|
|
600
|
-
prompt,
|
|
601
|
-
message_history=message_history,
|
|
602
|
-
usage_limits=UsageLimits(request_limit=get_message_limit()),
|
|
603
|
-
event_stream_handler=stream_handler,
|
|
604
|
-
)
|
|
512
|
+
task = asyncio.create_task(
|
|
513
|
+
temp_agent.run(
|
|
514
|
+
prompt,
|
|
515
|
+
message_history=message_history,
|
|
516
|
+
usage_limits=UsageLimits(request_limit=get_message_limit()),
|
|
517
|
+
event_stream_handler=stream_handler,
|
|
605
518
|
)
|
|
606
|
-
|
|
519
|
+
)
|
|
520
|
+
_active_subagent_tasks.add(task)
|
|
607
521
|
|
|
608
522
|
try:
|
|
609
523
|
result = await task
|
|
610
524
|
finally:
|
|
611
525
|
_active_subagent_tasks.discard(task)
|
|
612
|
-
if task.cancelled():
|
|
613
|
-
if get_use_dbos() and workflow_id:
|
|
614
|
-
await DBOS.cancel_workflow_async(workflow_id)
|
|
615
526
|
|
|
616
527
|
# Extract the response from the result
|
|
617
528
|
response = result.output
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "newcode"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.9"
|
|
8
8
|
description = "AI-powered code generation agent platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11,<3.14"
|
|
@@ -24,7 +24,6 @@ dependencies = [
|
|
|
24
24
|
"ripgrep==14.1.0",
|
|
25
25
|
"tenacity>=8.2.0",
|
|
26
26
|
"playwright>=1.40.0",
|
|
27
|
-
"dbos>=2.11.0",
|
|
28
27
|
"fastapi>=0.109.0",
|
|
29
28
|
"uvicorn[standard]>=0.27.0",
|
|
30
29
|
"websockets>=12.0",
|
|
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
|