Add project tools and strict provider execution

This commit is contained in:
rob
2026-07-20 22:27:36 -03:00
parent c289e812fb
commit 6a88fe2e0f
19 changed files with 1504 additions and 84 deletions
+215 -1
View File
@@ -8,7 +8,7 @@ import pytest
import yaml
from cmdforge.providers import (
Provider, ProviderResult,
Provider, ProviderResult, ProviderExecutionPolicy,
load_providers, save_providers, get_provider,
add_provider, delete_provider,
call_provider, discover_installed_providers, mock_provider,
@@ -60,6 +60,19 @@ class TestProvider:
provider = Provider.from_dict(data)
assert provider.description == ""
def test_legacy_policy_field_aliases_are_canonicalized(self):
provider = Provider.from_dict({
"name": "legacy-policy",
"command": "provider",
"model_id": "model-a",
"max_input_tokens": 8192,
})
assert provider.model == "model-a"
assert provider.max_context_tokens == 8192
assert provider.to_dict()["model"] == "model-a"
assert provider.to_dict()["max_context_tokens"] == 8192
def test_roundtrip(self):
original = Provider(
name="custom",
@@ -90,6 +103,13 @@ class TestProvider:
fallback_chain=["backup", "mock"],
api_key_env="TEST_API_KEY",
pty_config={"prompt_pattern": ">"},
locality="remote",
capabilities=["text", "structured-json"],
model_digest="sha256:abc",
cost_class="low",
latency_class="fast",
max_context_tokens=131072,
data_policy="internal",
)
assert Provider.from_dict(original.to_dict()) == original
@@ -516,6 +536,200 @@ class TestProviderFallback:
# Fallback to mock should succeed
assert result.success is True
assert "[MOCK]" in result.text
assert result.requested_provider == "primary"
assert result.actual_provider == "mock"
assert result.attempted_providers == ["primary", "mock"]
assert result.fallback_used is True
def test_no_fallback_fails_closed(self, temp_providers_file):
save_providers([
Provider("primary", "nonexistent-cmd", fallback="mock"),
Provider("mock", "mock"),
])
result = call_provider(
"primary", "Test prompt",
execution_policy=ProviderExecutionPolicy(allow_fallback=False),
)
assert result.success is False
assert result.requested_provider == "primary"
assert result.actual_provider is None
assert result.attempted_providers == ["primary"]
assert result.fallback_used is False
def test_private_data_requires_explicit_compatible_policy(
self, temp_providers_file
):
save_providers([
Provider(
"local", "unused", locality="local",
capabilities=["structured-json"],
),
])
result = call_provider(
"local", "private packet",
execution_policy=ProviderExecutionPolicy(
allow_fallback=False,
required_locality="local",
required_capabilities=("structured-json",),
data_classification="private",
),
)
assert result.success is False
assert "data_policy is unspecified" in result.error
def test_require_local_rejects_ollama_redirected_to_remote_host(
self, temp_providers_file, monkeypatch
):
save_providers([
Provider(
"ollama-private", "ollama run safe", locality="local",
data_policy="private",
),
])
monkeypatch.setenv("OLLAMA_HOST", "gpu.example.test:11434")
result = call_provider(
"ollama-private", "private packet",
execution_policy=ProviderExecutionPolicy(
allow_fallback=False,
required_locality="local",
data_classification="private",
),
)
assert result.success is False
assert "locality is remote" in result.error
def test_ollama_digest_is_observed_from_local_api(
self, temp_providers_file, monkeypatch
):
save_providers([
Provider(
"ollama-safe", "ollama run safe:latest", model="safe:latest",
locality="local", data_policy="private",
),
])
monkeypatch.delenv("OLLAMA_HOST", raising=False)
class Response:
def __enter__(self):
return self
def __exit__(self, *args):
return False
def read(self):
return (
b'{"models":[{"name":"safe:latest","model":"safe:latest",'
b'"digest":"abcdef"}]}'
)
with (
patch("urllib.request.urlopen", return_value=Response()),
patch(
"cmdforge.providers.call_provider_subprocess",
return_value=ProviderResult(text="safe", success=True),
),
):
result = call_provider(
"ollama-safe", "private",
execution_policy=ProviderExecutionPolicy(
allow_fallback=False,
required_locality="local",
data_classification="private",
require_model_identity=True,
require_model_digest=True,
),
)
assert result.model == "safe:latest"
assert result.model_digest == "sha256:abcdef"
assert result.model_identity_source == "ollama-api"
def test_policy_eligible_provider_reports_verified_metadata(
self, temp_providers_file
):
provider = Provider(
"local", "local-ai", model="model-a",
model_digest="sha256:123", locality="local",
capabilities=["structured-json"], data_policy="private",
)
save_providers([provider])
low_level = ProviderResult(text='{"ok": true}', success=True)
with patch(
"cmdforge.providers.call_provider_subprocess",
return_value=low_level,
):
result = call_provider(
"local", "private packet",
execution_policy=ProviderExecutionPolicy(
allow_fallback=False,
required_locality="local",
required_capabilities=("structured-json",),
data_classification="private",
require_model_identity=True,
require_model_digest=True,
),
)
assert result.success is True
assert result.provenance() == {
"success": True,
"requested_provider": "local",
"actual_provider": "local",
"attempted_providers": ["local"],
"fallback_used": False,
"model": "model-a",
"model_digest": "sha256:123",
"locality": "local",
"model_identity_source": "provider-config",
}
def test_fallback_chain_skips_policy_ineligible_provider(
self, temp_providers_file
):
save_providers([
Provider(
"primary", "primary", fallback_chain=["remote", "local"],
locality="local", data_policy="private",
),
Provider(
"remote", "remote", locality="remote", data_policy="private",
),
Provider(
"local", "local", locality="local", data_policy="private",
model="safe-model",
),
])
def invoke(provider, prompt, timeout, max_tokens):
if provider.name == "primary":
return ProviderResult(text="", success=False, error="offline")
assert provider.name == "local"
return ProviderResult(text="safe", success=True)
with patch(
"cmdforge.providers.call_provider_subprocess", side_effect=invoke
) as low_level:
result = call_provider(
"primary", "private packet",
execution_policy=ProviderExecutionPolicy(
required_locality="local",
data_classification="private",
),
)
assert result.success is True
assert result.actual_provider == "local"
assert result.attempted_providers == ["primary", "remote", "local"]
assert [call.args[0].name for call in low_level.call_args_list] == [
"primary", "local"
]
def test_fallback_chain(self, temp_providers_file):
"""Fallback can chain to another provider with fallback."""