Integration prompt — ai-ahu-chatbot (filled, gateway live at http://192.168.83.20:8200)
We are introducing a central GPU/LLM gateway (ahu-gpu-manager) that all model traffic must flow through. It is already deployed and verified at http://192.168.83.20:8200 (OpenAI-compatible /v1/*, synthesis route at /synthesis/v1/*, priority queueing, audit events). Canonical contract: ../ahu-gpu-manager/docs/CONVENTIONS.md — read it first; on any conflict it wins. Your job is to prepare this repo for it. Hard constraint: every change must be backwards-compatible and dormant — with no new env vars set, behavior must be byte-for-byte identical to today. Do not flip any live env values in infra/env/*.env; only add commented-out entries showing the future values.
1. Header propagation in the Agno agents
In apps/internal-agent/dash/agents.py and its mirror apps/public-agent/dash/agents.py, the models built by _resolve_model() / _build_model_from_slot() (via OpenAILike) currently send no identifying headers — only the orchestrator's direct calls do. Add default headers to the model construction:
X-Tenant-Id: ahu-chatbotX-Surface: from the existingSURFACEenv (internal|public)X-Priority:interactivefor both the tool-loop model and the synthesis model (the gateway maps legacyplanning/synthesisvalues tointeractiveanyway; useinteractivedirectly)
If Agno supports per-run extra headers, also propagate the per-run user_id as X-User-Id; if it only supports client-level headers, add the static ones and leave a # TODO(gateway) noting the per-run limitation. Verify against the installed agno==2.4.7 API — do not guess.
2. Close the bare-OpenAI egress
apps/internal-agent/app/api/knowledge.py:421 (and the public-agent mirror if present) constructs a bare OpenAI() client calling model="gpt-4o" — this bypasses MODEL_GATEWAY_URL and hits api.openai.com directly. Change it to construct the client from the same gateway-resolution logic the agents use (base_url from MODEL_GATEWAY_URL + /v1 when set, model name from a new env KNOWLEDGE_LLM_MODEL defaulting to the current gpt-4o). When MODEL_GATEWAY_URL is unset, behavior must be unchanged.
3. Queue-awareness in the orchestrator LLM client
In apps/public-web/src/lib/orchestrator/llm/client.ts:
- On
429or503responses, readRetry-AfterandX-Queue-Depthheaders and include them in the thrown error object so callers can degrade with a friendly "sistem sedang sibuk" message instead of a generic failure. - Add opt-in structured queue events: when a new env
LLM_QUEUE_EVENTS=onis set, send headerX-Queue-Events: onon streaming requests and parse SSE frames of the formevent: queue/data: {"position":N,"eta_ms":M}that may arrive before the first chat chunk. Surface them via a callback soorchestrate.tscan forward a status event to the browser stream (reuse the existing SSE status/error event channel) — the user should see "Antrian ke-N (±Xs)" rather than a spinner. Also handleevent: errorframes (data: {"status":..., "code":...}) that the gateway may emit after an early-committed stream if the upstream fails. Unknown SSE event types must be ignored gracefully. - Send an
Idempotency-Keyheader on each request, derived from the existing per-request/session identifiers (deterministic — never random-per-attempt).
4. Env preparation (commented, not active)
In infra/env/internal.env, infra/env/public.env, infra/env/shared.env, add commented blocks:
# --- ahu-gpu-manager gateway (uncomment to flip; revert = re-comment + redeploy) ---
# MODEL_GATEWAY_URL=http://192.168.83.20:8200
# SYNTHESIS_GATEWAY_URL=http://192.168.83.20:8200/synthesis
# EMBEDDER_BASE_URL=http://192.168.83.20:8200/v1
# LLM_QUEUE_EVENTS=on
Note in a comment that once flipped, SYNTHESIS_API_KEY is no longer needed by this repo (the gateway holds the DashScope key server-side and its registry refuses external upstreams in prod) and should be removed from these env files.
Model names: keep sending the canonical names (Qwen/Qwen3.6-35B-A3B-FP8, qwen3.5-397b-a17b, Qwen/Qwen3-Embedding-4B) — the gateway routes by model name but forwards request bodies verbatim, so aliases the upstream doesn't recognize will 404 at the model server.
5. Verification
- Run the existing test suites; nothing may regress.
- With no new envs set, confirm (by reading the constructed clients or a local smoke run) that request URLs, headers minus the new static X- headers, and bodies are unchanged against the current vLLM endpoint.
- Optional live check (safe, additive): with the new envs exported in a local shell only, one chat turn through
http://192.168.83.20:8200— the gateway is live and its/healthzshould show your call ingateway_requests_total{tenant="ahu-chatbot"}on/metrics. - Type-check and lint clean.
Report back: files changed, any Agno API limitations found for per-run headers, and anything in the header/queue-event contract that needed interpretation.