Solution · Agent chat

A chat where agent replies become working interfaces.

Stream replies people can stop, render their Markdown safely, autocomplete mentions and commands, and attach blueprints that are validated before the player paints them. The demo uses fixture replies, no live model.

Status: in development

Ask the demo agent

Try this

  • Run “Support triage” and press Stop before the reply ends: the text so far stays, marked as stopped.
  • Run “Weekly report”, open the report preview, and read why the forecast attachment was refused.
  • Type @, / or : and a letter in the composer, choose with the arrow keys and press Enter.
  • Copy the last reply as Slack, Discord, Teams or WhatsApp text.

Use Reset to return to the starting example.

Ari (demo agent)

Hi! 👋 I answer from fixtures, with no live model. Pick a scenario, or type / for a command, @ to mention a teammate and : for an emoji.
Press Enter to send. Press Shift+Enter for a new line.

Copy the last reply for another chat

Hi! 👋 I answer from fixtures, with no live model. Pick a scenario, or type `/` for a command, `@` to mention a teammate and `:` for an emoji.

Every construct has a direct spelling in this format.

If the interactive demo cannot load, use the static preview above.

From a request in the thread to an interface people can use.

Watch the reply arrive, and stop it.

Replies stream into the thread without reading out every token: the finished message is announced once. Stop keeps what was written and marks it as stopped.

  • Thread

in development

Mention people and run commands from the composer.

Type @ to mention a teammate, / for a command or : for an emoji. The list follows the combobox pattern: arrows choose, Enter inserts, Escape closes.

  • Composer autocomplete

in development

Paint only what validates.

A reply can attach a blueprint. The card validates it with the catalog validator first and paints it with the player; one that fails is shown as refused, with the reasons.

  • Blueprint attachments

From a streamed reply to a painted blueprint.

  1. Stream the reply

    Apply start, delta and end events to the message list. Plain text only; Stop ends the stream and keeps the partial text.

    Package: @texuli/chat

  2. Read the Markdown

    Message text is read by the shared CommonMark parser and filtered to safe nodes: no HTML, links through the untrusted URL policy.

    Package: @texuli/core

  3. Validate the attachment

    Check an attached blueprint against the agent catalog at the untrusted tier before anything paints.

    Package: @texuli/catalog

  4. Paint it

    Hand the validated value to the player; a refused one shows its reasons instead.

    Package: @texuli/player

  5. Share it elsewhere

    Write a reply in another chat dialect (Slack, Discord, Teams, WhatsApp) and see what had to be adapted.

    Package: @texuli/core

Agent chat is built from @texuli/player, @texuli/catalog, @texuli/chat and @texuli/core, on @texuli/blocks, @texuli/charts, @texuli/data, @texuli/media, @texuli/workflows, texuli, @texuli/tokens, @texuli/primitives and @texuli/spec.

Solution

Agent chat

Packages

  • L7@texuli/playerPaints a validated blueprint attachment.Subpaths: .
  • L6@texuli/catalogValidates an attachment against the agent catalog before it paints.Subpaths: ./validate
  • L4@texuli/chatThread, message list, composer, streaming events and the attachment card; on npm, with autocomplete, stopped replies and ChatAttachment released in 0.18.0.Subpaths: .
  • L0@texuli/coreReads message Markdown into safe nodes and writes a reply in chat dialects (subpaths released in 0.18.0).Subpaths: ./markdown · ./markdown-dialects

Built on

  • L5@texuli/blocks (Content blocks)
  • L4@texuli/charts (Charts)
  • L4@texuli/data (Data views)
  • L4@texuli/media (Media)
  • L4@texuli/workflows (Workflow graphs)
  • L3texuli (Styled components)
  • L2@texuli/tokens (Theme tokens)
  • L1@texuli/primitives (Headless primitives)
  • L0@texuli/spec (Blueprint contract)

Build with Agent chat

Start with a thread

Stream a reply

<script lang="ts">
import { applyChatStreamEvent, type ChatMessage, ChatThread } from '@texuli/chat';

let messages = $state<ChatMessage[]>([]);
const agent = { id: 'agent', name: 'Example agent' };

function onSend(body: string) {
  messages = [...messages, { id: crypto.randomUUID(), author: { id: 'me', name: 'Me' }, at: Date.now(), body }];
  const id = crypto.randomUUID();
  messages = applyChatStreamEvent(messages, { type: 'start', id, author: agent, at: Date.now() });
  messages = applyChatStreamEvent(messages, { type: 'delta', id, text: 'Hello from **example.com**.' });
  messages = applyChatStreamEvent(messages, { type: 'end', id });
}
</script>

<ChatThread {messages} currentUserId="me" {onSend} />

Attach a blueprint (in development, released in 0.18.0)

<script lang="ts">
import { validateDraft } from '@texuli/catalog/validate';
import { ChatAttachment } from '@texuli/chat';
import { createPlayerCatalog, Player } from '@texuli/player';

let { blueprint }: { blueprint: unknown } = $props();
const catalog = createPlayerCatalog();
const check = (artifact: unknown) => {
  const result = validateDraft(artifact, { catalog, tier: 'untrusted' });
  return result.ok && result.draft
    ? { ok: true as const, value: result.draft }
    : { ok: false as const, reasons: result.diagnostics.map((d) => d.message) };
};
</script>

<ChatAttachment artifact={blueprint} title="Report" {check}>
  {#snippet preview(value)}<Player blueprint={value} label="Report" />{/snippet}
</ChatAttachment>

Verified by tests/e2e/site-solution-agent-chat.spec.ts

Keep building

For agents

An agent writes plain text and blueprints. The host validates every blueprint against the catalog before it paints, and message text never becomes HTML. This demo replays fixtures; it calls no model.

  • @texuli/chat@texuli/chat: In development

    Thread, message list, composer and streaming events; published on npm.

  • Composer autocomplete, stopped replies and ChatAttachmentComposer autocomplete, stopped replies and ChatAttachment: Planned

    Released in 0.18.0 (pre-1.0).

Platforms

  • Web

    Web: In development

    Svelte 5 packages published on npm (pre-1.0).

  • Compose Desktop

    Compose Desktop: Planned

    Kotlin Multiplatform renderer on the JVM, built in this repository.

  • Android

    Android: Planned

    Native renderer target.

  • iOS

    iOS: Planned

    Native renderer target.

How the native renderer works

Start building with Agent chat

A thread whose replies paint validated blueprints.

A low horizon of stacked cubes rising to one glowing pearl cube under a wide open skyA low horizon of stacked cubes rising to one glowing pearl cube under a wide open sky