coding-proxy 0.2.4a2__tar.gz → 0.2.4a3__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.2.4a2 → coding_proxy-0.2.4a3}/.github/workflows/release.yml +2 -133
- coding_proxy-0.2.4a3/.pre-commit-config.yaml +57 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/AGENTS.md +1 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/CHANGELOG.md +3 -3
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/PKG-INFO +3 -3
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/README.md +2 -2
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/docs/zh-CN/README.md +2 -2
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/pyproject.toml +2 -1
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/config/config.default.yaml +1 -1
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/server/dashboard.py +23 -9
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/uv.lock +101 -1
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/.github/workflows/ci.yml +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/.github/workflows/coverage.yml +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/.gitignore +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/CLAUDE.md +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/LICENSE +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/assets/dashboard-v0.2.3.png +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/docs/ci-cd.md +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/docs/framework.md +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/docs/user-guide.md +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/__main__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/auth/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/auth/providers/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/auth/providers/base.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/auth/providers/github.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/auth/providers/google.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/auth/runtime.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/auth/store.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/cli/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/cli/auth_commands.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/cli/banner.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/compat/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/compat/canonical.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/compat/session_store.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/config/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/config/auth_schema.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/config/loader.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/config/resiliency.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/config/routing.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/config/schema.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/config/server.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/config/vendors.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/convert/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/convert/anthropic_to_gemini.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/convert/anthropic_to_openai.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/convert/gemini_sse_adapter.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/convert/gemini_to_anthropic.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/convert/openai_to_anthropic.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/logging/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/logging/db.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/logging/formatters.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/logging/stats.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/model/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/model/auth.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/model/compat.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/model/constants.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/model/pricing.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/model/token.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/model/vendor.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/pricing.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/circuit_breaker.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/error_classifier.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/executor.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/model_mapper.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/quota_guard.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/rate_limit.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/retry.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/router.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/session_manager.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/tier.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/usage_parser.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/routing/usage_recorder.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/server/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/server/app.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/server/factory.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/server/request_normalizer.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/server/responses.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/server/routes.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/streaming/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/streaming/anthropic_compat.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/alibaba.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/anthropic.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/antigravity.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/base.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/copilot.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/copilot_models.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/copilot_token_manager.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/copilot_urls.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/doubao.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/kimi.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/minimax.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/mixins.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/native_anthropic.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/token_manager.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/xiaomi.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/vendors/zhipu.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/__init__.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_antigravity.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_app_routes.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_auto_login.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_banner.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_circuit_breaker.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_cli_usage.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_compat.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_config_init.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_config_loader.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_convert_request.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_convert_response.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_convert_sse.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_copilot.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_copilot_convert_request.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_copilot_convert_response.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_copilot_models.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_copilot_urls.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_currency.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_error_classifier.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_logging_dual_write.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_mixins.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_model_auth.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_model_compat.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_model_constants.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_model_mapper.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_model_pricing.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_model_token.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_model_vendor.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_native_vendors.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_parse_usage.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_pricing.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_quota_guard.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_rate_limit.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_request_normalizer.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_router_chain.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_router_executor.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_runtime_reauth.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_schema.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_streaming_anthropic_compat.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_tier.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_tiers_config.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_time_range.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_token_logger.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_token_manager.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_types.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_vendor_streaming.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_vendors.py +0 -0
- {coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/tests/test_zhipu.py +0 -0
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
# =============================================================================
|
|
2
|
-
# coding-proxy: PyPI Publishing Pipeline (
|
|
2
|
+
# coding-proxy: PyPI Publishing Pipeline (3-Stage Unified Pipeline)
|
|
3
3
|
# =============================================================================
|
|
4
4
|
# Trigger: GitHub Release publication event (release.types: [published])
|
|
5
5
|
#
|
|
6
|
-
# Architecture:
|
|
6
|
+
# Architecture: 3-Stage Serial Pipeline (prerelease only — 所有生产发布均走预发布)
|
|
7
7
|
#
|
|
8
8
|
# Stage 1 (build): 矩阵构建 3.12/3.13/3.14,上传 artifacts
|
|
9
9
|
# Stage 2 (publish-testpypi): 发布到 TestPyPI 供验证
|
|
10
10
|
# Stage 3 (publish-to-pypi): ⏸ Production Approval Gate (environment: pypi)
|
|
11
11
|
# 审批通过后自动:Promote Release + Publish to PyPI
|
|
12
|
-
# Stage 4 (update-changelog): 从 Release notes 生成 Changelog PR → master
|
|
13
12
|
#
|
|
14
13
|
# 设计决策 — Stage 3 合并审批与发布的理由:
|
|
15
14
|
# pypa/gh-action-pypi-publish@release/v1 始终优先尝试 OIDC Trusted Publishing。
|
|
@@ -21,9 +20,6 @@
|
|
|
21
20
|
# Pre-requisites — 需要在 GitHub Settings 一次性手动配置:
|
|
22
21
|
# 1. repo → Settings → Environments → "pypi"
|
|
23
22
|
# → Required reviewers: 添加审批人员(Production Approval Gate 所需)
|
|
24
|
-
# 2. repo → Settings → Actions → General → Workflow permissions
|
|
25
|
-
# → "Read and write permissions"(Stage 4 推分支所需)
|
|
26
|
-
# → 勾选 "Allow GitHub Actions to create and approve pull requests"
|
|
27
23
|
#
|
|
28
24
|
# Authentication:
|
|
29
25
|
# - TEST_PYPI_API_TOKEN: TestPyPI API Token(repository secret)
|
|
@@ -197,130 +193,3 @@ jobs:
|
|
|
197
193
|
with:
|
|
198
194
|
skip-existing: true
|
|
199
195
|
verbose: true
|
|
200
|
-
|
|
201
|
-
# ===========================================================================
|
|
202
|
-
# Stage 5: UPDATE CHANGELOG -- 自动生成 Changelog PR → master
|
|
203
|
-
# ===========================================================================
|
|
204
|
-
update-changelog:
|
|
205
|
-
name: Update Changelog
|
|
206
|
-
runs-on: ubuntu-latest
|
|
207
|
-
needs: publish-to-pypi
|
|
208
|
-
if: github.event.release.prerelease == true
|
|
209
|
-
timeout-minutes: 10
|
|
210
|
-
permissions:
|
|
211
|
-
contents: write # git push 新分支
|
|
212
|
-
pull-requests: write # 创建 PR
|
|
213
|
-
|
|
214
|
-
steps:
|
|
215
|
-
- name: Checkout repository
|
|
216
|
-
uses: actions/checkout@v4
|
|
217
|
-
with:
|
|
218
|
-
fetch-depth: 0
|
|
219
|
-
persist-credentials: true
|
|
220
|
-
|
|
221
|
-
- name: Extract stable version from prerelease tag
|
|
222
|
-
id: version
|
|
223
|
-
run: |
|
|
224
|
-
PRERELEASE_TAG="${{ github.ref_name }}"
|
|
225
|
-
# v0.2.0a1 → v0.2.0(移除预发布后缀 a*/b*/rc*)
|
|
226
|
-
STABLE_VERSION=$(echo "$PRERELEASE_TAG" | sed 's/\(v[0-9]*\.[0-9]*\.[0-9]*\).*/\1/')
|
|
227
|
-
echo "prerelease_tag=$PRERELEASE_TAG" >> "$GITHUB_OUTPUT"
|
|
228
|
-
echo "stable_version=$STABLE_VERSION" >> "$GITHUB_OUTPUT"
|
|
229
|
-
echo "branch_name=chore/changelog-$STABLE_VERSION" >> "$GITHUB_OUTPUT"
|
|
230
|
-
echo "Extracted: $PRERELEASE_TAG → $STABLE_VERSION"
|
|
231
|
-
|
|
232
|
-
- name: Check if Changelog entry already exists
|
|
233
|
-
id: check
|
|
234
|
-
run: |
|
|
235
|
-
STABLE="${{ steps.version.outputs.stable_version }}"
|
|
236
|
-
if grep -qF "[$STABLE]" CHANGELOG.md; then
|
|
237
|
-
echo "exists=true" >> "$GITHUB_OUTPUT"
|
|
238
|
-
echo "ℹ️ Changelog entry for $STABLE already exists, skipping PR creation"
|
|
239
|
-
else
|
|
240
|
-
echo "exists=false" >> "$GITHUB_OUTPUT"
|
|
241
|
-
echo "✅ No existing entry for $STABLE, will create PR"
|
|
242
|
-
fi
|
|
243
|
-
|
|
244
|
-
- name: Fetch release body and update CHANGELOG.md
|
|
245
|
-
if: steps.check.outputs.exists == 'false'
|
|
246
|
-
uses: actions/github-script@v7
|
|
247
|
-
with:
|
|
248
|
-
script: |
|
|
249
|
-
const fs = require('fs');
|
|
250
|
-
const { owner, repo } = context.repo;
|
|
251
|
-
|
|
252
|
-
// 通过 API 获取 Release body,避免 shell 特殊字符注入问题
|
|
253
|
-
const release = await github.rest.repos.getReleaseByTag({
|
|
254
|
-
owner,
|
|
255
|
-
repo,
|
|
256
|
-
tag: '${{ steps.version.outputs.prerelease_tag }}',
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
const stable = '${{ steps.version.outputs.stable_version }}';
|
|
260
|
-
const date = new Date().toISOString().slice(0, 10);
|
|
261
|
-
const releaseUrl = `https://github.com/${owner}/${repo}/releases/tag/${{ steps.version.outputs.prerelease_tag }}`;
|
|
262
|
-
const body = release.data.body || '';
|
|
263
|
-
|
|
264
|
-
// 构建新条目
|
|
265
|
-
const newEntry = `\n## [${stable}](${releaseUrl}) — ${date}\n\n${body}\n`;
|
|
266
|
-
|
|
267
|
-
// 读取 CHANGELOG.md,在 ## [Unreleased] 行后插入新条目
|
|
268
|
-
let content = fs.readFileSync('CHANGELOG.md', 'utf8');
|
|
269
|
-
const marker = '## [Unreleased]';
|
|
270
|
-
const idx = content.indexOf(marker);
|
|
271
|
-
if (idx === -1) {
|
|
272
|
-
core.setFailed('CHANGELOG.md 中未找到 ## [Unreleased] 标记,无法插入条目');
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
const insertPos = idx + marker.length;
|
|
276
|
-
content = content.slice(0, insertPos) + newEntry + content.slice(insertPos);
|
|
277
|
-
fs.writeFileSync('CHANGELOG.md', content, 'utf8');
|
|
278
|
-
core.info(`✅ CHANGELOG.md updated with entry for ${stable}`);
|
|
279
|
-
|
|
280
|
-
- name: Create branch and commit
|
|
281
|
-
if: steps.check.outputs.exists == 'false'
|
|
282
|
-
run: |
|
|
283
|
-
BRANCH="${{ steps.version.outputs.branch_name }}"
|
|
284
|
-
STABLE="${{ steps.version.outputs.stable_version }}"
|
|
285
|
-
|
|
286
|
-
git config user.name "github-actions[bot]"
|
|
287
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
288
|
-
|
|
289
|
-
git checkout -b "$BRANCH"
|
|
290
|
-
git add CHANGELOG.md
|
|
291
|
-
git commit -m "docs(changelog): add entry for $STABLE"
|
|
292
|
-
git push origin "$BRANCH"
|
|
293
|
-
|
|
294
|
-
- name: Create Pull Request
|
|
295
|
-
if: steps.check.outputs.exists == 'false'
|
|
296
|
-
uses: actions/github-script@v7
|
|
297
|
-
with:
|
|
298
|
-
script: |
|
|
299
|
-
const { owner, repo } = context.repo;
|
|
300
|
-
const stable = '${{ steps.version.outputs.stable_version }}';
|
|
301
|
-
const branch = '${{ steps.version.outputs.branch_name }}';
|
|
302
|
-
const prereleaseTag = '${{ steps.version.outputs.prerelease_tag }}';
|
|
303
|
-
const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${{ github.run_id }}`;
|
|
304
|
-
|
|
305
|
-
const pr = await github.rest.pulls.create({
|
|
306
|
-
owner,
|
|
307
|
-
repo,
|
|
308
|
-
title: `docs(changelog): 补充 ${stable} 发版说明`,
|
|
309
|
-
body: [
|
|
310
|
-
`## 摘要`,
|
|
311
|
-
``,
|
|
312
|
-
`自动生成的 PR,为 **${stable}** 正式版补充 CHANGELOG 条目。`,
|
|
313
|
-
``,
|
|
314
|
-
`- 来源:[\`${prereleaseTag}\`](https://github.com/${owner}/${repo}/releases/tag/${prereleaseTag}) Release notes`,
|
|
315
|
-
`- 目标分支:\`master\``,
|
|
316
|
-
``,
|
|
317
|
-
`请审阅 CHANGELOG 条目后合并。`,
|
|
318
|
-
``,
|
|
319
|
-
`> 🤖 由 [发布流水线](${runUrl}) 自动生成`,
|
|
320
|
-
].join('\n'),
|
|
321
|
-
head: branch,
|
|
322
|
-
base: 'master',
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
core.notice(`✅ PR created: ${pr.data.html_url}`);
|
|
326
|
-
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# coding-proxy: Pre-commit Hooks Configuration
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# 目的: 在代码提交前自动执行 Ruff lint/format 及通用卫生检查,作为 CI 的前置守护
|
|
5
|
+
#
|
|
6
|
+
# 设计决策:使用 local hook(language: system + uv run)而非 astral-sh/ruff-pre-commit
|
|
7
|
+
# - 遵循 Single Source of Truth 原则:Ruff 版本由 uv.lock 唯一管控,消除版本漂移
|
|
8
|
+
# - 与 CI 命令形态完全镜像(uv run ruff check/format)
|
|
9
|
+
# - 符合 AGENTS.md 包管理规范(统一使用 uv)
|
|
10
|
+
#
|
|
11
|
+
# 安装:uv run pre-commit install
|
|
12
|
+
# 手动全量检查:uv run pre-commit run --all-files
|
|
13
|
+
# =============================================================================
|
|
14
|
+
|
|
15
|
+
minimum_pre_commit_version: "4.0.0"
|
|
16
|
+
|
|
17
|
+
repos:
|
|
18
|
+
# ---------------------------------------------------------------------------
|
|
19
|
+
# 通用代码卫生检查(pre-commit-hooks 官方钩子集)
|
|
20
|
+
# 轻量级、无额外依赖、执行极快
|
|
21
|
+
# ---------------------------------------------------------------------------
|
|
22
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
23
|
+
rev: v5.0.0
|
|
24
|
+
hooks:
|
|
25
|
+
- id: trailing-whitespace # 去除行尾空白
|
|
26
|
+
- id: end-of-file-fixer # 确保文件以换行符结尾
|
|
27
|
+
- id: check-yaml
|
|
28
|
+
args: ["--unsafe"] # 兼容 GitHub Actions ${{ }} 表达式语法
|
|
29
|
+
- id: check-toml # 校验 TOML 语法(pyproject.toml)
|
|
30
|
+
- id: check-merge-conflict # 阻止提交含未解决 merge conflict 标记的文件
|
|
31
|
+
- id: check-added-large-files
|
|
32
|
+
args: ["--maxkb=1024"] # 阈值 1MB(assets/dashboard-v0.2.3.png 为 944KB)
|
|
33
|
+
|
|
34
|
+
# ---------------------------------------------------------------------------
|
|
35
|
+
# Ruff: local hook,直接调用 uv 安装的 Ruff(与 CI 版本完全一致)
|
|
36
|
+
# 前置条件:uv sync --dev 已执行
|
|
37
|
+
# ---------------------------------------------------------------------------
|
|
38
|
+
- repo: local
|
|
39
|
+
hooks:
|
|
40
|
+
# 对应 CI: uv run ruff check .
|
|
41
|
+
# --fix: 自动修复安全可修复问题(isort、UP 现代化等),降低开发摩擦
|
|
42
|
+
# --exit-non-zero-on-fix: 修复后返回非零码,触发 git 重新暂存已修复文件
|
|
43
|
+
- id: ruff-lint
|
|
44
|
+
name: Ruff (lint + auto-fix)
|
|
45
|
+
language: system
|
|
46
|
+
entry: uv run ruff check --fix --exit-non-zero-on-fix
|
|
47
|
+
types_or: [python, pyi]
|
|
48
|
+
require_serial: false
|
|
49
|
+
|
|
50
|
+
# 对应 CI: uv run ruff format --check .
|
|
51
|
+
# 本地直接 format(自动修复格式),CI 保留 --check 模式作为最终防线
|
|
52
|
+
- id: ruff-format
|
|
53
|
+
name: Ruff (format)
|
|
54
|
+
language: system
|
|
55
|
+
entry: uv run ruff format
|
|
56
|
+
types_or: [python, pyi]
|
|
57
|
+
require_serial: false
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
2. **Temp Management**: 临时产物(执行计划等)一律收敛至 `.temp/` 并及时清理;
|
|
47
47
|
3. **Link Validity**: 确保所有引用的 URL 可访问且具备明确的上下文价值;
|
|
48
48
|
4. **Git Commit**: 在需要提交变更到 Git 时,一律使用 Shell 调用 Claude Code 的自定义 Slash Command: `/commit` 进行 git commit 操作(若环境中未安装 Claude Code,则直接读取 `~/.claude/commands/commit.md`,按照其中的规则进行 git commit 操作)。不要执行 Rebase。
|
|
49
|
+
5. **Pre-commit Hooks**: 克隆仓库后执行 `uv run pre-commit install` 激活本地 Git hooks,使 Ruff lint(含 auto-fix)、Ruff format 及通用代码卫生检查在每次 commit 前自动运行。若 hooks 自动修复了问题,提交会被中断,执行 `git add -p` 审阅修复内容后重新提交即可。
|
|
49
50
|
- **Package Management Standardization (包管理规范)**:
|
|
50
51
|
1. **Python**: 严禁使用 pip/poetry,**必须**统一使用 `uv` 进行包管理与脚本执行(如 `uv run`);
|
|
51
52
|
2. **JavaScript/TypeScript**: 严禁使用 npm/yarn,**必须**统一使用 `pnpm` 进行包管理与脚本执行。
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
## [v0.1.1](https://github.com/ThreeFish-AI/coding-proxy/releases/tag/v0.1.1) — 2026-04-05
|
|
72
72
|
|
|
73
73
|
> [!IMPORTANT]
|
|
74
|
-
>
|
|
75
|
-
> **🎉 coding-proxy MVP 惊艳登场!**
|
|
76
|
-
>
|
|
74
|
+
>
|
|
75
|
+
> **🎉 coding-proxy MVP 惊艳登场!**
|
|
76
|
+
>
|
|
77
77
|
> 仅需配置一行环境变量,立刻为你的 Claude Code 接入“永不宕机”的多源智能引擎。主供应商打盹?毫秒级自动无缝切换备用通道,全天候护航你的编码心流,向打断大声说不!
|
|
78
78
|
|
|
79
79
|
### ✨ 核心亮点
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coding-proxy
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4a3
|
|
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
|
|
@@ -145,7 +145,7 @@ graph RL
|
|
|
145
145
|
|
|
146
146
|
subgraph CodingProxy["⚡ coding-proxy"]
|
|
147
147
|
direction RL
|
|
148
|
-
|
|
148
|
+
|
|
149
149
|
Router["RequestRouter<br/><code>routing/router.py</code>"]:::router
|
|
150
150
|
|
|
151
151
|
Router -->NTier
|
|
@@ -178,7 +178,7 @@ graph RL
|
|
|
178
178
|
Tier2 -. "🆘 Safety Net Downgrade" .-> TierN
|
|
179
179
|
end
|
|
180
180
|
|
|
181
|
-
end
|
|
181
|
+
end
|
|
182
182
|
|
|
183
183
|
Client -->|"POST /v1/messages"| CodingProxy
|
|
184
184
|
```
|
|
@@ -118,7 +118,7 @@ graph RL
|
|
|
118
118
|
|
|
119
119
|
subgraph CodingProxy["⚡ coding-proxy"]
|
|
120
120
|
direction RL
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
Router["RequestRouter<br/><code>routing/router.py</code>"]:::router
|
|
123
123
|
|
|
124
124
|
Router -->NTier
|
|
@@ -151,7 +151,7 @@ graph RL
|
|
|
151
151
|
Tier2 -. "🆘 Safety Net Downgrade" .-> TierN
|
|
152
152
|
end
|
|
153
153
|
|
|
154
|
-
end
|
|
154
|
+
end
|
|
155
155
|
|
|
156
156
|
Client -->|"POST /v1/messages"| CodingProxy
|
|
157
157
|
```
|
|
@@ -118,7 +118,7 @@ graph RL
|
|
|
118
118
|
|
|
119
119
|
subgraph CodingProxy["⚡ coding-proxy"]
|
|
120
120
|
direction RL
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
Router["RequestRouter<br/><code>routing/router.py</code>"]:::router
|
|
123
123
|
|
|
124
124
|
Router -->NTier
|
|
@@ -151,7 +151,7 @@ graph RL
|
|
|
151
151
|
Tier2 -. "🆘 Safety Net Downgrade" .-> TierN
|
|
152
152
|
end
|
|
153
153
|
|
|
154
|
-
end
|
|
154
|
+
end
|
|
155
155
|
|
|
156
156
|
Client -->|"POST /v1/messages"| CodingProxy
|
|
157
157
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "coding-proxy"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.4a3"
|
|
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"
|
|
@@ -47,6 +47,7 @@ dev = [
|
|
|
47
47
|
"pytest-asyncio>=1.3",
|
|
48
48
|
"pytest-cov>=6.0",
|
|
49
49
|
"ruff>=0.9.0",
|
|
50
|
+
"pre-commit>=4.0",
|
|
50
51
|
]
|
|
51
52
|
|
|
52
53
|
# ── Ruff: Linter & Formatter(替代 flake8 + isort + Black + pyupgrade 等 6+ 工具) ──
|
|
@@ -911,8 +911,21 @@ function updateVendorStatus(status) {
|
|
|
911
911
|
}).join('');
|
|
912
912
|
}
|
|
913
913
|
|
|
914
|
+
// ── 按 tiers 顺序排序 vendor 列表 ─────────────────────────
|
|
915
|
+
function sortByTierOrder(vendors, tierOrder) {
|
|
916
|
+
if (!tierOrder || !tierOrder.length) return vendors.sort();
|
|
917
|
+
const orderMap = {};
|
|
918
|
+
tierOrder.forEach((name, i) => { orderMap[name] = i; });
|
|
919
|
+
const maxIdx = tierOrder.length;
|
|
920
|
+
return vendors.sort((a, b) => {
|
|
921
|
+
const ia = orderMap[a] ?? maxIdx;
|
|
922
|
+
const ib = orderMap[b] ?? maxIdx;
|
|
923
|
+
return ia !== ib ? ia - ib : a.localeCompare(b);
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
|
|
914
927
|
// ── 时序折线图(请求量,按 vendor)────────────────────────
|
|
915
|
-
function buildTimeline(rows) {
|
|
928
|
+
function buildTimeline(rows, tierOrder) {
|
|
916
929
|
const vendorDateMap = {};
|
|
917
930
|
const allDates = new Set();
|
|
918
931
|
for (const r of rows) {
|
|
@@ -923,7 +936,7 @@ function buildTimeline(rows) {
|
|
|
923
936
|
allDates.add(d);
|
|
924
937
|
}
|
|
925
938
|
const dates = [...allDates].sort();
|
|
926
|
-
const vendors = Object.keys(vendorDateMap)
|
|
939
|
+
const vendors = sortByTierOrder(Object.keys(vendorDateMap), tierOrder);
|
|
927
940
|
|
|
928
941
|
if (chartTimeline) chartTimeline.destroy();
|
|
929
942
|
const ctx = document.getElementById('chart-timeline').getContext('2d');
|
|
@@ -962,14 +975,14 @@ function buildTimeline(rows) {
|
|
|
962
975
|
}
|
|
963
976
|
|
|
964
977
|
// ── 供应商分布环形图 ──────────────────────────────────────
|
|
965
|
-
function buildVendorDist(rows) {
|
|
978
|
+
function buildVendorDist(rows, tierOrder) {
|
|
966
979
|
const vendorTotals = {};
|
|
967
980
|
for (const r of rows) {
|
|
968
981
|
const v = r.vendor;
|
|
969
982
|
if (!isValidLabel(v)) continue;
|
|
970
983
|
vendorTotals[v] = (vendorTotals[v] || 0) + (r.total_requests || 0);
|
|
971
984
|
}
|
|
972
|
-
const labels = Object.keys(vendorTotals)
|
|
985
|
+
const labels = sortByTierOrder(Object.keys(vendorTotals), tierOrder);
|
|
973
986
|
const data = labels.map(v => vendorTotals[v]);
|
|
974
987
|
|
|
975
988
|
if (chartVendorDist) chartVendorDist.destroy();
|
|
@@ -1027,7 +1040,7 @@ function buildVendorDist(rows) {
|
|
|
1027
1040
|
}
|
|
1028
1041
|
|
|
1029
1042
|
// ── Token 量趋势折线图(按 vendor)───────────────────────
|
|
1030
|
-
function buildTokenTimeline(rows) {
|
|
1043
|
+
function buildTokenTimeline(rows, tierOrder) {
|
|
1031
1044
|
const vendorDateMap = {};
|
|
1032
1045
|
const allDates = new Set();
|
|
1033
1046
|
for (const r of rows) {
|
|
@@ -1040,7 +1053,7 @@ function buildTokenTimeline(rows) {
|
|
|
1040
1053
|
allDates.add(d);
|
|
1041
1054
|
}
|
|
1042
1055
|
const dates = [...allDates].sort();
|
|
1043
|
-
const vendors = Object.keys(vendorDateMap)
|
|
1056
|
+
const vendors = sortByTierOrder(Object.keys(vendorDateMap), tierOrder);
|
|
1044
1057
|
|
|
1045
1058
|
if (chartTokenTimeline) chartTokenTimeline.destroy();
|
|
1046
1059
|
const ctx = document.getElementById('chart-token-timeline').getContext('2d');
|
|
@@ -1258,9 +1271,10 @@ async function refresh() {
|
|
|
1258
1271
|
updateChartTitles(days);
|
|
1259
1272
|
|
|
1260
1273
|
const rows = timeline.rows || [];
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1274
|
+
const tierOrder = (status.tiers || []).map(t => t.name);
|
|
1275
|
+
buildTimeline(rows, tierOrder);
|
|
1276
|
+
buildVendorDist(rows, tierOrder);
|
|
1277
|
+
buildTokenTimeline(rows, tierOrder);
|
|
1264
1278
|
buildModelTokenTimeline(rows);
|
|
1265
1279
|
|
|
1266
1280
|
document.getElementById('refresh-time').textContent = '上次刷新: ' + now();
|
|
@@ -51,6 +51,15 @@ wheels = [
|
|
|
51
51
|
{ url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" },
|
|
52
52
|
]
|
|
53
53
|
|
|
54
|
+
[[package]]
|
|
55
|
+
name = "cfgv"
|
|
56
|
+
version = "3.5.0"
|
|
57
|
+
source = { registry = "https://pypi.org/simple" }
|
|
58
|
+
sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" }
|
|
59
|
+
wheels = [
|
|
60
|
+
{ url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" },
|
|
61
|
+
]
|
|
62
|
+
|
|
54
63
|
[[package]]
|
|
55
64
|
name = "click"
|
|
56
65
|
version = "8.3.1"
|
|
@@ -65,7 +74,7 @@ wheels = [
|
|
|
65
74
|
|
|
66
75
|
[[package]]
|
|
67
76
|
name = "coding-proxy"
|
|
68
|
-
version = "0.2.
|
|
77
|
+
version = "0.2.4a3"
|
|
69
78
|
source = { editable = "." }
|
|
70
79
|
dependencies = [
|
|
71
80
|
{ name = "aiosqlite" },
|
|
@@ -80,6 +89,7 @@ dependencies = [
|
|
|
80
89
|
|
|
81
90
|
[package.dev-dependencies]
|
|
82
91
|
dev = [
|
|
92
|
+
{ name = "pre-commit" },
|
|
83
93
|
{ name = "pytest" },
|
|
84
94
|
{ name = "pytest-asyncio" },
|
|
85
95
|
{ name = "pytest-cov" },
|
|
@@ -100,6 +110,7 @@ requires-dist = [
|
|
|
100
110
|
|
|
101
111
|
[package.metadata.requires-dev]
|
|
102
112
|
dev = [
|
|
113
|
+
{ name = "pre-commit", specifier = ">=4.0" },
|
|
103
114
|
{ name = "pytest", specifier = ">=9.0" },
|
|
104
115
|
{ name = "pytest-asyncio", specifier = ">=1.3" },
|
|
105
116
|
{ name = "pytest-cov", specifier = ">=6.0" },
|
|
@@ -199,6 +210,15 @@ wheels = [
|
|
|
199
210
|
{ url = "https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl", hash = "sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61", size = 211346, upload-time = "2026-03-17T10:33:15.691Z" },
|
|
200
211
|
]
|
|
201
212
|
|
|
213
|
+
[[package]]
|
|
214
|
+
name = "distlib"
|
|
215
|
+
version = "0.4.0"
|
|
216
|
+
source = { registry = "https://pypi.org/simple" }
|
|
217
|
+
sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" }
|
|
218
|
+
wheels = [
|
|
219
|
+
{ url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" },
|
|
220
|
+
]
|
|
221
|
+
|
|
202
222
|
[[package]]
|
|
203
223
|
name = "fastapi"
|
|
204
224
|
version = "0.135.2"
|
|
@@ -215,6 +235,15 @@ wheels = [
|
|
|
215
235
|
{ url = "https://files.pythonhosted.org/packages/8f/ea/18f6d0457f9efb2fc6fa594857f92810cadb03024975726db6546b3d6fcf/fastapi-0.135.2-py3-none-any.whl", hash = "sha256:0af0447d541867e8db2a6a25c23a8c4bd80e2394ac5529bd87501bbb9e240ca5", size = 117407, upload-time = "2026-03-23T14:12:43.284Z" },
|
|
216
236
|
]
|
|
217
237
|
|
|
238
|
+
[[package]]
|
|
239
|
+
name = "filelock"
|
|
240
|
+
version = "3.28.0"
|
|
241
|
+
source = { registry = "https://pypi.org/simple" }
|
|
242
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d6/17/6e8890271880903e3538660a21d63a6c1fea969ac71d0d6b608b78727fa9/filelock-3.28.0.tar.gz", hash = "sha256:4ed1010aae813c4ee8d9c660e4792475ee60c4a0ba76073ceaf862bd317e3ca6", size = 56474, upload-time = "2026-04-14T22:54:33.625Z" }
|
|
243
|
+
wheels = [
|
|
244
|
+
{ url = "https://files.pythonhosted.org/packages/3b/21/2f728888c45033d34a417bfcd248ea2564c9e08ab1bfd301377cf05d5586/filelock-3.28.0-py3-none-any.whl", hash = "sha256:de9af6712788e7171df1b28b15eba2446c69721433fa427a9bee07b17820a9db", size = 39189, upload-time = "2026-04-14T22:54:32.037Z" },
|
|
245
|
+
]
|
|
246
|
+
|
|
218
247
|
[[package]]
|
|
219
248
|
name = "h11"
|
|
220
249
|
version = "0.16.0"
|
|
@@ -252,6 +281,15 @@ wheels = [
|
|
|
252
281
|
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
|
|
253
282
|
]
|
|
254
283
|
|
|
284
|
+
[[package]]
|
|
285
|
+
name = "identify"
|
|
286
|
+
version = "2.6.18"
|
|
287
|
+
source = { registry = "https://pypi.org/simple" }
|
|
288
|
+
sdist = { url = "https://files.pythonhosted.org/packages/46/c4/7fb4db12296cdb11893d61c92048fe617ee853f8523b9b296ac03b43757e/identify-2.6.18.tar.gz", hash = "sha256:873ac56a5e3fd63e7438a7ecbc4d91aca692eb3fefa4534db2b7913f3fc352fd", size = 99580, upload-time = "2026-03-15T18:39:50.319Z" }
|
|
289
|
+
wheels = [
|
|
290
|
+
{ url = "https://files.pythonhosted.org/packages/46/33/92ef41c6fad0233e41d3d84ba8e8ad18d1780f1e5d99b3c683e6d7f98b63/identify-2.6.18-py2.py3-none-any.whl", hash = "sha256:8db9d3c8ea9079db92cafb0ebf97abdc09d52e97f4dcf773a2e694048b7cd737", size = 99394, upload-time = "2026-03-15T18:39:48.915Z" },
|
|
291
|
+
]
|
|
292
|
+
|
|
255
293
|
[[package]]
|
|
256
294
|
name = "idna"
|
|
257
295
|
version = "3.11"
|
|
@@ -291,6 +329,15 @@ wheels = [
|
|
|
291
329
|
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
|
|
292
330
|
]
|
|
293
331
|
|
|
332
|
+
[[package]]
|
|
333
|
+
name = "nodeenv"
|
|
334
|
+
version = "1.10.0"
|
|
335
|
+
source = { registry = "https://pypi.org/simple" }
|
|
336
|
+
sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" }
|
|
337
|
+
wheels = [
|
|
338
|
+
{ url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" },
|
|
339
|
+
]
|
|
340
|
+
|
|
294
341
|
[[package]]
|
|
295
342
|
name = "packaging"
|
|
296
343
|
version = "26.0"
|
|
@@ -300,6 +347,15 @@ wheels = [
|
|
|
300
347
|
{ url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" },
|
|
301
348
|
]
|
|
302
349
|
|
|
350
|
+
[[package]]
|
|
351
|
+
name = "platformdirs"
|
|
352
|
+
version = "4.9.6"
|
|
353
|
+
source = { registry = "https://pypi.org/simple" }
|
|
354
|
+
sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" }
|
|
355
|
+
wheels = [
|
|
356
|
+
{ url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" },
|
|
357
|
+
]
|
|
358
|
+
|
|
303
359
|
[[package]]
|
|
304
360
|
name = "pluggy"
|
|
305
361
|
version = "1.6.0"
|
|
@@ -309,6 +365,22 @@ wheels = [
|
|
|
309
365
|
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
|
310
366
|
]
|
|
311
367
|
|
|
368
|
+
[[package]]
|
|
369
|
+
name = "pre-commit"
|
|
370
|
+
version = "4.5.1"
|
|
371
|
+
source = { registry = "https://pypi.org/simple" }
|
|
372
|
+
dependencies = [
|
|
373
|
+
{ name = "cfgv" },
|
|
374
|
+
{ name = "identify" },
|
|
375
|
+
{ name = "nodeenv" },
|
|
376
|
+
{ name = "pyyaml" },
|
|
377
|
+
{ name = "virtualenv" },
|
|
378
|
+
]
|
|
379
|
+
sdist = { url = "https://files.pythonhosted.org/packages/40/f1/6d86a29246dfd2e9b6237f0b5823717f60cad94d47ddc26afa916d21f525/pre_commit-4.5.1.tar.gz", hash = "sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61", size = 198232, upload-time = "2025-12-16T21:14:33.552Z" }
|
|
380
|
+
wheels = [
|
|
381
|
+
{ url = "https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl", hash = "sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77", size = 226437, upload-time = "2025-12-16T21:14:32.409Z" },
|
|
382
|
+
]
|
|
383
|
+
|
|
312
384
|
[[package]]
|
|
313
385
|
name = "pydantic"
|
|
314
386
|
version = "2.12.5"
|
|
@@ -447,6 +519,19 @@ wheels = [
|
|
|
447
519
|
{ url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" },
|
|
448
520
|
]
|
|
449
521
|
|
|
522
|
+
[[package]]
|
|
523
|
+
name = "python-discovery"
|
|
524
|
+
version = "1.2.2"
|
|
525
|
+
source = { registry = "https://pypi.org/simple" }
|
|
526
|
+
dependencies = [
|
|
527
|
+
{ name = "filelock" },
|
|
528
|
+
{ name = "platformdirs" },
|
|
529
|
+
]
|
|
530
|
+
sdist = { url = "https://files.pythonhosted.org/packages/de/ef/3bae0e537cfe91e8431efcba4434463d2c5a65f5a89edd47c6cf2f03c55f/python_discovery-1.2.2.tar.gz", hash = "sha256:876e9c57139eb757cb5878cbdd9ae5379e5d96266c99ef731119e04fffe533bb", size = 58872, upload-time = "2026-04-07T17:28:49.249Z" }
|
|
531
|
+
wheels = [
|
|
532
|
+
{ url = "https://files.pythonhosted.org/packages/d8/db/795879cc3ddfe338599bddea6388cc5100b088db0a4caf6e6c1af1c27e04/python_discovery-1.2.2-py3-none-any.whl", hash = "sha256:e1ae95d9af875e78f15e19aed0c6137ab1bb49c200f21f5061786490c9585c7a", size = 31894, upload-time = "2026-04-07T17:28:48.09Z" },
|
|
533
|
+
]
|
|
534
|
+
|
|
450
535
|
[[package]]
|
|
451
536
|
name = "pyyaml"
|
|
452
537
|
version = "6.0.3"
|
|
@@ -601,3 +686,18 @@ sdist = { url = "https://files.pythonhosted.org/packages/e3/ad/4a96c425be6fb67e0
|
|
|
601
686
|
wheels = [
|
|
602
687
|
{ url = "https://files.pythonhosted.org/packages/0a/89/f8827ccff89c1586027a105e5630ff6139a64da2515e24dafe860bd9ae4d/uvicorn-0.42.0-py3-none-any.whl", hash = "sha256:96c30f5c7abe6f74ae8900a70e92b85ad6613b745d4879eb9b16ccad15645359", size = 68830, upload-time = "2026-03-16T06:19:48.325Z" },
|
|
603
688
|
]
|
|
689
|
+
|
|
690
|
+
[[package]]
|
|
691
|
+
name = "virtualenv"
|
|
692
|
+
version = "21.2.4"
|
|
693
|
+
source = { registry = "https://pypi.org/simple" }
|
|
694
|
+
dependencies = [
|
|
695
|
+
{ name = "distlib" },
|
|
696
|
+
{ name = "filelock" },
|
|
697
|
+
{ name = "platformdirs" },
|
|
698
|
+
{ name = "python-discovery" },
|
|
699
|
+
]
|
|
700
|
+
sdist = { url = "https://files.pythonhosted.org/packages/0c/98/3a7e644e19cb26133488caff231be390579860bbbb3da35913c49a1d0a46/virtualenv-21.2.4.tar.gz", hash = "sha256:b294ef68192638004d72524ce7ef303e9d0cf5a44c95ce2e54a7500a6381cada", size = 5850742, upload-time = "2026-04-14T22:15:31.438Z" }
|
|
701
|
+
wheels = [
|
|
702
|
+
{ url = "https://files.pythonhosted.org/packages/27/8d/edd0bd910ff803c308ee9a6b7778621af0d10252219ad9f19ef4d4982a61/virtualenv-21.2.4-py3-none-any.whl", hash = "sha256:29d21e941795206138d0f22f4e45ff7050e5da6c6472299fb7103318763861ac", size = 5831232, upload-time = "2026-04-14T22:15:29.342Z" },
|
|
703
|
+
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/convert/anthropic_to_gemini.py
RENAMED
|
File without changes
|
{coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/convert/anthropic_to_openai.py
RENAMED
|
File without changes
|
{coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/convert/gemini_sse_adapter.py
RENAMED
|
File without changes
|
{coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/src/coding/proxy/convert/gemini_to_anthropic.py
RENAMED
|
File without changes
|
{coding_proxy-0.2.4a2 → coding_proxy-0.2.4a3}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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.2.4a2 → coding_proxy-0.2.4a3}/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.2.4a2 → coding_proxy-0.2.4a3}/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
|