From 9c1affe9f5636573a4c36e684cffc973f64f3551 Mon Sep 17 00:00:00 2001 From: pewdiepie-archdaemon Date: Fri, 5 Jun 2026 12:16:47 +0900 Subject: [PATCH] fix: make agent loopback base port env-configurable (#2752) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _COOKBOOK_BASE was hardcoded to http://localhost:7000 with no env-var override anywhere in the codebase. Tools that do an internal HTTP loopback (app_api, trigger_research, cookbook state read/write) silently fail with "All connection attempts failed" whenever the running uvicorn isn't on port 7000 — which is most non-default deployments and any side-by-side multi-instance setup. The misleading "Task triggered" message from manage_tasks during a research request hides that the underlying research never starts. Resolution order, lowest to highest priority: 1. Fallback http://127.0.0.1:7000 (preserves legacy default). 2. APP_PORT — derive http://127.0.0.1:$APP_PORT (matches docker-compose which already reads APP_PORT). 3. ODYSSEUS_INTERNAL_BASE — explicit override (e.g. behind a TLS proxy where loopback isn't 127.0.0.1). 127.0.0.1 instead of "localhost" avoids IPv6/DNS ambiguity for a strictly-local call. No API or schema change. Defaults preserved: existing setups on port 7000 are unaffected. Caught by #2752. --- src/tool_implementations.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/tool_implementations.py b/src/tool_implementations.py index c7b264970..938c3e679 100644 --- a/src/tool_implementations.py +++ b/src/tool_implementations.py @@ -2479,7 +2479,21 @@ async def do_manage_calendar(content: str, owner: Optional[str] = None) -> Dict: # Cookbook routes loopback. The agent's tool calls run in-process but # need to reach admin-gated cookbook routes; we ride the per-process # internal token so require_admin lets us through. See core/middleware.py. -_COOKBOOK_BASE = "http://localhost:7000" +# +# Resolution order: +# 1. ODYSSEUS_INTERNAL_BASE — explicit override (e.g. behind a TLS proxy). +# 2. APP_PORT — derive http://127.0.0.1:$APP_PORT (matches docker-compose). +# 3. Fallback http://127.0.0.1:7000 — preserves legacy default. +# +# 127.0.0.1 (not "localhost") avoids IPv6/DNS ambiguity for a strictly-local +# call. Without this, tools that loop back (app_api, trigger_research, +# cookbook state read/write) fail with "All connection attempts failed" +# whenever the running uvicorn isn't on 7000 — which is most non-default +# deployments and any side-by-side multi-instance setup. +_COOKBOOK_BASE = os.environ.get( + "ODYSSEUS_INTERNAL_BASE", + f"http://127.0.0.1:{os.environ.get('APP_PORT', '7000')}", +) def _internal_headers(owner: Optional[str] = None) -> Dict[str, str]: