From 0afaf94ee9c7df646924cf8e6b9c771fbad5840e Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Wed, 24 Jun 2026 21:41:27 +0200 Subject: [PATCH] references: pointer renderer --- .../runtime/references/reference_pointers.py | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 surfsense_backend/app/agents/chat/runtime/references/reference_pointers.py diff --git a/surfsense_backend/app/agents/chat/runtime/references/reference_pointers.py b/surfsense_backend/app/agents/chat/runtime/references/reference_pointers.py new file mode 100644 index 000000000..ce7966275 --- /dev/null +++ b/surfsense_backend/app/agents/chat/runtime/references/reference_pointers.py @@ -0,0 +1,58 @@ +"""Render resolved references into a ```` pointer block. + +Pointers, not content: each line names what the user referenced and how to +reach it (a path, a connector handle, a title) so the model knows what to +retrieve from. Actual content is pulled later via tools, never injected here. +""" + +from __future__ import annotations + +from .models import ReferenceKind, ResolvedReference + +_HEADER = ( + "The user pointed at these with @ this turn. They are scope, not content " + "— when the question is about them, retrieve from them before answering." +) + + +def render_reference_pointers(references: list[ResolvedReference]) -> str | None: + """Render references as one read-only pointer block. + + Returns ``None`` when there is nothing to render so callers can skip the + block entirely. + """ + if not references: + return None + + lines = [_render_pointer(reference) for reference in references] + return ( + "\n" + f"{_HEADER}\n" + + "\n".join(lines) + + "\n" + ) + + +def _render_pointer(reference: ResolvedReference) -> str: + """One ``- {kind} {id} — {handle}`` line, shaped per kind.""" + head = f"- {reference.kind.value} {reference.entity_id} — " + return head + _handle(reference) + + +def _handle(reference: ResolvedReference) -> str: + """The human-reachable handle: connector provider, a path, or a title.""" + label = _clean(reference.label) + if reference.kind is ReferenceKind.CONNECTOR: + provider = _clean(reference.provider) if reference.provider else "" + return f"{provider} ({label})" if provider else label + if reference.path: + return f'"{label}" ({reference.path})' + return f'"{label}"' + + +def _clean(text: str) -> str: + """Collapse whitespace so a title can't break the one-line pointer.""" + return " ".join(text.split()) + + +__all__ = ["render_reference_pointers"]