devcopilot 0.2.0__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.
- devcopilot-0.2.0/.env.example +209 -0
- devcopilot-0.2.0/.github/dependabot.yml +13 -0
- devcopilot-0.2.0/.github/workflows/publish.yml +50 -0
- devcopilot-0.2.0/.github/workflows/tests.yml +73 -0
- devcopilot-0.2.0/.gitignore +17 -0
- devcopilot-0.2.0/.python-version +1 -0
- devcopilot-0.2.0/AGENTS.md +98 -0
- devcopilot-0.2.0/ARCHITECTURE.md +680 -0
- devcopilot-0.2.0/CLAUDE.md +98 -0
- devcopilot-0.2.0/LICENSE +21 -0
- devcopilot-0.2.0/PKG-INFO +687 -0
- devcopilot-0.2.0/README.md +656 -0
- devcopilot-0.2.0/api/__init__.py +17 -0
- devcopilot-0.2.0/api/admin_config.py +1303 -0
- devcopilot-0.2.0/api/admin_routes.py +287 -0
- devcopilot-0.2.0/api/admin_static/admin.css +459 -0
- devcopilot-0.2.0/api/admin_static/admin.js +497 -0
- devcopilot-0.2.0/api/admin_static/index.html +77 -0
- devcopilot-0.2.0/api/admin_urls.py +34 -0
- devcopilot-0.2.0/api/app.py +194 -0
- devcopilot-0.2.0/api/command_utils.py +164 -0
- devcopilot-0.2.0/api/dependencies.py +144 -0
- devcopilot-0.2.0/api/detection.py +152 -0
- devcopilot-0.2.0/api/gateway_model_ids.py +54 -0
- devcopilot-0.2.0/api/model_catalog.py +133 -0
- devcopilot-0.2.0/api/model_router.py +125 -0
- devcopilot-0.2.0/api/models/__init__.py +45 -0
- devcopilot-0.2.0/api/models/anthropic.py +234 -0
- devcopilot-0.2.0/api/models/openai_responses.py +28 -0
- devcopilot-0.2.0/api/models/responses.py +60 -0
- devcopilot-0.2.0/api/optimization_handlers.py +154 -0
- devcopilot-0.2.0/api/request_pipeline.py +424 -0
- devcopilot-0.2.0/api/routes.py +156 -0
- devcopilot-0.2.0/api/runtime.py +334 -0
- devcopilot-0.2.0/api/validation_log.py +48 -0
- devcopilot-0.2.0/api/web_server_tools.py +22 -0
- devcopilot-0.2.0/api/web_tools/__init__.py +17 -0
- devcopilot-0.2.0/api/web_tools/constants.py +15 -0
- devcopilot-0.2.0/api/web_tools/egress.py +99 -0
- devcopilot-0.2.0/api/web_tools/outbound.py +278 -0
- devcopilot-0.2.0/api/web_tools/parsers.py +104 -0
- devcopilot-0.2.0/api/web_tools/request.py +87 -0
- devcopilot-0.2.0/api/web_tools/streaming.py +206 -0
- devcopilot-0.2.0/assets/admin-messaging.png +0 -0
- devcopilot-0.2.0/assets/admin-page.png +0 -0
- devcopilot-0.2.0/assets/cc-model-picker.png +0 -0
- devcopilot-0.2.0/assets/codex-model-picker.png +0 -0
- devcopilot-0.2.0/assets/codex.png +0 -0
- devcopilot-0.2.0/assets/how-it-works.mmd +57 -0
- devcopilot-0.2.0/assets/how-it-works.svg +1 -0
- devcopilot-0.2.0/assets/pic.png +0 -0
- devcopilot-0.2.0/cli/__init__.py +5 -0
- devcopilot-0.2.0/cli/claude_env.py +12 -0
- devcopilot-0.2.0/cli/entrypoints.py +166 -0
- devcopilot-0.2.0/cli/launchers/__init__.py +1 -0
- devcopilot-0.2.0/cli/launchers/claude.py +84 -0
- devcopilot-0.2.0/cli/launchers/codex.py +204 -0
- devcopilot-0.2.0/cli/launchers/codex_model_catalog.py +186 -0
- devcopilot-0.2.0/cli/launchers/common.py +93 -0
- devcopilot-0.2.0/cli/managed/__init__.py +6 -0
- devcopilot-0.2.0/cli/managed/claude.py +215 -0
- devcopilot-0.2.0/cli/managed/manager.py +157 -0
- devcopilot-0.2.0/cli/managed/session.py +260 -0
- devcopilot-0.2.0/cli/process_registry.py +78 -0
- devcopilot-0.2.0/config/__init__.py +5 -0
- devcopilot-0.2.0/config/constants.py +13 -0
- devcopilot-0.2.0/config/logging_config.py +159 -0
- devcopilot-0.2.0/config/nim.py +118 -0
- devcopilot-0.2.0/config/paths.py +91 -0
- devcopilot-0.2.0/config/provider_catalog.py +259 -0
- devcopilot-0.2.0/config/provider_ids.py +7 -0
- devcopilot-0.2.0/config/settings.py +538 -0
- devcopilot-0.2.0/core/__init__.py +1 -0
- devcopilot-0.2.0/core/anthropic/__init__.py +46 -0
- devcopilot-0.2.0/core/anthropic/content.py +31 -0
- devcopilot-0.2.0/core/anthropic/conversion.py +587 -0
- devcopilot-0.2.0/core/anthropic/emitted_sse_tracker.py +346 -0
- devcopilot-0.2.0/core/anthropic/errors.py +70 -0
- devcopilot-0.2.0/core/anthropic/native_messages_request.py +280 -0
- devcopilot-0.2.0/core/anthropic/native_sse_block_policy.py +313 -0
- devcopilot-0.2.0/core/anthropic/provider_stream_error.py +34 -0
- devcopilot-0.2.0/core/anthropic/server_tool_sse.py +14 -0
- devcopilot-0.2.0/core/anthropic/sse.py +440 -0
- devcopilot-0.2.0/core/anthropic/stream_contracts.py +205 -0
- devcopilot-0.2.0/core/anthropic/stream_recovery.py +346 -0
- devcopilot-0.2.0/core/anthropic/stream_recovery_session.py +133 -0
- devcopilot-0.2.0/core/anthropic/thinking.py +140 -0
- devcopilot-0.2.0/core/anthropic/tokens.py +117 -0
- devcopilot-0.2.0/core/anthropic/tools.py +212 -0
- devcopilot-0.2.0/core/anthropic/utils.py +9 -0
- devcopilot-0.2.0/core/openai_responses/__init__.py +5 -0
- devcopilot-0.2.0/core/openai_responses/adapter.py +31 -0
- devcopilot-0.2.0/core/openai_responses/anthropic_sse.py +59 -0
- devcopilot-0.2.0/core/openai_responses/errors.py +22 -0
- devcopilot-0.2.0/core/openai_responses/events.py +19 -0
- devcopilot-0.2.0/core/openai_responses/ids.py +21 -0
- devcopilot-0.2.0/core/openai_responses/input.py +258 -0
- devcopilot-0.2.0/core/openai_responses/items.py +37 -0
- devcopilot-0.2.0/core/openai_responses/reasoning.py +52 -0
- devcopilot-0.2.0/core/openai_responses/stream.py +25 -0
- devcopilot-0.2.0/core/openai_responses/stream_state.py +654 -0
- devcopilot-0.2.0/core/openai_responses/tools.py +374 -0
- devcopilot-0.2.0/core/openai_responses/usage.py +37 -0
- devcopilot-0.2.0/core/rate_limit.py +60 -0
- devcopilot-0.2.0/core/trace.py +216 -0
- devcopilot-0.2.0/messaging/__init__.py +26 -0
- devcopilot-0.2.0/messaging/cli_event_constants.py +67 -0
- devcopilot-0.2.0/messaging/command_context.py +66 -0
- devcopilot-0.2.0/messaging/command_dispatcher.py +37 -0
- devcopilot-0.2.0/messaging/commands.py +275 -0
- devcopilot-0.2.0/messaging/event_parser.py +181 -0
- devcopilot-0.2.0/messaging/limiter.py +300 -0
- devcopilot-0.2.0/messaging/models.py +36 -0
- devcopilot-0.2.0/messaging/node_event_pipeline.py +127 -0
- devcopilot-0.2.0/messaging/node_runner.py +342 -0
- devcopilot-0.2.0/messaging/platforms/__init__.py +15 -0
- devcopilot-0.2.0/messaging/platforms/base.py +228 -0
- devcopilot-0.2.0/messaging/platforms/discord.py +567 -0
- devcopilot-0.2.0/messaging/platforms/factory.py +103 -0
- devcopilot-0.2.0/messaging/platforms/outbox.py +144 -0
- devcopilot-0.2.0/messaging/platforms/telegram.py +688 -0
- devcopilot-0.2.0/messaging/platforms/voice_flow.py +295 -0
- devcopilot-0.2.0/messaging/rendering/__init__.py +3 -0
- devcopilot-0.2.0/messaging/rendering/discord_markdown.py +318 -0
- devcopilot-0.2.0/messaging/rendering/markdown_tables.py +49 -0
- devcopilot-0.2.0/messaging/rendering/profiles.py +55 -0
- devcopilot-0.2.0/messaging/rendering/telegram_markdown.py +327 -0
- devcopilot-0.2.0/messaging/safe_diagnostics.py +17 -0
- devcopilot-0.2.0/messaging/session.py +334 -0
- devcopilot-0.2.0/messaging/transcript.py +581 -0
- devcopilot-0.2.0/messaging/transcription.py +164 -0
- devcopilot-0.2.0/messaging/trees/__init__.py +15 -0
- devcopilot-0.2.0/messaging/trees/data.py +482 -0
- devcopilot-0.2.0/messaging/trees/manager.py +433 -0
- devcopilot-0.2.0/messaging/trees/processor.py +179 -0
- devcopilot-0.2.0/messaging/trees/repository.py +177 -0
- devcopilot-0.2.0/messaging/turn_intake.py +235 -0
- devcopilot-0.2.0/messaging/ui_updates.py +101 -0
- devcopilot-0.2.0/messaging/voice.py +76 -0
- devcopilot-0.2.0/messaging/workflow.py +200 -0
- devcopilot-0.2.0/providers/__init__.py +31 -0
- devcopilot-0.2.0/providers/base.py +152 -0
- devcopilot-0.2.0/providers/cerebras/__init__.py +7 -0
- devcopilot-0.2.0/providers/cerebras/client.py +31 -0
- devcopilot-0.2.0/providers/cerebras/request.py +55 -0
- devcopilot-0.2.0/providers/codestral/__init__.py +7 -0
- devcopilot-0.2.0/providers/codestral/client.py +34 -0
- devcopilot-0.2.0/providers/deepseek/__init__.py +11 -0
- devcopilot-0.2.0/providers/deepseek/client.py +51 -0
- devcopilot-0.2.0/providers/deepseek/request.py +475 -0
- devcopilot-0.2.0/providers/defaults.py +41 -0
- devcopilot-0.2.0/providers/error_mapping.py +309 -0
- devcopilot-0.2.0/providers/exceptions.py +113 -0
- devcopilot-0.2.0/providers/fireworks/__init__.py +5 -0
- devcopilot-0.2.0/providers/fireworks/client.py +45 -0
- devcopilot-0.2.0/providers/fireworks/request.py +48 -0
- devcopilot-0.2.0/providers/gemini/__init__.py +7 -0
- devcopilot-0.2.0/providers/gemini/client.py +49 -0
- devcopilot-0.2.0/providers/gemini/request.py +199 -0
- devcopilot-0.2.0/providers/groq/__init__.py +7 -0
- devcopilot-0.2.0/providers/groq/client.py +31 -0
- devcopilot-0.2.0/providers/groq/request.py +83 -0
- devcopilot-0.2.0/providers/kimi/__init__.py +10 -0
- devcopilot-0.2.0/providers/kimi/client.py +53 -0
- devcopilot-0.2.0/providers/kimi/request.py +42 -0
- devcopilot-0.2.0/providers/llamacpp/__init__.py +3 -0
- devcopilot-0.2.0/providers/llamacpp/client.py +16 -0
- devcopilot-0.2.0/providers/lmstudio/__init__.py +5 -0
- devcopilot-0.2.0/providers/lmstudio/client.py +16 -0
- devcopilot-0.2.0/providers/mistral/__init__.py +7 -0
- devcopilot-0.2.0/providers/mistral/client.py +31 -0
- devcopilot-0.2.0/providers/mistral/request.py +37 -0
- devcopilot-0.2.0/providers/model_listing.py +133 -0
- devcopilot-0.2.0/providers/nvidia_nim/__init__.py +7 -0
- devcopilot-0.2.0/providers/nvidia_nim/client.py +91 -0
- devcopilot-0.2.0/providers/nvidia_nim/request.py +430 -0
- devcopilot-0.2.0/providers/nvidia_nim/voice.py +95 -0
- devcopilot-0.2.0/providers/ollama/__init__.py +7 -0
- devcopilot-0.2.0/providers/ollama/client.py +39 -0
- devcopilot-0.2.0/providers/open_router/__init__.py +7 -0
- devcopilot-0.2.0/providers/open_router/client.py +124 -0
- devcopilot-0.2.0/providers/open_router/request.py +42 -0
- devcopilot-0.2.0/providers/opencode/__init__.py +11 -0
- devcopilot-0.2.0/providers/opencode/client.py +31 -0
- devcopilot-0.2.0/providers/opencode/request.py +35 -0
- devcopilot-0.2.0/providers/rate_limit.py +300 -0
- devcopilot-0.2.0/providers/registry.py +527 -0
- devcopilot-0.2.0/providers/transports/__init__.py +1 -0
- devcopilot-0.2.0/providers/transports/anthropic_messages/__init__.py +5 -0
- devcopilot-0.2.0/providers/transports/anthropic_messages/http.py +118 -0
- devcopilot-0.2.0/providers/transports/anthropic_messages/recovery.py +206 -0
- devcopilot-0.2.0/providers/transports/anthropic_messages/stream.py +295 -0
- devcopilot-0.2.0/providers/transports/anthropic_messages/transport.py +236 -0
- devcopilot-0.2.0/providers/transports/openai_chat/__init__.py +5 -0
- devcopilot-0.2.0/providers/transports/openai_chat/recovery.py +217 -0
- devcopilot-0.2.0/providers/transports/openai_chat/stream.py +384 -0
- devcopilot-0.2.0/providers/transports/openai_chat/tool_calls.py +293 -0
- devcopilot-0.2.0/providers/transports/openai_chat/transport.py +156 -0
- devcopilot-0.2.0/providers/wafer/__init__.py +10 -0
- devcopilot-0.2.0/providers/wafer/client.py +50 -0
- devcopilot-0.2.0/providers/zai/__init__.py +10 -0
- devcopilot-0.2.0/providers/zai/client.py +46 -0
- devcopilot-0.2.0/providers/zai/request.py +42 -0
- devcopilot-0.2.0/pyproject.toml +130 -0
- devcopilot-0.2.0/scripts/ci.ps1 +210 -0
- devcopilot-0.2.0/scripts/ci.sh +211 -0
- devcopilot-0.2.0/scripts/install.ps1 +416 -0
- devcopilot-0.2.0/scripts/install.sh +345 -0
- devcopilot-0.2.0/scripts/uninstall.ps1 +175 -0
- devcopilot-0.2.0/scripts/uninstall.sh +192 -0
- devcopilot-0.2.0/server.py +32 -0
- devcopilot-0.2.0/smoke/README.md +180 -0
- devcopilot-0.2.0/smoke/__init__.py +1 -0
- devcopilot-0.2.0/smoke/capabilities.py +474 -0
- devcopilot-0.2.0/smoke/conftest.py +128 -0
- devcopilot-0.2.0/smoke/features.py +520 -0
- devcopilot-0.2.0/smoke/lib/__init__.py +1 -0
- devcopilot-0.2.0/smoke/lib/child_process.py +44 -0
- devcopilot-0.2.0/smoke/lib/claude_cli_matrix.py +787 -0
- devcopilot-0.2.0/smoke/lib/config.py +403 -0
- devcopilot-0.2.0/smoke/lib/e2e.py +676 -0
- devcopilot-0.2.0/smoke/lib/http.py +71 -0
- devcopilot-0.2.0/smoke/lib/local_providers.py +85 -0
- devcopilot-0.2.0/smoke/lib/report.py +107 -0
- devcopilot-0.2.0/smoke/lib/report_summary.py +53 -0
- devcopilot-0.2.0/smoke/lib/server.py +116 -0
- devcopilot-0.2.0/smoke/lib/skips.py +69 -0
- devcopilot-0.2.0/smoke/prereq/__init__.py +1 -0
- devcopilot-0.2.0/smoke/prereq/test_api_prereq_live.py +196 -0
- devcopilot-0.2.0/smoke/prereq/test_auth_prereq_live.py +52 -0
- devcopilot-0.2.0/smoke/prereq/test_cli_prereq_live.py +83 -0
- devcopilot-0.2.0/smoke/prereq/test_client_shapes_prereq_live.py +49 -0
- devcopilot-0.2.0/smoke/prereq/test_local_provider_endpoints_prereq_live.py +36 -0
- devcopilot-0.2.0/smoke/prereq/test_messaging_prereq_live.py +113 -0
- devcopilot-0.2.0/smoke/prereq/test_provider_prereq_live.py +106 -0
- devcopilot-0.2.0/smoke/prereq/test_tools_prereq_live.py +63 -0
- devcopilot-0.2.0/smoke/prereq/test_voice_prereq_live.py +53 -0
- devcopilot-0.2.0/smoke/product/__init__.py +1 -0
- devcopilot-0.2.0/smoke/product/test_api_product_live.py +202 -0
- devcopilot-0.2.0/smoke/product/test_auth_product_live.py +53 -0
- devcopilot-0.2.0/smoke/product/test_cli_package_product_live.py +99 -0
- devcopilot-0.2.0/smoke/product/test_client_product_live.py +108 -0
- devcopilot-0.2.0/smoke/product/test_config_extensibility_product_live.py +177 -0
- devcopilot-0.2.0/smoke/product/test_live_platform_product_live.py +127 -0
- devcopilot-0.2.0/smoke/product/test_local_provider_product_live.py +60 -0
- devcopilot-0.2.0/smoke/product/test_messaging_product_live.py +132 -0
- devcopilot-0.2.0/smoke/product/test_nvidia_nim_cli_product_live.py +70 -0
- devcopilot-0.2.0/smoke/product/test_openrouter_free_cli_product_live.py +72 -0
- devcopilot-0.2.0/smoke/product/test_provider_product_live.py +561 -0
- devcopilot-0.2.0/smoke/product/test_voice_product_live.py +62 -0
- devcopilot-0.2.0/tests/__init__.py +1 -0
- devcopilot-0.2.0/tests/api/test_admin.py +512 -0
- devcopilot-0.2.0/tests/api/test_anthropic_request_passthrough.py +202 -0
- devcopilot-0.2.0/tests/api/test_api.py +271 -0
- devcopilot-0.2.0/tests/api/test_app_lifespan_and_errors.py +669 -0
- devcopilot-0.2.0/tests/api/test_auth.py +118 -0
- devcopilot-0.2.0/tests/api/test_dependencies.py +691 -0
- devcopilot-0.2.0/tests/api/test_detection.py +122 -0
- devcopilot-0.2.0/tests/api/test_model_listing.py +169 -0
- devcopilot-0.2.0/tests/api/test_model_router.py +202 -0
- devcopilot-0.2.0/tests/api/test_models_validators.py +216 -0
- devcopilot-0.2.0/tests/api/test_openai_responses.py +756 -0
- devcopilot-0.2.0/tests/api/test_optimization_handlers.py +229 -0
- devcopilot-0.2.0/tests/api/test_request_pipeline.py +259 -0
- devcopilot-0.2.0/tests/api/test_request_utils.py +635 -0
- devcopilot-0.2.0/tests/api/test_request_utils_filepaths_and_suggestions.py +130 -0
- devcopilot-0.2.0/tests/api/test_response_models.py +199 -0
- devcopilot-0.2.0/tests/api/test_routes_optimizations.py +180 -0
- devcopilot-0.2.0/tests/api/test_runtime_safe_logging.py +69 -0
- devcopilot-0.2.0/tests/api/test_safe_logging.py +204 -0
- devcopilot-0.2.0/tests/api/test_server_module.py +33 -0
- devcopilot-0.2.0/tests/api/test_validation_log.py +33 -0
- devcopilot-0.2.0/tests/api/test_web_server_tools.py +670 -0
- devcopilot-0.2.0/tests/cli/test_cli.py +711 -0
- devcopilot-0.2.0/tests/cli/test_cli_manager_edge_cases.py +110 -0
- devcopilot-0.2.0/tests/cli/test_cli_ownership.py +21 -0
- devcopilot-0.2.0/tests/cli/test_codex_model_catalog.py +171 -0
- devcopilot-0.2.0/tests/cli/test_entrypoints.py +568 -0
- devcopilot-0.2.0/tests/cli/test_managed_claude.py +137 -0
- devcopilot-0.2.0/tests/cli/test_process_registry.py +92 -0
- devcopilot-0.2.0/tests/config/test_config.py +846 -0
- devcopilot-0.2.0/tests/config/test_logging_config.py +103 -0
- devcopilot-0.2.0/tests/conftest.py +211 -0
- devcopilot-0.2.0/tests/contracts/test_admin_provider_manifest.py +66 -0
- devcopilot-0.2.0/tests/contracts/test_architecture_contracts.py +81 -0
- devcopilot-0.2.0/tests/contracts/test_capability_map.py +48 -0
- devcopilot-0.2.0/tests/contracts/test_feature_manifest.py +121 -0
- devcopilot-0.2.0/tests/contracts/test_import_boundaries.py +437 -0
- devcopilot-0.2.0/tests/contracts/test_local_provider_smoke.py +89 -0
- devcopilot-0.2.0/tests/contracts/test_nvidia_nim_cli_matrix.py +500 -0
- devcopilot-0.2.0/tests/contracts/test_provider_catalog_order.py +32 -0
- devcopilot-0.2.0/tests/contracts/test_smoke_config.py +411 -0
- devcopilot-0.2.0/tests/contracts/test_smoke_tiers.py +90 -0
- devcopilot-0.2.0/tests/contracts/test_stream_contracts.py +191 -0
- devcopilot-0.2.0/tests/core/anthropic/test_native_sse_block_policy.py +133 -0
- devcopilot-0.2.0/tests/core/anthropic/test_stream_recovery.py +226 -0
- devcopilot-0.2.0/tests/core/openai_responses/test_conversion.py +406 -0
- devcopilot-0.2.0/tests/core/openai_responses/test_sse.py +625 -0
- devcopilot-0.2.0/tests/core/test_strict_sliding_window.py +38 -0
- devcopilot-0.2.0/tests/core/test_trace.py +131 -0
- devcopilot-0.2.0/tests/messaging/test_discord_markdown.py +203 -0
- devcopilot-0.2.0/tests/messaging/test_discord_platform.py +380 -0
- devcopilot-0.2.0/tests/messaging/test_event_parser.py +192 -0
- devcopilot-0.2.0/tests/messaging/test_extract_text.py +109 -0
- devcopilot-0.2.0/tests/messaging/test_handler.py +744 -0
- devcopilot-0.2.0/tests/messaging/test_handler_context_isolation.py +158 -0
- devcopilot-0.2.0/tests/messaging/test_handler_format.py +131 -0
- devcopilot-0.2.0/tests/messaging/test_handler_integration.py +187 -0
- devcopilot-0.2.0/tests/messaging/test_handler_markdown_and_status_edges.py +469 -0
- devcopilot-0.2.0/tests/messaging/test_limiter.py +258 -0
- devcopilot-0.2.0/tests/messaging/test_messaging.py +197 -0
- devcopilot-0.2.0/tests/messaging/test_messaging_factory.py +124 -0
- devcopilot-0.2.0/tests/messaging/test_platform_outbox.py +108 -0
- devcopilot-0.2.0/tests/messaging/test_platform_voice_flow.py +244 -0
- devcopilot-0.2.0/tests/messaging/test_reliability.py +138 -0
- devcopilot-0.2.0/tests/messaging/test_rendering_profiles.py +17 -0
- devcopilot-0.2.0/tests/messaging/test_restart_reply_restore.py +182 -0
- devcopilot-0.2.0/tests/messaging/test_robust_formatting.py +91 -0
- devcopilot-0.2.0/tests/messaging/test_session_store_edge_cases.py +253 -0
- devcopilot-0.2.0/tests/messaging/test_stream_transcript_contract.py +62 -0
- devcopilot-0.2.0/tests/messaging/test_telegram.py +115 -0
- devcopilot-0.2.0/tests/messaging/test_telegram_edge_cases.py +311 -0
- devcopilot-0.2.0/tests/messaging/test_transcript.py +343 -0
- devcopilot-0.2.0/tests/messaging/test_transcription.py +137 -0
- devcopilot-0.2.0/tests/messaging/test_transcription_nim.py +39 -0
- devcopilot-0.2.0/tests/messaging/test_tree_concurrency.py +604 -0
- devcopilot-0.2.0/tests/messaging/test_tree_processor.py +262 -0
- devcopilot-0.2.0/tests/messaging/test_tree_queue.py +815 -0
- devcopilot-0.2.0/tests/messaging/test_tree_repository.py +143 -0
- devcopilot-0.2.0/tests/messaging/test_voice_handlers.py +176 -0
- devcopilot-0.2.0/tests/messaging/test_voice_services.py +42 -0
- devcopilot-0.2.0/tests/provider_request_mocks.py +25 -0
- devcopilot-0.2.0/tests/providers/test_anthropic_messages.py +556 -0
- devcopilot-0.2.0/tests/providers/test_anthropic_messages_429_retry.py +247 -0
- devcopilot-0.2.0/tests/providers/test_cerebras.py +221 -0
- devcopilot-0.2.0/tests/providers/test_codestral.py +182 -0
- devcopilot-0.2.0/tests/providers/test_converter.py +682 -0
- devcopilot-0.2.0/tests/providers/test_deepseek.py +1120 -0
- devcopilot-0.2.0/tests/providers/test_error_mapping.py +300 -0
- devcopilot-0.2.0/tests/providers/test_fireworks.py +185 -0
- devcopilot-0.2.0/tests/providers/test_gemini.py +458 -0
- devcopilot-0.2.0/tests/providers/test_groq.py +236 -0
- devcopilot-0.2.0/tests/providers/test_kimi.py +123 -0
- devcopilot-0.2.0/tests/providers/test_llamacpp.py +355 -0
- devcopilot-0.2.0/tests/providers/test_lmstudio.py +411 -0
- devcopilot-0.2.0/tests/providers/test_mistral.py +182 -0
- devcopilot-0.2.0/tests/providers/test_model_validation.py +523 -0
- devcopilot-0.2.0/tests/providers/test_nim_request_clone.py +40 -0
- devcopilot-0.2.0/tests/providers/test_nvidia_nim.py +782 -0
- devcopilot-0.2.0/tests/providers/test_nvidia_nim_request.py +493 -0
- devcopilot-0.2.0/tests/providers/test_ollama.py +271 -0
- devcopilot-0.2.0/tests/providers/test_open_router.py +703 -0
- devcopilot-0.2.0/tests/providers/test_openai_compat_5xx_retry.py +113 -0
- devcopilot-0.2.0/tests/providers/test_parsers.py +510 -0
- devcopilot-0.2.0/tests/providers/test_provider_rate_limit.py +486 -0
- devcopilot-0.2.0/tests/providers/test_provider_transport_logging.py +265 -0
- devcopilot-0.2.0/tests/providers/test_registry.py +246 -0
- devcopilot-0.2.0/tests/providers/test_sse_builder.py +435 -0
- devcopilot-0.2.0/tests/providers/test_streaming_errors.py +1145 -0
- devcopilot-0.2.0/tests/providers/test_subagent_interception.py +59 -0
- devcopilot-0.2.0/tests/providers/test_wafer.py +334 -0
- devcopilot-0.2.0/tests/providers/test_zai.py +109 -0
- devcopilot-0.2.0/tests/scripts/test_ci_scripts.py +301 -0
- devcopilot-0.2.0/tests/scripts/test_installers.py +291 -0
- devcopilot-0.2.0/tests/scripts/test_uninstallers.py +387 -0
- devcopilot-0.2.0/tests/stream_contract.py +18 -0
- devcopilot-0.2.0/uv.lock +2583 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# NVIDIA NIM Config
|
|
2
|
+
NVIDIA_NIM_API_KEY=""
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# OpenRouter Config
|
|
6
|
+
OPENROUTER_API_KEY=""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Mistral La Plateforme Config (Experiment plan free tier – rate limits; OpenAI-compatible at api.mistral.ai/v1)
|
|
10
|
+
MISTRAL_API_KEY=""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Mistral Codestral (separate key from La Plateforme; OpenAI-compatible at codestral.mistral.ai/v1)
|
|
14
|
+
CODESTRAL_API_KEY=""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# DeepSeek Config (uses native Anthropic Messages at api.deepseek.com/anthropic)
|
|
18
|
+
DEEPSEEK_API_KEY=""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Kimi Config (Anthropic-compatible Messages at api.moonshot.ai/anthropic/v1)
|
|
22
|
+
KIMI_API_KEY=""
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Wafer Config (uses native Anthropic Messages at pass.wafer.ai/v1/messages)
|
|
26
|
+
WAFER_API_KEY=""
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# OpenCode Zen (opencode.ai/zen/v1) and OpenCode Go (opencode.ai/zen/go/v1) share OPENCODE_API_KEY
|
|
30
|
+
OPENCODE_API_KEY=""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Z.ai Config (Anthropic-compatible Messages at api.z.ai/api/anthropic/v1)
|
|
34
|
+
ZAI_API_KEY=""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Fireworks AI Config (Anthropic-compatible Messages at api.fireworks.ai/inference/v1)
|
|
38
|
+
FIREWORKS_API_KEY=""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Gemini / Google AI Studio (OpenAI-compatible Chat Completions; see https://ai.google.dev/gemini-api/docs/openai)
|
|
42
|
+
GEMINI_API_KEY=""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Groq Cloud (OpenAI-compatible Chat Completions; see https://console.groq.com/docs/openai)
|
|
46
|
+
GROQ_API_KEY=""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Cerebras Inference (OpenAI-compatible Chat Completions; see https://inference-docs.cerebras.ai/resources/openai)
|
|
50
|
+
CEREBRAS_API_KEY=""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# LM Studio Config (local provider, no API key required)
|
|
54
|
+
LM_STUDIO_BASE_URL="http://localhost:1234/v1"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# Llama.cpp Config (local provider, no API key required)
|
|
58
|
+
LLAMACPP_BASE_URL="http://localhost:8080/v1"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# Ollama Config (local provider, no API key required)
|
|
62
|
+
OLLAMA_BASE_URL="http://localhost:11434"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# All Claude model requests are mapped to these models, plain model is fallback
|
|
66
|
+
# Format: provider_type/model/name
|
|
67
|
+
# Valid providers: "nvidia_nim" | "open_router" | "gemini" | "deepseek" | "mistral" | "mistral_codestral" | "opencode" | "opencode_go" | "wafer" | "kimi" | "cerebras" | "groq" | "fireworks" | "zai" | "lmstudio" | "llamacpp" | "ollama"
|
|
68
|
+
MODEL_OPUS=
|
|
69
|
+
MODEL_SONNET=
|
|
70
|
+
MODEL_HAIKU=
|
|
71
|
+
MODEL="nvidia_nim/nvidia/nemotron-3-super-120b-a12b"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# Optional live smoke model overrides. Provider smoke runs once per configured
|
|
75
|
+
# provider even when MODEL/MODEL_* route to a different provider.
|
|
76
|
+
DEVCOPILOT_SMOKE_MODEL_NVIDIA_NIM=
|
|
77
|
+
DEVCOPILOT_SMOKE_MODEL_OPEN_ROUTER=
|
|
78
|
+
DEVCOPILOT_SMOKE_MODEL_MISTRAL=
|
|
79
|
+
DEVCOPILOT_SMOKE_MODEL_MISTRAL_CODESTRAL=
|
|
80
|
+
DEVCOPILOT_SMOKE_MODEL_DEEPSEEK=
|
|
81
|
+
DEVCOPILOT_SMOKE_MODEL_LMSTUDIO=
|
|
82
|
+
DEVCOPILOT_SMOKE_MODEL_LLAMACPP=
|
|
83
|
+
DEVCOPILOT_SMOKE_MODEL_OLLAMA=
|
|
84
|
+
FCC_SMOKE_MODEL_KIMI=
|
|
85
|
+
FCC_SMOKE_MODEL_WAFER=
|
|
86
|
+
FCC_SMOKE_MODEL_OPENCODE=
|
|
87
|
+
FCC_SMOKE_MODEL_OPENCODE_GO=
|
|
88
|
+
FCC_SMOKE_MODEL_ZAI=
|
|
89
|
+
FCC_SMOKE_MODEL_FIREWORKS=
|
|
90
|
+
FCC_SMOKE_MODEL_GEMINI=
|
|
91
|
+
FCC_SMOKE_MODEL_GROQ=
|
|
92
|
+
FCC_SMOKE_MODEL_CEREBRAS=
|
|
93
|
+
FCC_SMOKE_NIM_MODELS=
|
|
94
|
+
FCC_SMOKE_NIM_EXTRA_MODELS=
|
|
95
|
+
FCC_SMOKE_OPENROUTER_FREE_MODELS=
|
|
96
|
+
FCC_SMOKE_OPENROUTER_FREE_EXTRA_MODELS=
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# Thinking output
|
|
100
|
+
# Per-Claude-model switches for provider reasoning requests and Claude thinking blocks.
|
|
101
|
+
# Blank per-model switches inherit ENABLE_MODEL_THINKING.
|
|
102
|
+
ENABLE_OPUS_THINKING=
|
|
103
|
+
ENABLE_SONNET_THINKING=
|
|
104
|
+
ENABLE_HAIKU_THINKING=
|
|
105
|
+
ENABLE_MODEL_THINKING=true
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# Provider config
|
|
109
|
+
# Per-provider proxy support: http and socks5, example: "http://username:password@host:port"
|
|
110
|
+
NVIDIA_NIM_PROXY=""
|
|
111
|
+
OPENROUTER_PROXY=""
|
|
112
|
+
MISTRAL_PROXY=""
|
|
113
|
+
CODESTRAL_PROXY=""
|
|
114
|
+
LMSTUDIO_PROXY=""
|
|
115
|
+
LLAMACPP_PROXY=""
|
|
116
|
+
KIMI_PROXY=""
|
|
117
|
+
WAFER_PROXY=""
|
|
118
|
+
OPENCODE_PROXY=""
|
|
119
|
+
OPENCODE_GO_PROXY=""
|
|
120
|
+
ZAI_PROXY=""
|
|
121
|
+
FIREWORKS_PROXY=""
|
|
122
|
+
GEMINI_PROXY=""
|
|
123
|
+
GROQ_PROXY=""
|
|
124
|
+
CEREBRAS_PROXY=""
|
|
125
|
+
|
|
126
|
+
PROVIDER_RATE_LIMIT=1
|
|
127
|
+
PROVIDER_RATE_WINDOW=3
|
|
128
|
+
PROVIDER_MAX_CONCURRENCY=5
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# HTTP client timeouts (seconds) for provider API requests
|
|
132
|
+
HTTP_READ_TIMEOUT=300
|
|
133
|
+
HTTP_WRITE_TIMEOUT=60
|
|
134
|
+
HTTP_CONNECT_TIMEOUT=60
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# Optional server API key (Anthropic-style)
|
|
138
|
+
ANTHROPIC_AUTH_TOKEN="freecc"
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
# Open /admin in the default browser when fcc-server becomes healthy (set 0/false/no to disable)
|
|
142
|
+
FCC_OPEN_BROWSER=true
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# Messaging Platform: "telegram" | "discord" | "none"
|
|
146
|
+
MESSAGING_PLATFORM="discord"
|
|
147
|
+
MESSAGING_RATE_LIMIT=1
|
|
148
|
+
MESSAGING_RATE_WINDOW=1
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# Voice Note Transcription
|
|
152
|
+
VOICE_NOTE_ENABLED=false
|
|
153
|
+
# WHISPER_DEVICE: "cpu" | "cuda" | "nvidia_nim"
|
|
154
|
+
# - "cpu"/"cuda": Hugging Face transformers Whisper (offline, free; install with: uv sync --extra voice_local)
|
|
155
|
+
# - "nvidia_nim": NVIDIA NIM Whisper via Riva gRPC (requires NVIDIA_NIM_API_KEY; install with: uv sync --extra voice)
|
|
156
|
+
# (Independent of MODEL=nvidia_nim/...: that selects the *chat* provider; this selects voice STT only.)
|
|
157
|
+
WHISPER_DEVICE="nvidia_nim"
|
|
158
|
+
# WHISPER_MODEL:
|
|
159
|
+
# - For cpu/cuda: Hugging Face ID or short name (tiny, base, small, medium, large-v2, large-v3, large-v3-turbo)
|
|
160
|
+
# - For nvidia_nim: NVIDIA NIM model (e.g., "nvidia/parakeet-ctc-1.1b-asr", "openai/whisper-large-v3")
|
|
161
|
+
# - For nvidia_nim, default to "openai/whisper-large-v3" for best performance
|
|
162
|
+
WHISPER_MODEL="openai/whisper-large-v3"
|
|
163
|
+
HF_TOKEN=""
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# Telegram Config
|
|
167
|
+
TELEGRAM_BOT_TOKEN=""
|
|
168
|
+
ALLOWED_TELEGRAM_USER_ID=""
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# Discord Config
|
|
172
|
+
DISCORD_BOT_TOKEN=""
|
|
173
|
+
ALLOWED_DISCORD_CHANNELS=""
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# Agent Config
|
|
177
|
+
ALLOWED_DIR=""
|
|
178
|
+
FAST_PREFIX_DETECTION=true
|
|
179
|
+
ENABLE_NETWORK_PROBE_MOCK=true
|
|
180
|
+
ENABLE_TITLE_GENERATION_SKIP=true
|
|
181
|
+
ENABLE_SUGGESTION_MODE_SKIP=true
|
|
182
|
+
ENABLE_FILEPATH_EXTRACTION_MOCK=true
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# Local Anthropic web_search / web_fetch handling (performs outbound HTTP; on by default)
|
|
186
|
+
ENABLE_WEB_SERVER_TOOLS=true
|
|
187
|
+
WEB_FETCH_ALLOWED_SCHEMES=http,https
|
|
188
|
+
WEB_FETCH_ALLOW_PRIVATE_NETWORKS=false
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
# Structured TRACE logs: lines with `"trace": true` merge ingress/routing/cli/provider/egress
|
|
192
|
+
# stages. Conversation text is logged in those payloads (verbatim). Values under keys named
|
|
193
|
+
# like ``api_key`` / ``authorization`` are redacted. Raw transport payloads still require
|
|
194
|
+
# the LOG_RAW_* toggles below.
|
|
195
|
+
#
|
|
196
|
+
# Verbose diagnostics (avoid logging raw prompts / SSE bodies in production)
|
|
197
|
+
DEBUG_PLATFORM_EDITS=false
|
|
198
|
+
DEBUG_SUBAGENT_STACK=false
|
|
199
|
+
# When true, also allows DEBUG-level httpx/httpcore/telegram log noise (not just payload logging).
|
|
200
|
+
LOG_RAW_API_PAYLOADS=false
|
|
201
|
+
LOG_RAW_SSE_EVENTS=false
|
|
202
|
+
# When true, log full exception text and tracebacks for unhandled errors (may leak request-derived data).
|
|
203
|
+
LOG_API_ERROR_TRACEBACKS=false
|
|
204
|
+
# When true, log message/transcription text previews in messaging adapters only (handler ingress always TRACEs verbatim text separately).
|
|
205
|
+
LOG_RAW_MESSAGING_CONTENT=false
|
|
206
|
+
# When true, log full Claude CLI stderr, non-JSON stdout lines, and parser error text.
|
|
207
|
+
LOG_RAW_CLI_DIAGNOSTICS=false
|
|
208
|
+
# When true, log full exception and CLI error message strings in messaging (may leak user content).
|
|
209
|
+
LOG_MESSAGING_ERROR_DETAILS=false
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "uv"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
groups:
|
|
8
|
+
minor-and-patch:
|
|
9
|
+
update-types: ["minor", "patch"]
|
|
10
|
+
- package-ecosystem: "github-actions"
|
|
11
|
+
directory: "/"
|
|
12
|
+
schedule:
|
|
13
|
+
interval: "weekly"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published] # triggers when you hit "Publish release" on GitHub
|
|
6
|
+
|
|
7
|
+
workflow_dispatch: # allows manual trigger from GitHub Actions tab
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
name: Build distribution
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v5
|
|
21
|
+
with:
|
|
22
|
+
version: "0.11.15"
|
|
23
|
+
enable-cache: true
|
|
24
|
+
|
|
25
|
+
- name: Build package
|
|
26
|
+
run: uv build
|
|
27
|
+
|
|
28
|
+
- name: Upload build artifacts
|
|
29
|
+
uses: actions/upload-artifact@v4
|
|
30
|
+
with:
|
|
31
|
+
name: dist
|
|
32
|
+
path: dist/
|
|
33
|
+
|
|
34
|
+
publish:
|
|
35
|
+
name: Publish to PyPI
|
|
36
|
+
needs: build
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
environment: pypi # matches the environment name set in PyPI trusted publisher
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write # required for trusted publishing (no token needed!)
|
|
41
|
+
|
|
42
|
+
steps:
|
|
43
|
+
- name: Download build artifacts
|
|
44
|
+
uses: actions/download-artifact@v4
|
|
45
|
+
with:
|
|
46
|
+
name: dist
|
|
47
|
+
path: dist/
|
|
48
|
+
|
|
49
|
+
- name: Publish to PyPI
|
|
50
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Branch protection: require every status check this workflow reports, for example:
|
|
2
|
+
# Ban type ignore suppressions
|
|
3
|
+
# ruff-format, ruff-check, ty, pytest
|
|
4
|
+
# GitHub may prefix with the workflow name (e.g. "CI / ruff-format"); use the names the branch protection UI offers after a run.
|
|
5
|
+
|
|
6
|
+
name: CI
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
branches: [main, master]
|
|
11
|
+
pull_request:
|
|
12
|
+
branches: [main, master]
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
no-type-ignore-suppressions:
|
|
20
|
+
name: Ban type ignore suppressions
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
timeout-minutes: 15
|
|
23
|
+
permissions:
|
|
24
|
+
contents: read
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
|
|
27
|
+
with:
|
|
28
|
+
ref: ${{ github.event.pull_request.head.sha || github.ref }}
|
|
29
|
+
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
|
|
30
|
+
fetch-depth: 1
|
|
31
|
+
|
|
32
|
+
- name: "Fail on type: ignore (no suppressions allowed)"
|
|
33
|
+
run: |
|
|
34
|
+
if grep -rE '# type: ignore|# ty: ignore' --include='*.py' . --exclude-dir=.venv --exclude-dir=.git; then
|
|
35
|
+
echo "::error::type: ignore / ty: ignore comments are not allowed. Fix the underlying type errors instead."
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
exit 0
|
|
39
|
+
|
|
40
|
+
quality:
|
|
41
|
+
name: ${{ matrix.id }}
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
timeout-minutes: 15
|
|
44
|
+
permissions:
|
|
45
|
+
contents: read
|
|
46
|
+
strategy:
|
|
47
|
+
fail-fast: false
|
|
48
|
+
matrix:
|
|
49
|
+
include:
|
|
50
|
+
- id: ruff-format
|
|
51
|
+
run: uv run ruff format --check
|
|
52
|
+
- id: ruff-check
|
|
53
|
+
run: uv run ruff check
|
|
54
|
+
- id: ty
|
|
55
|
+
run: uv run ty check
|
|
56
|
+
- id: pytest
|
|
57
|
+
run: uv run pytest -v --tb=short
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
|
|
60
|
+
with:
|
|
61
|
+
ref: ${{ github.event.pull_request.head.sha || github.ref }}
|
|
62
|
+
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
|
|
63
|
+
fetch-depth: 1
|
|
64
|
+
|
|
65
|
+
- name: Install uv
|
|
66
|
+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
|
|
67
|
+
with:
|
|
68
|
+
version: "0.11.15"
|
|
69
|
+
enable-cache: true
|
|
70
|
+
cache-python: true
|
|
71
|
+
|
|
72
|
+
- name: Run
|
|
73
|
+
run: ${{ matrix.run }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14.0
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# DEVCOPILOT DIRECTIVE
|
|
2
|
+
|
|
3
|
+
> This file is identical to DEVCOPILOT_CLAUDE.md. Keep them in sync.
|
|
4
|
+
|
|
5
|
+
## CODING ENVIRONMENT
|
|
6
|
+
|
|
7
|
+
- Install astral uv using "curl -LsSf https://astral.sh/uv/install.sh | sh" if not already installed and if already installed then update it to the latest version
|
|
8
|
+
- Install Python 3.14.0 stable using `uv python install 3.14.0` if not already installed (requires uv >=0.9; see `[tool.uv] required-version` in `pyproject.toml`)
|
|
9
|
+
- Always use `uv run` to run files instead of the global `python` command.
|
|
10
|
+
- Current uv ruff formatter is set to py314 which has supports multiple exception types without paranthesis (except TypeError, ValueError:)
|
|
11
|
+
- Read `.env.example` for environment variables.
|
|
12
|
+
- All CI checks must pass; failing checks block merge.
|
|
13
|
+
- Add tests for new changes (including edge cases).
|
|
14
|
+
- Before pushing, prefer `./scripts/ci.sh` (macOS/Linux) or `.\scripts\ci.ps1` (Windows) to run the local CI sequence; requires `uv` on PATH. The local scripts run Ruff in repair mode (`ruff format`, then `ruff check --fix`) before type checking and tests.
|
|
15
|
+
- Use `--only` / `--skip` (PowerShell: `-Only` / `-Skip`) to run a subset when iterating; use `--dry-run` to print commands without running them.
|
|
16
|
+
- GitHub CI remains check-only for Ruff (`ruff format --check`, `ruff check`) so branch protection verifies committed code.
|
|
17
|
+
- Fall back to individual repair commands when debugging local failures: `uv run ruff format`, `uv run ruff check --fix`, `uv run ty check`, `uv run pytest -v --tb=short`. Use GitHub-style checks only when verifying enforcement locally: `uv run ruff format --check`, `uv run ruff check`.
|
|
18
|
+
- Do not add `# type: ignore` or `# ty: ignore`; fix the underlying type issue.
|
|
19
|
+
- All 5 check IDs are represented in `scripts/ci.sh` / `scripts/ci.ps1` and enforced in `tests.yml` on push/merge (parallel jobs: suppression grep, ruff-format, ruff-check, ty, pytest).
|
|
20
|
+
- Branch protection: set **required status checks** to **all** of those statuses (e.g. **Ban type ignore suppressions**, **ruff-format**, **ruff-check**, **ty**, **pytest**—use the exact labels GitHub shows, which may be prefixed with **CI /**). Remove **ci** from required checks if it was previously added for the old gate job.
|
|
21
|
+
|
|
22
|
+
## IDENTITY & CONTEXT
|
|
23
|
+
|
|
24
|
+
- You are an expert Software Architect and Systems Engineer.
|
|
25
|
+
- Goal: Zero-defect, root-cause-oriented engineering for bugs; test-driven engineering for new features. Think carefully; no need to rush.
|
|
26
|
+
- Code: Write the simplest code possible. Keep the codebase minimal and modular.
|
|
27
|
+
|
|
28
|
+
## ARCHITECTURE PRINCIPLES
|
|
29
|
+
|
|
30
|
+
- **Shared utilities**: Put shared Anthropic protocol logic in neutral `core/anthropic/` modules. Do not have one provider import from another provider's utils.
|
|
31
|
+
- **DRY**: Extract shared base classes to eliminate duplication. Prefer composition over copy-paste.
|
|
32
|
+
- **Encapsulation**: Use accessor methods for internal state (e.g. `set_current_task()`), not direct `_attribute` assignment from outside.
|
|
33
|
+
- **Provider-specific config**: Keep provider-specific fields (e.g. `nim_settings`) in provider constructors, not in the base `ProviderConfig`.
|
|
34
|
+
- **Dead code**: Remove unused code, legacy systems, and hardcoded values. Use settings/config instead of literals (e.g. `settings.provider_type` not `"nvidia_nim"`).
|
|
35
|
+
- **Performance**: Use list accumulation for strings (not `+=` in loops), cache env vars at init, prefer iterative over recursive when stack depth matters.
|
|
36
|
+
- **Platform-agnostic naming**: Use generic names (e.g. `PLATFORM_EDIT`) not platform-specific ones (e.g. `TELEGRAM_EDIT`) in shared code.
|
|
37
|
+
- **No type ignores**: Do not add `# type: ignore` or `# ty: ignore`. Fix the underlying type issue.
|
|
38
|
+
- **Complete migrations**: When moving modules, update imports to the new owner and remove old compatibility shims in the same change unless preserving a published interface is explicitly required.
|
|
39
|
+
- **Maximum Test Coverage**: There should be maximum test coverage for everything, preferably live smoke test coverage to catch bugs early
|
|
40
|
+
|
|
41
|
+
## COGNITIVE WORKFLOW
|
|
42
|
+
|
|
43
|
+
1. **ANALYZE**: Read relevant files. Do not guess.
|
|
44
|
+
2. **PLAN**: Map out the logic. Identify root cause or required changes. Order changes by dependency.
|
|
45
|
+
3. **EXECUTE**: Fix the cause, not the symptom. Execute incrementally with clear commits.
|
|
46
|
+
4. **VERIFY**: Run `./scripts/ci.sh` or `.\scripts\ci.ps1`, plus relevant smoke tests when needed. Confirm the fix via logs or output.
|
|
47
|
+
5. **SPECIFICITY**: Do exactly as much as asked; nothing more, nothing less.
|
|
48
|
+
6. **PROPAGATION**: Changes impact multiple files; propagate updates correctly.
|
|
49
|
+
7. **VERSION**: If the commit touches production files on `main`, bump semver in the same commit (see [Versioning](#versioning-main)).
|
|
50
|
+
|
|
51
|
+
## VERSIONING (MAIN)
|
|
52
|
+
|
|
53
|
+
Every commit on `main` that changes a **production file** must include a semver bump in **`pyproject.toml`** in the **same commit**. Do not merge or push prod changes without updating the version.
|
|
54
|
+
|
|
55
|
+
### Production files
|
|
56
|
+
|
|
57
|
+
These paths count as production (runtime, packaging, or install surface):
|
|
58
|
+
|
|
59
|
+
- `api/`, `cli/`, `config/`, `core/`, `messaging/`, `providers/`
|
|
60
|
+
- `.env.example`
|
|
61
|
+
- `pyproject.toml` (dependencies, scripts, packaging)
|
|
62
|
+
- `scripts/install.sh`, `scripts/install.ps1`, `scripts/uninstall.sh`, `scripts/uninstall.ps1`, `scripts/ci.sh`, `scripts/ci.ps1`
|
|
63
|
+
|
|
64
|
+
These do **not** require a version bump on their own:
|
|
65
|
+
|
|
66
|
+
- `tests/`, `smoke/`
|
|
67
|
+
- Docs and assets: `README.md`, `assets/`, `AGENTS.md`, `CLAUDE.md`
|
|
68
|
+
- CI and repo config: `.github/`, `.gitignore`
|
|
69
|
+
|
|
70
|
+
If a single commit mixes production and non-production edits, still bump the version.
|
|
71
|
+
|
|
72
|
+
### Semver rules
|
|
73
|
+
|
|
74
|
+
Use `[project].version` as `MAJOR.MINOR.PATCH`:
|
|
75
|
+
|
|
76
|
+
- **PATCH** (`x.y.Z+1`): bug fixes, refactors with no user-visible behavior change, dependency updates, packaging/install fixes.
|
|
77
|
+
- **MINOR** (`x.Y+1.0`): backward-compatible features—new providers, admin fields, CLI commands, config options, or behavior additions.
|
|
78
|
+
- **MAJOR** (`X+1.0.0`): breaking changes—removed or renamed env vars, incompatible API/CLI/default changes, or migrations users must act on.
|
|
79
|
+
|
|
80
|
+
When unsure between PATCH and MINOR, prefer PATCH for fixes and MINOR for new capability.
|
|
81
|
+
|
|
82
|
+
### Required steps
|
|
83
|
+
|
|
84
|
+
1. Classify the change and choose the bump level.
|
|
85
|
+
2. Update `version` in `pyproject.toml`.
|
|
86
|
+
3. Run `uv lock` so `uv.lock` reflects the new package version.
|
|
87
|
+
4. Include the version and lockfile updates in the same commit as the production change.
|
|
88
|
+
|
|
89
|
+
Example commit on `main` after a packaging fix: bump `1.2.38` → `1.2.39`, run `uv lock`, commit together with the fix.
|
|
90
|
+
|
|
91
|
+
## SUMMARY STANDARDS
|
|
92
|
+
|
|
93
|
+
- Summaries must be technical and granular.
|
|
94
|
+
- Include: [Files Changed], [Logic Altered], [Verification Method], [Residual Risks] (if no residual risks then say none).
|
|
95
|
+
|
|
96
|
+
## TOOLS
|
|
97
|
+
|
|
98
|
+
- Prefer built-in tools (grep, read_file, etc.) over manual workflows. Check tool availability before use.
|