coding-proxy 0.3.1a9__tar.gz → 0.3.1a10__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.
Files changed (182) hide show
  1. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/PKG-INFO +1 -1
  2. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/pyproject.toml +1 -1
  3. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/server/dashboard.py +99 -24
  4. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/uv.lock +1 -1
  5. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/.github/workflows/ci.yml +0 -0
  6. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/.github/workflows/coverage.yml +0 -0
  7. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/.github/workflows/release.yml +0 -0
  8. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/.gitignore +0 -0
  9. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/.pre-commit-config.yaml +0 -0
  10. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/AGENTS.md +0 -0
  11. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/CHANGELOG.md +0 -0
  12. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/CLAUDE.md +0 -0
  13. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/LICENSE +0 -0
  14. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/README.md +0 -0
  15. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/assets/dashboard-v0.2.4.png +0 -0
  16. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/arch/config-reference.md +0 -0
  17. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/arch/convert.md +0 -0
  18. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/arch/design-patterns.md +0 -0
  19. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/arch/routing.md +0 -0
  20. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/arch/testing.md +0 -0
  21. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/arch/vendors.md +0 -0
  22. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/ci-cd.md +0 -0
  23. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/framework.md +0 -0
  24. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/guide/api-reference.md +0 -0
  25. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/guide/cli-reference.md +0 -0
  26. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/guide/dashboard.md +0 -0
  27. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/guide/monitoring.md +0 -0
  28. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/guide/quickstart.md +0 -0
  29. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/guide/vendors.md +0 -0
  30. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/issue.md +0 -0
  31. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/user-guide.md +0 -0
  32. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/docs/zh-CN/README.md +0 -0
  33. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/__init__.py +0 -0
  34. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/__init__.py +0 -0
  35. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/__main__.py +0 -0
  36. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/auth/__init__.py +0 -0
  37. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/auth/providers/__init__.py +0 -0
  38. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/auth/providers/base.py +0 -0
  39. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/auth/providers/github.py +0 -0
  40. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/auth/providers/google.py +0 -0
  41. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/auth/runtime.py +0 -0
  42. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/auth/store.py +0 -0
  43. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/cli/__init__.py +0 -0
  44. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/cli/auth_commands.py +0 -0
  45. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/cli/banner.py +0 -0
  46. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/compat/__init__.py +0 -0
  47. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/compat/canonical.py +0 -0
  48. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/compat/session_store.py +0 -0
  49. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/config/__init__.py +0 -0
  50. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/config/auth_schema.py +0 -0
  51. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/config/config.default.yaml +0 -0
  52. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/config/loader.py +0 -0
  53. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/config/resiliency.py +0 -0
  54. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/config/routing.py +0 -0
  55. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/config/schema.py +0 -0
  56. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/config/server.py +0 -0
  57. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/config/session_policy.py +0 -0
  58. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/config/vendors.py +0 -0
  59. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/convert/__init__.py +0 -0
  60. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/convert/anthropic_to_gemini.py +0 -0
  61. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/convert/anthropic_to_openai.py +0 -0
  62. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/convert/gemini_sse_adapter.py +0 -0
  63. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/convert/gemini_to_anthropic.py +0 -0
  64. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/convert/openai_to_anthropic.py +0 -0
  65. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/convert/vendor_channels.py +0 -0
  66. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/logging/__init__.py +0 -0
  67. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/logging/db.py +0 -0
  68. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/logging/formatters.py +0 -0
  69. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/logging/stats.py +0 -0
  70. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/model/__init__.py +0 -0
  71. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/model/auth.py +0 -0
  72. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/model/compat.py +0 -0
  73. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/model/constants.py +0 -0
  74. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/model/pricing.py +0 -0
  75. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/model/token.py +0 -0
  76. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/model/vendor.py +0 -0
  77. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/native_api/__init__.py +0 -0
  78. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/native_api/config.py +0 -0
  79. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/native_api/extractors/__init__.py +0 -0
  80. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/native_api/extractors/anthropic.py +0 -0
  81. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/native_api/extractors/gemini.py +0 -0
  82. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/native_api/extractors/openai.py +0 -0
  83. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/native_api/handler.py +0 -0
  84. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/native_api/operation.py +0 -0
  85. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/native_api/routes.py +0 -0
  86. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/native_api/usage_registry.py +0 -0
  87. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/pricing.py +0 -0
  88. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/__init__.py +0 -0
  89. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/circuit_breaker.py +0 -0
  90. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/error_classifier.py +0 -0
  91. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/executor.py +0 -0
  92. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/model_mapper.py +0 -0
  93. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/quota_guard.py +0 -0
  94. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/rate_limit.py +0 -0
  95. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/retry.py +0 -0
  96. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/router.py +0 -0
  97. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/session_manager.py +0 -0
  98. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/session_policy.py +0 -0
  99. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/tier.py +0 -0
  100. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/usage_parser.py +0 -0
  101. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/routing/usage_recorder.py +0 -0
  102. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/server/__init__.py +0 -0
  103. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/server/app.py +0 -0
  104. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/server/factory.py +0 -0
  105. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/server/responses.py +0 -0
  106. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/server/routes.py +0 -0
  107. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/streaming/__init__.py +0 -0
  108. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/streaming/anthropic_compat.py +0 -0
  109. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/__init__.py +0 -0
  110. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/alibaba.py +0 -0
  111. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/anthropic.py +0 -0
  112. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/antigravity.py +0 -0
  113. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/base.py +0 -0
  114. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/copilot.py +0 -0
  115. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/copilot_models.py +0 -0
  116. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/copilot_token_manager.py +0 -0
  117. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/copilot_urls.py +0 -0
  118. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/doubao.py +0 -0
  119. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/kimi.py +0 -0
  120. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/minimax.py +0 -0
  121. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/mixins.py +0 -0
  122. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/native_anthropic.py +0 -0
  123. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/token_manager.py +0 -0
  124. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/xiaomi.py +0 -0
  125. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/src/coding/proxy/vendors/zhipu.py +0 -0
  126. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/__init__.py +0 -0
  127. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_antigravity.py +0 -0
  128. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_app_routes.py +0 -0
  129. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_auto_login.py +0 -0
  130. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_banner.py +0 -0
  131. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_circuit_breaker.py +0 -0
  132. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_cli_usage.py +0 -0
  133. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_compat.py +0 -0
  134. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_config_init.py +0 -0
  135. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_config_loader.py +0 -0
  136. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_convert_request.py +0 -0
  137. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_convert_response.py +0 -0
  138. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_convert_sse.py +0 -0
  139. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_copilot.py +0 -0
  140. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_copilot_convert_request.py +0 -0
  141. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_copilot_convert_response.py +0 -0
  142. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_copilot_models.py +0 -0
  143. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_copilot_urls.py +0 -0
  144. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_currency.py +0 -0
  145. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_error_classifier.py +0 -0
  146. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_logging_dual_write.py +0 -0
  147. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_mixins.py +0 -0
  148. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_model_auth.py +0 -0
  149. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_model_compat.py +0 -0
  150. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_model_constants.py +0 -0
  151. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_model_mapper.py +0 -0
  152. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_model_pricing.py +0 -0
  153. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_model_token.py +0 -0
  154. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_model_vendor.py +0 -0
  155. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_native_api_base_url_override.py +0 -0
  156. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_native_api_extractors.py +0 -0
  157. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_native_api_handler.py +0 -0
  158. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_native_api_operation.py +0 -0
  159. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_native_api_routes.py +0 -0
  160. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_native_vendors.py +0 -0
  161. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_parse_usage.py +0 -0
  162. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_parse_usage_gemini.py +0 -0
  163. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_pricing.py +0 -0
  164. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_quota_guard.py +0 -0
  165. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_rate_limit.py +0 -0
  166. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_router_chain.py +0 -0
  167. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_router_executor.py +0 -0
  168. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_runtime_reauth.py +0 -0
  169. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_schema.py +0 -0
  170. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_session_aware.py +0 -0
  171. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_streaming_anthropic_compat.py +0 -0
  172. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_tier.py +0 -0
  173. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_tiers_config.py +0 -0
  174. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_time_range.py +0 -0
  175. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_token_logger.py +0 -0
  176. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_token_logger_native_columns.py +0 -0
  177. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_token_manager.py +0 -0
  178. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_types.py +0 -0
  179. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_vendor_channels.py +0 -0
  180. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_vendor_streaming.py +0 -0
  181. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_vendors.py +0 -0
  182. {coding_proxy-0.3.1a9 → coding_proxy-0.3.1a10}/tests/test_zhipu.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coding-proxy
3
- Version: 0.3.1a9
3
+ Version: 0.3.1a10
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.3.1a9"
3
+ version = "0.3.1a10"
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"
@@ -397,8 +397,8 @@ _DASHBOARD_HTML = """<!DOCTYPE html>
397
397
  .empty-icon { font-size: 32px; margin-bottom: 8px; opacity: .5; }
398
398
  /* ── Sessions Panel ── */
399
399
  .sessions-card { grid-column: 1 / -1; animation-delay: .1s; }
400
- .session-table-wrap { overflow-x: auto; max-height: 480px; overflow-y: auto; }
401
- .session-table { width: 100%; border-collapse: collapse; font-size: 13px; }
400
+ .session-table-wrap { overflow: hidden; }
401
+ .session-table { width: 100%; border-collapse: collapse; font-size: 13px; table-layout: fixed; }
402
402
  .session-table th {
403
403
  position: sticky; top: 0; z-index: 1;
404
404
  background: var(--bg-card); padding: 10px 12px;
@@ -406,9 +406,11 @@ _DASHBOARD_HTML = """<!DOCTYPE html>
406
406
  color: var(--text-secondary); text-transform: uppercase; letter-spacing: .5px;
407
407
  border-bottom: 1px solid var(--border);
408
408
  }
409
- .session-table td { padding: 8px 12px; border-bottom: 1px solid var(--border-subtle); white-space: nowrap; }
409
+ .session-table td { padding: 8px 12px; border-bottom: 1px solid var(--border-subtle); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
410
410
  .session-table tr:hover td { background: var(--bg-card-hover); }
411
- .session-key { font-family: 'JetBrains Mono', monospace; font-size: 12px; color: var(--accent-blue); cursor: default; }
411
+ .session-table .session-key { font-family: 'JetBrains Mono', monospace; font-size: 12px; color: var(--accent-blue); cursor: default; white-space: normal; overflow: visible; }
412
+ .session-id { line-height: 1.4; word-break: break-all; }
413
+ .session-meta { font-size: 10px; color: var(--text-tertiary); line-height: 1.2; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
412
414
  .session-tag {
413
415
  display: inline-block; font-size: 11px; padding: 2px 7px;
414
416
  border-radius: 8px; margin: 1px 2px;
@@ -430,6 +432,21 @@ _DASHBOARD_HTML = """<!DOCTYPE html>
430
432
  .bind-select:hover { border-color: rgba(88,166,255,.4); color: var(--text-primary); }
431
433
  .bind-select:focus { border-color: rgba(88,166,255,.6); box-shadow: 0 0 0 2px rgba(88,166,255,.1); }
432
434
  .bind-select option { background: var(--bg-card); color: var(--text-primary); }
435
+ /* ── 分页 ── */
436
+ .session-pagination {
437
+ display: flex; align-items: center; justify-content: space-between;
438
+ padding: 10px 12px; border-top: 1px solid var(--border-subtle);
439
+ font-size: 12px; color: var(--text-secondary);
440
+ }
441
+ .page-btn {
442
+ padding: 4px 10px; border-radius: 6px;
443
+ background: rgba(48,54,61,.4); border: 1px solid rgba(255,255,255,.08);
444
+ color: var(--text-secondary); font-size: 12px; cursor: pointer;
445
+ transition: all .15s ease;
446
+ }
447
+ .page-btn:hover:not(:disabled) { background: var(--bg-card-hover); color: var(--text-primary); border-color: rgba(88,166,255,.3); }
448
+ .page-btn:disabled { opacity: .35; cursor: default; }
449
+ .page-info { font-family: 'JetBrains Mono', monospace; font-size: 12px; }
433
450
  /* ── 加载态 ── */
434
451
  .loading { opacity: .4; pointer-events: none; }
435
452
  /* ── 图表标签截断 ── */
@@ -623,9 +640,21 @@ _DASHBOARD_HTML = """<!DOCTYPE html>
623
640
  </div>
624
641
  <div class="session-table-wrap" id="sessions-table-wrap">
625
642
  <table class="session-table">
643
+ <colgroup>
644
+ <col style="width:22%">
645
+ <col style="width:8%">
646
+ <col style="width:7%">
647
+ <col style="width:7%">
648
+ <col style="width:14%">
649
+ <col style="width:12%">
650
+ <col style="width:8%">
651
+ <col style="width:8%">
652
+ <col style="width:8%">
653
+ <col style="width:6%">
654
+ </colgroup>
626
655
  <thead>
627
656
  <tr>
628
- <th>Session</th>
657
+ <th>Session ID</th>
629
658
  <th>Last Active</th>
630
659
  <th>Requests</th>
631
660
  <th>Tokens</th>
@@ -641,6 +670,14 @@ _DASHBOARD_HTML = """<!DOCTYPE html>
641
670
  <tr><td colspan="10" class="empty">Loading...</td></tr>
642
671
  </tbody>
643
672
  </table>
673
+ <div class="session-pagination" id="session-pagination">
674
+ <span class="page-info" id="page-info"></span>
675
+ <div style="display:flex;gap:6px;align-items:center">
676
+ <button class="page-btn" id="btn-prev" onclick="changePage(-1)">Prev</button>
677
+ <span class="page-info" id="page-num"></span>
678
+ <button class="page-btn" id="btn-next" onclick="changePage(1)">Next</button>
679
+ </div>
680
+ </div>
644
681
  </div>
645
682
  </div>
646
683
  </section>
@@ -1385,6 +1422,11 @@ function truncateKey(key, maxLen) {
1385
1422
  if (!key || key.length <= maxLen) return escapeHtml(key) || '–';
1386
1423
  return escapeHtml(key.slice(0, maxLen - 3)) + '…';
1387
1424
  }
1425
+ function parseSessionKey(raw) {
1426
+ try { var o = JSON.parse(raw); return { device_id: o.device_id||'', account_uuid: o.account_uuid||'', session_id: o.session_id||'' }; }
1427
+ catch(e) { return { device_id:'', account_uuid:'', session_id: raw || '' }; }
1428
+ }
1429
+ function shortId(s, n) { return s ? (s.length <= n ? s : s.slice(0, n) + '…') : ''; }
1388
1430
  function successBarHtml(pct) {
1389
1431
  if (pct == null) return '–';
1390
1432
  var p = Math.round(pct);
@@ -1415,10 +1457,17 @@ function formatVendorTags(vendors) {
1415
1457
  return '<span class="session-tag">' + formatVendorLabel(v.trim()) + '</span>';
1416
1458
  }).join('');
1417
1459
  }
1460
+ // ── Sessions Pagination State ──
1461
+ var allSessions = [];
1462
+ var sessionPage = 0;
1463
+ var sessionPageSize = 30;
1464
+ var sessionBindMap = {};
1465
+ var sessionAvailableVendors = [];
1466
+
1418
1467
  async function updateSessions() {
1419
1468
  try {
1420
1469
  var results = await Promise.allSettled([
1421
- fetchJSON('/api/dashboard/sessions?hours=24&limit=20'),
1470
+ fetchJSON('/api/dashboard/sessions?hours=24&limit=200'),
1422
1471
  fetchJSON('/api/session-vendor'),
1423
1472
  fetchJSON('/api/status'),
1424
1473
  ]);
@@ -1426,24 +1475,41 @@ async function updateSessions() {
1426
1475
  var data = results[0].value;
1427
1476
  var bindData = results[1].status === 'fulfilled' ? results[1].value : {bindings: []};
1428
1477
  var statusData = results[2].status === 'fulfilled' ? results[2].value : {tiers: []};
1429
- var sessions = data.sessions || [];
1430
- var bindings = bindData.bindings || [];
1431
- var availableVendors = (statusData.tiers || []).map(function(t) { return t.name; });
1432
- var tbody = document.getElementById('sessions-tbody');
1478
+ allSessions = data.sessions || [];
1479
+ sessionBindMap = {};
1480
+ (bindData.bindings || []).forEach(function(b) { sessionBindMap[b.session_key] = b.vendors; });
1481
+ sessionAvailableVendors = (statusData.tiers || []).map(function(t) { return t.name; });
1433
1482
  var subtitle = document.getElementById('sessions-subtitle');
1434
1483
  if (subtitle) subtitle.textContent = 'Last ' + data.hours + 'h';
1435
- if (!sessions.length) {
1436
- tbody.innerHTML = '<tr><td colspan="10" class="empty"><div class="empty-icon">📭</div>No session data</td></tr>';
1437
- return;
1438
- }
1439
- // Build binding lookup: session_key → vendors list
1440
- var bindMap = {};
1441
- bindings.forEach(function(b) { bindMap[b.session_key] = b.vendors; });
1442
- tbody.innerHTML = sessions.map(function(s) {
1443
- var boundVendors = bindMap[s.session_key];
1444
- var selectHtml = buildBindSelect(s.session_key, boundVendors, availableVendors);
1484
+ sessionPage = 0;
1485
+ renderSessionPage();
1486
+ } catch (e) {
1487
+ console.error('Sessions refresh error:', e);
1488
+ }
1489
+ }
1490
+
1491
+ function renderSessionPage() {
1492
+ var total = allSessions.length;
1493
+ var totalPages = Math.max(1, Math.ceil(total / sessionPageSize));
1494
+ if (sessionPage >= totalPages) sessionPage = totalPages - 1;
1495
+ var start = sessionPage * sessionPageSize;
1496
+ var page = allSessions.slice(start, start + sessionPageSize);
1497
+ var tbody = document.getElementById('sessions-tbody');
1498
+
1499
+ if (!total) {
1500
+ tbody.innerHTML = '<tr><td colspan="10" class="empty"><div class="empty-icon">📭</div>No session data</td></tr>';
1501
+ } else {
1502
+ tbody.innerHTML = page.map(function(s) {
1503
+ var parsed = parseSessionKey(s.session_key);
1504
+ var boundVendors = sessionBindMap[s.session_key];
1505
+ var selectHtml = buildBindSelect(s.session_key, boundVendors, sessionAvailableVendors);
1445
1506
  return '<tr>' +
1446
- '<td class="session-key" title="' + escapeHtml(s.session_key) + '">' + truncateKey(s.session_key, 22) + '</td>' +
1507
+ '<td class="session-key">' +
1508
+ '<div class="session-id" title="' + escapeHtml(s.session_key) + '">' + escapeHtml(parsed.session_id || s.session_key) + '</div>' +
1509
+ '<div class="session-meta" title="device: ' + escapeHtml(parsed.device_id) + ' | account: ' + escapeHtml(parsed.account_uuid) + '">' +
1510
+ 'dev:' + escapeHtml(shortId(parsed.device_id, 8)) + ' · acct:' + escapeHtml(shortId(parsed.account_uuid, 8)) +
1511
+ '</div>' +
1512
+ '</td>' +
1447
1513
  '<td>' + relativeTime(s.last_active_ts) + '</td>' +
1448
1514
  '<td style="font-family:JetBrains Mono,monospace">' + fmtNum(s.total_requests) + '</td>' +
1449
1515
  '<td style="font-family:JetBrains Mono,monospace">' + fmtTokens(s.total_tokens) + '</td>' +
@@ -1455,9 +1521,18 @@ async function updateSessions() {
1455
1521
  '<td>' + formatCategories(s.client_categories) + '</td>' +
1456
1522
  '</tr>';
1457
1523
  }).join('');
1458
- } catch (e) {
1459
- console.error('Sessions refresh error:', e);
1460
1524
  }
1525
+
1526
+ document.getElementById('page-info').textContent = total + ' sessions';
1527
+ document.getElementById('page-num').textContent = (sessionPage + 1) + ' / ' + totalPages;
1528
+ document.getElementById('btn-prev').disabled = (sessionPage === 0);
1529
+ document.getElementById('btn-next').disabled = (sessionPage >= totalPages - 1);
1530
+ }
1531
+
1532
+ function changePage(delta) {
1533
+ var totalPages = Math.max(1, Math.ceil(allSessions.length / sessionPageSize));
1534
+ sessionPage = Math.max(0, Math.min(totalPages - 1, sessionPage + delta));
1535
+ renderSessionPage();
1461
1536
  }
1462
1537
 
1463
1538
  function buildBindSelect(sessionKey, boundVendors, availableVendors) {
@@ -1807,7 +1882,7 @@ def register_dashboard_routes(app: Any) -> None:
1807
1882
  media_type="application/json",
1808
1883
  )
1809
1884
  hours = max(1.0, min(hours, 168.0))
1810
- limit = max(1, min(limit, 100))
1885
+ limit = max(1, min(limit, 200))
1811
1886
  try:
1812
1887
  sessions = await token_logger.query_recent_sessions(
1813
1888
  limit=limit, hours=hours
@@ -74,7 +74,7 @@ wheels = [
74
74
 
75
75
  [[package]]
76
76
  name = "coding-proxy"
77
- version = "0.3.1a9"
77
+ version = "0.3.1a10"
78
78
  source = { editable = "." }
79
79
  dependencies = [
80
80
  { name = "aiosqlite" },
File without changes