Require forwarded reviewer LLM credentials
This commit is contained in:
@@ -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":
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user