diff --git a/agents/core-logic/agent.py b/agents/core-logic/agent.py index 46c6c8d..534a66b 100644 --- a/agents/core-logic/agent.py +++ b/agents/core-logic/agent.py @@ -88,7 +88,7 @@ def _identity_token() -> str: def _mcp_headers() -> dict: return { - "X-MCP-Key": _MCP_SECRET, + "X-MCP-Key": _MCP_SECRET.strip(), "Content-Type": "application/json", } diff --git a/agents/core-logic/opax_mcp_client.py b/agents/core-logic/opax_mcp_client.py index c174d99..506bee5 100644 --- a/agents/core-logic/opax_mcp_client.py +++ b/agents/core-logic/opax_mcp_client.py @@ -177,6 +177,54 @@ def push_file(path: str, content: str, message: str = "", sha: str = "") -> dict return call_tool("push_file", {"path": path, "content": content, "message": message, "sha": sha}) +from pydantic import BaseModel, Field +from typing import Optional + +class TicketSource(BaseModel): + reporter: str + trigger: str + affected_service: str + project_id: str + +class ProposedAction(BaseModel): + execution_tool: str + tool_parameters: dict + parameter_hash: Optional[str] = None + +class Context(BaseModel): + summary: str + user_justification: str + conversation_history: list + +class Governance(BaseModel): + approval_status: str = "PENDING" + authorized_approver: str + requires_mfa: bool = True + timeout_minutes: int = 15 + +class A2H2ATicket(BaseModel): + ticket_id: Optional[str] = None + source: TicketSource + proposed_action: ProposedAction + context: Context + severity: str + governance: Governance + +# --------------------------------------------------------------------------- +# A2H2A (Human-in-the-Loop) +# --------------------------------------------------------------------------- +def create_a2h2a_ticket(ticket: A2H2ATicket) -> dict: + """Create a new A2H2A ticket for a sensitive operation.""" + resp = httpx.post( + f"{OPAX_MCP_URL}/api/v1/a2h2a/tickets", + headers=_headers(), + json=ticket.dict(), + timeout=30, + ) + resp.raise_for_status() + return resp.json() + + # --------------------------------------------------------------------------- # ADK FunctionTools — for bruk i agent.py # --------------------------------------------------------------------------- @@ -209,4 +257,5 @@ def get_all_function_tools() -> list: FunctionTool(func=list_open_issues), FunctionTool(func=create_issue), FunctionTool(func=push_file), + FunctionTool(func=create_a2h2a_ticket), ] diff --git a/agents/core-logic/root_agent.py b/agents/core-logic/root_agent.py index 573bfbb..b8fc38d 100644 --- a/agents/core-logic/root_agent.py +++ b/agents/core-logic/root_agent.py @@ -73,7 +73,7 @@ def _identity_token() -> str: def _mcp_headers() -> dict: return { - "X-MCP-Key": _MCP_SECRET, + "X-MCP-Key": _MCP_SECRET.strip(), "Content-Type": "application/json", } diff --git a/agents/tools/opax_mcp_client.py b/agents/tools/opax_mcp_client.py index 0342921..550eae8 100644 --- a/agents/tools/opax_mcp_client.py +++ b/agents/tools/opax_mcp_client.py @@ -192,6 +192,31 @@ def push_file(path: str, content: str, message: str = "", sha: str = "", repo: s return call_tool("push_file", {"path": path, "content": content, "message": message, "sha": sha, "repo": repo}) +# --------------------------------------------------------------------------- +# A2H2A +# --------------------------------------------------------------------------- +def create_a2h2a_ticket( + ticket_id: str, + source: dict, + proposed_action: dict, + context: dict, + severity: str, + governance: dict, +) -> dict: + """Creates an A2H2A ticket.""" + return call_tool( + "create_a2h2a_ticket", + { + "ticket_id": ticket_id, + "source": source, + "proposed_action": proposed_action, + "context": context, + "severity": severity, + "governance": governance, + }, + ) + + # --------------------------------------------------------------------------- # ADK FunctionTools — for bruk i agent.py # --------------------------------------------------------------------------- @@ -231,4 +256,6 @@ def get_all_function_tools() -> list: FunctionTool(func=list_open_issues), FunctionTool(func=create_github_issue), FunctionTool(func=push_file), + # A2H2A + FunctionTool(func=create_a2h2a_ticket), ] diff --git a/main.py b/main.py index 1a82767..04ef60a 100644 --- a/main.py +++ b/main.py @@ -124,7 +124,7 @@ async def require_iap(request: Request, call_next): from google.auth.transport import requests as grequests id_token.verify_oauth2_token( token, grequests.Request(), - audience=os.environ.get("SERVICE_URL", "https://osvauco-agent-357036551735.us-central1.run.app") + audience=os.environ.get("SERVICE_URL", "https://osvauco-agent-zjbqp3prqq-uc.a.run.app") ) return await call_next(request) except Exception as e: @@ -208,7 +208,7 @@ def require_auth(func): from google.auth.transport import requests as grequests idinfo = id_token.verify_oauth2_token( token, grequests.Request(), - audience=os.environ.get("SERVICE_URL", "https://osvauco-agent-357036551735.us-central1.run.app") + audience=os.environ.get("SERVICE_URL", "https://osvauco-agent-zjbqp3prqq-uc.a.run.app") ) request.session['user'] = {'email': idinfo.get('email', 'service-account')} return await func(request, *args, **kwargs)