ccproxy-api 0.1.1__tar.gz → 0.1.2__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 (273) hide show
  1. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/CHANGELOG.md +15 -0
  2. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/PKG-INFO +1 -1
  3. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/_version.py +2 -2
  4. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/dependencies.py +3 -0
  5. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/claude_sdk/converter.py +1 -1
  6. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/claude_sdk/options.py +23 -1
  7. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/commands/__init__.py +2 -1
  8. ccproxy_api-0.1.2/ccproxy/cli/commands/permission.py +128 -0
  9. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/commands/serve.py +22 -0
  10. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/main.py +1 -1
  11. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/options/claude_options.py +22 -0
  12. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/settings.py +2 -0
  13. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/models/responses.py +36 -0
  14. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/services/claude_sdk_service.py +5 -1
  15. ccproxy_api-0.1.2/docs/examples.md +384 -0
  16. ccproxy_api-0.1.2/docs/index.md +279 -0
  17. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/pyproject.toml +1 -0
  18. ccproxy_api-0.1.1/docs/examples.md +0 -114
  19. ccproxy_api-0.1.1/docs/index.md +0 -175
  20. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/.env.example +0 -0
  21. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/.github/workflows/backend.yml +0 -0
  22. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/.github/workflows/build.yml +0 -0
  23. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/.github/workflows/ci.yml +0 -0
  24. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/.github/workflows/docs.yml +0 -0
  25. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/.github/workflows/frontend.yml.disabled +0 -0
  26. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/.github/workflows/release.yml +0 -0
  27. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/.gitignore +0 -0
  28. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/.pre-commit-config.yaml +0 -0
  29. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/.python-version +0 -0
  30. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/CONTRIBUTING.md +0 -0
  31. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/CONVENTIONS.md +0 -0
  32. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/Dockerfile +0 -0
  33. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/LICENSE +0 -0
  34. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/Makefile +0 -0
  35. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/README.md +0 -0
  36. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/TESTING.md +0 -0
  37. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/__init__.py +0 -0
  38. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/__main__.py +0 -0
  39. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/adapters/__init__.py +0 -0
  40. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/adapters/base.py +0 -0
  41. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/adapters/openai/__init__.py +0 -0
  42. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/adapters/openai/adapter.py +0 -0
  43. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/adapters/openai/models.py +0 -0
  44. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/adapters/openai/streaming.py +0 -0
  45. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/__init__.py +0 -0
  46. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/app.py +0 -0
  47. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/middleware/__init__.py +0 -0
  48. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/middleware/auth.py +0 -0
  49. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/middleware/cors.py +0 -0
  50. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/middleware/errors.py +0 -0
  51. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/middleware/headers.py +0 -0
  52. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/middleware/logging.py +0 -0
  53. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/middleware/request_id.py +0 -0
  54. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/middleware/server_header.py +0 -0
  55. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/responses.py +0 -0
  56. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/routes/__init__.py +0 -0
  57. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/routes/claude.py +0 -0
  58. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/routes/health.py +0 -0
  59. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/routes/metrics.py +0 -0
  60. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/api/routes/proxy.py +0 -0
  61. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/__init__.py +0 -0
  62. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/bearer.py +0 -0
  63. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/conditional.py +0 -0
  64. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/credentials_adapter.py +0 -0
  65. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/dependencies.py +0 -0
  66. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/exceptions.py +0 -0
  67. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/manager.py +0 -0
  68. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/models.py +0 -0
  69. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/oauth/__init__.py +0 -0
  70. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/oauth/models.py +0 -0
  71. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/oauth/routes.py +0 -0
  72. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/oauth/storage.py +0 -0
  73. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/storage/__init__.py +0 -0
  74. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/storage/base.py +0 -0
  75. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/storage/json_file.py +0 -0
  76. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/auth/storage/keyring.py +0 -0
  77. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/claude_sdk/__init__.py +0 -0
  78. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/claude_sdk/client.py +0 -0
  79. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/__init__.py +0 -0
  80. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/commands/auth.py +0 -0
  81. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/commands/config/__init__.py +0 -0
  82. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/commands/config/commands.py +0 -0
  83. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/commands/config/schema_commands.py +0 -0
  84. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/docker/__init__.py +0 -0
  85. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/docker/adapter_factory.py +0 -0
  86. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/docker/params.py +0 -0
  87. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/helpers.py +0 -0
  88. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/options/__init__.py +0 -0
  89. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/options/core_options.py +0 -0
  90. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/options/security_options.py +0 -0
  91. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/cli/options/server_options.py +0 -0
  92. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/__init__.py +0 -0
  93. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/auth.py +0 -0
  94. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/claude.py +0 -0
  95. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/cors.py +0 -0
  96. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/discovery.py +0 -0
  97. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/docker_settings.py +0 -0
  98. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/loader.py +0 -0
  99. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/observability.py +0 -0
  100. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/pricing.py +0 -0
  101. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/reverse_proxy.py +0 -0
  102. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/scheduler.py +0 -0
  103. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/security.py +0 -0
  104. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/server.py +0 -0
  105. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/config/validators.py +0 -0
  106. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/__init__.py +0 -0
  107. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/async_utils.py +0 -0
  108. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/constants.py +0 -0
  109. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/errors.py +0 -0
  110. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/http.py +0 -0
  111. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/http_transformers.py +0 -0
  112. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/interfaces.py +0 -0
  113. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/logging.py +0 -0
  114. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/middleware.py +0 -0
  115. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/proxy.py +0 -0
  116. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/system.py +0 -0
  117. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/transformers.py +0 -0
  118. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/types.py +0 -0
  119. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/core/validators.py +0 -0
  120. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/docker/__init__.py +0 -0
  121. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/docker/adapter.py +0 -0
  122. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/docker/docker_path.py +0 -0
  123. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/docker/middleware.py +0 -0
  124. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/docker/models.py +0 -0
  125. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/docker/protocol.py +0 -0
  126. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/docker/stream_process.py +0 -0
  127. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/docker/validators.py +0 -0
  128. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/models/__init__.py +0 -0
  129. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/models/errors.py +0 -0
  130. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/models/messages.py +0 -0
  131. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/models/requests.py +0 -0
  132. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/models/types.py +0 -0
  133. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/observability/__init__.py +0 -0
  134. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/observability/access_logger.py +0 -0
  135. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/observability/context.py +0 -0
  136. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/observability/metrics.py +0 -0
  137. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/observability/pushgateway.py +0 -0
  138. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/observability/sse_events.py +0 -0
  139. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/observability/stats_printer.py +0 -0
  140. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/observability/storage/__init__.py +0 -0
  141. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/observability/storage/duckdb_simple.py +0 -0
  142. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/observability/storage/models.py +0 -0
  143. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/pricing/__init__.py +0 -0
  144. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/pricing/cache.py +0 -0
  145. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/pricing/loader.py +0 -0
  146. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/pricing/models.py +0 -0
  147. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/pricing/updater.py +0 -0
  148. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/scheduler/__init__.py +0 -0
  149. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/scheduler/core.py +0 -0
  150. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/scheduler/exceptions.py +0 -0
  151. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/scheduler/manager.py +0 -0
  152. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/scheduler/registry.py +0 -0
  153. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/scheduler/tasks.py +0 -0
  154. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/services/__init__.py +0 -0
  155. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/services/credentials/__init__.py +0 -0
  156. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/services/credentials/config.py +0 -0
  157. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/services/credentials/manager.py +0 -0
  158. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/services/credentials/oauth_client.py +0 -0
  159. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/services/proxy_service.py +0 -0
  160. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/static/.keep +0 -0
  161. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/testing/__init__.py +0 -0
  162. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/testing/config.py +0 -0
  163. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/testing/content_generation.py +0 -0
  164. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/testing/mock_responses.py +0 -0
  165. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/testing/response_handlers.py +0 -0
  166. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/testing/scenarios.py +0 -0
  167. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/utils/__init__.py +0 -0
  168. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/utils/cost_calculator.py +0 -0
  169. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/ccproxy/utils/streaming_metrics.py +0 -0
  170. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/data/metrics.db +0 -0
  171. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/devenv.lock +0 -0
  172. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/devenv.nix +0 -0
  173. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docker-compose.monitoring.yml +0 -0
  174. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docker-compose.yml +0 -0
  175. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/README.md +0 -0
  176. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/api-reference.md +0 -0
  177. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/assets/extra.css +0 -0
  178. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/assets/extra.js +0 -0
  179. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/contributing.md +0 -0
  180. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/development/debugging-with-proxy.md +0 -0
  181. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/gen_ref_pages.py +0 -0
  182. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/getting-started/configuration.md +0 -0
  183. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/getting-started/installation.md +0 -0
  184. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/getting-started/quickstart.md +0 -0
  185. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/metrics-api.md +0 -0
  186. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/observability.md +0 -0
  187. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/systemd-setup.md +0 -0
  188. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/user-guide/api-usage.md +0 -0
  189. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/user-guide/authentication.md +0 -0
  190. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/user-guide/claude-code-options.md +0 -0
  191. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/user-guide/claude-sdk-compatibility.md +0 -0
  192. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/user-guide/mcp-integration.md +0 -0
  193. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/user-guide/pool-configuration.md +0 -0
  194. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/docs/user-guide/understanding-pool-logs.md +0 -0
  195. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/README.md +0 -0
  196. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/README_chat_agent.md +0 -0
  197. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/ai_code_discussion_demo.py +0 -0
  198. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/anthropic_streaming_demo.py +0 -0
  199. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/anthropic_tools_demo.py +0 -0
  200. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/client.py +0 -0
  201. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/common_utils.py +0 -0
  202. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/console_utils.py +0 -0
  203. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/openai_anthropic_conversation_demo.py +0 -0
  204. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/openai_claude_code_options_example.sh +0 -0
  205. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/openai_json_object_example.sh +0 -0
  206. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/openai_json_schema_example.sh +0 -0
  207. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/openai_streaming_demo.py +0 -0
  208. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/openai_structured_response_demo.py +0 -0
  209. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/openai_thinking_demo.py +0 -0
  210. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/openai_tools_demo.py +0 -0
  211. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/project_code_access_demo.py +0 -0
  212. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/simple_thinking_demo.py +0 -0
  213. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/examples/textual_chat_agent.py +0 -0
  214. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/mkdocs.yml +0 -0
  215. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/monitoring/grafana/dashboards/ccproxy-dashboard.json +0 -0
  216. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/monitoring/grafana/provisioning/dashboards/dashboard.yml +0 -0
  217. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/monitoring/grafana/provisioning/datasources/victoria-metrics.yml +0 -0
  218. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/scripts/act-run.sh +0 -0
  219. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/scripts/benchmark_startup_node.py +0 -0
  220. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/scripts/build-docs.sh +0 -0
  221. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/scripts/entrypoint.sh +0 -0
  222. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/scripts/format_version.py +0 -0
  223. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/scripts/serve-docs.sh +0 -0
  224. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/scripts/setup-systemd.sh +0 -0
  225. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/scripts/setup.sh +0 -0
  226. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/scripts/traffic_generator.py +0 -0
  227. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/systemd/ccproxy.service.template +0 -0
  228. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/test_config/test-config.toml +0 -0
  229. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/__init__.py +0 -0
  230. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/conftest.py +0 -0
  231. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/factories/MIGRATION_GUIDE.md +0 -0
  232. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/factories/README.md +0 -0
  233. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/factories/__init__.py +0 -0
  234. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/factories/fastapi_factory.py +0 -0
  235. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/MIGRATION_GUIDE.md +0 -0
  236. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/README.md +0 -0
  237. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/auth/MIGRATION_GUIDE.md +0 -0
  238. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/auth/__init__.py +0 -0
  239. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/auth/example_usage.py +0 -0
  240. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/claude_sdk/__init__.py +0 -0
  241. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/claude_sdk/internal_mocks.py +0 -0
  242. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/claude_sdk/responses.py +0 -0
  243. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/credentials.json +0 -0
  244. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/external_apis/__init__.py +0 -0
  245. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/external_apis/anthropic_api.py +0 -0
  246. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/proxy_service/__init__.py +0 -0
  247. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/proxy_service/oauth_mocks.py +0 -0
  248. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/fixtures/responses.json +0 -0
  249. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_access_logger_integration.py +0 -0
  250. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_adapters.py +0 -0
  251. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_api.py +0 -0
  252. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_auth.py +0 -0
  253. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_cli_auth_commands.py +0 -0
  254. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_cli_config.py +0 -0
  255. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_cli_serve.py +0 -0
  256. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_docker.py +0 -0
  257. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_duckdb_lifecycle.py +0 -0
  258. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_duckdb_settings_integration.py +0 -0
  259. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_fastapi_factory.py +0 -0
  260. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_http_transformers.py +0 -0
  261. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_metrics_api.py +0 -0
  262. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_observability.py +0 -0
  263. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_pricing.py +0 -0
  264. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_pushgateway_error_handling.py +0 -0
  265. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_queue_duckdb_storage.py +0 -0
  266. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_reset_endpoint.py +0 -0
  267. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_scheduler.py +0 -0
  268. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_scheduler_tasks.py +0 -0
  269. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_sse_events.py +0 -0
  270. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_sse_stream_filtering.py +0 -0
  271. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_stats_printer.py +0 -0
  272. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/tests/test_streaming.py +0 -0
  273. {ccproxy_api-0.1.1 → ccproxy_api-0.1.2}/uv.lock +0 -0
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.2] - 2025-07-22
9
+
10
+ ### Added
11
+ - **Permission Mode Support**: Restored `--permission-mode` option supporting default, acceptEdits, and bypassPermissions modes
12
+ - **Custom Permission Tool**: Restored `--permission-prompt-tool-name` option to specify custom permission tool names
13
+ - **Permission Response Models**: Added `PermissionToolAllowResponse` and `PermissionToolDenyResponse` models with proper JSON serialization
14
+
15
+ ### Changed
16
+ - **Message Formatting**: Modified `MessageConverter.combine_text_parts()` to join text parts with newlines instead of spaces, preserving formatting in multi-line content
17
+ - **Settings Integration**: Enhanced OptionsHandler to apply default Claude options from settings before API parameters
18
+ - **Configuration**: Extended settings to persist permission_mode and permission_prompt_tool_name
19
+
20
+ ### Fixed
21
+ - **Claude SDK Options**: Integrated Settings dependency into ClaudeSDKService to support configuration-based options
22
+
8
23
  ## [0.1.1] - 2025-07-22
9
24
 
10
25
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ccproxy-api
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: API server that provides an Anthropic and OpenAI compatible interface over Claude Code, allowing to use your Claude OAuth account or over the API.
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.1.1'
21
- __version_tuple__ = version_tuple = (0, 1, 1)
20
+ __version__ = version = '0.1.2'
21
+ __version_tuple__ = version_tuple = (0, 1, 2)
@@ -22,11 +22,13 @@ SettingsDep = Annotated[Settings, Depends(get_settings)]
22
22
 
23
23
 
24
24
  def get_claude_service(
25
+ settings: SettingsDep,
25
26
  auth_manager: AuthManagerDep,
26
27
  ) -> ClaudeSDKService:
27
28
  """Get Claude SDK service instance.
28
29
 
29
30
  Args:
31
+ settings: Application settings dependency
30
32
  auth_manager: Authentication manager dependency
31
33
 
32
34
  Returns:
@@ -39,6 +41,7 @@ def get_claude_service(
39
41
  return ClaudeSDKService(
40
42
  auth_manager=auth_manager,
41
43
  metrics=metrics,
44
+ settings=settings,
42
45
  )
43
46
 
44
47
 
@@ -109,7 +109,7 @@ class MessageConverter:
109
109
  for block in contents:
110
110
  text_parts.append(MessageConverter.extract_text_from_content(block))
111
111
 
112
- return " ".join(text_parts)
112
+ return "\n".join(text_parts)
113
113
 
114
114
  @staticmethod
115
115
  def convert_to_anthropic_response(
@@ -2,6 +2,7 @@
2
2
 
3
3
  from typing import Any
4
4
 
5
+ from ccproxy.config.settings import Settings
5
6
  from ccproxy.core.async_utils import patched_typing
6
7
 
7
8
 
@@ -14,8 +15,17 @@ class OptionsHandler:
14
15
  Handles creation and management of Claude SDK options.
15
16
  """
16
17
 
17
- @staticmethod
18
+ def __init__(self, settings: Settings | None = None) -> None:
19
+ """
20
+ Initialize options handler.
21
+
22
+ Args:
23
+ settings: Application settings containing default Claude options
24
+ """
25
+ self.settings = settings
26
+
18
27
  def create_options(
28
+ self,
19
29
  model: str,
20
30
  temperature: float | None = None,
21
31
  max_tokens: int | None = None,
@@ -37,6 +47,18 @@ class OptionsHandler:
37
47
  """
38
48
  options = ClaudeCodeOptions(model=model)
39
49
 
50
+ # First apply settings from configuration if available
51
+ if self.settings and self.settings.claude.code_options:
52
+ code_opts = self.settings.claude.code_options
53
+
54
+ # Apply settings from configuration
55
+ for attr_name in dir(code_opts):
56
+ if not attr_name.startswith("_"):
57
+ value = getattr(code_opts, attr_name, None)
58
+ if value is not None and hasattr(options, attr_name):
59
+ setattr(options, attr_name, value)
60
+
61
+ # Then apply API parameters (these override settings)
40
62
  if temperature is not None:
41
63
  options.temperature = temperature # type: ignore[attr-defined]
42
64
 
@@ -2,7 +2,8 @@
2
2
 
3
3
  from .auth import app as auth_app
4
4
  from .config import app as config_app
5
+ from .permission import app as permission_app
5
6
  from .serve import api
6
7
 
7
8
 
8
- __all__ = ["api", "auth_app", "config_app"]
9
+ __all__ = ["api", "auth_app", "config_app", "permission_app"]
@@ -0,0 +1,128 @@
1
+ """MCP permission prompt tool for Claude Code SDK."""
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import Annotated, Any, Optional
6
+
7
+ import typer
8
+ from structlog import get_logger
9
+
10
+ from ccproxy.config.settings import config_manager
11
+ from ccproxy.models.responses import (
12
+ PermissionToolAllowResponse,
13
+ PermissionToolDenyResponse,
14
+ )
15
+
16
+
17
+ app = typer.Typer(
18
+ rich_markup_mode="rich",
19
+ add_completion=False,
20
+ no_args_is_help=False,
21
+ pretty_exceptions_enable=False,
22
+ )
23
+
24
+ logger = get_logger(__name__)
25
+
26
+
27
+ @app.command()
28
+ def permission_tool(
29
+ tool_name: Annotated[
30
+ str, typer.Argument(help="Name of the tool to check permissions for")
31
+ ],
32
+ tool_input: Annotated[str, typer.Argument(help="JSON string of the tool input")],
33
+ config: Annotated[
34
+ Path | None,
35
+ typer.Option(
36
+ "--config",
37
+ "-c",
38
+ help="Path to configuration file (TOML, JSON, or YAML)",
39
+ exists=True,
40
+ file_okay=True,
41
+ dir_okay=False,
42
+ readable=True,
43
+ ),
44
+ ] = None,
45
+ ) -> None:
46
+ """
47
+ MCP permission prompt tool for Claude Code SDK.
48
+
49
+ This tool is used by the Claude Code SDK to check permissions for tool calls.
50
+ It returns a JSON response indicating whether the tool call should be allowed or denied.
51
+
52
+ Response format:
53
+ - Allow: {"behavior": "allow", "updatedInput": {...}}
54
+ - Deny: {"behavior": "deny", "message": "reason"}
55
+
56
+ Examples:
57
+ ccproxy-perm "bash" '{"command": "ls -la"}'
58
+ ccproxy-perm "edit_file" '{"path": "/etc/passwd", "content": "..."}'
59
+ """
60
+
61
+ try:
62
+ # Parse the tool input JSON
63
+ try:
64
+ input_data = json.loads(tool_input)
65
+ except json.JSONDecodeError as e:
66
+ response = PermissionToolDenyResponse(message=f"Invalid JSON input: {e}")
67
+ print(response.model_dump_json(by_alias=True))
68
+ raise typer.Exit(1) from e
69
+
70
+ # Load settings to get permission configuration
71
+ settings = config_manager.load_settings(config_path=config)
72
+
73
+ # Basic permission checking logic
74
+ # This can be extended with more sophisticated rules
75
+
76
+ # Check for potentially dangerous commands
77
+ dangerous_patterns = [
78
+ "rm -rf",
79
+ "sudo",
80
+ "passwd",
81
+ "chmod 777",
82
+ "/etc/passwd",
83
+ "/etc/shadow",
84
+ "format",
85
+ "mkfs",
86
+ ]
87
+
88
+ # Convert input to string for pattern matching
89
+ input_str = json.dumps(input_data).lower()
90
+
91
+ # Check for dangerous patterns
92
+ for pattern in dangerous_patterns:
93
+ if pattern in input_str:
94
+ response = PermissionToolDenyResponse(
95
+ message=f"Tool call contains potentially dangerous pattern: {pattern}"
96
+ )
97
+ print(response.model_dump_json(by_alias=True))
98
+ return
99
+
100
+ # Check for specific tool restrictions
101
+ restricted_tools = {"exec", "system", "shell", "subprocess"}
102
+
103
+ if tool_name.lower() in restricted_tools:
104
+ response = PermissionToolDenyResponse(
105
+ message=f"Tool {tool_name} is restricted for security reasons"
106
+ )
107
+ print(response.model_dump_json(by_alias=True))
108
+ return
109
+
110
+ # Allow the tool call with original input
111
+ allow_response = PermissionToolAllowResponse(updated_input=input_data)
112
+ print(allow_response.model_dump_json(by_alias=True))
113
+
114
+ except Exception as e:
115
+ error_response = PermissionToolDenyResponse(
116
+ message=f"Error processing permission request: {e}"
117
+ )
118
+ print(error_response.model_dump_json(by_alias=True))
119
+ raise typer.Exit(1) from e
120
+
121
+
122
+ def main() -> None:
123
+ """Entry point for ccproxy-perm command."""
124
+ app()
125
+
126
+
127
+ if __name__ == "__main__":
128
+ main()
@@ -35,6 +35,7 @@ from ..options.claude_options import (
35
35
  validate_cwd,
36
36
  validate_max_thinking_tokens,
37
37
  validate_max_turns,
38
+ validate_permission_mode,
38
39
  )
39
40
  from ..options.security_options import SecurityOptions, validate_auth_token
40
41
  from ..options.server_options import (
@@ -393,6 +394,15 @@ def api(
393
394
  rich_help_panel="Claude Settings",
394
395
  ),
395
396
  ] = None,
397
+ permission_mode: Annotated[
398
+ str | None,
399
+ typer.Option(
400
+ "--permission-mode",
401
+ help="Permission mode: default, acceptEdits, or bypassPermissions",
402
+ callback=validate_permission_mode,
403
+ rich_help_panel="Claude Settings",
404
+ ),
405
+ ] = None,
396
406
  max_turns: Annotated[
397
407
  int | None,
398
408
  typer.Option(
@@ -411,6 +421,14 @@ def api(
411
421
  rich_help_panel="Claude Settings",
412
422
  ),
413
423
  ] = None,
424
+ permission_prompt_tool_name: Annotated[
425
+ str | None,
426
+ typer.Option(
427
+ "--permission-prompt-tool-name",
428
+ help="Permission prompt tool name",
429
+ rich_help_panel="Claude Settings",
430
+ ),
431
+ ] = None,
414
432
  # Core settings
415
433
  docker: Annotated[
416
434
  bool,
@@ -536,8 +554,10 @@ def api(
536
554
  disallowed_tools=disallowed_tools,
537
555
  claude_cli_path=claude_cli_path,
538
556
  append_system_prompt=append_system_prompt,
557
+ permission_mode=permission_mode,
539
558
  max_turns=max_turns,
540
559
  cwd=cwd,
560
+ permission_prompt_tool_name=permission_prompt_tool_name,
541
561
  )
542
562
 
543
563
  security_options = SecurityOptions(auth_token=auth_token)
@@ -558,7 +578,9 @@ def api(
558
578
  allowed_tools=claude_options.allowed_tools,
559
579
  disallowed_tools=claude_options.disallowed_tools,
560
580
  append_system_prompt=claude_options.append_system_prompt,
581
+ permission_mode=claude_options.permission_mode,
561
582
  max_turns=claude_options.max_turns,
583
+ permission_prompt_tool_name=claude_options.permission_prompt_tool_name,
562
584
  cwd=claude_options.cwd,
563
585
  )
564
586
 
@@ -28,7 +28,7 @@ from ccproxy.core.logging import setup_logging
28
28
 
29
29
  from .commands.auth import app as auth_app
30
30
  from .commands.config import app as config_app
31
- from .commands.serve import api, get_config_path_from_context
31
+ from .commands.serve import api
32
32
 
33
33
 
34
34
  def version_callback(value: bool) -> None:
@@ -32,6 +32,22 @@ def validate_max_turns(
32
32
  return value
33
33
 
34
34
 
35
+ def validate_permission_mode(
36
+ ctx: typer.Context, param: typer.CallbackParam, value: str | None
37
+ ) -> str | None:
38
+ """Validate permission mode."""
39
+ if value is None:
40
+ return None
41
+
42
+ valid_modes = {"default", "acceptEdits", "bypassPermissions"}
43
+ if value not in valid_modes:
44
+ raise typer.BadParameter(
45
+ f"Permission mode must be one of: {', '.join(valid_modes)}"
46
+ )
47
+
48
+ return value
49
+
50
+
35
51
  def validate_claude_cli_path(
36
52
  ctx: typer.Context, param: typer.CallbackParam, value: str | None
37
53
  ) -> str | None:
@@ -79,8 +95,10 @@ class ClaudeOptions:
79
95
  disallowed_tools: str | None = None,
80
96
  claude_cli_path: str | None = None,
81
97
  append_system_prompt: str | None = None,
98
+ permission_mode: str | None = None,
82
99
  max_turns: int | None = None,
83
100
  cwd: str | None = None,
101
+ permission_prompt_tool_name: str | None = None,
84
102
  ):
85
103
  """Initialize Claude options.
86
104
 
@@ -90,13 +108,17 @@ class ClaudeOptions:
90
108
  disallowed_tools: List of disallowed tools (comma-separated)
91
109
  claude_cli_path: Path to Claude CLI executable
92
110
  append_system_prompt: Additional system prompt to append
111
+ permission_mode: Permission mode
93
112
  max_turns: Maximum conversation turns
94
113
  cwd: Working directory path
114
+ permission_prompt_tool_name: Permission prompt tool name
95
115
  """
96
116
  self.max_thinking_tokens = max_thinking_tokens
97
117
  self.allowed_tools = allowed_tools
98
118
  self.disallowed_tools = disallowed_tools
99
119
  self.claude_cli_path = claude_cli_path
100
120
  self.append_system_prompt = append_system_prompt
121
+ self.permission_mode = permission_mode
101
122
  self.max_turns = max_turns
102
123
  self.cwd = cwd
124
+ self.permission_prompt_tool_name = permission_prompt_tool_name
@@ -467,9 +467,11 @@ class ConfigurationManager:
467
467
  claude_opts = {}
468
468
  for key in [
469
469
  "max_thinking_tokens",
470
+ "permission_mode",
470
471
  "cwd",
471
472
  "max_turns",
472
473
  "append_system_prompt",
474
+ "permission_prompt_tool_name",
473
475
  "continue_conversation",
474
476
  ]:
475
477
  if cli_args.get(key) is not None:
@@ -143,6 +143,42 @@ class APIError(BaseModel):
143
143
  )
144
144
 
145
145
 
146
+ class PermissionToolAllowResponse(BaseModel):
147
+ """Response model for allowed permission tool requests."""
148
+
149
+ behavior: Annotated[Literal["allow"], Field(description="Permission behavior")] = (
150
+ "allow"
151
+ )
152
+ updated_input: Annotated[
153
+ dict[str, Any],
154
+ Field(
155
+ description="Updated input parameters for the tool, or original input if unchanged",
156
+ alias="updatedInput",
157
+ ),
158
+ ]
159
+
160
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
161
+
162
+
163
+ class PermissionToolDenyResponse(BaseModel):
164
+ """Response model for denied permission tool requests."""
165
+
166
+ behavior: Annotated[Literal["deny"], Field(description="Permission behavior")] = (
167
+ "deny"
168
+ )
169
+ message: Annotated[
170
+ str,
171
+ Field(
172
+ description="Human-readable explanation of why the permission was denied"
173
+ ),
174
+ ]
175
+
176
+ model_config = ConfigDict(extra="forbid")
177
+
178
+
179
+ PermissionToolResponse = PermissionToolAllowResponse | PermissionToolDenyResponse
180
+
181
+
146
182
  class RateLimitError(APIError):
147
183
  """Rate limit error."""
148
184
 
@@ -18,6 +18,7 @@ from ccproxy.auth.manager import AuthManager
18
18
  from ccproxy.claude_sdk.client import ClaudeSDKClient
19
19
  from ccproxy.claude_sdk.converter import MessageConverter
20
20
  from ccproxy.claude_sdk.options import OptionsHandler
21
+ from ccproxy.config.settings import Settings
21
22
  from ccproxy.core.errors import (
22
23
  ClaudeProxyError,
23
24
  ServiceUnavailableError,
@@ -44,6 +45,7 @@ class ClaudeSDKService:
44
45
  sdk_client: ClaudeSDKClient | None = None,
45
46
  auth_manager: AuthManager | None = None,
46
47
  metrics: PrometheusMetrics | None = None,
48
+ settings: Settings | None = None,
47
49
  ) -> None:
48
50
  """
49
51
  Initialize Claude SDK service.
@@ -52,12 +54,14 @@ class ClaudeSDKService:
52
54
  sdk_client: Claude SDK client instance
53
55
  auth_manager: Authentication manager (optional)
54
56
  metrics: Prometheus metrics instance (optional)
57
+ settings: Application settings (optional)
55
58
  """
56
59
  self.sdk_client = sdk_client or ClaudeSDKClient()
57
60
  self.auth_manager = auth_manager
58
61
  self.metrics = metrics
62
+ self.settings = settings
59
63
  self.message_converter = MessageConverter()
60
- self.options_handler = OptionsHandler()
64
+ self.options_handler = OptionsHandler(settings=settings)
61
65
 
62
66
  async def create_completion(
63
67
  self,