{% extends "base.html" %} {% from "_macros.html" import icon, mark, model_avatar %} {% block title %}{{ chat.title if chat else "New chat" }} - LLeMbas{% endblock %} {% block head %} {% if terminal_enabled %} {% endif %} {% endblock %} {% block body_attrs %} data-authenticated="true"{% endblock %} {% block body %}
{% include "partials/sidebar.html" %}

{{ chat.title if chat else "New chat" }}

{# The mode is the one agent setting that changes mid-chat: it decides what gets asked about, not what the conversation is. In the header rather than the settings panel because it is looked at constantly -- it is the difference between being interrupted and not. #} {% if chat and chat.kind == "agent" %}
{{ icon("server", "icon--sm") }} {{ agent_profile.name if agent_profile else "connection missing" }}
{% endif %}
{# A link, not a script: the flag lives in the URL, so it survives a reload and can be bookmarked. On an existing temporary chat the same corner explains what temporary means and offers the way out -- without one, a conversation that turns out to matter is destroyed a day later with no recourse. #} {% if chat and chat.temporary %} Temporary {% elif not chat and can.get("chat.create") %} {{ icon("clock") }} {% endif %} {% if models %} {% if can.get("chat.model_select") or not chat %} {% include "chat/_model_picker.html" %} {% elif current_model %} {{ current_model.label }} {% endif %} {% endif %} {% if chat and (can.get("chat.system_prompt") or can.get("chat.params")) %} {% endif %} {% if chat and messages %} {% endif %} {% if terminal_enabled %} {# To the left of the inspector, and never open beside it: see the toggle group in app.js. #} {% endif %} {% if chat and user.is_admin %} {% endif %}
{% if chat and (can.get("chat.system_prompt") or can.get("chat.params")) %} {# Collapsed by default: per-chat overrides, not everyday controls. Each field saves on change, so there is no half-applied state. #} {% endif %} {% if not models %} {# Every fresh install lands here, so it points at the fix. #}
{{ icon("server", "empty__mark") }}

No models available

{% if user.is_admin %} Add an OpenAI-compatible connection and LLeMbas will load its models. {% else %} No model connections have been set up yet. Ask an administrator. {% endif %}

{% if user.is_admin %} {{ icon("server", "icon--sm") }} Set up a connection {% endif %}
{% else %}
{% if not messages %}
{{ mark(cls="empty__mark", uid="intro") }}

What would you ask?

Speak, friend, and enter.

{# Only on a chat that does not exist yet. An empty chat someone opened on purpose already has a model and a prompt chosen. #} {% if not chat and suggestions %}
{% for suggestion in suggestions %} {% endfor %}
{% endif %}
{% endif %} {# The same include the rewind response returns, so the conversation is described in one place. Markdown was rendered server-side in pages.py, keyed by message id. #} {% include "chat/_thread.html" %}
{% include "chat/_composer.html" %} {% endif %}
{# Third and fourth children of .shell, mirroring the sidebar opposite. The terminal comes first so it sits to the left of the inspector. #} {% if terminal_enabled %} {% include "chat/_terminal.html" %} {% endif %} {% if chat and user.is_admin %} {% include "chat/_inspector.html" %} {% endif %}
{% endblock %} {% block scripts %} {% if terminal_enabled %} {# Only where it can be used. xterm is nearly three times everything else vendored, so a plain chat must never load it. #} {% endif %} {% endblock %}