from __future__ import annotations import json import subprocess from pathlib import Path import tomllib import pytest from nexum_core.api import NEXUM_CORE_VERSION from nexum_runtime.capabilities import capability_catalog from nexum_runtime.executor import execute_tool_call from nexum_runtime.protocols import a2a_request, agent_card, mcp_request from nexum_runtime.tooling.contracts import ToolCall def test_protocol_version_matches_release_package() -> None: pyproject = Path(__file__).resolve().parents[1] / "pyproject.toml" project = tomllib.loads(pyproject.read_text(encoding="utf-8"))["project"] assert NEXUM_CORE_VERSION == project["version"] def test_capability_catalog_exposes_general_capabilities() -> None: catalog = capability_catalog() assert catalog["count"] >= 26 identifiers = [row["capability_id"] for row in catalog["capabilities"]] assert len(identifiers) == len(set(identifiers)) assert "self-correction" in identifiers assert "self-improvement" in identifiers assert "portable-connectors" in identifiers assert "language-packs" in identifiers rows = { row["capability_id"]: row for row in catalog["capabilities"] } assert "without a configured topology limit" in rows["self-improvement"][ "description" ] assert "model" in rows["parallel-dependencies"]["surfaces"] def test_mcp_initialization_listing_and_real_tool_call(tmp_path: Path) -> None: initialized = mcp_request( {"jsonrpc": "2.0", "id": 1, "method": "initialize"}, workspace=str(tmp_path), session_id="mcp-session", tools_enabled=True, ) assert initialized["result"]["serverInfo"]["name"] == "Nexum NNF X" assert initialized["result"]["serverInfo"]["version"] == NEXUM_CORE_VERSION listed = mcp_request( {"jsonrpc": "2.0", "id": 2, "method": "tools/list"}, workspace=str(tmp_path), session_id="mcp-session", tools_enabled=True, ) names = {row["name"] for row in listed["result"]["tools"]} assert { "Read", "GitStatus", "TaskStart", "BrowserNavigate", "ReproductionRun", "TriageCreate", "DisclosureCreate", "PatchApply", } <= names assert "AgentDelegate" not in names (tmp_path / "evidence.txt").write_text("real-mcp-result", encoding="utf-8") called = mcp_request( { "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "Read", "arguments": {"path": "evidence.txt"}, "call_id": "mcp-read", }, }, workspace=str(tmp_path), session_id="mcp-session", tools_enabled=True, ) structured = called["result"]["structuredContent"] assert structured["ok"] is True assert structured["output"] == "real-mcp-result" with pytest.raises(ValueError, match="caller-owned"): mcp_request( { "jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": { "name": "AgentDelegate", "arguments": { "agent": "reviewer", "objective": "Review the change", }, }, }, workspace=str(tmp_path), session_id="mcp-session", tools_enabled=True, ) def test_repository_connector_runs_through_common_executor(tmp_path: Path) -> None: subprocess.run(["git", "init", "-q"], cwd=tmp_path, check=True) (tmp_path / "tracked.txt").write_text("value", encoding="utf-8") result = execute_tool_call( ToolCall( name="GitStatus", args={"repository": "."}, raw="", call_id="git-status", ), cwd=str(tmp_path), session_id="repository-session", ) assert result.ok is True assert "tracked.txt" in result.output assert result.artifact_id.startswith("art_") def test_agent_card_and_delegated_request_use_shared_harness_result() -> None: card = agent_card("https://nexum.example") assert card["url"] == "https://nexum.example/a2a" assert card["version"] == NEXUM_CORE_VERSION assert card["capabilities"]["streaming"] is False assert len(card["skills"]) > 20 received: list[dict[str, object]] = [] def run_agent(payload: dict[str, object]) -> dict[str, object]: received.append(payload) return { "message": "completed", "final_text": "delegated result", "metadata": {"session_id": payload["session_id"]}, } response = a2a_request( { "jsonrpc": "2.0", "id": "request-1", "method": "message/send", "params": { "contextId": "delegated-session", "message": { "parts": [{"kind": "text", "text": "inspect the workspace"}] }, }, }, run_agent=run_agent, ) assert received == [ {"prompt": "inspect the workspace", "session_id": "delegated-session"} ] artifact = response["result"]["artifacts"][0] assert artifact["parts"][0]["text"] == "delegated result" def test_delegated_request_exposes_pending_model_selected_calls() -> None: def run_agent(_payload: dict[str, object]) -> dict[str, object]: return { "message": "external_tool_handoff", "tool_calls": [ { "id": "call_external", "type": "function", "function": { "name": "ExternalLookup", "arguments": '{"query":"status"}', }, } ], } payload = { "jsonrpc": "2.0", "id": "request-2", "method": "message/send", "params": { "contextId": "delegated-session", "message": {"parts": [{"kind": "text", "text": "look it up"}]}, }, } response = a2a_request(payload, run_agent=run_agent) assert response["result"]["status"]["state"] == "input-required" pending = response["result"]["metadata"]["pending_tool_calls"] assert pending[0]["id"] == "call_external" payload["method"] = "message/stream" with pytest.raises(ValueError, match="unsupported"): a2a_request(payload, run_agent=run_agent) def test_dynamic_tool_is_rediscoverable_after_registration(tmp_path: Path) -> None: created = execute_tool_call( ToolCall( name="CreateTool", args={ "name": "workspace_summary", "command": "pwd", "description": "Show the active workspace", }, raw="", call_id="create-dynamic", ), cwd=str(tmp_path), session_id="dynamic-session", ) assert created.ok is True catalog = execute_tool_call( ToolCall( name="ToolCatalog", args={"query": "workspace_summary"}, raw="", call_id="catalog-dynamic", ), cwd=str(tmp_path), session_id="dynamic-session", ) rows = json.loads(catalog.output)["tools"] assert rows[0]["name"] == "workspace_summary" assert rows[0]["invocation"] == "RunDynamicTool"