{% from "_macros.html" import icon %} {# What the model did before answering. Rendered both live (streamed as a whole block, like the reasoning and the answer) and from the stored message afterwards, so the sources behind an answer stay in the transcript rather than vanishing when the stream ends. EVERYTHING in here comes from a search provider and is untrusted, exactly as much as model output is. Jinja autoescaping covers the text; the URL is checked separately, because `is_linkable` is the only thing standing between a result carrying a javascript: URL and an anchor pointing at it. #} {% for event in tool_events %}
{{ icon("globe", "icon--sm tool-activity__icon") }} {% if event.status == "error" %} Web search failed {% elif event.query %} Searched the web for “{{ event.query }}” {% else %} Searched the web {% endif %} {% if event.results %} · {{ event.results | length }} result{{ '' if event.results | length == 1 else 's' }} {% endif %} {{ icon("chevron-down", "icon--sm reasoning__chevron") }}
{% if event.error %}

{{ event.error }}

{% elif not event.results %}

Nothing was found.

{% endif %} {% for result in event.results %}
{% set scheme = result.url.split(":")[0] | lower %} {% if scheme in ("http", "https") %} {{ result.title }} {% else %} {# Not a link. A search result is third-party text and its URL is not trusted to be safe to click. #} {{ result.title }} {% endif %} {{ result.host }} {% if result.snippet %}

{{ result.snippet }}

{% endif %}
{% endfor %}
{% endfor %}