ccproxy-api 0.1.0__py3-none-any.whl → 0.1.2__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.
- ccproxy/_version.py +2 -2
- ccproxy/api/app.py +70 -0
- ccproxy/api/dependencies.py +3 -0
- ccproxy/api/routes/claude.py +0 -6
- ccproxy/api/routes/proxy.py +13 -6
- ccproxy/auth/conditional.py +84 -0
- ccproxy/claude_sdk/converter.py +1 -1
- ccproxy/claude_sdk/options.py +23 -1
- ccproxy/cli/commands/__init__.py +2 -1
- ccproxy/cli/commands/auth.py +59 -43
- ccproxy/cli/commands/config/commands.py +2 -2
- ccproxy/cli/commands/permission.py +128 -0
- ccproxy/cli/commands/serve.py +322 -82
- ccproxy/cli/main.py +33 -111
- ccproxy/cli/options/claude_options.py +1 -93
- ccproxy/cli/options/core_options.py +1 -13
- ccproxy/cli/options/security_options.py +1 -9
- ccproxy/cli/options/server_options.py +1 -52
- ccproxy/config/auth.py +2 -2
- ccproxy/config/docker_settings.py +1 -1
- ccproxy/config/pricing.py +5 -6
- ccproxy/config/scheduler.py +5 -6
- ccproxy/core/async_utils.py +1 -1
- ccproxy/core/types.py +3 -9
- ccproxy/models/messages.py +1 -2
- ccproxy/pricing/models.py +5 -6
- ccproxy/services/claude_sdk_service.py +5 -1
- ccproxy/services/proxy_service.py +6 -7
- {ccproxy_api-0.1.0.dist-info → ccproxy_api-0.1.2.dist-info}/METADATA +62 -7
- {ccproxy_api-0.1.0.dist-info → ccproxy_api-0.1.2.dist-info}/RECORD +33 -31
- ccproxy_api-0.1.2.dist-info/entry_points.txt +4 -0
- ccproxy_api-0.1.0.dist-info/entry_points.txt +0 -2
- {ccproxy_api-0.1.0.dist-info → ccproxy_api-0.1.2.dist-info}/WHEEL +0 -0
- {ccproxy_api-0.1.0.dist-info → ccproxy_api-0.1.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -78,99 +78,7 @@ def validate_cwd(
|
|
|
78
78
|
return value
|
|
79
79
|
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
"""Max thinking tokens parameter."""
|
|
83
|
-
return typer.Option(
|
|
84
|
-
None,
|
|
85
|
-
"--max-thinking-tokens",
|
|
86
|
-
help="Maximum thinking tokens for Claude Code",
|
|
87
|
-
callback=validate_max_thinking_tokens,
|
|
88
|
-
rich_help_panel="Claude Settings",
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def allowed_tools_option() -> Any:
|
|
93
|
-
"""Allowed tools parameter."""
|
|
94
|
-
return typer.Option(
|
|
95
|
-
None,
|
|
96
|
-
"--allowed-tools",
|
|
97
|
-
help="List of allowed tools (comma-separated)",
|
|
98
|
-
rich_help_panel="Claude Settings",
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
def disallowed_tools_option() -> Any:
|
|
103
|
-
"""Disallowed tools parameter."""
|
|
104
|
-
return typer.Option(
|
|
105
|
-
None,
|
|
106
|
-
"--disallowed-tools",
|
|
107
|
-
help="List of disallowed tools (comma-separated)",
|
|
108
|
-
rich_help_panel="Claude Settings",
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
def claude_cli_path_option() -> Any:
|
|
113
|
-
"""Claude CLI path parameter."""
|
|
114
|
-
return typer.Option(
|
|
115
|
-
None,
|
|
116
|
-
"--claude-cli-path",
|
|
117
|
-
help="Path to Claude CLI executable",
|
|
118
|
-
callback=validate_claude_cli_path,
|
|
119
|
-
rich_help_panel="Claude Settings",
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def append_system_prompt_option() -> Any:
|
|
124
|
-
"""Append system prompt parameter."""
|
|
125
|
-
return typer.Option(
|
|
126
|
-
None,
|
|
127
|
-
"--append-system-prompt",
|
|
128
|
-
help="Additional system prompt to append",
|
|
129
|
-
rich_help_panel="Claude Settings",
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def permission_mode_option() -> Any:
|
|
134
|
-
"""Permission mode parameter."""
|
|
135
|
-
return typer.Option(
|
|
136
|
-
None,
|
|
137
|
-
"--permission-mode",
|
|
138
|
-
help="Permission mode: default, acceptEdits, or bypassPermissions",
|
|
139
|
-
callback=validate_permission_mode,
|
|
140
|
-
rich_help_panel="Claude Settings",
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def max_turns_option() -> Any:
|
|
145
|
-
"""Max turns parameter."""
|
|
146
|
-
return typer.Option(
|
|
147
|
-
None,
|
|
148
|
-
"--max-turns",
|
|
149
|
-
help="Maximum conversation turns",
|
|
150
|
-
callback=validate_max_turns,
|
|
151
|
-
rich_help_panel="Claude Settings",
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
def cwd_option() -> Any:
|
|
156
|
-
"""Working directory parameter."""
|
|
157
|
-
return typer.Option(
|
|
158
|
-
None,
|
|
159
|
-
"--cwd",
|
|
160
|
-
help="Working directory path",
|
|
161
|
-
callback=validate_cwd,
|
|
162
|
-
rich_help_panel="Claude Settings",
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def permission_prompt_tool_name_option() -> Any:
|
|
167
|
-
"""Permission prompt tool name parameter."""
|
|
168
|
-
return typer.Option(
|
|
169
|
-
None,
|
|
170
|
-
"--permission-prompt-tool-name",
|
|
171
|
-
help="Permission prompt tool name",
|
|
172
|
-
rich_help_panel="Claude Settings",
|
|
173
|
-
)
|
|
81
|
+
# Factory functions removed - use Annotated syntax directly in commands
|
|
174
82
|
|
|
175
83
|
|
|
176
84
|
class ClaudeOptions:
|
|
@@ -6,19 +6,7 @@ from typing import Any
|
|
|
6
6
|
import typer
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
"""Configuration file parameter."""
|
|
11
|
-
return typer.Option(
|
|
12
|
-
None,
|
|
13
|
-
"--config",
|
|
14
|
-
"-c",
|
|
15
|
-
help="Path to configuration file (TOML, JSON, or YAML)",
|
|
16
|
-
exists=True,
|
|
17
|
-
file_okay=True,
|
|
18
|
-
dir_okay=False,
|
|
19
|
-
readable=True,
|
|
20
|
-
rich_help_panel="Configuration",
|
|
21
|
-
)
|
|
9
|
+
# Factory functions removed - use Annotated syntax directly in commands
|
|
22
10
|
|
|
23
11
|
|
|
24
12
|
class CoreOptions:
|
|
@@ -18,15 +18,7 @@ def validate_auth_token(
|
|
|
18
18
|
return value
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
"""Auth token parameter."""
|
|
23
|
-
return typer.Option(
|
|
24
|
-
None,
|
|
25
|
-
"--auth-token",
|
|
26
|
-
help="Bearer token for API authentication",
|
|
27
|
-
callback=validate_auth_token,
|
|
28
|
-
rich_help_panel="Security Settings",
|
|
29
|
-
)
|
|
21
|
+
# Factory functions removed - use Annotated syntax directly in commands
|
|
30
22
|
|
|
31
23
|
|
|
32
24
|
class SecurityOptions:
|
|
@@ -32,58 +32,7 @@ def validate_log_level(
|
|
|
32
32
|
return value.upper()
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
"""Port parameter."""
|
|
37
|
-
return typer.Option(
|
|
38
|
-
None,
|
|
39
|
-
"--port",
|
|
40
|
-
"-p",
|
|
41
|
-
help="Port to run the server on",
|
|
42
|
-
callback=validate_port,
|
|
43
|
-
rich_help_panel="Server Settings",
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def host_option() -> Any:
|
|
48
|
-
"""Host parameter."""
|
|
49
|
-
return typer.Option(
|
|
50
|
-
None,
|
|
51
|
-
"--host",
|
|
52
|
-
"-h",
|
|
53
|
-
help="Host to bind the server to",
|
|
54
|
-
rich_help_panel="Server Settings",
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def reload_option() -> Any:
|
|
59
|
-
"""Reload parameter."""
|
|
60
|
-
return typer.Option(
|
|
61
|
-
None,
|
|
62
|
-
"--reload/--no-reload",
|
|
63
|
-
help="Enable auto-reload for development",
|
|
64
|
-
rich_help_panel="Server Settings",
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def log_level_option() -> Any:
|
|
69
|
-
"""Log level parameter."""
|
|
70
|
-
return typer.Option(
|
|
71
|
-
None,
|
|
72
|
-
"--log-level",
|
|
73
|
-
help="Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)",
|
|
74
|
-
callback=validate_log_level,
|
|
75
|
-
rich_help_panel="Server Settings",
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def log_file_option() -> Any:
|
|
80
|
-
"""Log file parameter."""
|
|
81
|
-
return typer.Option(
|
|
82
|
-
None,
|
|
83
|
-
"--log-file",
|
|
84
|
-
help="Path to JSON log file. If specified, logs will be written to this file in JSON format",
|
|
85
|
-
rich_help_panel="Server Settings",
|
|
86
|
-
)
|
|
35
|
+
# Factory functions removed - use Annotated syntax directly in commands
|
|
87
36
|
|
|
88
37
|
|
|
89
38
|
class ServerOptions:
|
ccproxy/config/auth.py
CHANGED
|
@@ -10,9 +10,9 @@ from pydantic import BaseModel, Field, field_validator
|
|
|
10
10
|
def _get_default_storage_paths() -> list[Path]:
|
|
11
11
|
"""Get default storage paths"""
|
|
12
12
|
return [
|
|
13
|
-
Path("~/.config/claude/.credentials.json"),
|
|
14
|
-
Path("~/.claude/.credentials.json"),
|
|
15
13
|
Path("~/.config/ccproxy/credentials.json"),
|
|
14
|
+
Path("~/.claude/.credentials.json"),
|
|
15
|
+
Path("~/.config/claude/.credentials.json"),
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
|
|
@@ -158,7 +158,7 @@ class DockerSettings(BaseModel):
|
|
|
158
158
|
"""Docker configuration settings for running Claude commands in containers."""
|
|
159
159
|
|
|
160
160
|
docker_image: str = Field(
|
|
161
|
-
default=f"ghcr.io/caddyglow/ccproxy:{format_version(__version__, level='docker')}",
|
|
161
|
+
default=f"ghcr.io/caddyglow/ccproxy-api:{format_version(__version__, level='docker')}",
|
|
162
162
|
description="Docker image to use for Claude commands",
|
|
163
163
|
)
|
|
164
164
|
|
ccproxy/config/pricing.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
5
|
from pydantic import Field, field_validator
|
|
6
|
-
from pydantic_settings import BaseSettings
|
|
6
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
7
7
|
|
|
8
8
|
from ccproxy.core.system import get_xdg_cache_home
|
|
9
9
|
|
|
@@ -81,8 +81,7 @@ class PricingSettings(BaseSettings):
|
|
|
81
81
|
raise ValueError("Source URL must start with http:// or https://")
|
|
82
82
|
return v
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
""
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
case_sensitive = False
|
|
84
|
+
model_config = SettingsConfigDict(
|
|
85
|
+
env_prefix="PRICING__",
|
|
86
|
+
case_sensitive=False,
|
|
87
|
+
)
|
ccproxy/config/scheduler.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Scheduler configuration settings."""
|
|
2
2
|
|
|
3
3
|
from pydantic import Field
|
|
4
|
-
from pydantic_settings import BaseSettings
|
|
4
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class SchedulerSettings(BaseSettings):
|
|
@@ -82,8 +82,7 @@ class SchedulerSettings(BaseSettings):
|
|
|
82
82
|
description="Interval in seconds between stats printing",
|
|
83
83
|
)
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
""
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
case_sensitive = False
|
|
85
|
+
model_config = SettingsConfigDict(
|
|
86
|
+
env_prefix="SCHEDULER__",
|
|
87
|
+
case_sensitive=False,
|
|
88
|
+
)
|
ccproxy/core/async_utils.py
CHANGED
|
@@ -319,7 +319,7 @@ def format_version(version: str, level: str) -> str:
|
|
|
319
319
|
# Docker-compatible version (no + characters)
|
|
320
320
|
if suffix:
|
|
321
321
|
return f"{base_version}-{suffix}"
|
|
322
|
-
return
|
|
322
|
+
return f"{major}.{minor}"
|
|
323
323
|
elif level == "npm":
|
|
324
324
|
# NPM-compatible version
|
|
325
325
|
if suffix:
|
ccproxy/core/types.py
CHANGED
|
@@ -4,7 +4,7 @@ from dataclasses import dataclass, field
|
|
|
4
4
|
from enum import Enum
|
|
5
5
|
from typing import Any, Optional, Union
|
|
6
6
|
|
|
7
|
-
from pydantic import BaseModel, Field
|
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class ProxyMethod(str, Enum):
|
|
@@ -106,10 +106,7 @@ class ProxyConfig(BaseModel):
|
|
|
106
106
|
default=10, description="Maximum number of redirects to follow"
|
|
107
107
|
)
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
"""Pydantic configuration."""
|
|
111
|
-
|
|
112
|
-
extra = "forbid"
|
|
109
|
+
model_config = ConfigDict(extra="forbid")
|
|
113
110
|
|
|
114
111
|
|
|
115
112
|
class MiddlewareConfig(BaseModel):
|
|
@@ -123,7 +120,4 @@ class MiddlewareConfig(BaseModel):
|
|
|
123
120
|
default_factory=dict, description="Additional middleware configuration"
|
|
124
121
|
)
|
|
125
122
|
|
|
126
|
-
|
|
127
|
-
"""Pydantic configuration."""
|
|
128
|
-
|
|
129
|
-
extra = "allow"
|
|
123
|
+
model_config = ConfigDict(extra="allow")
|
ccproxy/models/messages.py
CHANGED
|
@@ -34,8 +34,7 @@ class MetadataParams(BaseModel):
|
|
|
34
34
|
Field(description="External identifier for the user", max_length=256),
|
|
35
35
|
] = None
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
extra = "allow" # Allow additional fields in metadata
|
|
37
|
+
model_config = ConfigDict(extra="allow") # Allow additional fields in metadata
|
|
39
38
|
|
|
40
39
|
|
|
41
40
|
class ToolChoiceParams(BaseModel):
|
ccproxy/pricing/models.py
CHANGED
|
@@ -4,7 +4,7 @@ from collections.abc import Iterator
|
|
|
4
4
|
from decimal import Decimal
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
|
-
from pydantic import BaseModel, Field, RootModel, field_validator
|
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field, RootModel, field_validator
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class ModelPricing(BaseModel):
|
|
@@ -32,11 +32,10 @@ class ModelPricing(BaseModel):
|
|
|
32
32
|
return v
|
|
33
33
|
raise TypeError(f"Cannot convert {type(v)} to Decimal")
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
json_encoders = {Decimal: lambda v: float(v)}
|
|
35
|
+
model_config = ConfigDict(
|
|
36
|
+
arbitrary_types_allowed=True,
|
|
37
|
+
json_encoders={Decimal: lambda v: float(v)},
|
|
38
|
+
)
|
|
40
39
|
|
|
41
40
|
|
|
42
41
|
class PricingData(RootModel[dict[str, ModelPricing]]):
|
|
@@ -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,
|
|
@@ -446,7 +446,10 @@ class ProxyService:
|
|
|
446
446
|
async def _get_access_token(self) -> str:
|
|
447
447
|
"""Get access token for upstream authentication.
|
|
448
448
|
|
|
449
|
-
|
|
449
|
+
Uses OAuth credentials from Claude CLI for upstream authentication.
|
|
450
|
+
|
|
451
|
+
NOTE: The SECURITY__AUTH_TOKEN is only for authenticating incoming requests,
|
|
452
|
+
not for upstream authentication.
|
|
450
453
|
|
|
451
454
|
Returns:
|
|
452
455
|
Valid access token
|
|
@@ -454,12 +457,8 @@ class ProxyService:
|
|
|
454
457
|
Raises:
|
|
455
458
|
HTTPException: If no valid token is available
|
|
456
459
|
"""
|
|
457
|
-
#
|
|
458
|
-
|
|
459
|
-
logger.debug("using_configured_auth_token")
|
|
460
|
-
return self.settings.security.auth_token
|
|
461
|
-
|
|
462
|
-
# Fall back to OAuth credentials
|
|
460
|
+
# Always use OAuth credentials for upstream authentication
|
|
461
|
+
# The SECURITY__AUTH_TOKEN is only for client authentication, not upstream
|
|
463
462
|
try:
|
|
464
463
|
access_token = await self.credentials_manager.get_access_token()
|
|
465
464
|
if not access_token:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ccproxy-api
|
|
3
|
-
Version: 0.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
|
|
@@ -43,14 +43,26 @@ It includes a translation layer to support both Anthropic and OpenAI-compatible
|
|
|
43
43
|
# The official claude-code CLI is required for SDK mode
|
|
44
44
|
npm install -g @anthropic-ai/claude-code
|
|
45
45
|
|
|
46
|
-
#
|
|
47
|
-
|
|
46
|
+
# run it with uv
|
|
47
|
+
uvx ccproxy-api
|
|
48
|
+
|
|
49
|
+
# run it with pipx
|
|
50
|
+
pipx run ccproxy-api
|
|
51
|
+
|
|
52
|
+
# install with uv
|
|
53
|
+
uv tool install ccproxy-api
|
|
54
|
+
|
|
55
|
+
# Install ccproxy with pip
|
|
56
|
+
pipx install ccproxy-api
|
|
48
57
|
|
|
49
58
|
# Optional: Enable shell completion
|
|
50
59
|
eval "$(ccproxy --show-completion zsh)" # For zsh
|
|
51
60
|
eval "$(ccproxy --show-completion bash)" # For bash
|
|
52
61
|
```
|
|
53
62
|
|
|
63
|
+
|
|
64
|
+
For dev version replace `ccproxy-api` with `git+https://github.com/caddyglow/ccproxy-api.git@dev`
|
|
65
|
+
|
|
54
66
|
## Authentication
|
|
55
67
|
|
|
56
68
|
The proxy uses two different authentication mechanisms depending on the mode.
|
|
@@ -61,12 +73,23 @@ The proxy uses two different authentication mechanisms depending on the mode.
|
|
|
61
73
|
claude /login
|
|
62
74
|
```
|
|
63
75
|
|
|
76
|
+
It's also possible now to get a long live token to avoid renewing issues
|
|
77
|
+
using
|
|
78
|
+
```sh
|
|
79
|
+
```bash
|
|
80
|
+
claude setup-token`
|
|
81
|
+
|
|
64
82
|
2. **ccproxy (`api` mode):**
|
|
65
83
|
This mode uses its own OAuth2 flow to obtain credentials for direct API access.
|
|
66
84
|
```bash
|
|
67
85
|
ccproxy auth login
|
|
68
86
|
```
|
|
69
|
-
|
|
87
|
+
|
|
88
|
+
If you are already connected with Claude CLI the credentials should be found automatically
|
|
89
|
+
|
|
90
|
+
You can check the status of these credentials with `ccproxy auth validate` and `ccproxy auth info`.
|
|
91
|
+
|
|
92
|
+
Warning is show on start up if no credentials are setup.
|
|
70
93
|
|
|
71
94
|
## Usage
|
|
72
95
|
|
|
@@ -102,6 +125,38 @@ export ANTHROPIC_BASE_URL="http://localhost:8000/api"
|
|
|
102
125
|
export ANTHROPIC_API_KEY="dummy-key"
|
|
103
126
|
```
|
|
104
127
|
|
|
128
|
+
|
|
129
|
+
## Using with Aider
|
|
130
|
+
|
|
131
|
+
CCProxy works seamlessly with Aider and other AI coding assistants:
|
|
132
|
+
|
|
133
|
+
### Anthropic Mode
|
|
134
|
+
```bash
|
|
135
|
+
export ANTHROPIC_API_KEY=dummy
|
|
136
|
+
export ANTHROPIC_BASE_URL=http://127.0.0.1:8000/api
|
|
137
|
+
aider --model claude-sonnet-4-20250514
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### OpenAI Mode with Model Mapping
|
|
141
|
+
|
|
142
|
+
If your tool only supports OpenAI settings, ccproxy automatically maps OpenAI models to Claude:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
export OPENAI_API_KEY=dummy
|
|
146
|
+
export OPENAI_BASE_URL=http://127.0.0.1:8000/api/v1
|
|
147
|
+
aider --model o3-mini
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### API Mode (Direct Proxy)
|
|
151
|
+
|
|
152
|
+
For minimal interference and direct API access:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
export OPENAI_API_KEY=dummy
|
|
156
|
+
export OPENAI_BASE_URL=http://127.0.0.1:8000/api/v1
|
|
157
|
+
aider --model o3-mini
|
|
158
|
+
```
|
|
159
|
+
|
|
105
160
|
### `curl` Example
|
|
106
161
|
|
|
107
162
|
```bash
|
|
@@ -185,16 +240,16 @@ You can enable token authentication for the proxy. This supports multiple header
|
|
|
185
240
|
**1. Generate a Token:**
|
|
186
241
|
```bash
|
|
187
242
|
ccproxy generate-token
|
|
188
|
-
# Output:
|
|
243
|
+
# Output: SECURITY__AUTH_TOKEN=abc123xyz789...
|
|
189
244
|
```
|
|
190
245
|
|
|
191
246
|
**2. Configure the Token:**
|
|
192
247
|
```bash
|
|
193
248
|
# Set environment variable
|
|
194
|
-
export
|
|
249
|
+
export SECURITY__AUTH_TOKEN=abc123xyz789...
|
|
195
250
|
|
|
196
251
|
# Or add to .env file
|
|
197
|
-
echo "
|
|
252
|
+
echo "SECURITY__AUTH_TOKEN=abc123xyz789..." >> .env
|
|
198
253
|
```
|
|
199
254
|
|
|
200
255
|
**3. Use in Requests:**
|