Handle LiteLLM path variants for chat completions

Two fixes:
1. Add /chat/completions alias (no /v1 prefix) — LiteLLM custom_openai
   and openai_like providers post here directly.
2. Passthrough now redirects any path ending in chat/completions to the
   proper /v1/chat/completions handler instead of forwarding blindly.
   This catches v1/messages/chat/completions and other wrong paths that
   result from misconfigured api_base in Agent0.

Both routes get full agent routing, recollection injection, and loop
detection — they're not raw passthroughs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-21 19:49:17 +02:00
parent 7ed61b4823
commit 8aaa205dba
+16
View File
@@ -1103,6 +1103,14 @@ async def openai_chat_completions(request: Request) -> Response:
raise raise
# Alias: some LiteLLM provider types (custom_openai, openai_like) omit the
# /v1 prefix and post directly to /chat/completions.
@app.post("/chat/completions")
async def openai_chat_completions_no_prefix(request: Request) -> Response:
"""Alias for /v1/chat/completions — handles LiteLLM providers that omit /v1."""
return await openai_chat_completions(request)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# /iknowthat — manual write path # /iknowthat — manual write path
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -3070,6 +3078,14 @@ async def models_ui() -> str:
@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "HEAD"]) @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "HEAD"])
async def passthrough(path: str, request: Request) -> Response: async def passthrough(path: str, request: Request) -> Response:
cfg = request.app.state.yaml_config cfg = request.app.state.yaml_config
# Some LiteLLM configurations build wrong paths like v1/messages/chat/completions
# (when api_base already includes /v1/messages) or v1/chat/completions without
# a leading slash. Redirect all chat-completion variants to the proper handler.
if path.endswith("chat/completions") and request.method == "POST":
log.info("passthrough redirect %s → /v1/chat/completions", path)
return await openai_chat_completions(request)
if path.startswith("v1/"): if path.startswith("v1/"):
upstream = cfg["upstream_anthropic"] upstream = cfg["upstream_anthropic"]
relay_headers = ANTHROPIC_RELAY_HEADERS relay_headers = ANTHROPIC_RELAY_HEADERS