ccproxy-api 0.1.3__py3-none-any.whl → 0.1.5__py3-none-any.whl

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 (54) hide show
  1. ccproxy/_version.py +2 -2
  2. ccproxy/adapters/openai/adapter.py +1 -1
  3. ccproxy/adapters/openai/streaming.py +1 -0
  4. ccproxy/api/app.py +134 -224
  5. ccproxy/api/dependencies.py +22 -2
  6. ccproxy/api/middleware/errors.py +27 -3
  7. ccproxy/api/middleware/logging.py +4 -0
  8. ccproxy/api/responses.py +6 -1
  9. ccproxy/api/routes/claude.py +222 -17
  10. ccproxy/api/routes/proxy.py +25 -6
  11. ccproxy/api/services/permission_service.py +2 -2
  12. ccproxy/claude_sdk/__init__.py +4 -8
  13. ccproxy/claude_sdk/client.py +661 -131
  14. ccproxy/claude_sdk/exceptions.py +16 -0
  15. ccproxy/claude_sdk/manager.py +219 -0
  16. ccproxy/claude_sdk/message_queue.py +342 -0
  17. ccproxy/claude_sdk/options.py +5 -0
  18. ccproxy/claude_sdk/session_client.py +546 -0
  19. ccproxy/claude_sdk/session_pool.py +550 -0
  20. ccproxy/claude_sdk/stream_handle.py +538 -0
  21. ccproxy/claude_sdk/stream_worker.py +392 -0
  22. ccproxy/claude_sdk/streaming.py +53 -11
  23. ccproxy/cli/commands/serve.py +96 -0
  24. ccproxy/cli/options/claude_options.py +47 -0
  25. ccproxy/config/__init__.py +0 -3
  26. ccproxy/config/claude.py +171 -23
  27. ccproxy/config/discovery.py +10 -1
  28. ccproxy/config/scheduler.py +4 -4
  29. ccproxy/config/settings.py +19 -1
  30. ccproxy/core/http_transformers.py +305 -73
  31. ccproxy/core/logging.py +108 -12
  32. ccproxy/core/transformers.py +5 -0
  33. ccproxy/models/claude_sdk.py +57 -0
  34. ccproxy/models/detection.py +126 -0
  35. ccproxy/observability/access_logger.py +72 -14
  36. ccproxy/observability/metrics.py +151 -0
  37. ccproxy/observability/storage/duckdb_simple.py +12 -0
  38. ccproxy/observability/storage/models.py +16 -0
  39. ccproxy/observability/streaming_response.py +107 -0
  40. ccproxy/scheduler/manager.py +31 -6
  41. ccproxy/scheduler/tasks.py +122 -0
  42. ccproxy/services/claude_detection_service.py +269 -0
  43. ccproxy/services/claude_sdk_service.py +334 -131
  44. ccproxy/services/proxy_service.py +91 -200
  45. ccproxy/utils/__init__.py +9 -1
  46. ccproxy/utils/disconnection_monitor.py +83 -0
  47. ccproxy/utils/id_generator.py +12 -0
  48. ccproxy/utils/startup_helpers.py +408 -0
  49. {ccproxy_api-0.1.3.dist-info → ccproxy_api-0.1.5.dist-info}/METADATA +29 -2
  50. {ccproxy_api-0.1.3.dist-info → ccproxy_api-0.1.5.dist-info}/RECORD +53 -41
  51. ccproxy/config/loader.py +0 -105
  52. {ccproxy_api-0.1.3.dist-info → ccproxy_api-0.1.5.dist-info}/WHEEL +0 -0
  53. {ccproxy_api-0.1.3.dist-info → ccproxy_api-0.1.5.dist-info}/entry_points.txt +0 -0
  54. {ccproxy_api-0.1.3.dist-info → ccproxy_api-0.1.5.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,408 @@
1
+ """Startup utility functions for application lifecycle management.
2
+
3
+ This module contains simple utility functions to extract and organize
4
+ the complex startup logic from the main lifespan function, following
5
+ the KISS principle and avoiding overengineering.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from datetime import UTC, datetime
11
+ from typing import TYPE_CHECKING
12
+
13
+ import structlog
14
+ from fastapi import FastAPI
15
+
16
+ from ccproxy.auth.credentials_adapter import CredentialsAuthManager
17
+ from ccproxy.auth.exceptions import CredentialsNotFoundError
18
+ from ccproxy.observability import get_metrics
19
+
20
+ # Note: get_claude_cli_info is imported locally to avoid circular imports
21
+ from ccproxy.observability.storage.duckdb_simple import SimpleDuckDBStorage
22
+ from ccproxy.scheduler.errors import SchedulerError
23
+ from ccproxy.scheduler.manager import start_scheduler, stop_scheduler
24
+ from ccproxy.services.claude_detection_service import ClaudeDetectionService
25
+ from ccproxy.services.claude_sdk_service import ClaudeSDKService
26
+ from ccproxy.services.credentials.manager import CredentialsManager
27
+
28
+
29
+ # Note: get_permission_service is imported locally to avoid circular imports
30
+
31
+ if TYPE_CHECKING:
32
+ from ccproxy.config.settings import Settings
33
+
34
+ logger = structlog.get_logger(__name__)
35
+
36
+
37
+ async def validate_authentication_startup(app: FastAPI, settings: Settings) -> None:
38
+ """Validate authentication credentials at startup.
39
+
40
+ Args:
41
+ app: FastAPI application instance
42
+ settings: Application settings
43
+ """
44
+ try:
45
+ credentials_manager = CredentialsManager()
46
+ validation = await credentials_manager.validate()
47
+
48
+ if validation.valid and not validation.expired:
49
+ credentials = validation.credentials
50
+ oauth_token = credentials.claude_ai_oauth if credentials else None
51
+
52
+ if oauth_token and oauth_token.expires_at_datetime:
53
+ hours_until_expiry = int(
54
+ (
55
+ oauth_token.expires_at_datetime - datetime.now(UTC)
56
+ ).total_seconds()
57
+ / 3600
58
+ )
59
+ logger.debug(
60
+ "auth_token_valid",
61
+ expires_in_hours=hours_until_expiry,
62
+ subscription_type=oauth_token.subscription_type,
63
+ credentials_path=str(validation.path) if validation.path else None,
64
+ )
65
+ else:
66
+ logger.debug("auth_token_valid", credentials_path=str(validation.path))
67
+ elif validation.expired:
68
+ logger.warning(
69
+ "auth_token_expired",
70
+ message="Authentication token has expired. Please run 'ccproxy auth login' to refresh.",
71
+ credentials_path=str(validation.path) if validation.path else None,
72
+ )
73
+ else:
74
+ logger.warning(
75
+ "auth_token_invalid",
76
+ message="Authentication token is invalid. Please run 'ccproxy auth login'.",
77
+ credentials_path=str(validation.path) if validation.path else None,
78
+ )
79
+ except CredentialsNotFoundError:
80
+ logger.warning(
81
+ "auth_token_not_found",
82
+ message="No authentication credentials found. Please run 'ccproxy auth login' to authenticate.",
83
+ searched_paths=settings.auth.storage.storage_paths,
84
+ )
85
+ except Exception as e:
86
+ logger.error(
87
+ "auth_token_validation_error",
88
+ error=str(e),
89
+ message="Failed to validate authentication token. The server will continue without authentication.",
90
+ exc_info=True,
91
+ )
92
+
93
+
94
+ async def check_claude_cli_startup(app: FastAPI, settings: Settings) -> None:
95
+ """Check Claude CLI availability at startup.
96
+
97
+ Args:
98
+ app: FastAPI application instance
99
+ settings: Application settings
100
+ """
101
+ try:
102
+ from ccproxy.api.routes.health import get_claude_cli_info
103
+
104
+ claude_info = await get_claude_cli_info()
105
+
106
+ if claude_info.status == "available":
107
+ logger.info(
108
+ "claude_cli_available",
109
+ status=claude_info.status,
110
+ version=claude_info.version,
111
+ binary_path=claude_info.binary_path,
112
+ )
113
+ else:
114
+ logger.warning(
115
+ "claude_cli_unavailable",
116
+ status=claude_info.status,
117
+ error=claude_info.error,
118
+ binary_path=claude_info.binary_path,
119
+ message=f"Claude CLI status: {claude_info.status}",
120
+ )
121
+ except Exception as e:
122
+ logger.error(
123
+ "claude_cli_check_failed",
124
+ error=str(e),
125
+ message="Failed to check Claude CLI status during startup",
126
+ )
127
+
128
+
129
+ async def initialize_log_storage_startup(app: FastAPI, settings: Settings) -> None:
130
+ """Initialize log storage if needed and backend is DuckDB.
131
+
132
+ Args:
133
+ app: FastAPI application instance
134
+ settings: Application settings
135
+ """
136
+ if (
137
+ settings.observability.needs_storage_backend
138
+ and settings.observability.log_storage_backend == "duckdb"
139
+ ):
140
+ try:
141
+ storage = SimpleDuckDBStorage(
142
+ database_path=settings.observability.duckdb_path
143
+ )
144
+ await storage.initialize()
145
+ app.state.log_storage = storage
146
+ logger.debug(
147
+ "log_storage_initialized",
148
+ backend="duckdb",
149
+ path=str(settings.observability.duckdb_path),
150
+ collection_enabled=settings.observability.logs_collection_enabled,
151
+ )
152
+ except Exception as e:
153
+ logger.error("log_storage_initialization_failed", error=str(e))
154
+ # Continue without log storage (graceful degradation)
155
+
156
+
157
+ async def initialize_log_storage_shutdown(app: FastAPI) -> None:
158
+ """Close log storage if initialized.
159
+
160
+ Args:
161
+ app: FastAPI application instance
162
+ """
163
+ if hasattr(app.state, "log_storage") and app.state.log_storage:
164
+ try:
165
+ await app.state.log_storage.close()
166
+ logger.debug("log_storage_closed")
167
+ except Exception as e:
168
+ logger.error("log_storage_close_failed", error=str(e))
169
+
170
+
171
+ async def setup_scheduler_startup(app: FastAPI, settings: Settings) -> None:
172
+ """Start scheduler system and configure tasks.
173
+
174
+ Args:
175
+ app: FastAPI application instance
176
+ settings: Application settings
177
+ """
178
+ try:
179
+ scheduler = await start_scheduler(settings)
180
+ app.state.scheduler = scheduler
181
+ logger.debug("scheduler_initialized")
182
+
183
+ # Add session pool stats task if session manager is available
184
+ if (
185
+ scheduler
186
+ and hasattr(app.state, "session_manager")
187
+ and app.state.session_manager
188
+ ):
189
+ try:
190
+ # Add session pool stats task that runs every minute
191
+ await scheduler.add_task(
192
+ task_name="session_pool_stats",
193
+ task_type="pool_stats",
194
+ interval_seconds=60, # Every minute
195
+ enabled=True,
196
+ pool_manager=app.state.session_manager,
197
+ )
198
+ logger.debug("session_pool_stats_task_added", interval_seconds=60)
199
+ except Exception as e:
200
+ logger.error(
201
+ "session_pool_stats_task_add_failed",
202
+ error=str(e),
203
+ error_type=type(e).__name__,
204
+ )
205
+ except SchedulerError as e:
206
+ logger.error("scheduler_initialization_failed", error=str(e))
207
+ # Continue startup even if scheduler fails (graceful degradation)
208
+
209
+
210
+ async def setup_scheduler_shutdown(app: FastAPI) -> None:
211
+ """Stop scheduler system.
212
+
213
+ Args:
214
+ app: FastAPI application instance
215
+ """
216
+ try:
217
+ scheduler = getattr(app.state, "scheduler", None)
218
+ await stop_scheduler(scheduler)
219
+ logger.debug("scheduler_stopped_lifespan")
220
+ except SchedulerError as e:
221
+ logger.error("scheduler_stop_failed", error=str(e))
222
+
223
+
224
+ async def setup_session_manager_shutdown(app: FastAPI) -> None:
225
+ """Shutdown Claude SDK session manager if it was created.
226
+
227
+ Args:
228
+ app: FastAPI application instance
229
+ """
230
+ if hasattr(app.state, "session_manager") and app.state.session_manager:
231
+ try:
232
+ await app.state.session_manager.shutdown()
233
+ logger.debug("claude_sdk_session_manager_shutdown")
234
+ except Exception as e:
235
+ logger.error("claude_sdk_session_manager_shutdown_failed", error=str(e))
236
+
237
+
238
+ async def initialize_claude_detection_startup(app: FastAPI, settings: Settings) -> None:
239
+ """Initialize Claude detection service.
240
+
241
+ Args:
242
+ app: FastAPI application instance
243
+ settings: Application settings
244
+ """
245
+ try:
246
+ logger.debug("initializing_claude_detection")
247
+ detection_service = ClaudeDetectionService(settings)
248
+ claude_data = await detection_service.initialize_detection()
249
+ app.state.claude_detection_data = claude_data
250
+ app.state.claude_detection_service = detection_service
251
+ logger.debug(
252
+ "claude_detection_completed",
253
+ version=claude_data.claude_version,
254
+ cached_at=claude_data.cached_at.isoformat(),
255
+ )
256
+ except Exception as e:
257
+ logger.error("claude_detection_startup_failed", error=str(e))
258
+ # Continue startup with fallback - detection service will provide fallback data
259
+ detection_service = ClaudeDetectionService(settings)
260
+ app.state.claude_detection_data = detection_service._get_fallback_data()
261
+ app.state.claude_detection_service = detection_service
262
+
263
+
264
+ async def initialize_claude_sdk_startup(app: FastAPI, settings: Settings) -> None:
265
+ """Initialize ClaudeSDKService and store in app state.
266
+
267
+ Args:
268
+ app: FastAPI application instance
269
+ settings: Application settings
270
+ """
271
+ try:
272
+ # Create auth manager with settings
273
+ auth_manager = CredentialsAuthManager()
274
+
275
+ # Get global metrics instance
276
+ metrics = get_metrics()
277
+
278
+ # Check if session pool should be enabled from settings configuration
279
+ use_session_pool = settings.claude.sdk_session_pool.enabled
280
+
281
+ # Initialize session manager if session pool is enabled
282
+ session_manager = None
283
+ if use_session_pool:
284
+ from ccproxy.claude_sdk.manager import SessionManager
285
+
286
+ # Create SessionManager with dependency injection
287
+ session_manager = SessionManager(
288
+ settings=settings, metrics_factory=lambda: metrics
289
+ )
290
+
291
+ # Start the session manager (initializes session pool if enabled)
292
+ await session_manager.start()
293
+
294
+ # Create ClaudeSDKService instance
295
+ claude_service = ClaudeSDKService(
296
+ auth_manager=auth_manager,
297
+ metrics=metrics,
298
+ settings=settings,
299
+ session_manager=session_manager,
300
+ )
301
+
302
+ # Store in app state for reuse in dependencies
303
+ app.state.claude_service = claude_service
304
+ app.state.session_manager = (
305
+ session_manager # Store session_manager for shutdown
306
+ )
307
+ logger.debug("claude_sdk_service_initialized")
308
+ except Exception as e:
309
+ logger.error("claude_sdk_service_initialization_failed", error=str(e))
310
+ # Continue startup even if ClaudeSDKService fails (graceful degradation)
311
+
312
+
313
+ async def initialize_permission_service_startup(
314
+ app: FastAPI, settings: Settings
315
+ ) -> None:
316
+ """Initialize permission service (conditional on builtin_permissions).
317
+
318
+ Args:
319
+ app: FastAPI application instance
320
+ settings: Application settings
321
+ """
322
+ if settings.claude.builtin_permissions:
323
+ try:
324
+ from ccproxy.api.services.permission_service import get_permission_service
325
+
326
+ permission_service = get_permission_service()
327
+
328
+ # Only connect terminal handler if not using external handler
329
+ if settings.server.use_terminal_permission_handler:
330
+ # terminal_handler = TerminalPermissionHandler()
331
+
332
+ # TODO: Terminal handler should subscribe to events from the service
333
+ # instead of trying to set a handler directly
334
+ # The service uses an event-based architecture, not direct handlers
335
+
336
+ # logger.info(
337
+ # "permission_handler_configured",
338
+ # handler_type="terminal",
339
+ # message="Connected terminal handler to permission service",
340
+ # )
341
+ # app.state.terminal_handler = terminal_handler
342
+ pass
343
+ else:
344
+ logger.debug(
345
+ "permission_handler_configured",
346
+ handler_type="external_sse",
347
+ message="Terminal permission handler disabled - use 'ccproxy permission-handler connect' to handle permissions",
348
+ )
349
+ logger.warning(
350
+ "permission_handler_required",
351
+ message="Start external handler with: ccproxy permission-handler connect",
352
+ )
353
+
354
+ # Start the permission service
355
+ await permission_service.start()
356
+
357
+ # Store references in app state
358
+ app.state.permission_service = permission_service
359
+
360
+ logger.debug(
361
+ "permission_service_initialized",
362
+ timeout_seconds=permission_service._timeout_seconds,
363
+ terminal_handler_enabled=settings.server.use_terminal_permission_handler,
364
+ builtin_permissions_enabled=True,
365
+ )
366
+ except Exception as e:
367
+ logger.error("permission_service_initialization_failed", error=str(e))
368
+ # Continue without permission service (API will work but without prompts)
369
+ else:
370
+ logger.debug(
371
+ "permission_service_skipped",
372
+ builtin_permissions_enabled=False,
373
+ message="Built-in permission handling disabled - users can configure custom MCP servers and permission tools",
374
+ )
375
+
376
+
377
+ async def setup_permission_service_shutdown(app: FastAPI, settings: Settings) -> None:
378
+ """Stop permission service (if it was initialized).
379
+
380
+ Args:
381
+ app: FastAPI application instance
382
+ settings: Application settings
383
+ """
384
+ if (
385
+ hasattr(app.state, "permission_service")
386
+ and app.state.permission_service
387
+ and settings.claude.builtin_permissions
388
+ ):
389
+ try:
390
+ await app.state.permission_service.stop()
391
+ logger.debug("permission_service_stopped")
392
+ except Exception as e:
393
+ logger.error("permission_service_stop_failed", error=str(e))
394
+
395
+
396
+ async def flush_streaming_batches_shutdown(app: FastAPI) -> None:
397
+ """Flush any remaining streaming log batches.
398
+
399
+ Args:
400
+ app: FastAPI application instance
401
+ """
402
+ try:
403
+ from ccproxy.utils.simple_request_logger import flush_all_streaming_batches
404
+
405
+ await flush_all_streaming_batches()
406
+ logger.debug("streaming_batches_flushed")
407
+ except Exception as e:
408
+ logger.error("streaming_batches_flush_failed", error=str(e))
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ccproxy-api
3
- Version: 0.1.3
3
+ Version: 0.1.5
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
7
7
  Requires-Dist: aiofiles>=24.1.0
8
8
  Requires-Dist: aiosqlite>=0.21.0
9
- Requires-Dist: claude-code-sdk>=0.0.14
9
+ Requires-Dist: claude-code-sdk>=0.0.19
10
10
  Requires-Dist: duckdb-engine>=0.17.0
11
11
  Requires-Dist: duckdb>=1.1.0
12
12
  Requires-Dist: fastapi-mcp
@@ -182,6 +182,33 @@ CLAUDE__SDK_MESSAGE_MODE=formatted ccproxy
182
182
  CLAUDE__PRETTY_FORMAT=false ccproxy
183
183
  ```
184
184
 
185
+ ## Claude SDK Pool Mode
186
+
187
+ CCProxy supports connection pooling for Claude Code SDK clients to improve request performance by maintaining a pool of pre-initialized Claude instances.
188
+
189
+ ### Benefits
190
+ - **Reduced Latency**: Eliminates Claude Code startup overhead on each request
191
+ - **Improved Performance**: Reuses established connections for faster response times
192
+ - **Resource Efficiency**: Maintains a configurable pool size to balance performance and resource usage
193
+
194
+ ### Usage
195
+ Pool mode is disabled by default and can be enabled using the CLI flag:
196
+
197
+ ```bash
198
+ # Enable pool mode with default settings
199
+ ccproxy --sdk-enable-pool
200
+
201
+ # Configure pool size (default: 3)
202
+ ccproxy --sdk-enable-pool --sdk-pool-size 5
203
+ ```
204
+
205
+ ### Limitations
206
+ - **No Dynamic Options**: Pool instances cannot change Claude options (max_tokens, model, etc.) after initialization
207
+ - **Shared Configuration**: All requests using the pool must use identical Claude configuration
208
+ - **Memory Usage**: Each pool instance consumes additional memory
209
+
210
+ Pool mode is most effective for high-frequency requests with consistent configuration requirements.
211
+
185
212
  ## Using with Aider
186
213
 
187
214
  CCProxy works seamlessly with Aider and other AI coding assistants:
@@ -1,34 +1,34 @@
1
1
  ccproxy/__init__.py,sha256=VrtzUTUA8MwpYqFJAiwKLPxRdMRc7UOzFi2VB_1W9qw,62
2
2
  ccproxy/__main__.py,sha256=kcejcfzAaMnFiSxEiVtNl-_TwynpntkupRxqG5XR15s,116
3
- ccproxy/_version.py,sha256=NIzzV8ZM0W-CSLuEs1weG4zPrn_-8yr1AwwI1iuS6yo,511
3
+ ccproxy/_version.py,sha256=Y4jy4bEMmwl_qNPCmiMFnlQ2ofMoqyG37hp8uwI3m10,511
4
4
  ccproxy/adapters/__init__.py,sha256=CMr5MPIFigfazoXfhyD2eLqBrutzaSzBaEi8u2i9xJQ,206
5
5
  ccproxy/adapters/base.py,sha256=aufx8ho9LhF0kmTsCvw1a9K3lk5YyYymJV8h_wt5TpU,2191
6
6
  ccproxy/adapters/openai/__init__.py,sha256=CEOtyALpgaq6XT6upZKt0u_ilvnXIyH9K2hFXZJ-hOY,1063
7
- ccproxy/adapters/openai/adapter.py,sha256=qjo3bbNIQKlzxLt8r51gv_Se1ShuJREisFyboOcLs-E,37958
7
+ ccproxy/adapters/openai/adapter.py,sha256=8g9jBtEET_NEZKt27prw_Go9WMS_BJUoxyvhoMk74-g,37960
8
8
  ccproxy/adapters/openai/models.py,sha256=tg5NLFmTAOjLd2-gjqRQPU3IkL9ATftXv4ZugGw-rwc,11645
9
- ccproxy/adapters/openai/streaming.py,sha256=9EcqK5XebN7JRpB3MddR_VYeejkIKlMVFaYxMCeiOko,23218
9
+ ccproxy/adapters/openai/streaming.py,sha256=-nhKVPqCfAlV8PDi5-q3dVyslCpAu5DHh0BCrBfb9GU,23219
10
10
  ccproxy/api/__init__.py,sha256=_u4wpzvN4Y0qS4CTaGp8nD8ZopB0HeFxnIIw9GYjvvk,527
11
- ccproxy/api/app.py,sha256=sfIBoDhRw17a40qsQ6vlCgAtcJG0IOQcIMEsQCwruwg,16157
12
- ccproxy/api/dependencies.py,sha256=e4vgUaRULPlOWUPF5ZcS5UJNCXdBORklfIw7-FFX4IE,6162
13
- ccproxy/api/responses.py,sha256=eipdbHLQcrUjBYJd-Q5bEWUoiFlmPiDB0wdySFNubx4,2905
11
+ ccproxy/api/app.py,sha256=VgRC5kM8ztfhPhZ86MZre-7olQkmvtp6m4h6Ov3Bj9g,11853
12
+ ccproxy/api/dependencies.py,sha256=-oGT8XSXpyyxenUMXTs5Ap3wJRbda4mfDagDW01pkoE,6989
13
+ ccproxy/api/responses.py,sha256=97TUQ8KF_eKLBRWgAnziGZBjBfJtY13cjgM_o0k_lDc,3062
14
14
  ccproxy/api/middleware/__init__.py,sha256=S887PXY40Tnb0IFGei4Sgs7sygkcoT0IEOciOO7IDBc,284
15
15
  ccproxy/api/middleware/auth.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  ccproxy/api/middleware/cors.py,sha256=u8bnWmBXRG9J2etbQdNsQOTIQY6PFWawk2Oa0Ei1x3s,1666
17
- ccproxy/api/middleware/errors.py,sha256=WsFLkoe3TMD5hjmhKWWcMEJVX9NAWEudOcujciL22o4,21909
17
+ ccproxy/api/middleware/errors.py,sha256=YMfg5ovad7BMAiGK-66BCVacLveRX5ylJIRr1BFf3lE,22939
18
18
  ccproxy/api/middleware/headers.py,sha256=zGhF3F11TKeb3zY5qzblU3Sdwx1MSlqm2QSOqtVfpoY,1775
19
- ccproxy/api/middleware/logging.py,sha256=NDkIjIIQlAjr4m8nCXOe9na2Intc1Q_aYQZ2zWACeZw,7069
19
+ ccproxy/api/middleware/logging.py,sha256=fGHacI_vRtQs9LpKpCebVUpo7bSC6qy4hbqftmLe_Uk,7353
20
20
  ccproxy/api/middleware/request_content_logging.py,sha256=aIH1G9kjNr4-O5IFoisI9fO93rPePVWBQJM4wX1NCnY,10333
21
21
  ccproxy/api/middleware/request_id.py,sha256=OOZh63FYP_JY3olZNzgzVdPFZUJFT_KerZxYMxsPmyQ,2538
22
22
  ccproxy/api/middleware/server_header.py,sha256=9A3c7L12CFkQftMOZwB5JzqocGWymuV8AT_u_Y2s9RA,2329
23
23
  ccproxy/api/routes/__init__.py,sha256=xXoslArg915ZTmN2ITQ-i3iO7fu8ZkQAMrSgC41U5oA,664
24
- ccproxy/api/routes/claude.py,sha256=hA6SPyuZbkUq8JoSKnvceN1j211uGNuNdsye8dM_TXQ,6498
24
+ ccproxy/api/routes/claude.py,sha256=lERvCRFiHfhfQC6uYaUSRwplSRvUbn3of0tACYib4x0,15079
25
25
  ccproxy/api/routes/health.py,sha256=6eIoZ5oCBG8npDXqTnAU-rLWgO53b4E6SA0l12bAkjA,18932
26
26
  ccproxy/api/routes/mcp.py,sha256=-EVGid0uNOWeXP4w8F_hKUp1odkNnFXPHPmaOGC0UzQ,5389
27
27
  ccproxy/api/routes/metrics.py,sha256=MHG2nEGu3amrU6zJCuH2RktM8kg2EFxu4xNOFCzXMn4,40813
28
28
  ccproxy/api/routes/permissions.py,sha256=dvbWORmmAce7VZWlZPvchTCO9F6fauavmSbs8hUltKE,6231
29
- ccproxy/api/routes/proxy.py,sha256=sFOS62sEqlr_xkTr9fg-eSQMuUflnnDdkEvHj4Fx8es,7373
29
+ ccproxy/api/routes/proxy.py,sha256=flx4fyhYFsZvImLbwXy2qSEVVnlOA8xc0uR0T3-hUBI,8364
30
30
  ccproxy/api/services/__init__.py,sha256=_n4k1Ciao8BEbiMBSldq82nbs7N8qXu_1TcBwWLV8bE,167
31
- ccproxy/api/services/permission_service.py,sha256=x7YDTsxHKSbF8QoCEUwfemPIXXOQ4mJSjXBJSSu1pBg,12022
31
+ ccproxy/api/services/permission_service.py,sha256=mG6HGRQ5sly9rfA8ii601Rx5R-MunVAjOy3ky8Jqsoc,12024
32
32
  ccproxy/api/ui/__init__.py,sha256=oEgfWr8pgSO7uHYQBchJ2QspFrFsqTCO8mLPlfhHTfU,147
33
33
  ccproxy/api/ui/permission_handler_protocol.py,sha256=_jZAQ1KN5dK1Z28jqaW90Ggt8usVTR1P7pEKPWGN9SY,972
34
34
  ccproxy/api/ui/terminal_permission_handler.py,sha256=GuD_RyQCiuxJtFJI-SKsWPvw1brz1_IGz31YjLVQ9js,20195
@@ -48,19 +48,26 @@ ccproxy/auth/storage/__init__.py,sha256=5thfvXhc8HGJblQWMiG6ZPl594RpbTGdAgyAlpAe
48
48
  ccproxy/auth/storage/base.py,sha256=Gw20tabOKTwey6YrOm09Bxu-MYJuMIrQULLJT6RQ07E,1357
49
49
  ccproxy/auth/storage/json_file.py,sha256=iZBFCJ5EsZeFtlT7ORTXcEdAvMADIaDTXUPEBSjMcr0,5027
50
50
  ccproxy/auth/storage/keyring.py,sha256=qg4q-O-Y6D7y4HQfgg5g9bhUpuD9DAec9npWne0VLwg,5950
51
- ccproxy/claude_sdk/__init__.py,sha256=4r3KBqL5dXo6NI6hu8RjIRMm18OkOLCVJoKgDaAZQ8A,487
52
- ccproxy/claude_sdk/client.py,sha256=KxUJ80WmBNlV6HgD3GNSDf0fDOJpuZfXjKf-S3IVo4s,9397
51
+ ccproxy/claude_sdk/__init__.py,sha256=b794sieTPU1HEH_CmtqFK1be_p-bMUopi4v8gxRET9M,482
52
+ ccproxy/claude_sdk/client.py,sha256=YPgi4Uql8YW_fKFA6TAAmy5aDA-T0F5T_HJf7o9bbLY,29799
53
53
  ccproxy/claude_sdk/converter.py,sha256=GeU7AzbzK1ltaiUEr60mG4VYaSup95Z6OxVSG9Pu0PY,19035
54
- ccproxy/claude_sdk/options.py,sha256=ClgmCHPS0nljYK3OiZx72Sq09mjUQMHS1hnOrUW7Hbs,6821
54
+ ccproxy/claude_sdk/exceptions.py,sha256=LYUmy4K4TnrOixINScswc-Xg31gZJbbFimZgw9hIfy4,428
55
+ ccproxy/claude_sdk/manager.py,sha256=UuUhFNSF6UTaonmllHzwORwrXjcv1k_DwkHmsYJUhqY,7319
56
+ ccproxy/claude_sdk/message_queue.py,sha256=V2BU2Wdsdfb-TyfvOzYMszeEcdcBmVkiqB52IjS_oM8,11136
57
+ ccproxy/claude_sdk/options.py,sha256=uM1PdM4Uypb5HagvLGR0l4URbcxSQMcMd1pY1P2_uHM,7079
55
58
  ccproxy/claude_sdk/parser.py,sha256=1LcZOTkaKLSxZO_iVIvpZq44vUjApvMIA8Wlv61V6Jo,7193
56
- ccproxy/claude_sdk/streaming.py,sha256=n-lUoihuTcanl8E_feuQPF2-dTCfNNsf5nevLc3si-4,12581
59
+ ccproxy/claude_sdk/session_client.py,sha256=ipKvWyFx7nCI4n1VHbCsqbSjo5HdMC1P2lrX8fkTy8g,20052
60
+ ccproxy/claude_sdk/session_pool.py,sha256=BX0I4TdtgfVDEJozjmoSQTls24s-3KfFNTSSAgmA9LM,23993
61
+ ccproxy/claude_sdk/stream_handle.py,sha256=bu2WjWZmhRFyzhjH4UeYe9NmFeAonR9zBfyDirJJ1XE,20576
62
+ ccproxy/claude_sdk/stream_worker.py,sha256=CjyzNDVIFvoPLMXfmF6juJlxRYpiRRBM-IS3oQuEPpc,13429
63
+ ccproxy/claude_sdk/streaming.py,sha256=FjyLKS1fbBLf3hXtBhwyZzmSvWvOMxOZqrIxQDul_ik,14765
57
64
  ccproxy/cli/__init__.py,sha256=_vISKEqzAsAYrTZ-j9ScxTUtFZp3RVRbIvGpCcu--SU,262
58
65
  ccproxy/cli/helpers.py,sha256=LHGh5ZSywPUY61XVaSD5mx2eaIF4bi8hzbdMCJ0YRrQ,3814
59
66
  ccproxy/cli/main.py,sha256=QLdSbSm3PjvwluL6WO7kpe8S7qrgsw2VjMR84aZ2fsg,2452
60
67
  ccproxy/cli/commands/__init__.py,sha256=eWugiC37ualVtsTazu7GBCV7kZ12xkAnTUztjV7kVao,200
61
68
  ccproxy/cli/commands/auth.py,sha256=crpPeJ5Xs5I-xl5BC27HUJxlTHgcjL7GeMH0e31DXQc,20716
62
69
  ccproxy/cli/commands/permission_handler.py,sha256=rdPxXCZ3pK6a93eKED2XFNIwtnNcTW5XjM-X7edBcb0,18463
63
- ccproxy/cli/commands/serve.py,sha256=EZQCZiFWZixYA6_uY6Lthuktb50l-cx12lVn33S2rTU,29192
70
+ ccproxy/cli/commands/serve.py,sha256=1tV_QxSPEd_W14E-biYbpQzxuu_RZ4mzrEgBuVP7ogE,32917
64
71
  ccproxy/cli/commands/config/__init__.py,sha256=uX8VewtrMu5X8VAx5ym1slwNtlICDBEs3S1HfoFe5Qo,376
65
72
  ccproxy/cli/commands/config/commands.py,sha256=ukAr55NLFTg67f5czpjbuz_Ap_mwFIMIfMGHeXv_E5c,28917
66
73
  ccproxy/cli/commands/config/schema_commands.py,sha256=ZSuK_Q1bWp8WUOSbkuwKz_4TwrxkRsA6MOt_-y1eiVs,4218
@@ -68,37 +75,36 @@ ccproxy/cli/docker/__init__.py,sha256=4x9QO8SF9aloJFs4xrUEhGcSmoosIYmjcMTk4-GnHB
68
75
  ccproxy/cli/docker/adapter_factory.py,sha256=dbO_MGrrAsyF0DDZMKbrk4oMx2xAMZPihOAviF7D5zY,5022
69
76
  ccproxy/cli/docker/params.py,sha256=cAkszIkS6lztpXxRuHRGBseA0n6n-huwyydDRKUHjSM,7378
70
77
  ccproxy/cli/options/__init__.py,sha256=OiToWXDNOXnO-fuPz2H5qXYwp9ht7uB12-4wxqner1Q,340
71
- ccproxy/cli/options/claude_options.py,sha256=co3kyNxjH9brYcV7xRNU38Rd7BhqwQeRnXqRM4ZJKQQ,4222
78
+ ccproxy/cli/options/claude_options.py,sha256=zkH0YHf_KLmkgkpIQsO-0C9IKFri8wxqrgKk0c2UEB0,5885
72
79
  ccproxy/cli/options/core_options.py,sha256=80qVieUiUMYwjDKVeFfBDGjF1a8P1qB8Ppf-zSZ1eek,552
73
80
  ccproxy/cli/options/security_options.py,sha256=95TfENdeAsDMes7SH39mQJERgrqoL4jZEKvZL7NlzJQ,873
74
81
  ccproxy/cli/options/server_options.py,sha256=y37dtZGWuuYcDOn92zSzKwblnTgq65ZJJk2fWBA__s4,1935
75
- ccproxy/config/__init__.py,sha256=RVXg7sdADdX9-Z-67OYoNlQxby6UN9tThNtg_XzjZ1I,976
82
+ ccproxy/config/__init__.py,sha256=OGN54wL_XB-vP-g603NhqsSxYvKEXvBXVuEIxLV_tb4,891
76
83
  ccproxy/config/auth.py,sha256=CDc5qiexq4jH3Ve39tnL1Vn5c5bOUBWUdi7j4VLwewU,4653
77
- ccproxy/config/claude.py,sha256=2rOxpULXckJasTpeEUlUu0IAeVPAkH8XkEJRTZnmuS4,7139
84
+ ccproxy/config/claude.py,sha256=i0ybt8BPFLIdIn5257cNxVzJc22mO2pirVxEQT8rxWo,12468
78
85
  ccproxy/config/cors.py,sha256=eNxrNuPN7Ujh9_2fIWu6kmOIeYNuqn0NTuCsBYvctFM,2505
79
- ccproxy/config/discovery.py,sha256=ZwByXmmSq14ScRwXe1slHWvg5pLWFxXWxvGNFkZxRik,2255
86
+ ccproxy/config/discovery.py,sha256=lz5L0YcyVruZnXOxEXOD_4zg0k4W-woOGML9zwpmexQ,2487
80
87
  ccproxy/config/docker_settings.py,sha256=5D8eBSyWActgBGE7cIb4HObqlvE-7jxylmUBn5UxLM4,8390
81
- ccproxy/config/loader.py,sha256=kgeShuaeNjTHI7lX2VWSFlE4ugOJW9HAT-FJesKLegE,3100
82
88
  ccproxy/config/observability.py,sha256=5AwQFEFxJLUStGP5gjL_5i8Hk8KdrXKY7ocITYg8jZQ,5466
83
89
  ccproxy/config/pricing.py,sha256=RzsNQHYmv5P-BcRDV4GSkSIDImFIFEEC7roFu5jeocE,2613
84
90
  ccproxy/config/reverse_proxy.py,sha256=hep4ubV7-4ZgdO1_WqY56b5yrYyHCdQgYayUHKH3tfo,866
85
- ccproxy/config/scheduler.py,sha256=RNexGYY2yUg7rt1jgmMAfLg-1dT3YejTl2qNIsp8w2U,3060
91
+ ccproxy/config/scheduler.py,sha256=SFMkFwssu3SiBVrvi3Yh1vRtkOO3iEkt0ltsnaRP8-A,3198
86
92
  ccproxy/config/security.py,sha256=luNy1J6xXSKPRjAVTmF1mqSpN4h0I_1CllBJfaYbq0Q,493
87
93
  ccproxy/config/server.py,sha256=71Ih6huVn52demV6jNrixM8jqXVqfFrBpIvWIlmhlww,2527
88
- ccproxy/config/settings.py,sha256=jTo3nXMaePKCJqAV4Ejv9-q39t4fKxAUHsssxSMOf6I,17798
94
+ ccproxy/config/settings.py,sha256=akemhsi8afRmcGrydkRTpHmlykIERh9kvHMwBMTsspw,18477
89
95
  ccproxy/config/validators.py,sha256=EciRiEF7qGBcDp2Ms10VXyfAWXY_2uPPglvGh7EVLDs,5754
90
96
  ccproxy/core/__init__.py,sha256=ZreOdlUlCn7R5GlS3EdpvIj5fO9sySbQKnuR8o6vwXI,6400
91
97
  ccproxy/core/async_utils.py,sha256=slRQkIGctjZb6ZxridoJscFKVbyW2SYREieQjkpP_e8,19855
92
98
  ccproxy/core/constants.py,sha256=mmkcOfKNnvu3h5paZ6GL72ecAK4XdBI4tXlmgImGyzI,2735
93
99
  ccproxy/core/errors.py,sha256=gP1rh-k-KpE5OcVbFcdMdZSmDshvcoXdbVynIx864gc,8459
94
100
  ccproxy/core/http.py,sha256=pj3UM9TDL13_sU0ULGuA2wvVg58uxOCy-ib3zugjelo,9317
95
- ccproxy/core/http_transformers.py,sha256=jx4mcK6mAw9-Y4IkQGlW_S6L2sg1230y2pchJwztlas,16324
101
+ ccproxy/core/http_transformers.py,sha256=nIiKMbH9IpQeiaZC8XxxGR_fIYQPw7fI0vEbKBqR3J0,24993
96
102
  ccproxy/core/interfaces.py,sha256=zzucgNTvui7fGQ8vjLzCba-itJZh0Fs6GrDAZNJfGXo,6366
97
- ccproxy/core/logging.py,sha256=_KdCkabhJmPjapxenJcXNHsSybzPboSqASGem1bcKGY,6801
103
+ ccproxy/core/logging.py,sha256=xwWsFTqGLrGrjQzgV2MphrwHg4i8YDW591xlhUGl7l4,10171
98
104
  ccproxy/core/middleware.py,sha256=libv7wo-y9nni9hp7GCkYUKlIKihAwG0iHvjcv_RTs8,3355
99
105
  ccproxy/core/proxy.py,sha256=6lFqNiGFQFlh61q32imbUD-RJAK2RJHJNyYLwAmUYr0,4615
100
106
  ccproxy/core/system.py,sha256=91rMtlRtY4yxSsnPV5qZJaXHNFzvcrRZ1nQwS4CwG68,1019
101
- ccproxy/core/transformers.py,sha256=Ubv6Vcq_q1Myrn-mns06AkBRt4kiTid2Ww_cmv2DPVA,7699
107
+ ccproxy/core/transformers.py,sha256=BpOweWwpuUKEsLe32zqqTN0iNPRVXjyAoW1jBPSO0C8,7884
102
108
  ccproxy/core/types.py,sha256=kGRMzb6VI5KWa3aFKWgQ3gChqdHPrPoOyZ0QPT1m18E,3554
103
109
  ccproxy/core/validators.py,sha256=k2z71lz-zKhRdtx3tYgJllqFnEcQ-eivj1kf3aVej0s,7367
104
110
  ccproxy/docker/__init__.py,sha256=gO9FJepIWneXPANgsAJKx_VL9rt7pcX3hbRcwnSyzJk,1833
@@ -110,7 +116,8 @@ ccproxy/docker/protocol.py,sha256=uFJvKfTYhO8ROUo_tcMIuXYqhjK-eFIJV-U5Bora-jA,65
110
116
  ccproxy/docker/stream_process.py,sha256=XahXegGG6B-7RsZAb9J8OA7sz7xi8CmRzEI4vBJLwTI,9071
111
117
  ccproxy/docker/validators.py,sha256=OY-dkU88CLIeMBfv4P5QoVB7miQ8BD7kIgaMHxF7TsU,5764
112
118
  ccproxy/models/__init__.py,sha256=yaz9lC0roh0u7C33rHrGW46lrwbyyAa_evpAlA5BzYw,3548
113
- ccproxy/models/claude_sdk.py,sha256=iUACoZQS_29OjjG-A6FNslL_J_IKFtJdgabxs3FIhNk,13893
119
+ ccproxy/models/claude_sdk.py,sha256=T-6HpAPe2a17sd27HE7ttFENh2JxwrFrnGBwMwDwovs,15522
120
+ ccproxy/models/detection.py,sha256=-O1oIMK-8maBO_77ns-MlV82U3TZwh-8oYJd7XuE6dw,4576
114
121
  ccproxy/models/errors.py,sha256=B2rbL-17ZI9emDOca2A2fLOcH1-_77t_xqDmiPf6fgY,1329
115
122
  ccproxy/models/messages.py,sha256=halc96Yxx3R5Xa9F5Q53iFZs0MJMDRfAA0fSxaij51U,8013
116
123
  ccproxy/models/permissions.py,sha256=uhlzHc56rDzekjQMN8ITPCrh-0lamcgzTwx1OA2y67w,3612
@@ -118,15 +125,16 @@ ccproxy/models/requests.py,sha256=k4oeGbSCsbm3E5_3JT4h7hjrkSsgNgLIlb99BypSoHk,27
118
125
  ccproxy/models/responses.py,sha256=4rJNCbCoQtjiRzwoQLwK-sVJT2HFsZ2U6Vw63CZ1ztw,7820
119
126
  ccproxy/models/types.py,sha256=27MUg7pVGrK5oWzcrtG_IAoScEcrF20thO94bxZXQww,2729
120
127
  ccproxy/observability/__init__.py,sha256=5n9yQBbMLAQVAEJZD-2t4CKfI0Wx2aoDH7d2ynPM4bg,1503
121
- ccproxy/observability/access_logger.py,sha256=q6-5pdzZzW-jAZPIaiAeqoYXp8HrCw93F80OoM0XJZU,13095
128
+ ccproxy/observability/access_logger.py,sha256=h23GbxRYhPz26-z3rQfFSg12lqwssiXEkJRNmyBJspQ,15755
122
129
  ccproxy/observability/context.py,sha256=sfOdhgLY6LxLzOkJuzjqBsZV2e8ozAiYp79bhE2oqG4,14581
123
- ccproxy/observability/metrics.py,sha256=4D4cz9Ns8JjAX9_RHo7Z7bQA9xfeEZkUL7T9HMy4OTg,16150
130
+ ccproxy/observability/metrics.py,sha256=460SDpwQEpIpHPgg7vA6BhZPcYVhyQEpP20k_qZhUvI,21017
124
131
  ccproxy/observability/pushgateway.py,sha256=t7jGCP7dQirBjQyX-nz4S6MKKIHErU9yQMqgfCiP0BQ,12708
125
132
  ccproxy/observability/sse_events.py,sha256=CVumUxVlXV5tpqVozymaLW4pBTEM90KBYWS9jAJ6Dzk,10697
126
133
  ccproxy/observability/stats_printer.py,sha256=-QSiAMiurQlMzdMQcS0bNcswm5dDaIzTeS1bUqMeVQY,30110
134
+ ccproxy/observability/streaming_response.py,sha256=I9YsCdOMFR6gEkAoDkaGJO0kF1mdZHMrHYvbn45mzyo,4157
127
135
  ccproxy/observability/storage/__init__.py,sha256=iAnhODA2PD3PxheoRgJv5KFCTUK_QwxxFa2Ne230RTg,47
128
- ccproxy/observability/storage/duckdb_simple.py,sha256=lnENvs8p1OMaicsYLn8U5lPeCd0pOhjvNUN_HFqRekA,24789
129
- ccproxy/observability/storage/models.py,sha256=6q5yuVwHXZZfXdT9VDYOevgi8psLBMJnuCVHKBc4TTk,1423
136
+ ccproxy/observability/storage/duckdb_simple.py,sha256=pHcz8D7fJ0Qrhj4W0iN1TGTOIHxF_HKpyTHruTCTlUQ,25441
137
+ ccproxy/observability/storage/models.py,sha256=Xca4z6rCRB3HjCm50Wwge96MFAUoUKF9f6S_lGdBzHE,2307
130
138
  ccproxy/pricing/__init__.py,sha256=8EKUTusWT_URBO8_jzHQ2JWIv11JYZxiyk1WoA_slHE,450
131
139
  ccproxy/pricing/cache.py,sha256=j0X0VWICAV2WPWSY8TQTsRZ04fX0_tuegJRp9Lw7Dgk,6506
132
140
  ccproxy/pricing/loader.py,sha256=F7Ciu39xBdY6QqUbDNNM2FmX0zqFhrMCed_-YLkLdvI,8633
@@ -135,12 +143,13 @@ ccproxy/pricing/updater.py,sha256=OKbozb2SIe4yrwWVsQd5ryopZrJ06mIDP6y166-l_tg,10
135
143
  ccproxy/scheduler/__init__.py,sha256=qVe6NeKPn6NgMqEaG4_K4cYZBCpbFM7g6ptNPEzhi8c,1160
136
144
  ccproxy/scheduler/core.py,sha256=Lvhc3i2bfbEnX-2n8lgDBM7YG7TKEnZC3tf8KC5u67M,10344
137
145
  ccproxy/scheduler/errors.py,sha256=k7dcid0_te7IwwQaad-Jkj7MWFBgIOdgD_y_n5joio0,817
138
- ccproxy/scheduler/manager.py,sha256=-A6y9ANFHcQeGIlb9ABY4jGBxwPZbdxLPQDpLvKuQew,6879
146
+ ccproxy/scheduler/manager.py,sha256=C6nS7PB9_YHfWiqhXnsHeYsTZKeJ1ZZKSD53JOQfuBY,7811
139
147
  ccproxy/scheduler/registry.py,sha256=MaCuOEiJiYjlKS2Yqp3PxeWXpf8AqNPCQ_qeWbWtBCw,4058
140
- ccproxy/scheduler/tasks.py,sha256=JJoG9zfdI8jg53xy-9iUaFdM5pD1E1Z-j8S6OHXl0BI,20595
148
+ ccproxy/scheduler/tasks.py,sha256=ROIRQcrB3zntZDJ53pabK53a18bPaHYJI1TvS9wwRAI,24944
141
149
  ccproxy/services/__init__.py,sha256=ZvnelD15eFLlWHsucYXBFGNrdT7ncdP1KLnqzJNGOCs,251
142
- ccproxy/services/claude_sdk_service.py,sha256=2yRc1uN4fQQjIynJo2Ur0d7o1ds46mEH5GwKyAFupTQ,17748
143
- ccproxy/services/proxy_service.py,sha256=2QSQ92uag5j2NFxgcHVuxFVK3SlmiufqVWaWpyK5VaM,55650
150
+ ccproxy/services/claude_detection_service.py,sha256=aRg_aSucpi07DLzIKfDbLGYzjCLUXSpVScYcjLgSKbM,9941
151
+ ccproxy/services/claude_sdk_service.py,sha256=IuT4XP116fXzk20SUiYhKiKRoOxeeo7jlGzKVLH2NEo,25954
152
+ ccproxy/services/proxy_service.py,sha256=3rxemTu2KytC8UNy_rai7XUd2AP8yqYYHKlxH1Ker58,51397
144
153
  ccproxy/services/credentials/__init__.py,sha256=fkCWqxlUyGVA1mxGicn4cvdbYJQo09SG9NoGKzUun3s,1394
145
154
  ccproxy/services/credentials/config.py,sha256=97W3GqtxZlBv45oDHJ-plsHiSeFvNI-FTMZEw4CsPes,3221
146
155
  ccproxy/services/credentials/manager.py,sha256=AnRvl1_v-eSbAEcmHMcUMmo7UpvTnAHe9QO5caL1JMY,19905
@@ -152,15 +161,18 @@ ccproxy/testing/content_generation.py,sha256=in2F_W1RSnQYKXYCavMrYXPLBrqVn_Bogx8
152
161
  ccproxy/testing/mock_responses.py,sha256=GaegneKCVJSxoptLCUseriZ_wV_TfRnpD-vB0t60N3M,9200
153
162
  ccproxy/testing/response_handlers.py,sha256=TSfBHzHLw8d3Y95zJ8wYewU9f5Wh89bl7DRfa-49ze0,6311
154
163
  ccproxy/testing/scenarios.py,sha256=lVTkf1TbqPnWAfY2VbXez6dSFHsohuXerDmh37iC5VU,9200
155
- ccproxy/utils/__init__.py,sha256=MBEWNgdZh4Ev-LcltUhkMBboR1QHYNeri3oOy1KQeDo,213
164
+ ccproxy/utils/__init__.py,sha256=klTwpS5lbhi0Bg6QXIbX01-7oXaLoGjhHf1MKq_4aQQ,431
156
165
  ccproxy/utils/cost_calculator.py,sha256=mHquyA_1vnPVZ2smjdPwThCJtGu-rF9n8ZvIrAwTF78,7276
166
+ ccproxy/utils/disconnection_monitor.py,sha256=EOKJoTD_wDZ-l-yoOqx6Z488NZm2fFKW3KOwKlTELkE,3128
167
+ ccproxy/utils/id_generator.py,sha256=k6R_W40lJSPi_it4M99EVg9eRD138oC4bv_8Ua3X8ms,301
157
168
  ccproxy/utils/model_mapping.py,sha256=7TA3Jew_lg4IqMvoOvalDo1Vzozjb_Zq4749hPgPZGA,6602
158
169
  ccproxy/utils/models_provider.py,sha256=F0_nwNsx-gGhobdTnPQh9zfrhOfw7cBrW2RR09SYY3Q,4434
159
170
  ccproxy/utils/simple_request_logger.py,sha256=d54aXW_0P7zewGRzjwDu7QfJ-DGn4zJXu2R5hGXh-rU,8223
171
+ ccproxy/utils/startup_helpers.py,sha256=oR_7DfqXpPKW0Aa0QT-qZydsX7qgqfJK_89LE342YCQ,15253
160
172
  ccproxy/utils/streaming_metrics.py,sha256=JkvmWJ9s1fuKi7x1NoSoderUuT-mU6MQfbnN5GmziYE,7761
161
173
  ccproxy/utils/version_checker.py,sha256=D-6a5qV9sPTqkTZHucHZ-xCd8Wdy29lxnVgcvdBs10w,4839
162
- ccproxy_api-0.1.3.dist-info/METADATA,sha256=yBFMjRfCIDm5YKswyxjLNAGB9q04yTSQQNL_l25deno,12170
163
- ccproxy_api-0.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
164
- ccproxy_api-0.1.3.dist-info/entry_points.txt,sha256=XLke7uRmx6c1G3Ejnvm74x_eTKKtCgRRSk1dXIBFyg4,128
165
- ccproxy_api-0.1.3.dist-info/licenses/LICENSE,sha256=httxSCpTrEOkipisMeGXSrZhTB-4MRIorQU0hS1B6eQ,1066
166
- ccproxy_api-0.1.3.dist-info/RECORD,,
174
+ ccproxy_api-0.1.5.dist-info/METADATA,sha256=SbCiCzP1Ob76Dfr4VEfGUpnPEZxNQ72GxgoyKgcd5z4,13272
175
+ ccproxy_api-0.1.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
176
+ ccproxy_api-0.1.5.dist-info/entry_points.txt,sha256=XLke7uRmx6c1G3Ejnvm74x_eTKKtCgRRSk1dXIBFyg4,128
177
+ ccproxy_api-0.1.5.dist-info/licenses/LICENSE,sha256=httxSCpTrEOkipisMeGXSrZhTB-4MRIorQU0hS1B6eQ,1066
178
+ ccproxy_api-0.1.5.dist-info/RECORD,,