code-puppy 0.0.908__tar.gz → 0.0.910__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.908 → code_puppy-0.0.910}/PKG-INFO +1 -1
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_builder.py +22 -2
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/claude_cache_client.py +77 -40
- code_puppy-0.0.910/code_puppy/claude_thinking_display.py +71 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/pyproject.toml +1 -1
- {code_puppy-0.0.908 → code_puppy-0.0.910}/.gitignore +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/LICENSE +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/README.md +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/__main__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/_plugin_i18n_lifecycle.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/_pydantic_tool_helpers.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/_pydantic_video_patch.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agent_completion_inbox.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agent_execution_context.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_code_mode.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_code_mode_guidance.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_compaction.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_diagnostics.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_foreign_thinking.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_history.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_key_listeners.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_model_message_transform.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_non_streaming_render.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_output_limits.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_run_signals.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_runtime.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_steer_processor.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_subagent_recursion.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_windows_console.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/_wire_tool_names.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/agent_code_puppy.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/agent_creator_agent.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/agent_helios.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/agent_manager.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/agent_model_judge.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/agent_planning.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/agent_qa_kitten.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/agent_web_retriever.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/base_agent.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/event_stream_handler.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/json_agent.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/retry_checkpoint.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/retry_profiles.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/run_stats.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/smooth_stream.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/stream_status.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/subagent_stream_handler.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/agents/thinking_output.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/asyncio_cleanup.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/atomic_io.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/atomic_json.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/ca_bundle.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/callbacks.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/capabilities/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/capabilities/compaction.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/capabilities/eager_timing.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/chatgpt_codex_client.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/claude_oauth_transport.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/cli_runner.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/add_model_details.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/add_model_menu.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/add_model_menus.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/add_model_vllm.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/agent_menu.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/attachments.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/autosave_menu.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/autosave_search.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/clipboard.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/colors_menu.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/command_handler.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/command_registry.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/completers.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/completion_cache.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/config_apply.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/config_commands.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/core_commands.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/file_index.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/file_path_completion.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/help_catalog.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/help_overlay.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/image_utils.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/load_context_completion.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/base.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/edit_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/handler.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/help_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/install_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/install_menu.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/list_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/logs_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/mcp_servers_store.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/remove_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/restart_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/search_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/silence_warning_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/start_all_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/start_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/status_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/stop_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/trust_command.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/utils.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp_binding_menu.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp_completion.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/menu_session.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/model_picker_completion.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/model_settings_defs.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/model_settings_menu.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/onboarding_slides.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/onboarding_wizard.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/pagination.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/pin_command_completion.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/refresh_models.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/session_browser.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/session_browser_data.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/session_commands.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/set_menu.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/set_menu_catalog.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/set_menu_schema.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/set_menu_settings.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/set_menu_shims.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/set_menu_values.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/shell_passthrough.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/skills_completion.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/tui_style.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/uc_menu.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/utils.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/config.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/config_file.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/diagnostics.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/error_logging.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/events/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/events/bridge.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/file_completion_io.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/file_completion_tokens.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/gemini_code_assist.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/gemini_common.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/gemini_model.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/hook_engine/README.md +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/hook_engine/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/hook_engine/aliases.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/hook_engine/engine.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/hook_engine/executor.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/hook_engine/matcher.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/hook_engine/models.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/hook_engine/registry.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/hook_engine/validator.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/http_retry.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/http_utils.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/httpx2_utils.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/audit.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/catalog.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/formats.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/interpolation.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/locale.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/locales/en-US.json +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/locales/es.json +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/locales/fr-CA.json +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/plugin_catalog.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/plurals.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/pseudo.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/i18n/translate.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/kennel_provider.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/keymap.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/list_filtering.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/main.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/agent_bindings.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/async_lifecycle.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/blocking_startup.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/circuit_breaker.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/config_wizard.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/dashboard.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/error_isolation.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/examples/retry_example.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/health_monitor.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/http_auth.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/managed_server.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/manager.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/manager_lifecycle.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/mcp_logs.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/project_config.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/registry.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/retry_manager.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/server_registry_catalog.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/status_tracker.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/system_tools.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/tool_arg_coercion.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_/toolset_utils.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_prompts/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/mcp_prompts/hook_creator.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/bar_painters.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/bar_rendering.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/bottom_bar.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/bus.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/chords.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/commands.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/editor_actions.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/editor_completion.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/editor_display.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/editor_history.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/editor_keys.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/editor_paste.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/editor_queue.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/editor_submission.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/external_editor.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/identity_line.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/idle_status.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/inline_bar.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/line_editor.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/markdown_patches.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/menu_lifecycle.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/message_queue.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/messages.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/pause_controller.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/prompt_prefix_style.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/queue_console.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/renderers.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/rich_renderer.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/run_ui.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/run_ui_wiring.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/speculation_line.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/speculation_stats.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/speculation_toggle.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/spinner/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/status_line.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/subagent_console.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/theme_accent.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/tool_output.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/messaging/transcript_guard.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/model_descriptions.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/model_factory.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/model_switching.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/model_utils.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/models.json +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/models_dev_api.json +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/models_dev_parser.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/observability.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/platform_utils.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/plugins/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/plugins/config.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/plugins/oauth_pasteback.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/plugins/oauth_puppy_html.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/plugins/trust.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/plugins/trust_notice.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/private_inference.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/provider_credentials.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/provider_identity.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/pydantic_patches.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/reopenable_async_client.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/round_robin_model.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/secret_store.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/secret_store_backends.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/session_format_migration.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/session_lifecycle.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/session_migration.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/session_storage.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/session_surrogate_unpickler.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/shared_credentials.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/skill_provider.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/splash.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/status_display.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/steer_metadata.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/terminal_utils.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/token_usage.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/_browser_registry.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/_lazy.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/agent_tools.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/approval_feedback.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ask_user_question/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ask_user_question/constants.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ask_user_question/demo_tui.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ask_user_question/handler.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ask_user_question/models.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ask_user_question/registration.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ask_user_question/renderers.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ask_user_question/terminal_ui.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ask_user_question/theme.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ask_user_question/tui_loop.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/__init__.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_control.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_interactions.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_locator_resolver.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_locators.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_manager.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_navigation.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_page_snapshot.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_screenshot.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_scripts.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_semantic_interactions.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/browser_workflows.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/browser/tool_registry.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/command_runner.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/common.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/display.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/file_modifications.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/file_operations.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/file_permission_state.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/fs_access.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/image_tools.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/io_backends.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/model_tools.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/ripgrep.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/shell_backgrounding.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/skills_tools.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/subagent_context.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/subagent_invocation.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/subagent_usage_metrics.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/tools_content.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/universal_constructor.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/tools/win_shell_io.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/undo_manager.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/universal_constructor_provider.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/version_checker.py +0 -0
- {code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/zai_model.py +0 -0
|
@@ -11,6 +11,7 @@ hook; see :func:`code_puppy.callbacks.on_wrap_pydantic_agent`.
|
|
|
11
11
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
+
import os
|
|
14
15
|
import uuid
|
|
15
16
|
from pathlib import Path
|
|
16
17
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple
|
|
@@ -142,6 +143,23 @@ def _truncate_agents_md(content: str, source: str, max_chars: int) -> str:
|
|
|
142
143
|
return content[:max_chars] + notice
|
|
143
144
|
|
|
144
145
|
|
|
146
|
+
def _same_file(candidate: Path, other: Optional[Path]) -> bool:
|
|
147
|
+
"""True when ``candidate`` is the very file ``other`` names.
|
|
148
|
+
|
|
149
|
+
Run from the home directory, ``.code_puppy/AGENTS.md`` *is* the global
|
|
150
|
+
``~/.code_puppy/AGENTS.md``; loading it again as project rules puts the
|
|
151
|
+
same text into the system prompt twice. Compared by filesystem identity,
|
|
152
|
+
so symlinks and path aliases count as the same file, while a distinct
|
|
153
|
+
project file with identical text still loads.
|
|
154
|
+
"""
|
|
155
|
+
if other is None:
|
|
156
|
+
return False
|
|
157
|
+
try:
|
|
158
|
+
return os.path.samefile(candidate, other)
|
|
159
|
+
except OSError:
|
|
160
|
+
return False
|
|
161
|
+
|
|
162
|
+
|
|
145
163
|
def load_puppy_rules() -> Optional[str]:
|
|
146
164
|
"""Load AGENT(S).md from global config dir and/or the current project dir.
|
|
147
165
|
|
|
@@ -163,12 +181,14 @@ def load_puppy_rules() -> Optional[str]:
|
|
|
163
181
|
max_chars = get_agents_md_max_chars()
|
|
164
182
|
|
|
165
183
|
global_rules: Optional[str] = None
|
|
184
|
+
global_file: Optional[Path] = None
|
|
166
185
|
for name in _AGENT_RULE_FILES:
|
|
167
186
|
candidate = Path(CONFIG_DIR) / name
|
|
168
187
|
if candidate.exists():
|
|
169
188
|
text = _read_rules_text(candidate)
|
|
170
189
|
if text is None:
|
|
171
190
|
continue
|
|
191
|
+
global_file = candidate
|
|
172
192
|
global_rules = _truncate_agents_md(
|
|
173
193
|
text,
|
|
174
194
|
source=f"global {_friendly_path(candidate)}",
|
|
@@ -183,7 +203,7 @@ def load_puppy_rules() -> Optional[str]:
|
|
|
183
203
|
if code_puppy_dir.is_dir():
|
|
184
204
|
for name in _AGENT_RULE_FILES:
|
|
185
205
|
candidate = code_puppy_dir / name
|
|
186
|
-
if candidate.exists():
|
|
206
|
+
if candidate.exists() and not _same_file(candidate, global_file):
|
|
187
207
|
text = _read_rules_text(candidate)
|
|
188
208
|
if text is None:
|
|
189
209
|
continue
|
|
@@ -198,7 +218,7 @@ def load_puppy_rules() -> Optional[str]:
|
|
|
198
218
|
if project_rules is None:
|
|
199
219
|
for name in _AGENT_RULE_FILES:
|
|
200
220
|
candidate = Path(name)
|
|
201
|
-
if candidate.exists():
|
|
221
|
+
if candidate.exists() and not _same_file(candidate, global_file):
|
|
202
222
|
text = _read_rules_text(candidate)
|
|
203
223
|
if text is None:
|
|
204
224
|
continue
|
|
@@ -24,6 +24,12 @@ from urllib.parse import parse_qs, urlencode, urlparse, urlunparse
|
|
|
24
24
|
import httpx2
|
|
25
25
|
|
|
26
26
|
from .claude_oauth_transport import ClaudeOAuthTransport
|
|
27
|
+
from .claude_thinking_display import (
|
|
28
|
+
_OFF_THINKING_TYPES,
|
|
29
|
+
_THINKING_OMITTED_WHEN_OFF,
|
|
30
|
+
_enforce_thinking_display_summary,
|
|
31
|
+
_thinking_endpoint,
|
|
32
|
+
)
|
|
27
33
|
from .http_retry import describe_exception
|
|
28
34
|
|
|
29
35
|
logger = logging.getLogger(__name__)
|
|
@@ -51,41 +57,6 @@ CLAUDE_CODE_SYSTEM_PROMPT = "You are Claude Code, Anthropic's official CLI for C
|
|
|
51
57
|
THINKING_DISPLAY_UPDATES_BETA = "thinking-display-updates-2026-08-18"
|
|
52
58
|
|
|
53
59
|
|
|
54
|
-
def _model_requires_thinking_summary(model_name):
|
|
55
|
-
if not model_name:
|
|
56
|
-
return False
|
|
57
|
-
from code_puppy.model_utils import should_use_anthropic_thinking_summary
|
|
58
|
-
|
|
59
|
-
return should_use_anthropic_thinking_summary(model_name)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def _model_supports_thinking_updates(model_name):
|
|
63
|
-
if not model_name:
|
|
64
|
-
return False
|
|
65
|
-
from code_puppy.model_utils import should_use_anthropic_thinking_updates
|
|
66
|
-
|
|
67
|
-
return should_use_anthropic_thinking_updates(model_name)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def _enforce_thinking_display_summary(payload):
|
|
71
|
-
if not isinstance(payload, dict):
|
|
72
|
-
return False
|
|
73
|
-
if not _model_requires_thinking_summary(payload.get("model")):
|
|
74
|
-
return False
|
|
75
|
-
thinking = payload.get("thinking")
|
|
76
|
-
if not isinstance(thinking, dict):
|
|
77
|
-
return False
|
|
78
|
-
display = thinking.get("display")
|
|
79
|
-
if display == "summarized":
|
|
80
|
-
return False
|
|
81
|
-
if display == "updates" and _model_supports_thinking_updates(payload.get("model")):
|
|
82
|
-
# Fable 5.1 legitimately asked for progress updates; don't clobber
|
|
83
|
-
# it back to summarized (which would drown status lines in reasoning).
|
|
84
|
-
return False
|
|
85
|
-
thinking["display"] = "summarized"
|
|
86
|
-
return True
|
|
87
|
-
|
|
88
|
-
|
|
89
60
|
class ClaudeCacheAsyncClient(ClaudeOAuthTransport, httpx2.AsyncClient):
|
|
90
61
|
"""Async HTTP client with Claude Code OAuth transformations.
|
|
91
62
|
|
|
@@ -196,14 +167,16 @@ class ClaudeCacheAsyncClient(ClaudeOAuthTransport, httpx2.AsyncClient):
|
|
|
196
167
|
return json.dumps(data).encode("utf-8")
|
|
197
168
|
|
|
198
169
|
@staticmethod
|
|
199
|
-
def _enforce_thinking_display_summary_body(
|
|
200
|
-
|
|
170
|
+
def _enforce_thinking_display_summary_body(
|
|
171
|
+
body: bytes, endpoint=None
|
|
172
|
+
) -> bytes | None:
|
|
173
|
+
"""Return a rewritten body when the thinking shape needs normalizing."""
|
|
201
174
|
try:
|
|
202
175
|
payload = json.loads(body.decode("utf-8"))
|
|
203
176
|
except Exception:
|
|
204
177
|
return None
|
|
205
178
|
if not isinstance(payload, dict) or not _enforce_thinking_display_summary(
|
|
206
|
-
payload
|
|
179
|
+
payload, endpoint
|
|
207
180
|
):
|
|
208
181
|
return None
|
|
209
182
|
return json.dumps(payload).encode("utf-8")
|
|
@@ -318,7 +291,7 @@ class ClaudeCacheAsyncClient(ClaudeOAuthTransport, httpx2.AsyncClient):
|
|
|
318
291
|
body_modified = True
|
|
319
292
|
if body_bytes:
|
|
320
293
|
summarized_body = self._enforce_thinking_display_summary_body(
|
|
321
|
-
body_bytes
|
|
294
|
+
body_bytes, _thinking_endpoint(url)
|
|
322
295
|
)
|
|
323
296
|
if summarized_body is not None:
|
|
324
297
|
body_bytes = summarized_body
|
|
@@ -354,6 +327,10 @@ class ClaudeCacheAsyncClient(ClaudeOAuthTransport, httpx2.AsyncClient):
|
|
|
354
327
|
except Exception as exc:
|
|
355
328
|
logger.debug("Error in Claude Code transformations: %s", exc)
|
|
356
329
|
response = await self._send_with_retries(request, *args, **kwargs)
|
|
330
|
+
if is_messages_endpoint:
|
|
331
|
+
request, response = await self._retry_without_thinking_after_400(
|
|
332
|
+
request, response, *args, **kwargs
|
|
333
|
+
)
|
|
357
334
|
try:
|
|
358
335
|
if (
|
|
359
336
|
oauth_request
|
|
@@ -389,9 +366,14 @@ class ClaudeCacheAsyncClient(ClaudeOAuthTransport, httpx2.AsyncClient):
|
|
|
389
366
|
retry_request.extensions["claude_oauth_refresh_attempted"] = (
|
|
390
367
|
True
|
|
391
368
|
)
|
|
392
|
-
|
|
369
|
+
retried = await self._send_with_retries(
|
|
393
370
|
retry_request, *args, **kwargs
|
|
394
371
|
)
|
|
372
|
+
if is_messages_endpoint:
|
|
373
|
+
_, retried = await self._retry_without_thinking_after_400(
|
|
374
|
+
retry_request, retried, *args, **kwargs
|
|
375
|
+
)
|
|
376
|
+
return retried
|
|
395
377
|
else:
|
|
396
378
|
logger.warning(
|
|
397
379
|
"Token recovery failed, returning original error"
|
|
@@ -400,6 +382,61 @@ class ClaudeCacheAsyncClient(ClaudeOAuthTransport, httpx2.AsyncClient):
|
|
|
400
382
|
logger.debug("Error during token refresh attempt: %s", exc)
|
|
401
383
|
return response
|
|
402
384
|
|
|
385
|
+
async def _retry_without_thinking_after_400(
|
|
386
|
+
self,
|
|
387
|
+
request: httpx2.Request,
|
|
388
|
+
response: httpx2.Response,
|
|
389
|
+
*args: Any,
|
|
390
|
+
**kwargs: Any,
|
|
391
|
+
) -> tuple[httpx2.Request, httpx2.Response]:
|
|
392
|
+
"""Resend once without ``thinking`` when the API refuses the off-switch.
|
|
393
|
+
|
|
394
|
+
Which "thinking off" shape a model accepts differs per model and
|
|
395
|
+
changes over time, so ask the API instead of keeping a list: a 400
|
|
396
|
+
that names ``thinking`` on a request that only asked for thinking
|
|
397
|
+
off is retried with the key omitted, which every probed model
|
|
398
|
+
accepts. The (endpoint, model) is remembered only once that retry
|
|
399
|
+
succeeds. Returns the request actually in effect so OAuth recovery
|
|
400
|
+
resends the corrected body, not the refused one.
|
|
401
|
+
"""
|
|
402
|
+
if response.status_code != 400:
|
|
403
|
+
return request, response
|
|
404
|
+
try:
|
|
405
|
+
body = self._extract_body_bytes(request)
|
|
406
|
+
payload = json.loads(body) if body else None
|
|
407
|
+
thinking = payload.get("thinking") if isinstance(payload, dict) else None
|
|
408
|
+
if not isinstance(thinking, dict) or (
|
|
409
|
+
thinking.get("type") not in _OFF_THINKING_TYPES
|
|
410
|
+
):
|
|
411
|
+
return request, response
|
|
412
|
+
error = json.loads(await response.aread()).get("error") or {}
|
|
413
|
+
if "thinking" not in str(error.get("message", "")).lower():
|
|
414
|
+
return request, response
|
|
415
|
+
del payload["thinking"]
|
|
416
|
+
headers = {
|
|
417
|
+
k: v
|
|
418
|
+
for k, v in request.headers.items()
|
|
419
|
+
if k.lower() != "content-length"
|
|
420
|
+
}
|
|
421
|
+
retry_request = self.build_request(
|
|
422
|
+
method=request.method,
|
|
423
|
+
url=request.url,
|
|
424
|
+
headers=headers,
|
|
425
|
+
content=json.dumps(payload).encode("utf-8"),
|
|
426
|
+
extensions=dict(request.extensions),
|
|
427
|
+
)
|
|
428
|
+
except Exception as exc:
|
|
429
|
+
logger.debug("Could not retry without thinking: %s", exc)
|
|
430
|
+
return request, response
|
|
431
|
+
logger.info("Model refused thinking off-switch; retrying without thinking")
|
|
432
|
+
await response.aclose()
|
|
433
|
+
retried = await self._send_with_retries(retry_request, *args, **kwargs)
|
|
434
|
+
if retried.status_code < 400:
|
|
435
|
+
_THINKING_OMITTED_WHEN_OFF.add(
|
|
436
|
+
(_thinking_endpoint(request.url), payload.get("model"))
|
|
437
|
+
)
|
|
438
|
+
return retry_request, retried
|
|
439
|
+
|
|
403
440
|
async def _send_with_retries(
|
|
404
441
|
self, request: httpx2.Request, *args: Any, **kwargs: Any
|
|
405
442
|
) -> httpx2.Response:
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Thinking ``display`` / off-switch normalization for Anthropic request bodies.
|
|
2
|
+
|
|
3
|
+
The API only accepts ``display`` while thinking runs (``adaptive`` /
|
|
4
|
+
``enabled``). Which "thinking off" shape a model accepts differs per model, so
|
|
5
|
+
nothing here names a model: the client learns it from the provider's own 400.
|
|
6
|
+
|
|
7
|
+
Called by: claude_cache_client :: ClaudeCacheAsyncClient.send()
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _model_requires_thinking_summary(model_name):
|
|
12
|
+
if not model_name:
|
|
13
|
+
return False
|
|
14
|
+
from code_puppy.model_utils import should_use_anthropic_thinking_summary
|
|
15
|
+
|
|
16
|
+
return should_use_anthropic_thinking_summary(model_name)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _model_supports_thinking_updates(model_name):
|
|
20
|
+
if not model_name:
|
|
21
|
+
return False
|
|
22
|
+
from code_puppy.model_utils import should_use_anthropic_thinking_updates
|
|
23
|
+
|
|
24
|
+
return should_use_anthropic_thinking_updates(model_name)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# The API only accepts ``thinking.display`` while thinking actually runs.
|
|
28
|
+
_DISPLAY_THINKING_TYPES = frozenset({"adaptive", "enabled"})
|
|
29
|
+
_OFF_THINKING_TYPES = frozenset({"disabled", "between_tools"})
|
|
30
|
+
|
|
31
|
+
# (endpoint, model) pairs whose API refused an "off" thinking shape and then
|
|
32
|
+
# accepted the request without it (see ``_retry_without_thinking_after_400``).
|
|
33
|
+
# Never listed by name: each family accepts a different off-switch, and the
|
|
34
|
+
# same model ID can sit behind providers that disagree, hence the endpoint.
|
|
35
|
+
_THINKING_OMITTED_WHEN_OFF: set[tuple] = set()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _thinking_endpoint(url):
|
|
39
|
+
return (url.host, url.port, url.path)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _normalize_thinking_off(payload, thinking, endpoint):
|
|
43
|
+
modified = thinking.pop("display", None) is not None
|
|
44
|
+
if (
|
|
45
|
+
thinking.get("type") in _OFF_THINKING_TYPES
|
|
46
|
+
and (endpoint, payload.get("model")) in _THINKING_OMITTED_WHEN_OFF
|
|
47
|
+
):
|
|
48
|
+
del payload["thinking"]
|
|
49
|
+
return True
|
|
50
|
+
return modified
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _enforce_thinking_display_summary(payload, endpoint=None):
|
|
54
|
+
if not isinstance(payload, dict):
|
|
55
|
+
return False
|
|
56
|
+
thinking = payload.get("thinking")
|
|
57
|
+
if not isinstance(thinking, dict):
|
|
58
|
+
return False
|
|
59
|
+
if thinking.get("type") not in _DISPLAY_THINKING_TYPES:
|
|
60
|
+
return _normalize_thinking_off(payload, thinking, endpoint)
|
|
61
|
+
if not _model_requires_thinking_summary(payload.get("model")):
|
|
62
|
+
return False
|
|
63
|
+
display = thinking.get("display")
|
|
64
|
+
if display == "summarized":
|
|
65
|
+
return False
|
|
66
|
+
if display == "updates" and _model_supports_thinking_updates(payload.get("model")):
|
|
67
|
+
# Fable 5.1 legitimately asked for progress updates; don't clobber
|
|
68
|
+
# it back to summarized (which would drown status lines in reasoning).
|
|
69
|
+
return False
|
|
70
|
+
thinking["display"] = "summarized"
|
|
71
|
+
return True
|
|
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
|
|
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.908 → code_puppy-0.0.910}/code_puppy/command_line/load_context_completion.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/catalog_server_installer.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_puppy-0.0.908 → code_puppy-0.0.910}/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
|
{code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/mcp/silence_warning_command.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
|
{code_puppy-0.0.908 → code_puppy-0.0.910}/code_puppy/command_line/model_picker_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
|