Require forwarded reviewer LLM credentials

This commit is contained in:
robert
2026-06-03 20:59:02 -03:00
parent f13dd0ac72
commit e609aa34ef
2 changed files with 78 additions and 3 deletions

View File

@@ -117,10 +117,25 @@ def build_reviewer_graph(
) )
) )
missing_llm_fields = [
name
for name, value in (
("llm_model", ctx.llm_model),
("llm_base_url", ctx.llm_base_url),
("llm_api_key", ctx.llm_api_key),
)
if not value
]
if missing_llm_fields:
raise ValueError(
"reviewer requires forwarded ctx.llm credentials; missing "
+ ", ".join(missing_llm_fields)
)
model_kwargs: dict[str, Any] = { model_kwargs: dict[str, Any] = {
"model": ctx.llm_model or settings.litellm_model, "model": ctx.llm_model,
"base_url": ctx.llm_base_url or (settings.litellm_url + "/v1"), "base_url": ctx.llm_base_url,
"api_key": ctx.llm_api_key or settings.litellm_key, "api_key": ctx.llm_api_key,
"stream_usage": True, "stream_usage": True,
} }
if ctx.llm_temperature_mode != "omit": if ctx.llm_temperature_mode != "omit":

View File

@@ -13,6 +13,8 @@ if str(ROOT) not in sys.path:
from a2a_pack import LocalRunContext, NoAuth # noqa: E402 from a2a_pack import LocalRunContext, NoAuth # noqa: E402
from agent import AgentReviewer # noqa: E402 from agent import AgentReviewer # noqa: E402
from agent_reviewer import builder as reviewer_builder # noqa: E402
from agent_reviewer.builder import ReviewerContext, build_reviewer_graph # noqa: E402
from agent_reviewer.tools import Finding, ReviewReport, ToolContext, build_tools # noqa: E402 from agent_reviewer.tools import Finding, ReviewReport, ToolContext, build_tools # noqa: E402
from agent_reviewer.config import load_settings # noqa: E402 from agent_reviewer.config import load_settings # noqa: E402
@@ -77,6 +79,64 @@ async def test_review_returns_structured_error_without_llm_credentials(
assert result["ref"] == "main" assert result["ref"] == "main"
def test_reviewer_graph_uses_forwarded_llm_credentials(
monkeypatch: pytest.MonkeyPatch,
) -> None:
captured: dict = {}
class FakeChatOpenAI:
def __init__(self, **kwargs: object) -> None:
captured["model_kwargs"] = kwargs
def fake_create_deep_agent(**kwargs: object) -> dict[str, object]:
captured["graph_kwargs"] = kwargs
return kwargs
monkeypatch.setattr(reviewer_builder, "ChatOpenAI", FakeChatOpenAI)
monkeypatch.setattr(reviewer_builder, "create_deep_agent", fake_create_deep_agent)
graph = build_reviewer_graph(
ReviewerContext(
agent_name="hello-agent",
ref="main",
gitea_token="gitea-read-token",
gitea_owner="gitea_admin",
llm_base_url="http://litellm.test/v1",
llm_api_key="scoped-grant-token",
llm_model="platform-model",
llm_temperature_mode="omit",
llm_extra_body={"extra_body": {"thinking": {"type": "disabled"}}},
),
completion_box={},
)
assert graph is captured["graph_kwargs"]
assert captured["model_kwargs"] == {
"model": "platform-model",
"base_url": "http://litellm.test/v1",
"api_key": "scoped-grant-token",
"stream_usage": True,
"extra_body": {"extra_body": {"thinking": {"type": "disabled"}}},
}
def test_reviewer_graph_rejects_missing_forwarded_llm_credentials(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setenv("A2A_LITELLM_KEY", "env-key-should-not-be-used")
with pytest.raises(ValueError, match="forwarded ctx\\.llm credentials"):
build_reviewer_graph(
ReviewerContext(
agent_name="hello-agent",
ref="main",
gitea_token="gitea-read-token",
gitea_owner="gitea_admin",
),
completion_box={},
)
def test_invalid_severity_rejected() -> None: def test_invalid_severity_rejected() -> None:
with pytest.raises(Exception): with pytest.raises(Exception):
Finding( Finding(