fix(s41): pass required credential in AzureFoundryBackend.create_chat_client
This commit is contained in:
parent
eb552f854e
commit
82c85d5e7c
4 changed files with 27 additions and 2 deletions
|
|
@ -11,6 +11,7 @@ dependencies = [
|
||||||
# Beta-integrasjoner legges til per-fase (med snevert pre-release-scope) når de faktisk trengs.
|
# Beta-integrasjoner legges til per-fase (med snevert pre-release-scope) når de faktisk trengs.
|
||||||
"agent-framework-core>=1.9.0,<2", # kjerne (GA) — to-sidig pin (S2.5): major-bump krever re-verifisering av privat-API-premissene (test_maf_version_guard)
|
"agent-framework-core>=1.9.0,<2", # kjerne (GA) — to-sidig pin (S2.5): major-bump krever re-verifisering av privat-API-premissene (test_maf_version_guard)
|
||||||
"agent-framework-foundry>=1.8.2", # Azure/Foundry-profil: FoundryChatClient (GA)
|
"agent-framework-foundry>=1.8.2", # Azure/Foundry-profil: FoundryChatClient (GA)
|
||||||
|
"azure-identity>=1.25", # S4.1: AzureFoundryBackend passes an explicit AzureCliCredential (Foundry requires it); already transitive via foundry — promoted to a declared direct dep (zero new install weight)
|
||||||
"agent-framework-openai>=1.8.2", # OpenAI + OpenAI-kompatible lokale endpoints (GA) → lokal profil
|
"agent-framework-openai>=1.8.2", # OpenAI + OpenAI-kompatible lokale endpoints (GA) → lokal profil
|
||||||
# Promotert dev→core i Fase 2 (MVP-runtime, ikke lenger spike-only):
|
# Promotert dev→core i Fase 2 (MVP-runtime, ikke lenger spike-only):
|
||||||
"agent-framework-orchestrations>=1.0.0", # GA orchestration builders (GroupChat/Concurrent/Magentic); resolves med core 1.9.0
|
"agent-framework-orchestrations>=1.0.0", # GA orchestration builders (GroupChat/Concurrent/Magentic); resolves med core 1.9.0
|
||||||
|
|
|
||||||
|
|
@ -103,8 +103,17 @@ class AzureFoundryBackend:
|
||||||
endpoint = os.environ.get("PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT")
|
endpoint = os.environ.get("PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT")
|
||||||
if not endpoint:
|
if not endpoint:
|
||||||
raise ValueError("PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT is required for the AZURE profile")
|
raise ValueError("PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT is required for the AZURE profile")
|
||||||
# Credential resolves lazily via Azure DefaultAzureCredential (az login / MI).
|
# FoundryChatClient REQUIRES an explicit credential (verified against agent-framework-foundry
|
||||||
return FoundryChatClient(project_endpoint=endpoint, model=model)
|
# 1.8.2 — it raises ``ValueError`` without one; there is NO lazy DefaultAzureCredential
|
||||||
|
# default). Lazy import so the LOCAL path never pulls azure.identity. AzureCliCredential is
|
||||||
|
# the documented, friction-minimal path on a non-Azure host — constructing it acquires NO
|
||||||
|
# token (``az login`` is the operator's manual step), so this is not auto-login. Recipe:
|
||||||
|
# docs/2026-07-15-foundry-auth-recipe.md.
|
||||||
|
from azure.identity.aio import AzureCliCredential
|
||||||
|
|
||||||
|
return FoundryChatClient(
|
||||||
|
project_endpoint=endpoint, model=model, credential=AzureCliCredential()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LocalBackend:
|
class LocalBackend:
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,19 @@ def test_azure_backend_fails_fast_without_endpoint(monkeypatch: pytest.MonkeyPat
|
||||||
get_backend("azure").create_chat_client(model="dummy-deployment")
|
get_backend("azure").create_chat_client(model="dummy-deployment")
|
||||||
|
|
||||||
|
|
||||||
|
def test_azure_backend_constructs_with_credential(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
|
# S4.1: FoundryChatClient REQUIRES an explicit credential (verified: pinned agent-framework-
|
||||||
|
# foundry 1.8.2 raises ValueError without it). The backend now supplies a lazy
|
||||||
|
# AzureCliCredential — construction succeeds OFFLINE (no token acquired until first use).
|
||||||
|
# Detach point: drop credential= in create_chat_client → construction raises → RED.
|
||||||
|
monkeypatch.setenv(
|
||||||
|
"PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT",
|
||||||
|
"https://x.services.ai.azure.com/api/projects/p",
|
||||||
|
)
|
||||||
|
client = get_backend("azure").create_chat_client(model="gpt-4o-mini")
|
||||||
|
assert isinstance(client, BaseChatClient)
|
||||||
|
|
||||||
|
|
||||||
def test_model_map_resolves_role_to_model(monkeypatch: pytest.MonkeyPatch) -> None:
|
def test_model_map_resolves_role_to_model(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
monkeypatch.delenv("PORTFOLIO_MODEL_MAP", raising=False)
|
monkeypatch.delenv("PORTFOLIO_MODEL_MAP", raising=False)
|
||||||
assert resolve_model("local", "proposer") == "qwen3:4b"
|
assert resolve_model("local", "proposer") == "qwen3:4b"
|
||||||
|
|
|
||||||
2
uv.lock
generated
2
uv.lock
generated
|
|
@ -1420,6 +1420,7 @@ dependencies = [
|
||||||
{ name = "agent-framework-foundry" },
|
{ name = "agent-framework-foundry" },
|
||||||
{ name = "agent-framework-openai" },
|
{ name = "agent-framework-openai" },
|
||||||
{ name = "agent-framework-orchestrations" },
|
{ name = "agent-framework-orchestrations" },
|
||||||
|
{ name = "azure-identity" },
|
||||||
{ name = "mcp" },
|
{ name = "mcp" },
|
||||||
{ name = "pulp" },
|
{ name = "pulp" },
|
||||||
{ name = "pydantic" },
|
{ name = "pydantic" },
|
||||||
|
|
@ -1439,6 +1440,7 @@ requires-dist = [
|
||||||
{ name = "agent-framework-foundry", specifier = ">=1.8.2" },
|
{ name = "agent-framework-foundry", specifier = ">=1.8.2" },
|
||||||
{ name = "agent-framework-openai", specifier = ">=1.8.2" },
|
{ name = "agent-framework-openai", specifier = ">=1.8.2" },
|
||||||
{ name = "agent-framework-orchestrations", specifier = ">=1.0.0" },
|
{ name = "agent-framework-orchestrations", specifier = ">=1.0.0" },
|
||||||
|
{ name = "azure-identity", specifier = ">=1.25" },
|
||||||
{ name = "mcp", specifier = ">=1.28.0" },
|
{ name = "mcp", specifier = ">=1.28.0" },
|
||||||
{ name = "pulp", specifier = ">=2.8" },
|
{ name = "pulp", specifier = ">=2.8" },
|
||||||
{ name = "pydantic", specifier = ">=2.11,<3" },
|
{ name = "pydantic", specifier = ">=2.11,<3" },
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue