Features ======== This page describes what Smarter Chat does, as its users see it. The same component runs in the web console's prompt engineering workbench and on any page that embeds the `@smarter.sh/ui-chat `__ npm package. Features that only the workbench turns on by default are marked as such. The Chat -------- When it loads, the chat fetches its LLMClient's configuration, which gives it everything it displays before the first prompt: the LLMClient's app name and version, its LLM provider and model, the number of plugins it has, the placeholder text of the message box, the assistant's name, the welcome message, and the example prompts, which the LLMClient's manifest declares (``appName``, ``appAssistant``, ``appWelcomeMessage``, ``appExamplePrompts``, ``appPlaceholder``). The header shows the title, with a green check if the LLMClient is valid (a red cross if it is not), and a rocket if it is deployed, or "(sandbox)" if it is not. Below the title is the provider and model, for example ``openai gpt-4o-mini with 3 additional plugins``. Chat sessions persist. The configuration includes the chat session's history, so reloading the page restores the conversation. Each chat session has a 64-character key, which the chat saves in a cookie for the page's path, so that each LLMClient's page keeps its own session. The **new chat** button, a blank page, discards the key and starts a new session. If the LLMClient allows file attachments (``appFileAttachment`` in its manifest), the message box has an attach button, which sends the text of a ``.py``, ``.txt``, ``.md``, ``.json``, ``.yaml``, ``.yml`` or ``.csv`` file as a message. Prompt Progress --------------- A prompt can take a while: the LLM may call tools, plugins and MCP servers, and each tool call adds another round trip to the LLM. While a prompt runs, the chat displays each step as it happens: - each request to the LLM: "Sending the prompt to the LLM", then "Sending the tool results to the LLM" for each later round trip, - each tool the LLM calls, and its response, - each plugin that runs, - each MCP server tool that is called, responds or fails. The typing indicator names the current step, for example "Stanley: Calling tool stackademy_sql". When the response arrives, it replaces the steps. In production mode, only the typing indicator names the steps. Progress is streamed from the server as Server-Sent Events. See :doc:`The Chat API Contract `. Errors ------ A failed prompt, for example one that the LLM provider rejects because of a bad api key or a rate limit, is displayed in the thread as an error message, with the provider's own error text. A configuration that can't be loaded, for example because the LLMClient doesn't exist or the user may not use it, is displayed the same way, and the header reads "Smarter Chat is not available". When the LLM stops because it reached the LLMClient's maximum number of tokens, the chat says so, and suggests raising ``defaultMaxTokens`` in the LLMClient's manifest. This matters most for reasoning models, which can spend all of their tokens reasoning and return an empty response that would otherwise display as nothing at all. Sandbox Mode and Production Mode -------------------------------- *Turned on in the workbench; off by default in the npm package (the* ``toggleMetadata`` *prop), which is then always in production mode.* The **Sandbox mode / Production mode** button shows and hides the backend's own messages in the thread: the system prompt, tool results, Smarter's notes, for example about the plugins it selected and the tokens it charged, and the prompt's progress. In production mode, the thread is the conversation as the LLMClient's users see it. The Console's Server Logs tab follows the mode: in sandbox mode it streams every log record, DEBUG included, and in production mode only the records at the platform's log level (``smarter_settings.log_level``) and above. Switching modes reconnects the stream, which replays the recent history at the new level. How Messages Are Rendered ------------------------- The LLM's responses, and the backend's messages, are GitHub flavored markdown: headings, bold, italics, strikethrough, lists, tables, block quotes, inline code, fenced code blocks, links and images. A line break is a line break, as in any chat. The LLM is told so: Smarter adds a note to the system prompt of each request it sends to an OpenAI-compatible provider, which is not saved in the chat session's history. Your own messages are displayed as you typed them, except for their links and images. Links and images Raw html is displayed as text. ``![alt](url)`` is an image, scaled to fit its chat bubble, which opens at full size in a new tab, and ``[![alt](url)](href)`` is an image that links to ``href``. Links open in a new tab. Urls must be ``http(s)`` or relative to the page. Images may also be base64 ``png``, ``jpeg``, ``gif`` or ``webp`` data urls, for example from a tool that generates them. Anything else, such as a ``javascript:`` url, stays as text. Code Fenced code blocks are syntax highlighted, in GitHub's dark theme, with a header that names the language and a **Copy** button. Highlighting covers the common languages (Python, JavaScript, TypeScript, Bash, JSON, YAML, SQL, Go, Rust, Java, C, C++, C#, HTML, CSS and more), plus Dockerfile, nginx and PowerShell. Math Math, written in LaTeX, is typeset by `KaTeX `__: ``\( ... \)`` is inline math, and ``\[ ... \]`` or ``$$ ... $$`` is an equation displayed on a line of its own, which scrolls sideways if it is wider than its chat bubble. A single dollar sign is not math, so prices stay as text. Math in inline code and code blocks stays as code, and LaTeX that KaTeX cannot typeset, such as an equation that is still streaming, is displayed as its source. Screen readers read the equation's MathML. Diagrams A fenced code block whose language is ``mermaid`` is drawn as a `Mermaid `__ diagram, such as a flowchart or a sequence diagram, whose **Code** button shows its source instead, and back. A diagram that Mermaid cannot draw, for example because of a syntax error, stays as its code. Mermaid is large, so it is downloaded only when a message first has a diagram. It runs at its ``strict`` security level, with plain text labels, and its svg is sanitized again before it is displayed, because the diagram comes from the LLM. All of the html that the chat renders from messages is sanitized with `DOMPurify `__, so nothing in a message can run a script. The Console ----------- *Turned on in the workbench; on by default in the npm package too (the* ``showConsole`` *prop), which suits only wide pages.* The Console is a simulated terminal beside the chat. Its tabs display, as JSON: .. list-table:: :header-rows: 1 :widths: 20 80 * - Tab - Contents * - Server Logs - Your server logs, as they stream in, in the colors and font of the web console's log viewer. Long lines scroll horizontally, or wrap, with the tab's **Wrap lines** button. Present only when log viewing in the browser is enabled (``SMARTER_ENABLE_DASHBOARD_SERVER_LOGS``), and then selected first. A new chat clears it. * - Api Calls - The chat session's requests to the LLM provider. * - Tool Calls - The chat session's tool calls. * - Plugin Usage - The plugins that the chat session used. * - Config - The LLMClient's complete configuration, as the config api returns it. Drag the separator between the chat and the Console to resize them, or focus it and use the arrow keys. The chat takes between 20% and 80% of the width, a third by default. The panel button in the chat's header hides the Console, which slides out to the right, and back. The browser remembers the width, whether the Console is visible, and whether log lines wrap.