Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions autobot-backend/advanced_rag_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1046,14 +1046,11 @@ async def get_optimized_context(self, query: str, max_context_length: int = 2000
header = self._build_context_header(query, context_parts, query_context)
final_context = header + "\n---\n".join(context_parts)

# #10552: inspect assembled RAG context through the content firewall
from security.content_firewall import ContentSource, get_content_firewall
# #10552, #16771: the one shared RAG inspection point
from security.content_firewall import inspect_rag_context

fw_verdict = await get_content_firewall().inspect(
final_context, source=ContentSource.RAG, context_label=query[:80]
)
fw_verdict = await inspect_rag_context(final_context, context_label=query[:80])
if fw_verdict.blocked:
logger.warning("RAG context blocked by content firewall (risk=%s)", fw_verdict.risk.value)
return "[RAG context blocked by content firewall]", metrics
final_context = fw_verdict.content

Expand Down
23 changes: 4 additions & 19 deletions autobot-backend/chat_workflow/llm_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,10 @@
from prompt_manager import get_language_instruction, get_prompt, resolve_language

from .models import WorkflowSession
from .outbound_url import _VALID_URL_SCHEMES, _normalize_outbound_url

logger = get_logger(__name__)

# Issue #380: Module-level tuple for URL scheme validation
_VALID_URL_SCHEMES = ("http://", "https://")


def _normalize_outbound_url(url: str) -> str:
"""Rewrite a 0.0.0.0 bind-address host to 127.0.0.1 for outbound calls.

Bug fix: the Ollama endpoint is sometimes configured as
``http://0.0.0.0:11434`` (a server *bind* address — "all interfaces").
0.0.0.0 is not a valid *connect* target, so an outbound client request to
it raises aiohttp.ClientError, the LLM call fails, and no assistant reply is
produced. Normalize it to loopback so the call reaches a locally-bound
Ollama. No-op for any other host.
"""
if not url:
return url
return url.replace("//0.0.0.0:", "//127.0.0.1:").replace("//0.0.0.0/", "//127.0.0.1/")


async def _emit_system_prompt_ready(system_prompt: str, session: Any) -> str:
"""Emit ON_SYSTEM_PROMPT_READY to registered extensions and return result.
Expand Down Expand Up @@ -961,7 +944,9 @@ async def _prepare_llm_request_params(
if knowledge_context and citations:
from services.knowledge.service import budget_grounded_context

knowledge_context, citations = await budget_grounded_context(citations, model_name=selected_model)
knowledge_context, citations = await budget_grounded_context(
citations, model_name=selected_model, context_label=message[:80]
)
else:
session.metadata["used_knowledge"] = False

Expand Down
28 changes: 28 additions & 0 deletions autobot-backend/chat_workflow/outbound_url.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2025-2026 mrveiss
# SPDX-License-Identifier: Apache-2.0
# AutoBot - AI-Powered Automation Platform
# Author: mrveiss
"""
Outbound URL normalization for the LLM request path.

Extracted from llm_handler.py (#16930 review, to keep it under its
file-size ceiling) -- a move, not a behaviour change.
"""

# Issue #380: Module-level tuple for URL scheme validation
_VALID_URL_SCHEMES = ("http://", "https://")


def _normalize_outbound_url(url: str) -> str:
"""Rewrite a 0.0.0.0 bind-address host to 127.0.0.1 for outbound calls.

Bug fix: the Ollama endpoint is sometimes configured as
``http://0.0.0.0:11434`` (a server *bind* address — "all interfaces").
0.0.0.0 is not a valid *connect* target, so an outbound client request to
it raises aiohttp.ClientError, the LLM call fails, and no assistant reply is
produced. Normalize it to loopback so the call reaches a locally-bound
Ollama. No-op for any other host.
"""
if not url:
return url
return url.replace("//0.0.0.0:", "//127.0.0.1:").replace("//0.0.0.0/", "//127.0.0.1/")
10 changes: 10 additions & 0 deletions autobot-backend/security/content_firewall.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,13 @@ async def _emit_firewall_event(verdict: FirewallVerdict, task_id: str | None) ->
# ---------------------------------------------------------------------------

get_content_firewall = lazy_singleton(ContentFirewall)


async def inspect_rag_context(content: str, *, context_label: str = "") -> FirewallVerdict:
"""The one inspection point every RAG path calls before context reaches
the model (#16771) -- both advanced_rag_optimizer's search-based path and
knowledge.service's chat retrieval path route through this, so there is
one place that knows RAG content goes through ContentSource.RAG, not two
copies that can drift.
"""
return await get_content_firewall().inspect(content, source=ContentSource.RAG, context_label=context_label)
Loading
Loading