fix(models): gemini-2.5-flash (light) + gemini-2.5-pro (heavy), LOCATION=global for modellkall
This commit is contained in:
parent
f711f7be74
commit
7585a485e0
|
|
@ -1,16 +1,17 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
agent.py — Cloud Run entrypoint for OSVauco OPAX agent.
|
||||
agent.py — OSVauco OPAX agent.
|
||||
|
||||
Modes:
|
||||
light (standard) — gemini-2.0-flash-001, $1/task hard stop
|
||||
heavy (audit+) — gemini-2.5-pro-001, $3/task hard stop
|
||||
light — gemini-2.5-flash, $1/task
|
||||
heavy — gemini-2.5-pro, $3/task
|
||||
|
||||
Legacy values 'A' and 'A+' are accepted and normalized.
|
||||
Authorized users for heavy: opax, admin
|
||||
Legacy 'A' / 'A+' normaliseres automatisk.
|
||||
Authoriserte brukere for heavy: opax, admin
|
||||
|
||||
Requires: google-adk >= 1.0.0,<2.0.0
|
||||
google-cloud-aiplatform >= 1.112.0
|
||||
Gjeldende modell-tilgjengelighet (mai 2026):
|
||||
gemini-2.0-flash-001 kun for eksisterende kunder — bruk IKKE.
|
||||
gemini-2.5-flash / gemini-2.5-pro krever GOOGLE_CLOUD_LOCATION=global.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
|
|
@ -26,18 +27,18 @@ from google.genai import types
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT", "propane-will-491900-m5")
|
||||
LOCATION = os.environ.get("GOOGLE_CLOUD_LOCATION", "us-central1")
|
||||
LOCATION = os.environ.get("GOOGLE_CLOUD_LOCATION", "global")
|
||||
RAG_CORPUS = os.environ.get("RAG_CORPUS", "")
|
||||
|
||||
# Light mode — pinned to stable versioned alias
|
||||
ORCHESTRATOR_MODEL = os.environ.get("ORCHESTRATOR_MODEL", "gemini-2.0-flash-001")
|
||||
SUBAGENT_MODEL = os.environ.get("SUBAGENT_MODEL", "gemini-2.0-flash-001")
|
||||
REASONING_MODEL = os.environ.get("REASONING_MODEL", "gemini-2.0-flash-001")
|
||||
# Light mode — gemini-2.5-flash (GA, global)
|
||||
ORCHESTRATOR_MODEL = os.environ.get("ORCHESTRATOR_MODEL", "gemini-2.5-flash")
|
||||
SUBAGENT_MODEL = os.environ.get("SUBAGENT_MODEL", "gemini-2.5-flash")
|
||||
REASONING_MODEL = os.environ.get("REASONING_MODEL", "gemini-2.5-flash")
|
||||
|
||||
# Heavy mode
|
||||
HEAVY_ORCHESTRATOR = os.environ.get("HEAVY_ORCHESTRATOR_MODEL", "gemini-2.5-pro-001")
|
||||
HEAVY_SUBAGENT = os.environ.get("HEAVY_SUBAGENT_MODEL", "gemini-2.5-pro-001")
|
||||
HEAVY_REASONING = os.environ.get("HEAVY_REASONING_MODEL", "gemini-2.5-flash-001")
|
||||
# Heavy mode — gemini-2.5-pro (GA, global)
|
||||
HEAVY_ORCHESTRATOR = os.environ.get("HEAVY_ORCHESTRATOR_MODEL", "gemini-2.5-pro")
|
||||
HEAVY_SUBAGENT = os.environ.get("HEAVY_SUBAGENT_MODEL", "gemini-2.5-pro")
|
||||
HEAVY_REASONING = os.environ.get("HEAVY_REASONING_MODEL", "gemini-2.5-flash")
|
||||
|
||||
BUDGET_LIGHT = float(os.environ.get("BUDGET_A_USD_PER_TASK", "1.0"))
|
||||
BUDGET_HEAVY = float(os.environ.get("HEAVY_MODE_BUDGET_USD_PER_DAY", "3.0"))
|
||||
|
|
@ -59,8 +60,7 @@ def _normalize_mode(mode: str) -> str:
|
|||
|
||||
|
||||
def authorize_mode(user_id: str, mode: str) -> None:
|
||||
"""Normalize mode first, then check authorization. Raises ValueError or PermissionError."""
|
||||
mode = _normalize_mode(mode) # raises ValueError for unknown modes
|
||||
mode = _normalize_mode(mode)
|
||||
if mode == "heavy" and user_id not in HEAVY_MODE_ALLOWED_USERS:
|
||||
raise PermissionError(
|
||||
f"User '{user_id}' is not authorized for heavy mode. "
|
||||
|
|
@ -80,11 +80,11 @@ if RAG_CORPUS:
|
|||
similarity_top_k=10,
|
||||
vector_distance_threshold=0.6,
|
||||
)
|
||||
logger.info(f"RAG tool initialised with corpus: {RAG_CORPUS}")
|
||||
logger.info(f"RAG tool initialised: {RAG_CORPUS}")
|
||||
except ImportError as e:
|
||||
logger.warning(f"VertexAiRagRetrieval not available — running without RAG: {e}")
|
||||
logger.warning(f"VertexAiRagRetrieval ikke tilgjengelig: {e}")
|
||||
else:
|
||||
logger.warning("RAG_CORPUS env var not set — running without RAG retrieval")
|
||||
logger.warning("RAG_CORPUS ikke satt — kjører uten RAG")
|
||||
|
||||
|
||||
def get_models_for_mode(mode: Mode) -> dict:
|
||||
|
|
@ -108,18 +108,16 @@ def get_models_for_mode(mode: Mode) -> dict:
|
|||
def build_agent(mode: str = "light") -> Agent:
|
||||
mode = _normalize_mode(mode)
|
||||
models = get_models_for_mode(mode)
|
||||
mode_label = "heavy" if mode == "heavy" else "light"
|
||||
instruction = (
|
||||
f"Du er OPAX — OSVauco AI-agent. "
|
||||
f"Modus: {mode_label}. Budsjettgrense per oppgave: ${models['budget_usd']}. "
|
||||
"Bruk retrieve_knowledge-verktøyet for å hente dokumentasjon og kontekst. "
|
||||
"Foretrekk alltid dokumenterte svar fremfor spekulasjon. "
|
||||
"Svar alltid på norsk (bokmål) med mindre brukeren eksplisitt ber om et annet språk."
|
||||
f"Du er OPAX — OSVauco AI-agent. Modus: {mode}. "
|
||||
f"Budsjettgrense per oppgave: ${models['budget_usd']}. "
|
||||
"Bruk retrieve_knowledge for å hente dokumentasjon. "
|
||||
"Svar på norsk (bokmål) med mindre annet er bedt om."
|
||||
)
|
||||
return Agent(
|
||||
model=models["orchestrator"],
|
||||
name="opax_agent",
|
||||
description=f"OPAX — OSVauco enterprise agent [{mode_label}]",
|
||||
description=f"OPAX — OSVauco enterprise agent [{mode}]",
|
||||
instruction=instruction,
|
||||
tools=[rag_tool] if rag_tool else [],
|
||||
)
|
||||
|
|
@ -162,9 +160,8 @@ def run(
|
|||
if __name__ == "__main__":
|
||||
import sys
|
||||
logging.basicConfig(level=logging.WARNING)
|
||||
query = sys.argv[1] if len(sys.argv) > 1 else "Hva er OPAX heavy mode?"
|
||||
requested_mode = sys.argv[2] if len(sys.argv) > 2 else "light"
|
||||
print(f"Mode : {requested_mode}")
|
||||
print(f"Query: {query}")
|
||||
query = sys.argv[1] if len(sys.argv) > 1 else "Hva er OPAX?"
|
||||
mode = sys.argv[2] if len(sys.argv) > 2 else "light"
|
||||
print(f"Mode: {mode} | Query: {query}")
|
||||
print("-" * 60)
|
||||
print(run(message=query, user_id="opax", mode=requested_mode))
|
||||
print(run(message=query, user_id="opax", mode=mode))
|
||||
|
|
|
|||
11
main.py
11
main.py
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
main.py — Cloud Run entrypoint for OSVauco OPAX agent.
|
||||
Modes: light (default, gemini-2.0-flash-001) | heavy (gemini-2.5-pro-001)
|
||||
ML-1: telemetri, state store, DAG-endepunkter.
|
||||
main.py — Cloud Run entrypoint, OSVauco OPAX.
|
||||
Modes: light (gemini-2.5-flash) | heavy (gemini-2.5-pro)
|
||||
ML-1: telemetri, state store, DAG.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
|
@ -31,7 +31,7 @@ class RunRequest(BaseModel):
|
|||
|
||||
|
||||
class DagRequest(BaseModel):
|
||||
messages: List[str] = Field(..., description="Liste av meldinger som kjøres parallelt")
|
||||
messages: List[str] = Field(...)
|
||||
user_id: str = "opax"
|
||||
session_id: str = "default"
|
||||
mode: str = "light"
|
||||
|
|
@ -45,7 +45,6 @@ def health():
|
|||
|
||||
@app.post("/run")
|
||||
def run_agent(req: RunRequest):
|
||||
# Validate mode and authorization before any work — returns 400/403 on bad input
|
||||
try:
|
||||
authorize_mode(req.user_id, req.mode)
|
||||
except ValueError as e:
|
||||
|
|
@ -71,7 +70,7 @@ def run_agent(req: RunRequest):
|
|||
finally:
|
||||
duration = round(time.monotonic() - start, 3)
|
||||
success = error_msg is None
|
||||
model = "gemini-2.0-flash-001" if req.mode in ("light", "A") else "gemini-2.5-pro-001"
|
||||
model = "gemini-2.5-flash" if req.mode in ("light", "A") else "gemini-2.5-pro"
|
||||
log_agent_call(
|
||||
agent_id=AGENT_ID,
|
||||
input_payload={"message": req.message, "mode": req.mode},
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user