from __future__ import annotations from fastapi import APIRouter, Request from fastapi.responses import JSONResponse from vocero_api.api.responses import validated_json_response from vocero_api.core import config as settings from vocero_api.core import logging as app_logging from vocero_api.core import urls as core_urls from vocero_api.models.responses import ConfigResponse router = APIRouter() def _effective_s2s_url(request: Request) -> str: return settings.SPEECH_TO_SPEECH_URL or core_urls._proxy_public_url(request) @router.get("/api/config", response_model=ConfigResponse) async def config(request: Request) -> JSONResponse: """Client bootstrap: whether web search is available, whether the deploy runs behind a load balancer (so the browser uses the /api/session proxy), and whether the user may instead set a direct s2s server URL. The LB address itself is intentionally NOT included. 2026-09-24: new top-level `apipilot` flag. When True the deploy exposes the new `/api/apipilot/tools` and `/api/apipilot/execute` proxy endpoints (see docs/client/tool-calling.md) that the browser may call directly instead of hardcoding upstream tool URLs / names.""" app_logging.logger.debug( "[INTERNAL] /api/config requested client=%s", request.client.host if request.client else "?" ) primary_prompt = settings.S2S_PRIMARY_PROMPT out = { "search": bool(settings.SERPER_KEY), "lb": bool(settings.LOAD_BALANCER_URL), "allowDirect": not settings.LOAD_BALANCER_URL, "s2sUrl": _effective_s2s_url(request), "primaryPrompt": primary_prompt, "reasoningType": settings.S2S_REASONING_TYPE, "injectProfile": settings.S2S_INJECT_PROFILE, "debugPrompt": settings.S2S_DEBUG_PROMPT, "startSessionMode": settings.S2S_START_SESSION_MODE, "theme": settings.S2S_THEME, "apipilot": bool(settings.S2S_APIPILOT_TOOLS_URL), } app_logging.logger.debug( "[INTERNAL] /api/config returned promptLen=%d reasoning=%s startSessionMode=%s theme=%s apipilot=%s", len(primary_prompt), settings.S2S_REASONING_TYPE, settings.S2S_START_SESSION_MODE or "-", settings.S2S_THEME or "-", out["apipilot"], ) return validated_json_response(out, ConfigResponse)