fix(hub): various fixes for hub connector

This commit is contained in:
Chris Christiansen 2026-09-05 13:04:04 +00:00
parent d649f9b301
commit 563b49da7c
5 changed files with 80 additions and 4 deletions

View File

@ -88,7 +88,7 @@ def _identity_token() -> str:
def _mcp_headers() -> dict: def _mcp_headers() -> dict:
return { return {
"X-MCP-Key": _MCP_SECRET, "X-MCP-Key": _MCP_SECRET.strip(),
"Content-Type": "application/json", "Content-Type": "application/json",
} }

View File

@ -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}) 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 # ADK FunctionTools — for bruk i agent.py
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -209,4 +257,5 @@ def get_all_function_tools() -> list:
FunctionTool(func=list_open_issues), FunctionTool(func=list_open_issues),
FunctionTool(func=create_issue), FunctionTool(func=create_issue),
FunctionTool(func=push_file), FunctionTool(func=push_file),
FunctionTool(func=create_a2h2a_ticket),
] ]

View File

@ -73,7 +73,7 @@ def _identity_token() -> str:
def _mcp_headers() -> dict: def _mcp_headers() -> dict:
return { return {
"X-MCP-Key": _MCP_SECRET, "X-MCP-Key": _MCP_SECRET.strip(),
"Content-Type": "application/json", "Content-Type": "application/json",
} }

View File

@ -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}) 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 # ADK FunctionTools — for bruk i agent.py
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -231,4 +256,6 @@ def get_all_function_tools() -> list:
FunctionTool(func=list_open_issues), FunctionTool(func=list_open_issues),
FunctionTool(func=create_github_issue), FunctionTool(func=create_github_issue),
FunctionTool(func=push_file), FunctionTool(func=push_file),
# A2H2A
FunctionTool(func=create_a2h2a_ticket),
] ]

View File

@ -124,7 +124,7 @@ async def require_iap(request: Request, call_next):
from google.auth.transport import requests as grequests from google.auth.transport import requests as grequests
id_token.verify_oauth2_token( id_token.verify_oauth2_token(
token, grequests.Request(), 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) return await call_next(request)
except Exception as e: except Exception as e:
@ -208,7 +208,7 @@ def require_auth(func):
from google.auth.transport import requests as grequests from google.auth.transport import requests as grequests
idinfo = id_token.verify_oauth2_token( idinfo = id_token.verify_oauth2_token(
token, grequests.Request(), 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')} request.session['user'] = {'email': idinfo.get('email', 'service-account')}
return await func(request, *args, **kwargs) return await func(request, *args, **kwargs)