local-openai2anthropic 0.1.0__py3-none-any.whl → 0.3.6__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.
- local_openai2anthropic/__init__.py +1 -1
- local_openai2anthropic/__main__.py +7 -0
- local_openai2anthropic/config.py +132 -18
- local_openai2anthropic/converter.py +107 -250
- local_openai2anthropic/daemon.py +382 -0
- local_openai2anthropic/daemon_runner.py +116 -0
- local_openai2anthropic/main.py +256 -33
- local_openai2anthropic/openai_types.py +149 -0
- local_openai2anthropic/protocol.py +1 -1
- local_openai2anthropic/router.py +211 -520
- local_openai2anthropic/streaming/__init__.py +6 -0
- local_openai2anthropic/streaming/handler.py +444 -0
- local_openai2anthropic/tools/__init__.py +14 -0
- local_openai2anthropic/tools/handler.py +357 -0
- local_openai2anthropic/utils/__init__.py +18 -0
- local_openai2anthropic/utils/tokens.py +96 -0
- local_openai2anthropic-0.3.6.dist-info/METADATA +374 -0
- local_openai2anthropic-0.3.6.dist-info/RECORD +25 -0
- local_openai2anthropic-0.1.0.dist-info/METADATA +0 -689
- local_openai2anthropic-0.1.0.dist-info/RECORD +0 -15
- {local_openai2anthropic-0.1.0.dist-info → local_openai2anthropic-0.3.6.dist-info}/WHEEL +0 -0
- {local_openai2anthropic-0.1.0.dist-info → local_openai2anthropic-0.3.6.dist-info}/entry_points.txt +0 -0
- {local_openai2anthropic-0.1.0.dist-info → local_openai2anthropic-0.3.6.dist-info}/licenses/LICENSE +0 -0
local_openai2anthropic/config.py
CHANGED
|
@@ -3,44 +3,137 @@
|
|
|
3
3
|
Configuration settings for the proxy server.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
+
import sys
|
|
6
7
|
from functools import lru_cache
|
|
8
|
+
from pathlib import Path
|
|
7
9
|
from typing import Optional
|
|
8
10
|
|
|
9
|
-
from
|
|
11
|
+
from pydantic import BaseModel, ConfigDict
|
|
10
12
|
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
def get_config_dir() -> Path:
|
|
15
|
+
"""Get platform-specific config directory.
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
Path to the config directory (~/.oa2a)
|
|
19
|
+
"""
|
|
20
|
+
return Path.home() / ".oa2a"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_config_file() -> Path:
|
|
24
|
+
"""Get config file path.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
Path to the config file (~/.oa2a/config.toml)
|
|
28
|
+
"""
|
|
29
|
+
return get_config_dir() / "config.toml"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def create_default_config() -> bool:
|
|
33
|
+
"""Create default config file if not exists.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
True if a new config file was created, False if it already exists
|
|
37
|
+
"""
|
|
38
|
+
config_file = get_config_file()
|
|
39
|
+
if config_file.exists():
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
config_dir = get_config_dir()
|
|
43
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
|
44
|
+
|
|
45
|
+
# Set restrictive permissions (0o600) for the config directory on Unix-like systems
|
|
46
|
+
if sys.platform != "win32":
|
|
47
|
+
config_dir.chmod(0o700)
|
|
48
|
+
|
|
49
|
+
default_config = """# OA2A Configuration File
|
|
50
|
+
# Place this file at ~/.oa2a/config.toml
|
|
51
|
+
|
|
52
|
+
# OpenAI API Configuration
|
|
53
|
+
openai_api_key = ""
|
|
54
|
+
openai_base_url = "https://api.openai.com/v1"
|
|
55
|
+
openai_org_id = ""
|
|
56
|
+
openai_project_id = ""
|
|
57
|
+
|
|
58
|
+
# Server Configuration
|
|
59
|
+
host = "0.0.0.0"
|
|
60
|
+
port = 8080
|
|
61
|
+
request_timeout = 300.0
|
|
62
|
+
|
|
63
|
+
# API Key for authenticating requests to this server (optional)
|
|
64
|
+
api_key = ""
|
|
65
|
+
|
|
66
|
+
# CORS settings
|
|
67
|
+
cors_origins = ["*"]
|
|
68
|
+
cors_credentials = true
|
|
69
|
+
cors_methods = ["*"]
|
|
70
|
+
cors_headers = ["*"]
|
|
71
|
+
|
|
72
|
+
# Logging
|
|
73
|
+
log_level = "INFO"
|
|
74
|
+
log_dir = "" # Empty uses platform-specific default
|
|
75
|
+
|
|
76
|
+
# Tavily Web Search Configuration
|
|
77
|
+
tavily_api_key = ""
|
|
78
|
+
tavily_timeout = 30.0
|
|
79
|
+
tavily_max_results = 5
|
|
80
|
+
websearch_max_uses = 5
|
|
81
|
+
"""
|
|
82
|
+
config_file.write_text(default_config, encoding="utf-8")
|
|
83
|
+
|
|
84
|
+
# Set restrictive permissions (0o600) for the config file on Unix-like systems
|
|
85
|
+
if sys.platform != "win32":
|
|
86
|
+
config_file.chmod(0o600)
|
|
87
|
+
|
|
88
|
+
return True
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def load_config_from_file() -> dict:
|
|
92
|
+
"""Load configuration from TOML file.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
Dictionary containing configuration values, empty dict if file doesn't exist
|
|
96
|
+
"""
|
|
97
|
+
if sys.version_info >= (3, 11):
|
|
98
|
+
import tomllib
|
|
99
|
+
else:
|
|
100
|
+
import tomli as tomllib
|
|
101
|
+
|
|
102
|
+
config_file = get_config_file()
|
|
103
|
+
if not config_file.exists():
|
|
104
|
+
return {}
|
|
105
|
+
with open(config_file, "rb") as f:
|
|
106
|
+
return tomllib.load(f)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class Settings(BaseModel):
|
|
110
|
+
"""Application settings loaded from config file."""
|
|
111
|
+
|
|
112
|
+
model_config = ConfigDict(extra="ignore")
|
|
113
|
+
|
|
22
114
|
# OpenAI API Configuration
|
|
23
|
-
openai_api_key: str
|
|
115
|
+
openai_api_key: Optional[str] = None
|
|
24
116
|
openai_base_url: str = "https://api.openai.com/v1"
|
|
25
117
|
openai_org_id: Optional[str] = None
|
|
26
118
|
openai_project_id: Optional[str] = None
|
|
27
|
-
|
|
119
|
+
|
|
28
120
|
# Server Configuration
|
|
29
121
|
host: str = "0.0.0.0"
|
|
30
122
|
port: int = 8080
|
|
31
123
|
request_timeout: float = 300.0 # 5 minutes
|
|
32
|
-
|
|
124
|
+
|
|
33
125
|
# API Key for authenticating requests to this server (optional)
|
|
34
126
|
api_key: Optional[str] = None
|
|
35
|
-
|
|
127
|
+
|
|
36
128
|
# CORS settings
|
|
37
129
|
cors_origins: list[str] = ["*"]
|
|
38
130
|
cors_credentials: bool = True
|
|
39
131
|
cors_methods: list[str] = ["*"]
|
|
40
132
|
cors_headers: list[str] = ["*"]
|
|
41
|
-
|
|
133
|
+
|
|
42
134
|
# Logging
|
|
43
135
|
log_level: str = "INFO"
|
|
136
|
+
log_dir: str = "" # Empty means use platform-specific default
|
|
44
137
|
|
|
45
138
|
# Tavily Web Search Configuration
|
|
46
139
|
tavily_api_key: Optional[str] = None
|
|
@@ -60,8 +153,29 @@ class Settings(BaseSettings):
|
|
|
60
153
|
headers["OpenAI-Project"] = self.openai_project_id
|
|
61
154
|
return headers
|
|
62
155
|
|
|
156
|
+
@classmethod
|
|
157
|
+
def from_toml(cls) -> "Settings":
|
|
158
|
+
"""Load settings from TOML config file.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
Settings instance populated from config file
|
|
162
|
+
"""
|
|
163
|
+
config_data = load_config_from_file()
|
|
164
|
+
return cls(**config_data)
|
|
165
|
+
|
|
63
166
|
|
|
64
167
|
@lru_cache
|
|
65
168
|
def get_settings() -> Settings:
|
|
66
|
-
"""Get cached settings instance.
|
|
67
|
-
|
|
169
|
+
"""Get cached settings instance.
|
|
170
|
+
|
|
171
|
+
Creates default config file if it doesn't exist and notifies the user.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
Settings instance loaded from config file
|
|
175
|
+
"""
|
|
176
|
+
created = create_default_config()
|
|
177
|
+
if created:
|
|
178
|
+
config_file = get_config_file()
|
|
179
|
+
print(f"Created default config file: {config_file}")
|
|
180
|
+
print("Please edit it to add your API keys and settings.")
|
|
181
|
+
return Settings.from_toml()
|