coding-proxy 0.4.1a6__tar.gz → 0.4.1a7__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.
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/PKG-INFO +1 -1
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/pyproject.toml +1 -1
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/logging/db.py +38 -1
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/executor.py +34 -3
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/session_manager.py +9 -4
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/usage_recorder.py +5 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/server/dashboard.py +17 -11
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_router_executor.py +6 -5
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/uv.lock +1 -1
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/.github/workflows/ci.yml +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/.github/workflows/coverage.yml +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/.github/workflows/release.yml +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/.gitignore +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/.pre-commit-config.yaml +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/AGENTS.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/CHANGELOG.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/CLAUDE.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/LICENSE +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/README.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/assets/dashboard-v0.4.0.png +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/assets/session-v0.4.0.png +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/agents/browser-validation.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/agents/issue.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/agents/knowledge-map.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/agents/reference-specifications.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/arch/config-reference.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/arch/convert.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/arch/design-patterns.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/arch/routing.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/arch/testing.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/arch/vendors.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/framework.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/guide/api-reference.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/guide/cli-reference.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/guide/dashboard.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/guide/monitoring.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/guide/quickstart.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/guide/vendors.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/ops/ci-cd.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/user-guide.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/docs/zh-CN/README.md +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/__main__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/auth/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/auth/providers/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/auth/providers/base.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/auth/providers/github.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/auth/providers/google.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/auth/runtime.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/auth/store.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/cli/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/cli/auth_commands.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/cli/banner.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/compat/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/compat/canonical.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/compat/session_store.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/config/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/config/auth_schema.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/config/config.default.yaml +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/config/loader.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/config/resiliency.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/config/routing.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/config/schema.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/config/server.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/config/session_policy.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/config/vendors.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/anthropic_to_gemini.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/anthropic_to_openai.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/gemini_sse_adapter.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/gemini_to_anthropic.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/openai_to_anthropic.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/vendor_channels.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/logging/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/logging/formatters.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/logging/stats.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/model/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/model/auth.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/model/compat.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/model/constants.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/model/pricing.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/model/token.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/model/vendor.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/config.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/extractors/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/extractors/anthropic.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/extractors/gemini.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/extractors/openai.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/handler.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/operation.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/routes.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/usage_registry.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/pricing.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/circuit_breaker.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/error_classifier.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/model_mapper.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/quota_guard.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/rate_limit.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/retry.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/router.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/session_policy.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/tier.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/routing/usage_parser.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/server/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/server/app.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/server/factory.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/server/responses.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/server/routes.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/streaming/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/streaming/anthropic_compat.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/alibaba.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/anthropic.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/antigravity.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/base.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/copilot.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/copilot_models.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/copilot_token_manager.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/copilot_urls.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/doubao.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/kimi.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/minimax.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/mixins.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/native_anthropic.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/token_manager.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/xiaomi.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/zhipu.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/e2e/__init__.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/e2e/conftest.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/e2e/test_e2e_http.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/e2e/test_e2e_token.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/e2e/test_e2e_vendor.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_antigravity.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_app_routes.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_auto_login.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_banner.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_circuit_breaker.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_cli_usage.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_compat.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_config_init.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_config_loader.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_convert_request.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_convert_response.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_convert_sse.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_copilot.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_copilot_convert_request.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_copilot_convert_response.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_copilot_models.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_copilot_urls.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_currency.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_error_classifier.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_logging_dual_write.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_mixins.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_model_auth.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_model_compat.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_model_constants.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_model_mapper.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_model_pricing.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_model_token.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_model_vendor.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_native_api_base_url_override.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_native_api_extractors.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_native_api_handler.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_native_api_operation.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_native_api_routes.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_native_vendors.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_parse_usage.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_parse_usage_gemini.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_pricing.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_quota_guard.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_rate_limit.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_router_chain.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_runtime_reauth.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_schema.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_session_aware.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_streaming_anthropic_compat.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_tier.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_tiers_config.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_time_range.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_token_logger.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_token_logger_native_columns.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_token_manager.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_types.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_vendor_channels.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_vendor_streaming.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_vendors.py +0 -0
- {coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/tests/test_zhipu.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coding-proxy
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1a7
|
|
4
4
|
Summary: A High-Availability, Transparent, and Smart Multi-Vendor Proxy for Claude Code. Support Claude Plans, GitHub Copilot, Google Antigravity, ZAI/GLM, MiniMax, Qwen, Xiaomi, Kimi, Doubao...
|
|
5
5
|
Project-URL: Source Code, https://github.com/ThreeFish-AI/coding-proxy
|
|
6
6
|
Project-URL: User Guide, https://github.com/ThreeFish-AI/coding-proxy/blob/master/docs/user-guide.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "coding-proxy"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.1a7"
|
|
4
4
|
description = "A High-Availability, Transparent, and Smart Multi-Vendor Proxy for Claude Code. Support Claude Plans, GitHub Copilot, Google Antigravity, ZAI/GLM, MiniMax, Qwen, Xiaomi, Kimi, Doubao..."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -190,6 +190,14 @@ CREATE TABLE IF NOT EXISTS usage_evidence (
|
|
|
190
190
|
);
|
|
191
191
|
"""
|
|
192
192
|
|
|
193
|
+
_CREATE_SESSION_META = """
|
|
194
|
+
CREATE TABLE IF NOT EXISTS session_meta (
|
|
195
|
+
session_key TEXT PRIMARY KEY,
|
|
196
|
+
title TEXT NOT NULL DEFAULT '',
|
|
197
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
|
198
|
+
);
|
|
199
|
+
"""
|
|
200
|
+
|
|
193
201
|
_CREATE_INDEXES = """
|
|
194
202
|
CREATE INDEX IF NOT EXISTS idx_usage_ts ON usage_log(ts);
|
|
195
203
|
CREATE INDEX IF NOT EXISTS idx_usage_vendor ON usage_log(vendor);
|
|
@@ -245,6 +253,7 @@ class TokenLogger:
|
|
|
245
253
|
self._db.row_factory = aiosqlite.Row
|
|
246
254
|
await self._db.execute("PRAGMA journal_mode=WAL")
|
|
247
255
|
await self._db.executescript(_CREATE_TABLES)
|
|
256
|
+
await self._db.executescript(_CREATE_SESSION_META)
|
|
248
257
|
# 迁移必须在建索引之前执行,确保 vendor 列已存在
|
|
249
258
|
await self._migrate_rename_backend_to_vendor()
|
|
250
259
|
await self._migrate_add_failover_from()
|
|
@@ -316,6 +325,28 @@ class TokenLogger:
|
|
|
316
325
|
"Migration: renamed 'backend' column to 'vendor' in %s", table
|
|
317
326
|
)
|
|
318
327
|
|
|
328
|
+
async def set_session_title(self, session_key: str, title: str) -> None:
|
|
329
|
+
"""为新 session 设置标题(幂等,仅首次写入)."""
|
|
330
|
+
if not self._db or not title or not session_key:
|
|
331
|
+
return
|
|
332
|
+
await self._db.execute(
|
|
333
|
+
"INSERT OR IGNORE INTO session_meta (session_key, title) VALUES (?, ?)",
|
|
334
|
+
(session_key, title),
|
|
335
|
+
)
|
|
336
|
+
await self._db.commit()
|
|
337
|
+
|
|
338
|
+
async def get_session_titles(self, session_keys: list[str]) -> dict[str, str]:
|
|
339
|
+
"""批量查询 session 标题."""
|
|
340
|
+
if not self._db or not session_keys:
|
|
341
|
+
return {}
|
|
342
|
+
placeholders = ",".join("?" for _ in session_keys)
|
|
343
|
+
cursor = await self._db.execute(
|
|
344
|
+
f"SELECT session_key, title FROM session_meta WHERE session_key IN ({placeholders})",
|
|
345
|
+
session_keys,
|
|
346
|
+
)
|
|
347
|
+
rows = await cursor.fetchall()
|
|
348
|
+
return {row["session_key"]: row["title"] for row in rows}
|
|
349
|
+
|
|
319
350
|
async def log(
|
|
320
351
|
self,
|
|
321
352
|
vendor: str,
|
|
@@ -621,7 +652,13 @@ class TokenLogger:
|
|
|
621
652
|
(cutoff_iso, limit),
|
|
622
653
|
)
|
|
623
654
|
rows = await cursor.fetchall()
|
|
624
|
-
|
|
655
|
+
sessions = [dict(row) for row in rows]
|
|
656
|
+
if sessions:
|
|
657
|
+
keys = [s["session_key"] for s in sessions]
|
|
658
|
+
titles = await self.get_session_titles(keys)
|
|
659
|
+
for s in sessions:
|
|
660
|
+
s["title"] = titles.get(s["session_key"], "")
|
|
661
|
+
return sessions
|
|
625
662
|
|
|
626
663
|
async def query_session_profile(self, session_key: str) -> dict | None:
|
|
627
664
|
"""查询单个会话的完整聚合数据."""
|
|
@@ -43,10 +43,29 @@ from .usage_recorder import UsageRecorder
|
|
|
43
43
|
# 向后兼容别名
|
|
44
44
|
BackendResponse = VendorResponse
|
|
45
45
|
NoCompatibleBackendError = NoCompatibleVendorError
|
|
46
|
-
from ..compat.canonical import
|
|
46
|
+
from ..compat.canonical import (
|
|
47
|
+
CanonicalPartType,
|
|
48
|
+
CompatibilityStatus,
|
|
49
|
+
build_canonical_request,
|
|
50
|
+
)
|
|
51
|
+
from ..model.compat import CanonicalRequest
|
|
47
52
|
|
|
48
53
|
logger = logging.getLogger(__name__)
|
|
49
54
|
|
|
55
|
+
_SESSION_TITLE_MAX_LEN = 30
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _extract_session_title(request: CanonicalRequest) -> str:
|
|
59
|
+
"""从规范化请求中提取首个用户消息文本作为 session 标题."""
|
|
60
|
+
for part in request.messages:
|
|
61
|
+
if (
|
|
62
|
+
part.role == "user"
|
|
63
|
+
and part.type == CanonicalPartType.TEXT
|
|
64
|
+
and part.text.strip()
|
|
65
|
+
):
|
|
66
|
+
return part.text.strip()[:_SESSION_TITLE_MAX_LEN]
|
|
67
|
+
return ""
|
|
68
|
+
|
|
50
69
|
|
|
51
70
|
def _build_semantic_rejection_diagnostic(body: dict[str, Any]) -> str:
|
|
52
71
|
"""构建语义拒绝的请求体诊断上下文.
|
|
@@ -393,10 +412,16 @@ class _RouteExecutor:
|
|
|
393
412
|
failed_tier_name: str | None = None
|
|
394
413
|
request_caps = build_request_capabilities(body)
|
|
395
414
|
canonical_request = build_canonical_request(body, headers)
|
|
396
|
-
session_record = await self._session_mgr.get_or_create_record(
|
|
415
|
+
session_record, is_new_session = await self._session_mgr.get_or_create_record(
|
|
397
416
|
canonical_request.session_key,
|
|
398
417
|
canonical_request.trace_id,
|
|
399
418
|
)
|
|
419
|
+
if is_new_session:
|
|
420
|
+
title = _extract_session_title(canonical_request)
|
|
421
|
+
if title:
|
|
422
|
+
await self._recorder.set_session_title(
|
|
423
|
+
canonical_request.session_key, title
|
|
424
|
+
)
|
|
400
425
|
incompatible_reasons: list[str] = []
|
|
401
426
|
effective_tiers = self._resolve_effective_tiers(canonical_request.session_key)
|
|
402
427
|
last_idx = len(effective_tiers) - 1
|
|
@@ -564,10 +589,16 @@ class _RouteExecutor:
|
|
|
564
589
|
failed_tier_name: str | None = None
|
|
565
590
|
request_caps = build_request_capabilities(body)
|
|
566
591
|
canonical_request = build_canonical_request(body, headers)
|
|
567
|
-
session_record = await self._session_mgr.get_or_create_record(
|
|
592
|
+
session_record, is_new_session = await self._session_mgr.get_or_create_record(
|
|
568
593
|
canonical_request.session_key,
|
|
569
594
|
canonical_request.trace_id,
|
|
570
595
|
)
|
|
596
|
+
if is_new_session:
|
|
597
|
+
title = _extract_session_title(canonical_request)
|
|
598
|
+
if title:
|
|
599
|
+
await self._recorder.set_session_title(
|
|
600
|
+
canonical_request.session_key, title
|
|
601
|
+
)
|
|
571
602
|
incompatible_reasons: list[str] = []
|
|
572
603
|
effective_tiers = self._resolve_effective_tiers(canonical_request.session_key)
|
|
573
604
|
last_idx = len(effective_tiers) - 1
|
|
@@ -19,13 +19,18 @@ class RouteSessionManager:
|
|
|
19
19
|
|
|
20
20
|
async def get_or_create_record(
|
|
21
21
|
self, session_key: str, trace_id: str
|
|
22
|
-
) -> CompatSessionRecord | None:
|
|
22
|
+
) -> tuple[CompatSessionRecord | None, bool]:
|
|
23
|
+
"""获取或创建兼容性会话记录.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
(record, is_new) — is_new 为 True 表示本次创建的新会话。
|
|
27
|
+
"""
|
|
23
28
|
if self._store is None:
|
|
24
|
-
return None
|
|
29
|
+
return None, False
|
|
25
30
|
record = await self._store.get(session_key)
|
|
26
31
|
if record is not None:
|
|
27
|
-
return record
|
|
28
|
-
return CompatSessionRecord(session_key=session_key, trace_id=trace_id)
|
|
32
|
+
return record, False
|
|
33
|
+
return CompatSessionRecord(session_key=session_key, trace_id=trace_id), True
|
|
29
34
|
|
|
30
35
|
def apply_compat_context(
|
|
31
36
|
self,
|
|
@@ -28,6 +28,11 @@ class UsageRecorder:
|
|
|
28
28
|
def set_pricing_table(self, table: PricingTable) -> None:
|
|
29
29
|
self._pricing_table = table
|
|
30
30
|
|
|
31
|
+
async def set_session_title(self, session_key: str, title: str) -> None:
|
|
32
|
+
"""为新 session 设置标题(委托给 TokenLogger)."""
|
|
33
|
+
if self._token_logger:
|
|
34
|
+
await self._token_logger.set_session_title(session_key, title)
|
|
35
|
+
|
|
31
36
|
# ── 用量信息构建 ──────────────────────────────────────
|
|
32
37
|
|
|
33
38
|
@staticmethod
|
|
@@ -411,6 +411,7 @@ _DASHBOARD_HTML = """<!DOCTYPE html>
|
|
|
411
411
|
.session-table td.cell-tags { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.8; vertical-align: middle; }
|
|
412
412
|
.session-table tr:hover td { background: var(--bg-card-hover); }
|
|
413
413
|
.session-table .session-key { font-family: 'JetBrains Mono', monospace; font-size: 12px; color: var(--accent-blue); cursor: default; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
414
|
+
.session-table .session-title { font-size: 12px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 0; }
|
|
414
415
|
.session-id { display: flex; align-items: center; gap: 4px; }
|
|
415
416
|
.session-id-text { overflow: hidden; text-overflow: ellipsis; }
|
|
416
417
|
.copy-btn { background: none; border: none; color: var(--text-tertiary); cursor: pointer; padding: 2px; border-radius: 4px; font-size: 12px; line-height: 1; opacity: .5; flex-shrink: 0; }
|
|
@@ -676,20 +677,22 @@ _DASHBOARD_HTML = """<!DOCTYPE html>
|
|
|
676
677
|
<div class="session-table-wrap" id="sessions-table-wrap">
|
|
677
678
|
<table class="session-table">
|
|
678
679
|
<colgroup>
|
|
679
|
-
<col style="width:
|
|
680
|
-
<col style="width:
|
|
680
|
+
<col style="width:10%">
|
|
681
|
+
<col style="width:15%">
|
|
681
682
|
<col style="width:6%">
|
|
683
|
+
<col style="width:5%">
|
|
684
|
+
<col style="width:5%">
|
|
685
|
+
<col style="width:15%">
|
|
686
|
+
<col style="width:10%">
|
|
682
687
|
<col style="width:6%">
|
|
683
|
-
<col style="width:
|
|
684
|
-
<col style="width:
|
|
685
|
-
<col style="width:
|
|
686
|
-
<col style="width:9%">
|
|
687
|
-
<col style="width:12%">
|
|
688
|
-
<col style="width:12%">
|
|
688
|
+
<col style="width:8%">
|
|
689
|
+
<col style="width:10%">
|
|
690
|
+
<col style="width:10%">
|
|
689
691
|
</colgroup>
|
|
690
692
|
<thead>
|
|
691
693
|
<tr>
|
|
692
694
|
<th>Session ID</th>
|
|
695
|
+
<th>Title</th>
|
|
693
696
|
<th>Last Active</th>
|
|
694
697
|
<th>Requests</th>
|
|
695
698
|
<th>Tokens</th>
|
|
@@ -702,7 +705,7 @@ _DASHBOARD_HTML = """<!DOCTYPE html>
|
|
|
702
705
|
</tr>
|
|
703
706
|
</thead>
|
|
704
707
|
<tbody id="sessions-tbody">
|
|
705
|
-
<tr><td colspan="
|
|
708
|
+
<tr><td colspan="11" class="empty">Loading...</td></tr>
|
|
706
709
|
</tbody>
|
|
707
710
|
</table>
|
|
708
711
|
<div class="session-pagination" id="session-pagination">
|
|
@@ -1573,7 +1576,7 @@ function renderSessionPage() {
|
|
|
1573
1576
|
var tbody = document.getElementById('sessions-tbody');
|
|
1574
1577
|
|
|
1575
1578
|
if (!total) {
|
|
1576
|
-
tbody.innerHTML = '<tr><td colspan="
|
|
1579
|
+
tbody.innerHTML = '<tr><td colspan="11" class="empty"><div class="empty-icon">📭</div>No session data</td></tr>';
|
|
1577
1580
|
} else {
|
|
1578
1581
|
tbody.innerHTML = page.map(function(s) {
|
|
1579
1582
|
var parsed = parseSessionKey(s.session_key);
|
|
@@ -1582,6 +1585,7 @@ function renderSessionPage() {
|
|
|
1582
1585
|
var modelsFull = (s.models || '').split(',').map(function(c){return c.trim();});
|
|
1583
1586
|
var vendorsFull = (s.vendors || '').split(',').map(function(v){return formatVendorLabel(v.trim());});
|
|
1584
1587
|
var sr = s.success_rate != null ? Math.round(s.success_rate) : null;
|
|
1588
|
+
var sessionTitle = s.title || '';
|
|
1585
1589
|
return '<tr data-row onclick="toggleRow(this)">' +
|
|
1586
1590
|
'<td class="session-key" onclick="event.stopPropagation()">' +
|
|
1587
1591
|
'<div class="session-id" data-key="' + escapeHtml(s.session_key) + '" title="' + escapeHtml(s.session_key) + '">' +
|
|
@@ -1592,6 +1596,7 @@ function renderSessionPage() {
|
|
|
1592
1596
|
'dev:' + escapeHtml(shortId(parsed.device_id, 8)) + ' · acct:' + escapeHtml(shortId(parsed.account_uuid, 8)) +
|
|
1593
1597
|
'</div>' +
|
|
1594
1598
|
'</td>' +
|
|
1599
|
+
'<td class="session-title" title="' + escapeHtml(sessionTitle) + '">' + (sessionTitle ? escapeHtml(sessionTitle) : '–') + '</td>' +
|
|
1595
1600
|
'<td>' + relativeTime(s.last_active_ts) + '</td>' +
|
|
1596
1601
|
'<td style="font-family:JetBrains Mono,monospace">' + fmtNum(s.total_requests) + '</td>' +
|
|
1597
1602
|
'<td style="font-family:JetBrains Mono,monospace">' + fmtTokens(s.total_tokens) + '</td>' +
|
|
@@ -1602,9 +1607,10 @@ function renderSessionPage() {
|
|
|
1602
1607
|
'<td onclick="event.stopPropagation()">' + selectHtml + '</td>' +
|
|
1603
1608
|
'<td>' + formatCategories(s.client_categories) + '</td>' +
|
|
1604
1609
|
'</tr>' +
|
|
1605
|
-
'<tr class="row-detail"><td colspan="
|
|
1610
|
+
'<tr class="row-detail"><td colspan="11"><div class="detail-card">' +
|
|
1606
1611
|
'<div class="detail-identity-row">' +
|
|
1607
1612
|
'<div class="detail-item"><div class="detail-label">Session ID</div><div class="detail-value" title="' + escapeHtml(s.session_key) + '">' + escapeHtml(parsed.session_id || s.session_key) + '</div></div>' +
|
|
1613
|
+
'<div class="detail-item"><div class="detail-label">Title</div><div class="detail-value">' + (sessionTitle ? escapeHtml(sessionTitle) : '–') + '</div></div>' +
|
|
1608
1614
|
'<div class="detail-item"><div class="detail-label">Device</div><div class="detail-value" title="' + escapeHtml(parsed.device_id || '') + '">' + (parsed.device_id ? escapeHtml(parsed.device_id) : '–') + '</div></div>' +
|
|
1609
1615
|
'<div class="detail-item"><div class="detail-label">Account</div><div class="detail-value" title="' + escapeHtml(parsed.account_uuid || '') + '">' + (parsed.account_uuid ? escapeHtml(parsed.account_uuid) : '–') + '</div></div>' +
|
|
1610
1616
|
'</div>' +
|
|
@@ -222,7 +222,7 @@ class TestTryGateTier:
|
|
|
222
222
|
headers = {}
|
|
223
223
|
caps = RequestCapabilities()
|
|
224
224
|
req = build_canonical_request(body, headers)
|
|
225
|
-
session_record = await exec_inst._session_mgr.get_or_create_record(
|
|
225
|
+
session_record, _is_new = await exec_inst._session_mgr.get_or_create_record(
|
|
226
226
|
req.session_key, req.trace_id
|
|
227
227
|
)
|
|
228
228
|
reasons: list[str] = []
|
|
@@ -246,7 +246,7 @@ class TestTryGateTier:
|
|
|
246
246
|
body = {"model": "test"}
|
|
247
247
|
headers = {}
|
|
248
248
|
req = build_canonical_request(body, headers)
|
|
249
|
-
session_record = await exec_inst._session_mgr.get_or_create_record(
|
|
249
|
+
session_record, _is_new = await exec_inst._session_mgr.get_or_create_record(
|
|
250
250
|
req.session_key, req.trace_id
|
|
251
251
|
)
|
|
252
252
|
reasons: list[str] = []
|
|
@@ -275,7 +275,7 @@ class TestTryGateTier:
|
|
|
275
275
|
body = {"model": "test", "thinking": {"type": "enabled"}}
|
|
276
276
|
headers = {}
|
|
277
277
|
req = build_canonical_request(body, headers)
|
|
278
|
-
session_record = await exec_inst._session_mgr.get_or_create_record(
|
|
278
|
+
session_record, _is_new = await exec_inst._session_mgr.get_or_create_record(
|
|
279
279
|
req.session_key, req.trace_id
|
|
280
280
|
)
|
|
281
281
|
reasons: list[str] = []
|
|
@@ -651,9 +651,10 @@ class TestRouteSessionManagerIntegration:
|
|
|
651
651
|
@pytest.mark.asyncio
|
|
652
652
|
async def test_get_or_create_without_store(self):
|
|
653
653
|
mgr = RouteSessionManager(compat_session_store=None)
|
|
654
|
-
record = await mgr.get_or_create_record("sk_test", "trace_1")
|
|
655
|
-
# 无 store 时返回 None
|
|
654
|
+
record, is_new = await mgr.get_or_create_record("sk_test", "trace_1")
|
|
655
|
+
# 无 store 时返回 (None, False)
|
|
656
656
|
assert record is None
|
|
657
|
+
assert is_new is False
|
|
657
658
|
|
|
658
659
|
@pytest.mark.asyncio
|
|
659
660
|
async def test_persist_session_without_store_is_noop(self):
|
|
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
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/anthropic_to_gemini.py
RENAMED
|
File without changes
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/anthropic_to_openai.py
RENAMED
|
File without changes
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/gemini_sse_adapter.py
RENAMED
|
File without changes
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/gemini_to_anthropic.py
RENAMED
|
File without changes
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/convert/openai_to_anthropic.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/extractors/__init__.py
RENAMED
|
File without changes
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/extractors/anthropic.py
RENAMED
|
File without changes
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/extractors/gemini.py
RENAMED
|
File without changes
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/native_api/extractors/openai.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/streaming/anthropic_compat.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
|
{coding_proxy-0.4.1a6 → coding_proxy-0.4.1a7}/src/coding/proxy/vendors/copilot_token_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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
|