Vocero needs to query AquaPortal on behalf of the caller selected by the existing phone link. This adds server-owned conversations and MCP tool execution for voice and HTTP reasoning while leaving the speech pipeline unchanged. Release notes: - Added browser-bound conversations that keep backend credentials server-side and isolate callers. - Connected the eight-tool AquaPortal catalog through authenticated Streamable HTTP with full input schemas and structured results. - Added bounded multi-step tool execution with cancellation, expiry, and stale-result protection. - Updated browser bootstrap, tool progress, reasoning headers, and conversation cleanup. - Disabled legacy unscoped content preloads in MCP mode and documented configuration and deployment constraints. - Preserved disabled-mode contracts and added local SDK, WebSocket, and browser regression coverage. Reviewed-on: AquaPortal/s2s#1
72 lines
2.9 KiB
Python
72 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
from vocero_api.core import config as settings
|
|
from vocero_api.core import logging as app_logging
|
|
|
|
|
|
# Resolve the execution URL for the startup banner using the same normalization
|
|
# as _apipilot_resolve_execute_url.
|
|
def _resolve_exec_url_for_startup_banner() -> str:
|
|
base = (settings.S2S_APIPILOT_TOOLS_EXECUTE_URL or settings.S2S_APIPILOT_TOOLS_URL).strip().rstrip("/")
|
|
if not base:
|
|
return ""
|
|
if base.lower().endswith("/execute"):
|
|
return base
|
|
return f"{base}/execute"
|
|
|
|
|
|
_STARTUP_APIPILOT_EXEC_URL = _resolve_exec_url_for_startup_banner()
|
|
del _resolve_exec_url_for_startup_banner
|
|
|
|
app_logging.logger.info(
|
|
"[STARTUP] Other externals — reasoning=%s serper=%s lb=%s s2sProxy=%s s2sDirect=%s userAuth=%s reportsApi=%s injectReports=%s reportsHintMax=%d reportsInjectMode=%s injectToday=%s summaryApi=%s summaryText=%s loginApi=%s injectProfile=%s debugPrompt=%s startSessionMode=%s theme=%s apipilotToolsUrl=%s apipilotExecuteUrlOverride=%s apipilotServiceToken=%s apipilotTtl=%ds apipilotTimeout=%.1fs apipilotReasoningPass2=%s apipilotApiKeyBypass=%s",
|
|
settings.S2S_REASONING_TYPE,
|
|
bool(settings.SERPER_KEY),
|
|
bool(settings.LOAD_BALANCER_URL),
|
|
bool(settings.S2S_PROXY_TARGET),
|
|
bool(settings.SPEECH_TO_SPEECH_URL),
|
|
bool(settings.VOCERO_USER_PHONE_AUTH_URL),
|
|
bool(settings.S2S_REPORT_LIST),
|
|
settings.S2S_INJECT_REPORTS,
|
|
settings.S2S_REPORTS_QUICK_HINT_MAX,
|
|
settings.S2S_REPORTS_INJECT_MODE,
|
|
settings.S2S_INJECT_TODAY,
|
|
bool(settings.S2S_LATEST_SUMMARY),
|
|
bool(settings.S2S_LATEST_SUMMARY_TEXT),
|
|
bool(settings.S2S_LOGIN_BY_PHONE),
|
|
settings.S2S_INJECT_PROFILE,
|
|
settings.S2S_DEBUG_PROMPT,
|
|
settings.S2S_START_SESSION_MODE or "-",
|
|
settings.S2S_THEME or "-",
|
|
settings.S2S_APIPILOT_TOOLS_URL or "-",
|
|
(settings.S2S_APIPILOT_TOOLS_EXECUTE_URL + f"(resolved:{_STARTUP_APIPILOT_EXEC_URL})")
|
|
if settings.S2S_APIPILOT_TOOLS_EXECUTE_URL
|
|
else "-",
|
|
"Y" if bool(settings.S2S_APIPILOT_SERVICE_TOKEN) else "-",
|
|
settings.APIPILOT_CACHE_TTL_SEC,
|
|
settings.APIPILOT_HTTP_TIMEOUT,
|
|
"Y" if (bool(settings.S2S_APIPILOT_TOOLS_URL) or bool(settings.S2S_APIPILOT_TOOLS_EXECUTE_URL)) else "-",
|
|
(
|
|
"YES head="
|
|
+ (
|
|
settings.S2S_APIPILOT_API_KEY[:6] + "..."
|
|
if len(settings.S2S_APIPILOT_API_KEY) > 6
|
|
else settings.S2S_APIPILOT_API_KEY
|
|
)
|
|
+ " (3 FORMS!)"
|
|
)
|
|
if settings.S2S_APIPILOT_API_KEY
|
|
else "-",
|
|
)
|
|
del _STARTUP_APIPILOT_EXEC_URL
|
|
|
|
if settings.S2S_MCP_URL:
|
|
app_logging.logger.info(
|
|
"[STARTUP] AquaPortal MCP enabled: per-caller sessions, legacy content preloads disabled; "
|
|
"operationTimeout=%ds maxCallsPerTurn=%d conversationTtl=%ds capacity=%d",
|
|
settings.S2S_MCP_TIMEOUT_SEC,
|
|
settings.S2S_MCP_MAX_CALLS_PER_TURN,
|
|
settings.S2S_CONVERSATION_TTL_SEC,
|
|
settings.S2S_MAX_CONVERSATIONS,
|
|
)
|