mirror of
https://github.com/katanemo/plano.git
synced 2026-06-17 15:25:17 +02:00
Upgrade black 23.1.0 -> 25.1.0 for Python 3.14 compatibility
black 23.1.0 uses ast.Str which was removed in Python 3.14, causing pre-commit CI to crash on any PR that touches Python files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
df2f1c7f29
commit
9858ce4d31
6 changed files with 112 additions and 88 deletions
|
|
@ -31,7 +31,7 @@ repos:
|
|||
pass_filenames: false
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.1.0
|
||||
rev: 25.1.0
|
||||
hooks:
|
||||
- id: black
|
||||
language_version: python3
|
||||
|
|
|
|||
|
|
@ -102,9 +102,7 @@ def validate_and_render_schema():
|
|||
if "model_aliases" in config:
|
||||
validate_model_aliases(config["model_aliases"], model_name_keys)
|
||||
|
||||
agent_orchestrator = resolve_agent_orchestrator(
|
||||
config, config.get("endpoints", {})
|
||||
)
|
||||
agent_orchestrator = resolve_agent_orchestrator(config, config.get("endpoints", {}))
|
||||
|
||||
data = build_template_data(
|
||||
prompt_gateway,
|
||||
|
|
|
|||
|
|
@ -435,9 +435,7 @@ def resolve_agent_orchestrator(config, endpoints):
|
|||
|
||||
Returns the orchestrator endpoint name, or None if not configured.
|
||||
"""
|
||||
use_orchestrator = config.get("overrides", {}).get(
|
||||
"use_agent_orchestrator", False
|
||||
)
|
||||
use_orchestrator = config.get("overrides", {}).get("use_agent_orchestrator", False)
|
||||
if not use_orchestrator:
|
||||
return None
|
||||
|
||||
|
|
|
|||
|
|
@ -296,9 +296,9 @@ def up(file, path, foreground, with_tracing, tracing_port):
|
|||
sys.exit(1)
|
||||
|
||||
# Update the OTEL endpoint so the gateway sends traces to the right port
|
||||
env_stage[
|
||||
"OTEL_TRACING_GRPC_ENDPOINT"
|
||||
] = f"http://host.docker.internal:{tracing_port}"
|
||||
env_stage["OTEL_TRACING_GRPC_ENDPOINT"] = (
|
||||
f"http://host.docker.internal:{tracing_port}"
|
||||
)
|
||||
|
||||
env.update(env_stage)
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -189,26 +189,26 @@ def get_function_parameters(node: ast.FunctionDef, tree: ast.AST) -> list:
|
|||
if isinstance(
|
||||
arg.annotation.value, ast.Name
|
||||
) and arg.annotation.value.id in ["list", "tuple", "set", "dict"]:
|
||||
param_info[
|
||||
"type"
|
||||
] = f"{arg.annotation.value.id}" # e.g., "List", "Tuple", etc.
|
||||
param_info["type"] = (
|
||||
f"{arg.annotation.value.id}" # e.g., "List", "Tuple", etc.
|
||||
)
|
||||
else:
|
||||
param_info["type"] = "[UNKNOWN - PLEASE FIX]"
|
||||
|
||||
# Default for unknown types
|
||||
else:
|
||||
param_info[
|
||||
"type"
|
||||
] = "[UNKNOWN - PLEASE FIX]" # If unable to detect type
|
||||
param_info["type"] = (
|
||||
"[UNKNOWN - PLEASE FIX]" # If unable to detect type
|
||||
)
|
||||
|
||||
# Handle default values
|
||||
if default is not None:
|
||||
if isinstance(default, ast.Constant) or isinstance(
|
||||
default, ast.NameConstant
|
||||
):
|
||||
param_info[
|
||||
"default"
|
||||
] = default.value # Use the default value directly
|
||||
param_info["default"] = (
|
||||
default.value
|
||||
) # Use the default value directly
|
||||
else:
|
||||
param_info["default"] = "[UNKNOWN DEFAULT]" # Unknown default type
|
||||
param_info["required"] = False # Optional since it has a default value
|
||||
|
|
|
|||
|
|
@ -154,16 +154,18 @@ class TestBuildClusters:
|
|||
"agent1": {"endpoint": "localhost", "port": 8000, "protocol": "http"}
|
||||
}
|
||||
endpoints = {
|
||||
"explicit1": {"endpoint": "api.example.com", "port": 443, "protocol": "https"}
|
||||
"explicit1": {
|
||||
"endpoint": "api.example.com",
|
||||
"port": 443,
|
||||
"protocol": "https",
|
||||
}
|
||||
}
|
||||
result = build_clusters(endpoints, agent_inferred)
|
||||
assert "agent1" in result
|
||||
assert "explicit1" in result
|
||||
|
||||
def test_infer_port_from_host_colon_port(self):
|
||||
clusters = build_clusters(
|
||||
{"svc": {"endpoint": "localhost:9090"}}, {}
|
||||
)
|
||||
clusters = build_clusters({"svc": {"endpoint": "localhost:9090"}}, {})
|
||||
assert clusters["svc"]["endpoint"] == "localhost"
|
||||
assert clusters["svc"]["port"] == 9090
|
||||
|
||||
|
|
@ -231,9 +233,11 @@ class TestProcessModelProviders:
|
|||
return [{"model_providers": model_providers}]
|
||||
|
||||
def test_happy_path(self):
|
||||
listeners = self._make_listeners([
|
||||
{"model": "openai/gpt-4o", "access_key": "$KEY", "default": True},
|
||||
])
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{"model": "openai/gpt-4o", "access_key": "$KEY", "default": True},
|
||||
]
|
||||
)
|
||||
providers, llms, keys = process_model_providers(listeners, {})
|
||||
# Should have the user provider + internal providers
|
||||
names = [p["name"] for p in providers]
|
||||
|
|
@ -242,21 +246,27 @@ class TestProcessModelProviders:
|
|||
assert "plano-orchestrator" in names
|
||||
|
||||
def test_duplicate_provider_name(self):
|
||||
listeners = self._make_listeners([
|
||||
{"name": "test1", "model": "openai/gpt-4o", "access_key": "$KEY"},
|
||||
{"name": "test1", "model": "openai/gpt-4o-mini", "access_key": "$KEY"},
|
||||
])
|
||||
with pytest.raises(ConfigValidationError, match="Duplicate model_provider name"):
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{"name": "test1", "model": "openai/gpt-4o", "access_key": "$KEY"},
|
||||
{"name": "test1", "model": "openai/gpt-4o-mini", "access_key": "$KEY"},
|
||||
]
|
||||
)
|
||||
with pytest.raises(
|
||||
ConfigValidationError, match="Duplicate model_provider name"
|
||||
):
|
||||
process_model_providers(listeners, {})
|
||||
|
||||
def test_provider_interface_with_supported_provider(self):
|
||||
listeners = self._make_listeners([
|
||||
{
|
||||
"model": "openai/gpt-4o",
|
||||
"access_key": "$KEY",
|
||||
"provider_interface": "openai",
|
||||
},
|
||||
])
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{
|
||||
"model": "openai/gpt-4o",
|
||||
"access_key": "$KEY",
|
||||
"provider_interface": "openai",
|
||||
},
|
||||
]
|
||||
)
|
||||
with pytest.raises(
|
||||
ConfigValidationError,
|
||||
match="provide provider interface as part of model name",
|
||||
|
|
@ -264,30 +274,36 @@ class TestProcessModelProviders:
|
|||
process_model_providers(listeners, {})
|
||||
|
||||
def test_duplicate_model_id(self):
|
||||
listeners = self._make_listeners([
|
||||
{"model": "openai/gpt-4o", "access_key": "$KEY"},
|
||||
{"model": "mistral/gpt-4o"},
|
||||
])
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{"model": "openai/gpt-4o", "access_key": "$KEY"},
|
||||
{"model": "mistral/gpt-4o"},
|
||||
]
|
||||
)
|
||||
with pytest.raises(ConfigValidationError, match="Duplicate model_id"):
|
||||
process_model_providers(listeners, {})
|
||||
|
||||
def test_custom_provider_requires_base_url(self):
|
||||
listeners = self._make_listeners([
|
||||
{"model": "custom/gpt-4o"},
|
||||
])
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{"model": "custom/gpt-4o"},
|
||||
]
|
||||
)
|
||||
with pytest.raises(
|
||||
ConfigValidationError, match="Must provide base_url and provider_interface"
|
||||
):
|
||||
process_model_providers(listeners, {})
|
||||
|
||||
def test_base_url_with_path_prefix(self):
|
||||
listeners = self._make_listeners([
|
||||
{
|
||||
"model": "custom/gpt-4o",
|
||||
"base_url": "http://custom.com/api/v2",
|
||||
"provider_interface": "openai",
|
||||
},
|
||||
])
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{
|
||||
"model": "custom/gpt-4o",
|
||||
"base_url": "http://custom.com/api/v2",
|
||||
"provider_interface": "openai",
|
||||
},
|
||||
]
|
||||
)
|
||||
providers, llms, keys = process_model_providers(listeners, {})
|
||||
# Find the custom provider
|
||||
custom = next(p for p in providers if p.get("cluster_name"))
|
||||
|
|
@ -296,61 +312,73 @@ class TestProcessModelProviders:
|
|||
assert custom["port"] == 80
|
||||
|
||||
def test_duplicate_routing_preference_name(self):
|
||||
listeners = self._make_listeners([
|
||||
{"model": "openai/gpt-4o-mini", "access_key": "$KEY", "default": True},
|
||||
{
|
||||
"model": "openai/gpt-4o",
|
||||
"access_key": "$KEY",
|
||||
"routing_preferences": [
|
||||
{"name": "code understanding", "description": "explains code"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"model": "openai/gpt-4.1",
|
||||
"access_key": "$KEY",
|
||||
"routing_preferences": [
|
||||
{"name": "code understanding", "description": "generates code"},
|
||||
],
|
||||
},
|
||||
])
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{"model": "openai/gpt-4o-mini", "access_key": "$KEY", "default": True},
|
||||
{
|
||||
"model": "openai/gpt-4o",
|
||||
"access_key": "$KEY",
|
||||
"routing_preferences": [
|
||||
{"name": "code understanding", "description": "explains code"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"model": "openai/gpt-4.1",
|
||||
"access_key": "$KEY",
|
||||
"routing_preferences": [
|
||||
{"name": "code understanding", "description": "generates code"},
|
||||
],
|
||||
},
|
||||
]
|
||||
)
|
||||
with pytest.raises(
|
||||
ConfigValidationError, match="Duplicate routing preference name"
|
||||
):
|
||||
process_model_providers(listeners, {})
|
||||
|
||||
def test_wildcard_cannot_be_default(self):
|
||||
listeners = self._make_listeners([
|
||||
{"model": "openai/*", "access_key": "$KEY", "default": True},
|
||||
])
|
||||
with pytest.raises(ConfigValidationError, match="Default models cannot be wildcards"):
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{"model": "openai/*", "access_key": "$KEY", "default": True},
|
||||
]
|
||||
)
|
||||
with pytest.raises(
|
||||
ConfigValidationError, match="Default models cannot be wildcards"
|
||||
):
|
||||
process_model_providers(listeners, {})
|
||||
|
||||
def test_invalid_model_name_format(self):
|
||||
listeners = self._make_listeners([
|
||||
{"model": "gpt-4o", "access_key": "$KEY"},
|
||||
])
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{"model": "gpt-4o", "access_key": "$KEY"},
|
||||
]
|
||||
)
|
||||
with pytest.raises(ConfigValidationError, match="Invalid model name"):
|
||||
process_model_providers(listeners, {})
|
||||
|
||||
def test_internal_providers_always_added(self):
|
||||
listeners = self._make_listeners([
|
||||
{"model": "openai/gpt-4o", "access_key": "$KEY"},
|
||||
])
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{"model": "openai/gpt-4o", "access_key": "$KEY"},
|
||||
]
|
||||
)
|
||||
providers, _, _ = process_model_providers(listeners, {})
|
||||
names = [p["name"] for p in providers]
|
||||
assert "arch-function" in names
|
||||
assert "plano-orchestrator" in names
|
||||
|
||||
def test_arch_router_added_when_routing_preferences_exist(self):
|
||||
listeners = self._make_listeners([
|
||||
{
|
||||
"model": "openai/gpt-4o",
|
||||
"access_key": "$KEY",
|
||||
"routing_preferences": [
|
||||
{"name": "coding", "description": "code tasks"},
|
||||
],
|
||||
},
|
||||
])
|
||||
listeners = self._make_listeners(
|
||||
[
|
||||
{
|
||||
"model": "openai/gpt-4o",
|
||||
"access_key": "$KEY",
|
||||
"routing_preferences": [
|
||||
{"name": "coding", "description": "code tasks"},
|
||||
],
|
||||
},
|
||||
]
|
||||
)
|
||||
providers, _, _ = process_model_providers(listeners, {})
|
||||
names = [p["name"] for p in providers]
|
||||
assert "arch-router" in names
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue