argo-proxy 3.2.0a0__tar.gz → 3.2.1__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.
- {argo_proxy-3.2.0a0/src/argo_proxy.egg-info → argo_proxy-3.2.1}/PKG-INFO +2 -2
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/pyproject.toml +1 -1
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1/src/argo_proxy.egg-info}/PKG-INFO +2 -2
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argo_proxy.egg-info/requires.txt +1 -1
- argo_proxy-3.2.1/src/argoproxy/__init__.py +1 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/app.py +0 -1
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/config/model.py +4 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/endpoints/dispatch.py +5 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/models.py +18 -5
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/performance.py +0 -4
- argo_proxy-3.2.0a0/src/argoproxy/__init__.py +0 -1
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/LICENSE +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/README.md +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/setup.cfg +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argo_proxy.egg-info/SOURCES.txt +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argo_proxy.egg-info/dependency_links.txt +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argo_proxy.egg-info/entry_points.txt +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argo_proxy.egg-info/top_level.txt +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/_vendor/__init__.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/_vendor/semver.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/_vendor/yaml.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/cli/__init__.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/cli/display.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/cli/handlers.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/cli/parser.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/config/__init__.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/config/interactive.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/config/io.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/config/validation.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/endpoints/dev_proxy.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/endpoints/extras.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/endpoints/passthrough.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/py.typed +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/utils/attack_logger.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/utils/image_processing.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/utils/logging.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/utils/misc.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/utils/models.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/src/argoproxy/utils/transports.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/test/test_chat_completions.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/test/test_embeddings.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/test/test_function_calling_multiple.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/test/test_function_calling_single.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/test/test_leaked_tool_parser.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/test/test_model_resolution.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/tests/test_config_migrate.py +0 -0
- {argo_proxy-3.2.0a0 → argo_proxy-3.2.1}/tests/test_unix_socket.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: argo-proxy
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.1
|
|
4
4
|
Summary: Proxy server to Argo API, OpenAI format compatible
|
|
5
5
|
Author-email: Peng Ding <oaklight@gmx.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -15,7 +15,7 @@ Requires-Python: >=3.10
|
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
17
|
Requires-Dist: aiohttp>=3.12.2
|
|
18
|
-
Requires-Dist: llm-rosetta>=0.7.
|
|
18
|
+
Requires-Dist: llm-rosetta>=0.7.0
|
|
19
19
|
Requires-Dist: pydantic>=2.11.7
|
|
20
20
|
Requires-Dist: tiktoken>=0.9.0
|
|
21
21
|
Requires-Dist: tqdm>=4.67.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: argo-proxy
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.1
|
|
4
4
|
Summary: Proxy server to Argo API, OpenAI format compatible
|
|
5
5
|
Author-email: Peng Ding <oaklight@gmx.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -15,7 +15,7 @@ Requires-Python: >=3.10
|
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
17
|
Requires-Dist: aiohttp>=3.12.2
|
|
18
|
-
Requires-Dist: llm-rosetta>=0.7.
|
|
18
|
+
Requires-Dist: llm-rosetta>=0.7.0
|
|
19
19
|
Requires-Dist: pydantic>=2.11.7
|
|
20
20
|
Requires-Dist: tiktoken>=0.9.0
|
|
21
21
|
Requires-Dist: tqdm>=4.67.1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "3.2.1"
|
|
@@ -92,7 +92,6 @@ async def prepare_app(app):
|
|
|
92
92
|
# Create optimized HTTP session
|
|
93
93
|
resolve_overrides = getattr(app["config"], "resolve_overrides", None)
|
|
94
94
|
http_session_manager = OptimizedHTTPSession(
|
|
95
|
-
user_agent=f"argo-proxy/{__version__}",
|
|
96
95
|
resolve_overrides=resolve_overrides if resolve_overrides else None,
|
|
97
96
|
**perf_config,
|
|
98
97
|
)
|
|
@@ -76,6 +76,10 @@ class ArgoConfig:
|
|
|
76
76
|
# Model list auto-refresh
|
|
77
77
|
model_refresh_interval_hours: float = 24 # 0 to disable
|
|
78
78
|
|
|
79
|
+
# Fallback models — used when an unrecognized model name is requested
|
|
80
|
+
default_chat_model: str = "argo:gpt-5.4-nano"
|
|
81
|
+
default_embed_model: str = "argo:text-embedding-3-small"
|
|
82
|
+
|
|
79
83
|
# Image processing settings
|
|
80
84
|
enable_payload_control: bool = False # Enable automatic payload size control
|
|
81
85
|
max_payload_size: int = 20 # MB default (total for all images)
|
|
@@ -288,6 +288,11 @@ def _build_upstream_headers(
|
|
|
288
288
|
"""Build HTTP headers for the upstream API request."""
|
|
289
289
|
headers: dict[str, str] = {"Content-Type": "application/json"}
|
|
290
290
|
|
|
291
|
+
# Pass through client's User-Agent to upstream (transparent proxy)
|
|
292
|
+
client_ua = request.headers.get("User-Agent")
|
|
293
|
+
if client_ua:
|
|
294
|
+
headers["User-Agent"] = client_ua
|
|
295
|
+
|
|
291
296
|
if should_use_username_passthrough():
|
|
292
297
|
api_key = _extract_client_credential(request, target_provider) or fallback_user
|
|
293
298
|
else:
|
|
@@ -51,6 +51,7 @@ _DEFAULT_CHAT_MODELS = flatten_mapping(
|
|
|
51
51
|
"gpt51": "argo:gpt-5.1",
|
|
52
52
|
"gpt52": "argo:gpt-5.2",
|
|
53
53
|
"gpt54": "argo:gpt-5.4",
|
|
54
|
+
"gpt54nano": "argo:gpt-5.4-nano",
|
|
54
55
|
"gpt55": "argo:gpt-5.5",
|
|
55
56
|
# gemini
|
|
56
57
|
"gemini25pro": "argo:gemini-2.5-pro",
|
|
@@ -308,7 +309,6 @@ async def get_upstream_model_list_async(
|
|
|
308
309
|
async with aiohttp.ClientSession(
|
|
309
310
|
connector=connector,
|
|
310
311
|
timeout=client_timeout,
|
|
311
|
-
headers={"User-Agent": "argo-proxy/1.0"},
|
|
312
312
|
) as session:
|
|
313
313
|
log_debug(f"Sending request to: {url}", context="models")
|
|
314
314
|
|
|
@@ -480,7 +480,7 @@ def _categorize_results(
|
|
|
480
480
|
unavailable.clear()
|
|
481
481
|
else:
|
|
482
482
|
log_error(
|
|
483
|
-
"Proceeding without unavailable models. Subsequent calls to these models will
|
|
483
|
+
"Proceeding without unavailable models. Subsequent calls to these models will use the configured default fallback",
|
|
484
484
|
context="models",
|
|
485
485
|
)
|
|
486
486
|
|
|
@@ -781,14 +781,27 @@ class ModelRegistry:
|
|
|
781
781
|
return model_name
|
|
782
782
|
|
|
783
783
|
if model_type == "chat":
|
|
784
|
-
default_model =
|
|
784
|
+
default_model = self._config.default_chat_model
|
|
785
785
|
elif model_type == "embed":
|
|
786
|
-
default_model =
|
|
786
|
+
default_model = self._config.default_embed_model
|
|
787
|
+
else:
|
|
788
|
+
default_model = self._config.default_chat_model
|
|
789
|
+
log_warning(
|
|
790
|
+
f"Unknown model_type '{model_type}', using chat fallback",
|
|
791
|
+
context="ModelRegistry",
|
|
792
|
+
)
|
|
787
793
|
log_warning(
|
|
788
794
|
f"Model '{model_name}' not found in registry, falling back to {default_model}",
|
|
789
795
|
context="ModelRegistry",
|
|
790
796
|
)
|
|
791
|
-
|
|
797
|
+
if default_model in self.available_models:
|
|
798
|
+
return self.available_models[default_model]
|
|
799
|
+
# Default model itself not in registry — return its name as-is
|
|
800
|
+
log_warning(
|
|
801
|
+
f"Default fallback model '{default_model}' not in registry either",
|
|
802
|
+
context="ModelRegistry",
|
|
803
|
+
)
|
|
804
|
+
return default_model
|
|
792
805
|
|
|
793
806
|
def as_openai_list(self) -> dict[str, Any]:
|
|
794
807
|
# Mock data for available models
|
|
@@ -93,7 +93,6 @@ class OptimizedHTTPSession:
|
|
|
93
93
|
read_timeout: Socket read timeout in seconds.
|
|
94
94
|
total_timeout: Total request timeout in seconds.
|
|
95
95
|
dns_cache_ttl: DNS cache TTL in seconds.
|
|
96
|
-
user_agent: User agent string.
|
|
97
96
|
resolve_overrides: Optional dict mapping "host:port" to IP address
|
|
98
97
|
for custom DNS resolution (similar to curl --resolve).
|
|
99
98
|
"""
|
|
@@ -108,7 +107,6 @@ class OptimizedHTTPSession:
|
|
|
108
107
|
read_timeout: int = 30,
|
|
109
108
|
total_timeout: int = 60,
|
|
110
109
|
dns_cache_ttl: int = 300,
|
|
111
|
-
user_agent: str = "argo-proxy",
|
|
112
110
|
resolve_overrides: dict[str, str] | None = None,
|
|
113
111
|
):
|
|
114
112
|
connector_kwargs: dict = {
|
|
@@ -137,7 +135,6 @@ class OptimizedHTTPSession:
|
|
|
137
135
|
)
|
|
138
136
|
|
|
139
137
|
self.session: aiohttp.ClientSession | None = None
|
|
140
|
-
self.user_agent = user_agent
|
|
141
138
|
|
|
142
139
|
async def create_session(self) -> aiohttp.ClientSession:
|
|
143
140
|
"""Create and return the HTTP session."""
|
|
@@ -145,7 +142,6 @@ class OptimizedHTTPSession:
|
|
|
145
142
|
self.session = aiohttp.ClientSession(
|
|
146
143
|
connector=self.connector,
|
|
147
144
|
timeout=self.timeout,
|
|
148
|
-
headers={"User-Agent": self.user_agent},
|
|
149
145
|
)
|
|
150
146
|
log_debug(
|
|
151
147
|
f"HTTP session created: {self.connector.limit} total, "
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "3.2.0a0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|