fix: route all agent loopback calls through internal_api_base() helper (#3322)

#2753 made the agent loopback base port-configurable but only for
_COOKBOOK_BASE in tool_implementations. Several other in-process loopback
calls still hardcoded http://localhost:7000 and broke off port 7000:
cookbook_serve_lifecycle (model-endpoints x2, shell/exec), builtin_actions
(model/serve), task_routes (calendar x3), and the gallery/email calls in
tool_implementations.

Extract the resolution (ODYSSEUS_INTERNAL_BASE / APP_PORT / 7000 fallback,
127.0.0.1 to avoid IPv6 ambiguity) into core.constants.internal_api_base()
and route every call site through it. Rename the now-misnamed _COOKBOOK_BASE
to _INTERNAL_BASE since it serves gallery/email/calendar/serve too. Adds a
test for the resolver plus a regression guard against reintroducing the
literal.

Part of #2752.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kenny Van de Maele
2026-06-07 23:22:09 +02:00
committed by GitHub
parent d85c5e335e
commit 76c1f42ab0
6 changed files with 116 additions and 53 deletions
+4 -3
View File
@@ -11,6 +11,7 @@ from fastapi import APIRouter, HTTPException, Request
from pydantic import BaseModel
from core.database import SessionLocal, ScheduledTask, TaskRun
from core.constants import internal_api_base
from src.auth_helpers import get_current_user
from src.task_scheduler import compute_next_run, HOUSEKEEPING_DEFAULTS
from routes.prefs_routes import _load_for_user, _save_for_user
@@ -56,7 +57,7 @@ def _maybe_cascade_calendar_event(task) -> None:
try:
with httpx.Client(timeout=10) as client:
r = client.delete(
f"http://localhost:7000/api/calendar/events/{uid}",
f"{internal_api_base()}/api/calendar/events/{uid}",
headers=headers,
)
if r.status_code >= 400:
@@ -81,7 +82,7 @@ def _maybe_cascade_calendar_event(task) -> None:
try:
with httpx.Client(timeout=10) as client:
# Find the Cookbook calendar.
cal_r = client.get("http://localhost:7000/api/calendar/calendars", headers=headers)
cal_r = client.get(f"{internal_api_base()}/api/calendar/calendars", headers=headers)
if cal_r.status_code >= 400:
return
cals = (cal_r.json() or {}).get("calendars", [])
@@ -98,7 +99,7 @@ def _maybe_cascade_calendar_event(task) -> None:
start = (now - _td(days=30)).isoformat()
end = (now + _td(days=365)).isoformat()
ev_r = client.get(
"http://localhost:7000/api/calendar/events",
f"{internal_api_base()}/api/calendar/events",
params={"start": start, "end": end, "calendar": cal_href},
headers=headers,
)