feat(jason): koble opax-mcp til Jason — opax_mcp_client.py + oppdater mcp_tools.py + jason-vauger.md
This commit is contained in:
parent
7d4b475189
commit
e96e9329d5
|
|
@ -1,16 +1,16 @@
|
||||||
# Jason Vauger — Personlig AI-assistent
|
# Jason Vauger — Personlig AI-assistent
|
||||||
|
|
||||||
**Status:** Under utvikling
|
**Status:** Aktiv (opax-mcp tilkoblet)
|
||||||
**Sist oppdatert:** 2026-06-01
|
**Sist oppdatert:** 2026-06-15
|
||||||
**Eier:** Marte Solbrekke Hein / OS-Vauco
|
**Eier:** Chris Christiansen / OS-Vauco
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Hvem er Jason Vauger?
|
## Hvem er Jason Vauger?
|
||||||
|
|
||||||
Jason Vauger er den personlige AI-assistenten til Marte — det øverste interface-laget i OSVauco-stacken. Jason er ikke en teknisk worker-agent, men en **persona** som wrapper hele systemet og kommuniserer med Marte i naturlig språk om alt fra daglige gjøremål til strategiske beslutninger.
|
Jason Vauger er den personlige AI-assistenten til Chris — det øverste interface-laget i OSVauco-stacken. Jason er ikke en teknisk worker-agent, men en **persona** som wrapper hele systemet og kommuniserer med Chris i naturlig språk om alt fra daglige gjøremål til strategiske beslutninger.
|
||||||
|
|
||||||
Når alt er oppe og går, er Jason det eneste grensesnittet Marte trenger.
|
Når alt er oppe og går, er Jason det eneste grensesnittet Chris trenger.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -22,14 +22,14 @@ Når alt er oppe og går, er Jason det eneste grensesnittet Marte trenger.
|
||||||
│ (Personlig assistent — persona-lag) │
|
│ (Personlig assistent — persona-lag) │
|
||||||
│ Naturlig språk inn/ut • Kontekst over tid │
|
│ Naturlig språk inn/ut • Kontekst over tid │
|
||||||
└────────────────┬────────────────────────────┘
|
└────────────────┬────────────────────────────┘
|
||||||
│ delegerer til
|
│ delegerer via
|
||||||
┌────────────────▼────────────────────────────┐
|
┌────────────────▼────────────────────────────┐
|
||||||
│ OPAX Orchestrator │
|
│ opax-mcp (Cloud Run) │
|
||||||
│ (PS Server-node / DAG hub) │
|
│ https://opax-mcp-zjbqp3prqq-uc.a.run.app │
|
||||||
|
│ 25 tools: billing, notify, gh, platform │
|
||||||
└──────┬──────┬──────┬──────┬──────┬──────────┘
|
└──────┬──────┬──────┬──────┬──────┬──────────┘
|
||||||
│ │ │ │ │
|
│ │ │ │ │
|
||||||
billing rag memory eval multi
|
billing notify github agents platform
|
||||||
-agent -agent -agent -agent -agent
|
|
||||||
```
|
```
|
||||||
|
|
||||||
| Egenskap | Verdi |
|
| Egenskap | Verdi |
|
||||||
|
|
@ -55,27 +55,26 @@ Når alt er oppe og går, er Jason det eneste grensesnittet Marte trenger.
|
||||||
- Bruker `agents/memory/` som langtidsminne
|
- Bruker `agents/memory/` som langtidsminne
|
||||||
- Bruker `agents/rag/` for dokumentkontekst og historikk
|
- Bruker `agents/rag/` for dokumentkontekst og historikk
|
||||||
|
|
||||||
### 3. Orchestrator-interface
|
### 3. Orchestrator-interface via opax-mcp
|
||||||
- Oversetter naturlig-språk-instruksjoner til OPAX DAG-kall
|
- Oversetter naturlig-språk-instruksjoner til opax-mcp tool-kall
|
||||||
- Delegerer billing-spørsmål til `billing-agent`
|
- Alle tool-kall går via `agents/tools/opax_mcp_client.py`
|
||||||
- Delegerer dokumentsøk til `rag-agent`
|
- Auth: Cloud Run IAM (lag 1) + X-MCP-Secret (lag 2)
|
||||||
- Rapporterer resultater tilbake i Martes format, ikke system-format
|
|
||||||
|
|
||||||
### 4. Infrastruktur-awareness
|
### 4. Infrastruktur-awareness
|
||||||
- Har innsikt i GCP-status, Cloud Run, kostnader (via Costguard)
|
- Har innsikt i GCP-status, Cloud Run, kostnader (via get_billing_summary)
|
||||||
- Kan varsle om unormale hendelser eller budsjettavvik
|
- Kan varsle om unormale hendelser eller budsjettavvik (via get_billing_anomalies)
|
||||||
- Kjenner til alle fire tjenester: OPAX, OS, Costguard, Threadstone
|
- CI/CD-status via get_build_status og list_commits
|
||||||
|
|
||||||
### 5. Handoff og dokumentasjon
|
### 5. Handoff og dokumentasjon
|
||||||
- Kan opprette GitHub Issues, PR-kommentarer og commit-noter
|
- Oppretter GitHub Issues via create_github_issue
|
||||||
|
- Pusher filer via push_file
|
||||||
- Logger viktige beslutninger og noter til repoet
|
- Logger viktige beslutninger og noter til repoet
|
||||||
- Fungerer som levende dokumentasjon av systemets tilstand
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Personlighet og tone
|
## Personlighet og tone
|
||||||
|
|
||||||
Jason er direkte, presis og lojal. Han er ikke en chatbot som prøver å imponere — han er en pålitelig assistent som gjør det som trengs uten unødvendig prat. Når Marte sier "fikset" betyr det fikset. Når hun sier "notis" betyr det logg det og ikke glem det.
|
Jason er direkte, presis og lojal. Han er ikke en chatbot som prøver å imponere — han er en pålitelig assistent som gjør det som trengs uten unødvendig prat. Når Chris sier "fikset" betyr det fikset. Når han sier "notis" betyr det logg det og ikke glem det.
|
||||||
|
|
||||||
- **Tone:** Profesjonell, men uformell. Norsk som standard.
|
- **Tone:** Profesjonell, men uformell. Norsk som standard.
|
||||||
- **Initiativ:** Tar ikke initiativ uten grunn — men varsler proaktivt ved viktige hendelser.
|
- **Initiativ:** Tar ikke initiativ uten grunn — men varsler proaktivt ved viktige hendelser.
|
||||||
|
|
@ -87,32 +86,47 @@ Jason er direkte, presis og lojal. Han er ikke en chatbot som prøver å imponer
|
||||||
|
|
||||||
| System | Integrasjon | Status |
|
| System | Integrasjon | Status |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| OPAX Orchestrator | Primær delegering | 🔄 Under bygging |
|
| opax-mcp Cloud Run | Primær tool-gateway (25 tools) | ✅ Aktiv |
|
||||||
|
| `agents/tools/opax_mcp_client.py` | REST-klient for alle tools | ✅ Aktiv |
|
||||||
|
| `agents/tools/mcp_tools.py` | ADK FunctionTool-wrapper | ✅ Aktiv |
|
||||||
|
| `agents/core-logic/agent.py` | Jason ADK agent runtime | 🔄 Kobles til ved neste deploy |
|
||||||
| `agents/memory/` | Langtidsminne / preferanser | 🔄 Under bygging |
|
| `agents/memory/` | Langtidsminne / preferanser | 🔄 Under bygging |
|
||||||
| `agents/rag/` | Dokumentkontekst og historikk | 🔄 Under bygging |
|
| `agents/rag/` | Dokumentkontekst og historikk | 🔄 Under bygging |
|
||||||
| `agents/tools/` | Verktøykall (GitHub, GCP, kalender) | 🔄 Under bygging |
|
|
||||||
| vauco-gemini-tui-bridge | Primær input-kanal | 🔄 Under bygging |
|
| vauco-gemini-tui-bridge | Primær input-kanal | 🔄 Under bygging |
|
||||||
| Costguard | Kostnadsovervåkning og varsler | ⏳ Planlagt |
|
| Costguard | Kostnadsovervåkning og varsler | ⏳ Planlagt |
|
||||||
| Threadstone | Prosjekt- og trådstyring | ⏳ Planlagt |
|
| Threadstone | Prosjekt- og trådstyring | ⏳ Planlagt |
|
||||||
| GitHub MCP | Issues, PRer, commits | ✅ Aktiv (via Perplexity) |
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vertex AI / ADK oppsett — neste steg
|
||||||
|
|
||||||
|
For å kjøre Jason i prod på Vertex AI Reasoning Engine:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Aktiver Reasoning Engine API
|
||||||
|
gcloud services enable aiplatform.googleapis.com \
|
||||||
|
--project=propane-will-491900-m5
|
||||||
|
|
||||||
|
# 2. Deploy Jason ADK agent
|
||||||
|
cd agents/core-logic
|
||||||
|
python deploy_agent.py
|
||||||
|
|
||||||
|
# 3. Sett MCP_SERVER_URL og MCP_SECRET som env i Cloud Run
|
||||||
|
gcloud run services update osvauco-agent \
|
||||||
|
--region=us-central1 \
|
||||||
|
--project=propane-will-491900-m5 \
|
||||||
|
--set-env-vars=MCP_SERVER_URL=https://opax-mcp-zjbqp3prqq-uc.a.run.app \
|
||||||
|
--set-secrets=MCP_SECRET=mcp-server-key:latest
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Avhengigheter og forutsetninger
|
## Avhengigheter og forutsetninger
|
||||||
|
|
||||||
- Alle OAuth-klienter for OPAX, OS, Costguard og Threadstone må være korrekt konfigurert (se [Issue #16](https://github.com/vauco-saas/OSVauco/issues/16) — revisjon ved domeneflytting fra ProISP til Google)
|
- `opax-mcp` Cloud Run service oppe på `https://opax-mcp-zjbqp3prqq-uc.a.run.app` ✅
|
||||||
|
- Secret Manager: `mcp-server-key` og `github-pat` konfigurert ✅
|
||||||
- Vertex AI Reasoning Engine tilgjengelig i GCP-prosjektet
|
- Vertex AI Reasoning Engine tilgjengelig i GCP-prosjektet
|
||||||
- RAG-korpus populert med relevante dokumenter
|
- RAG-korpus populert med relevante dokumenter
|
||||||
- Secret Manager konfigurert med nødvendige API-nøkler
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Fremtidige utvidelser (ML-3)
|
|
||||||
|
|
||||||
- Personlig læringsloop: Jason tilpasser seg Martes arbeidsmønster over tid
|
|
||||||
- Proaktive forslag basert på historikk og kontekst
|
|
||||||
- Integrasjon med kalender og eksterne tjenester
|
|
||||||
- Stemmeinterface via TUI-bridge
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@ Supports:
|
||||||
- Local stdio MCP server (dev/test only)
|
- Local stdio MCP server (dev/test only)
|
||||||
|
|
||||||
Requires: google-adk >= 2.0.0, google-auth, httpx
|
Requires: google-adk >= 2.0.0, google-auth, httpx
|
||||||
|
|
||||||
|
Auth-mønster for opax-mcp:
|
||||||
|
Cloud Run IAM : Authorization: Bearer <identity-token> (lag 1)
|
||||||
|
Tool-level : X-MCP-Secret: <mcp-server-key> (lag 2)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
@ -56,102 +60,11 @@ def get_maps_mcp_toolset() -> MCPToolset:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# --- OPAX-MCP (Vauco intern CI/CD-kanal) via FunctionTools ---
|
# --- OPAX-MCP tools (importert frå opax_mcp_client) ---
|
||||||
# Bruker httpx over REST i stedet for MCPToolset siden opax-mcp er en
|
|
||||||
# vanlig FastAPI-server, ikke en MCP streamable-server med session-handshake.
|
|
||||||
|
|
||||||
def _opax_identity_token() -> str:
|
|
||||||
"""
|
|
||||||
Hent Cloud Run identity token fra GCE metadata server.
|
|
||||||
Kjører på Cloud Run / GCE — audience må matche opax-mcp sin URL.
|
|
||||||
Fallback til ADC access token for lokal utvikling.
|
|
||||||
"""
|
|
||||||
import httpx
|
|
||||||
metadata_url = (
|
|
||||||
"http://metadata.google.internal/computeMetadata/v1/instance"
|
|
||||||
f"/service-accounts/default/identity?audience={OPAX_MCP_URL}&format=full"
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
resp = httpx.get(
|
|
||||||
metadata_url,
|
|
||||||
headers={"Metadata-Flavor": "Google"},
|
|
||||||
timeout=5,
|
|
||||||
)
|
|
||||||
if resp.status_code == 200 and resp.text.strip():
|
|
||||||
return resp.text.strip()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
# Fallback: ADC access token (lokal dev)
|
|
||||||
credentials, _ = google.auth.default()
|
|
||||||
credentials.refresh(google.auth.transport.requests.Request())
|
|
||||||
return credentials.token
|
|
||||||
|
|
||||||
|
|
||||||
def _opax_headers() -> dict:
|
|
||||||
"""Bygg auth-headers for opax-mcp: Cloud Run identity token + MCP-nøkkel."""
|
|
||||||
return {
|
|
||||||
"Authorization": f"Bearer {_opax_identity_token()}",
|
|
||||||
"X-MCP-Key": os.environ.get("MCP_SECRET", ""),
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def push_static(file_path: str, content: str, content_type: str = "text/html; charset=utf-8") -> dict:
|
|
||||||
"""Last opp en statisk fil (HTML/CSS/JS) til opax.vauco.no via GCS. file_path er relativ sti, f.eks. static/jason.html."""
|
|
||||||
import httpx
|
|
||||||
resp = httpx.post(
|
|
||||||
f"{OPAX_MCP_URL}/tools/push_static",
|
|
||||||
headers=_opax_headers(),
|
|
||||||
json={"file_path": file_path, "content": content, "content_type": content_type},
|
|
||||||
timeout=30,
|
|
||||||
)
|
|
||||||
resp.raise_for_status()
|
|
||||||
return resp.json()
|
|
||||||
|
|
||||||
def get_build_status() -> dict:
|
|
||||||
"""Hent status på siste Cloud Build-kjøring for OSVauco. Returnerer status, commit, varighet og logg-URL."""
|
|
||||||
import httpx
|
|
||||||
resp = httpx.get(
|
|
||||||
f"{OPAX_MCP_URL}/tools/get_build_status",
|
|
||||||
headers=_opax_headers(),
|
|
||||||
timeout=15,
|
|
||||||
)
|
|
||||||
resp.raise_for_status()
|
|
||||||
return resp.json()
|
|
||||||
|
|
||||||
def get_logs(lines: int = 50, severity: str = "DEFAULT") -> dict:
|
|
||||||
"""Hent siste Cloud Run-logger for osvauco-agent. severity: ERROR | WARNING | INFO | DEFAULT."""
|
|
||||||
import httpx
|
|
||||||
resp = httpx.get(
|
|
||||||
f"{OPAX_MCP_URL}/tools/get_logs",
|
|
||||||
headers=_opax_headers(),
|
|
||||||
params={"lines": lines, "severity": severity},
|
|
||||||
timeout=15,
|
|
||||||
)
|
|
||||||
resp.raise_for_status()
|
|
||||||
return resp.json()
|
|
||||||
|
|
||||||
def deploy_service(branch: str = "main", trigger_id: str = "") -> dict:
|
|
||||||
"""Trigger Cloud Build for å bygge og deploye osvauco-agent. Krever HITL-godkjenning fra Chris."""
|
|
||||||
import httpx
|
|
||||||
resp = httpx.post(
|
|
||||||
f"{OPAX_MCP_URL}/tools/deploy_service",
|
|
||||||
headers=_opax_headers(),
|
|
||||||
json={"branch": branch, "trigger_id": trigger_id},
|
|
||||||
timeout=15,
|
|
||||||
)
|
|
||||||
resp.raise_for_status()
|
|
||||||
return resp.json()
|
|
||||||
|
|
||||||
def get_opax_tools() -> list:
|
def get_opax_tools() -> list:
|
||||||
"""Returner liste med ADK FunctionTool-er for opax-mcp."""
|
"""Returner alle 25 opax-mcp tools som ADK FunctionTool-liste."""
|
||||||
from google.adk.tools import FunctionTool
|
from agents.tools.opax_mcp_client import get_all_function_tools
|
||||||
return [
|
return get_all_function_tools()
|
||||||
FunctionTool(func=push_static),
|
|
||||||
FunctionTool(func=get_build_status),
|
|
||||||
FunctionTool(func=get_logs),
|
|
||||||
FunctionTool(func=deploy_service),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# --- Local stdio MCP server (dev/test only) ---
|
# --- Local stdio MCP server (dev/test only) ---
|
||||||
|
|
|
||||||
234
agents/tools/opax_mcp_client.py
Normal file
234
agents/tools/opax_mcp_client.py
Normal file
|
|
@ -0,0 +1,234 @@
|
||||||
|
"""
|
||||||
|
opax_mcp_client.py — REST-klient for opax-mcp Cloud Run service.
|
||||||
|
Bruk denne for å kalle alle 25 tools frå Jason/Emma eller anna Python-kode.
|
||||||
|
|
||||||
|
Auth-lag:
|
||||||
|
1. Cloud Run IAM : Authorization: Bearer <identity-token> (automatisk)
|
||||||
|
2. Tool-level : X-MCP-Secret: <mcp-server-key> (frå Secret Manager)
|
||||||
|
|
||||||
|
URL: https://opax-mcp-zjbqp3prqq-uc.a.run.app
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import httpx
|
||||||
|
import google.auth
|
||||||
|
import google.auth.transport.requests
|
||||||
|
|
||||||
|
OPAX_MCP_URL = os.environ.get("MCP_SERVER_URL", "https://opax-mcp-zjbqp3prqq-uc.a.run.app")
|
||||||
|
MCP_SECRET = os.environ.get("MCP_SECRET", "")
|
||||||
|
|
||||||
|
|
||||||
|
def _identity_token() -> str:
|
||||||
|
"""Hent Cloud Run identity token (GCE metadata) eller ADC access token (lokal dev)."""
|
||||||
|
metadata_url = (
|
||||||
|
"http://metadata.google.internal/computeMetadata/v1/instance"
|
||||||
|
f"/service-accounts/default/identity?audience={OPAX_MCP_URL}&format=full"
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
resp = httpx.get(metadata_url, headers={"Metadata-Flavor": "Google"}, timeout=5)
|
||||||
|
if resp.status_code == 200 and resp.text.strip():
|
||||||
|
return resp.text.strip()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
credentials, _ = google.auth.default()
|
||||||
|
credentials.refresh(google.auth.transport.requests.Request())
|
||||||
|
return credentials.token
|
||||||
|
|
||||||
|
|
||||||
|
def _headers() -> dict:
|
||||||
|
return {
|
||||||
|
"Authorization": f"Bearer {_identity_token()}",
|
||||||
|
"X-MCP-Secret": MCP_SECRET,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def call_tool(tool: str, params: dict = None) -> dict:
|
||||||
|
"""Kall eit opax-mcp tool. Returnerer {tool, result}."""
|
||||||
|
resp = httpx.post(
|
||||||
|
f"{OPAX_MCP_URL}/tools/call",
|
||||||
|
headers=_headers(),
|
||||||
|
json={"tool": tool, "params": params or {}},
|
||||||
|
timeout=30,
|
||||||
|
)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return resp.json()
|
||||||
|
|
||||||
|
|
||||||
|
def list_tools() -> list:
|
||||||
|
"""List alle tilgjengelige tools i opax-mcp."""
|
||||||
|
resp = httpx.get(f"{OPAX_MCP_URL}/tools", headers=_headers(), timeout=10)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return resp.json().get("tools", [])
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Billing
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def get_billing_summary() -> dict:
|
||||||
|
"""Hent billing-oversikt for OSVauco (GCP-kostnader, token-forbruk)."""
|
||||||
|
return call_tool("get_billing_summary")
|
||||||
|
|
||||||
|
def get_billing_forecast() -> dict:
|
||||||
|
"""Hent token-estimat og kostnadsframskriving."""
|
||||||
|
return call_tool("get_billing_forecast")
|
||||||
|
|
||||||
|
def get_billing_credits() -> dict:
|
||||||
|
"""Hent gjenværende GCP-kreditter."""
|
||||||
|
return call_tool("get_billing_credits")
|
||||||
|
|
||||||
|
def get_billing_anomalies() -> dict:
|
||||||
|
"""Sjekk for kostnadanomalier og uventede spiker."""
|
||||||
|
return call_tool("get_billing_anomalies")
|
||||||
|
|
||||||
|
def get_billing_history() -> dict:
|
||||||
|
"""Hent historisk kostnadsdata."""
|
||||||
|
return call_tool("get_billing_history")
|
||||||
|
|
||||||
|
def get_billing_budget() -> dict:
|
||||||
|
"""Hent gjeldande budsjett for OSVauco."""
|
||||||
|
return call_tool("get_billing_budget")
|
||||||
|
|
||||||
|
def set_billing_budget(amount: float, currency: str = "USD") -> dict:
|
||||||
|
"""Sett nytt budsjett. amount er beløp i angitt valuta."""
|
||||||
|
return call_tool("set_billing_budget", {"amount": amount, "currency": currency})
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Onboarding
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def create_invite(email: str, name: str = "", tier: str = "starter") -> dict:
|
||||||
|
"""Opprett invite for ny bruker. tier: starter | pro | enterprise."""
|
||||||
|
return call_tool("create_invite", {"email": email, "name": name, "tier": tier})
|
||||||
|
|
||||||
|
def list_customers() -> dict:
|
||||||
|
"""List alle onboardede kunder."""
|
||||||
|
return call_tool("list_customers")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Notify
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def send_webhook(message: str, url: str = "") -> dict:
|
||||||
|
"""Send webhook-varsling. url er valgfri override."""
|
||||||
|
return call_tool("send_webhook", {"message": message, "url": url})
|
||||||
|
|
||||||
|
def send_email(to: str, subject: str, body: str) -> dict:
|
||||||
|
"""Send e-post via OPAX notify-modul."""
|
||||||
|
return call_tool("send_email", {"to": to, "subject": subject, "body": body})
|
||||||
|
|
||||||
|
def send_sms(to: str, message: str) -> dict:
|
||||||
|
"""Send SMS via OPAX notify-modul."""
|
||||||
|
return call_tool("send_sms", {"to": to, "message": message})
|
||||||
|
|
||||||
|
def get_notify_channels() -> dict:
|
||||||
|
"""List konfigurerte varslingskanalar."""
|
||||||
|
return call_tool("get_notify_channels")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Agents
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def run_jason(prompt: str) -> dict:
|
||||||
|
"""Kall Jason-agenten med ein prompt via OPAX."""
|
||||||
|
return call_tool("run_jason", {"prompt": prompt})
|
||||||
|
|
||||||
|
def run_emma(prompt: str) -> dict:
|
||||||
|
"""Kall Emma-agenten med ein prompt via OPAX."""
|
||||||
|
return call_tool("run_emma", {"prompt": prompt})
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Platform
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def get_health() -> dict:
|
||||||
|
"""Sjekk helsestatus for OPAX-plattformen."""
|
||||||
|
return call_tool("get_health")
|
||||||
|
|
||||||
|
def get_build_status() -> dict:
|
||||||
|
"""Hent status på siste Cloud Build-kjøring."""
|
||||||
|
return call_tool("get_build_status")
|
||||||
|
|
||||||
|
def get_state() -> dict:
|
||||||
|
"""Hent gjeldande systemtilstand for OSVauco."""
|
||||||
|
return call_tool("get_state")
|
||||||
|
|
||||||
|
def get_telemetry() -> dict:
|
||||||
|
"""Hent token-forbruk per modul."""
|
||||||
|
return call_tool("get_telemetry")
|
||||||
|
|
||||||
|
def run_terminal(command: str) -> dict:
|
||||||
|
"""Kjør kommando i OPAX terminal-exec. Krever HITL-godkjenning."""
|
||||||
|
return call_tool("run_terminal", {"command": command})
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# GitHub
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def list_commits(repo: str = "", limit: int = 10) -> dict:
|
||||||
|
"""List siste commits i repoet."""
|
||||||
|
return call_tool("list_commits", {"repo": repo, "limit": limit})
|
||||||
|
|
||||||
|
def get_file(path: str, repo: str = "") -> dict:
|
||||||
|
"""Hent innhald i ein fil frå GitHub."""
|
||||||
|
return call_tool("get_file", {"path": path, "repo": repo})
|
||||||
|
|
||||||
|
def list_open_issues(repo: str = "") -> dict:
|
||||||
|
"""List alle opne issues i repoet."""
|
||||||
|
return call_tool("list_open_issues", {"repo": repo})
|
||||||
|
|
||||||
|
def create_github_issue(title: str, body: str = "", repo: str = "") -> dict:
|
||||||
|
"""Opprett nytt GitHub issue."""
|
||||||
|
return call_tool("create_github_issue", {"title": title, "body": body, "repo": repo})
|
||||||
|
|
||||||
|
def push_file(path: str, content: str, message: str = "", sha: str = "", repo: str = "") -> dict:
|
||||||
|
"""Push/oppdater ein fil i GitHub. sha krevst ved oppdatering av eksisterande fil."""
|
||||||
|
return call_tool("push_file", {"path": path, "content": content, "message": message, "sha": sha, "repo": repo})
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# ADK FunctionTools — for bruk i agent.py
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def get_all_function_tools() -> list:
|
||||||
|
"""Returner alle 25 tools som ADK FunctionTool-liste for Jason/Emma."""
|
||||||
|
from google.adk.tools import FunctionTool
|
||||||
|
return [
|
||||||
|
# Billing
|
||||||
|
FunctionTool(func=get_billing_summary),
|
||||||
|
FunctionTool(func=get_billing_forecast),
|
||||||
|
FunctionTool(func=get_billing_credits),
|
||||||
|
FunctionTool(func=get_billing_anomalies),
|
||||||
|
FunctionTool(func=get_billing_history),
|
||||||
|
FunctionTool(func=get_billing_budget),
|
||||||
|
FunctionTool(func=set_billing_budget),
|
||||||
|
# Onboarding
|
||||||
|
FunctionTool(func=create_invite),
|
||||||
|
FunctionTool(func=list_customers),
|
||||||
|
# Notify
|
||||||
|
FunctionTool(func=send_webhook),
|
||||||
|
FunctionTool(func=send_email),
|
||||||
|
FunctionTool(func=send_sms),
|
||||||
|
FunctionTool(func=get_notify_channels),
|
||||||
|
# Agents
|
||||||
|
FunctionTool(func=run_jason),
|
||||||
|
FunctionTool(func=run_emma),
|
||||||
|
# Platform
|
||||||
|
FunctionTool(func=get_health),
|
||||||
|
FunctionTool(func=get_build_status),
|
||||||
|
FunctionTool(func=get_state),
|
||||||
|
FunctionTool(func=get_telemetry),
|
||||||
|
FunctionTool(func=run_terminal),
|
||||||
|
# GitHub
|
||||||
|
FunctionTool(func=list_commits),
|
||||||
|
FunctionTool(func=get_file),
|
||||||
|
FunctionTool(func=list_open_issues),
|
||||||
|
FunctionTool(func=create_github_issue),
|
||||||
|
FunctionTool(func=push_file),
|
||||||
|
]
|
||||||
Loading…
Reference in New Issue
Block a user