feat(mcp): Align client to JSON-RPC and update Emma model
- Refactor opax_mcp_client to use the JSON-RPC 2.0 MCP protocol. - Set the client fallback endpoint to: https://opax-mcp-357036551735.us-central1.run.app - Set run_emma’s fallback model to qwen2.5:7b. - Update run_emma’s MCP tool description to qwen2.5:7b.
This commit is contained in:
parent
a1d28db7c5
commit
054afd180c
|
|
@ -14,7 +14,7 @@ import httpx
|
||||||
import google.auth
|
import google.auth
|
||||||
import google.auth.transport.requests
|
import google.auth.transport.requests
|
||||||
|
|
||||||
OPAX_MCP_URL = os.environ.get("MCP_SERVER_URL", "https://opax-mcp-zjbqp3prqq-uc.a.run.app")
|
OPAX_MCP_URL = os.environ.get("MCP_SERVER_URL", "https://opax-mcp-357036551735.us-central1.run.app")
|
||||||
MCP_SECRET = os.environ.get("MCP_SECRET", "")
|
MCP_SECRET = os.environ.get("MCP_SECRET", "")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -44,22 +44,71 @@ def _headers() -> dict:
|
||||||
|
|
||||||
|
|
||||||
def call_tool(tool: str, params: dict = None) -> dict:
|
def call_tool(tool: str, params: dict = None) -> dict:
|
||||||
"""Kall eit opax-mcp tool. Returnerer {tool, result}."""
|
"""Kall eit tool på OPAX JSON-RPC MCP endepunktet."""
|
||||||
resp = httpx.post(
|
endpoint = OPAX_MCP_URL.rstrip("/") + "/"
|
||||||
f"{OPAX_MCP_URL}/tools/call",
|
payload = {
|
||||||
headers=_headers(),
|
"jsonrpc": "2.0",
|
||||||
json={"tool": tool, "params": params or {}},
|
"id": "opax-client-tools-call",
|
||||||
timeout=30,
|
"method": "tools/call",
|
||||||
)
|
"params": {
|
||||||
|
"name": tool,
|
||||||
|
"arguments": params or {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resp = httpx.post(endpoint, headers=_headers(), json=payload, timeout=30)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
return resp.json()
|
json_resp = resp.json()
|
||||||
|
|
||||||
|
if not isinstance(json_resp, dict):
|
||||||
|
raise RuntimeError("JSON-RPC response must be an object.")
|
||||||
|
|
||||||
|
error = json_resp.get("error")
|
||||||
|
if error:
|
||||||
|
if isinstance(error, dict):
|
||||||
|
raise RuntimeError(
|
||||||
|
f"JSON-RPC error {error.get('code')}: {error.get('message')}"
|
||||||
|
)
|
||||||
|
raise RuntimeError("JSON-RPC response contains an invalid error object.")
|
||||||
|
|
||||||
|
if "result" not in json_resp:
|
||||||
|
raise RuntimeError("JSON-RPC response missing 'result' field.")
|
||||||
|
|
||||||
|
return json_resp["result"]
|
||||||
|
|
||||||
|
|
||||||
def list_tools() -> list:
|
def list_tools() -> list:
|
||||||
"""List alle tilgjengelige tools i opax-mcp."""
|
"""List alle tilgjengelige tools frå OPAX JSON-RPC MCP endepunktet."""
|
||||||
resp = httpx.get(f"{OPAX_MCP_URL}/tools", headers=_headers(), timeout=10)
|
endpoint = OPAX_MCP_URL.rstrip("/") + "/"
|
||||||
|
payload = {
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": "opax-client-tools-list",
|
||||||
|
"method": "tools/list",
|
||||||
|
"params": {},
|
||||||
|
}
|
||||||
|
resp = httpx.post(endpoint, headers=_headers(), json=payload, timeout=10)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
return resp.json().get("tools", [])
|
json_resp = resp.json()
|
||||||
|
|
||||||
|
if not isinstance(json_resp, dict):
|
||||||
|
raise RuntimeError("JSON-RPC response must be an object.")
|
||||||
|
|
||||||
|
error = json_resp.get("error")
|
||||||
|
if error:
|
||||||
|
if isinstance(error, dict):
|
||||||
|
raise RuntimeError(
|
||||||
|
f"JSON-RPC error {error.get('code')}: {error.get('message')}"
|
||||||
|
)
|
||||||
|
raise RuntimeError("JSON-RPC response contains an invalid error object.")
|
||||||
|
|
||||||
|
result = json_resp.get("result")
|
||||||
|
if not isinstance(result, dict):
|
||||||
|
raise RuntimeError("JSON-RPC response missing object 'result' field.")
|
||||||
|
|
||||||
|
tools = result.get("tools")
|
||||||
|
if not isinstance(tools, list):
|
||||||
|
raise RuntimeError("JSON-RPC response missing 'result.tools' list.")
|
||||||
|
|
||||||
|
return tools
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ WORKSPACE_ADMIN_USER = "chris.christiansen@vauco.no"
|
||||||
|
|
||||||
# Emma-vm Ollama — direkte tilkobling
|
# Emma-vm Ollama — direkte tilkobling
|
||||||
OLLAMA_BASE_URL = os.environ.get("OLLAMA_BASE_URL", "http://34.13.238.133:11434")
|
OLLAMA_BASE_URL = os.environ.get("OLLAMA_BASE_URL", "http://34.13.238.133:11434")
|
||||||
EMMA_MODEL = os.environ.get("EMMA_MODEL", "gemma3:27b")
|
EMMA_MODEL = os.environ.get("EMMA_MODEL", "qwen2.5:7b")
|
||||||
EMMA_FAST_MODEL = os.environ.get("EMMA_FAST_MODEL", "gemma3:4b")
|
EMMA_FAST_MODEL = os.environ.get("EMMA_FAST_MODEL", "gemma3:4b")
|
||||||
EMMA_LIGHT_MODEL = os.environ.get("EMMA_LIGHT_MODEL", "qwen2.5:3b")
|
EMMA_LIGHT_MODEL = os.environ.get("EMMA_LIGHT_MODEL", "qwen2.5:3b")
|
||||||
|
|
||||||
|
|
@ -775,7 +775,7 @@ TOOLS = {
|
||||||
),
|
),
|
||||||
# AI Agents
|
# AI Agents
|
||||||
"run_jason": (run_jason, "Kjør Jason-agenten med en prompt", {"type":"object","properties":{"prompt":{"type":"string"},"mode":{"type":"string"}},"required":["prompt"]}),
|
"run_jason": (run_jason, "Kjør Jason-agenten med en prompt", {"type":"object","properties":{"prompt":{"type":"string"},"mode":{"type":"string"}},"required":["prompt"]}),
|
||||||
"run_emma": (run_emma, "Emma Vauger (gemma3:27b) — primær lokal AI", {"type":"object","properties":{"prompt":{"type":"string"}}}),
|
"run_emma": (run_emma, "Emma Vauger (qwen2.5:7b) — primær lokal AI", {"type":"object","properties":{"prompt":{"type":"string"}}}),
|
||||||
|
|
||||||
# Local models — read-only discovery
|
# Local models — read-only discovery
|
||||||
"list_emma_models": (
|
"list_emma_models": (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user