AkurAI Build
Menu

Public repository / master

AkurAI-Framework / site/frontend/chat-demo.html

Latest change 631417472adebacf9be16c712af89ca5d8a25c28 - Add RustAgent agent OS UI contract by Ólafur Búi Ólafsson

{% include "header" %}
    <main class="container">
      <header class="page-head">
        <span class="eyebrow">Live demo</span>
        <h1>AI chat primitives</h1>
        <p class="lede">A native-ESM port of <a href="https://github.com/assistant-ui/assistant-ui">assistant-ui</a>'s composable chat primitives — <strong>Thread</strong>, <strong>Message</strong>, <strong>Composer</strong>, and <strong>ActionBar</strong> — talking to the streaming <code>POST /api/assistant</code> endpoint over SSE. No React, no bundler, zero dependencies.</p>
      </header>

      <section style="margin: 1.5rem 0 3rem;">
        <!-- mountChat() replaces the contents of this element with the chat UI. -->
        <div id="chat"></div>
        <p class="small muted" style="margin-top: 1rem;">
          With no <code>AKURAI_LLM_URL</code> configured, the server emits an SSE
          <code>error</code> event — the assistant turn renders that inline so the demo
          still works. Open DevTools → Console for <code>[chat]</code> breadcrumbs.
        </p>
      </section>

      <section class="split" style="margin-bottom: 4rem;">
        <div>
          <h2>What you're looking at</h2>
          <p>Each turn auto-scrolls; scroll up and a "↓" button appears to jump back. Assistant text renders as Markdown (bold, lists, code). Hover a message for copy / retry / edit actions.</p>
          <p>The composer supports Enter-to-send, Shift+Enter for a newline, an attachment button, and — in browsers with the Web Speech API — a 🎤 dictation button.</p>
        </div>
        <div class="card">
          <h3 style="margin-top: 0;">Endpoint contract</h3>
          <p class="small muted" style="margin: 0 0 0.5rem;"><code>POST /api/assistant</code> → <code>text/event-stream</code>:</p>
          <ul class="small muted" style="margin: 0; padding-left: 1.4rem;">
            <li><code>delta</code> — token text, appended live</li>
            <li><code>tool_call</code> — JSON, emits <code>chat:toolcall</code> for tool-UI rendering</li>
            <li><code>done</code> — end of turn</li>
            <li><code>error</code> — shown inline</li>
          </ul>
        </div>
      </section>

      <section class="container cta">
        <h2>Compose your own</h2>
        <div class="btn-row center">
          <a class="btn btn-secondary" href="/docs/chat">Chat primitives documentation</a>
          <a class="btn btn-secondary" href="https://github.com/olibuijr/AkurAI-Framework">Source on GitHub</a>
        </div>
      </section>
    </main>

    <script type="module">
      import { mountChat } from "/ai/chat/index.js";
      import { registerAll, genericApprovalComponent } from "/ai/runtime/index.js";
      import { components } from "/ai/components-manifest.js";

      function initChat() {
        registerAll(components);
        registerAll([genericApprovalComponent]);
        const controller = mountChat("#chat", {
          greeting: "Hi! I'm a demo assistant. Send a message and watch the response stream in token by token.",
          placeholder: "Ask me anything…",
          emptyState: "Send a message to start the conversation.",
        });

        // Demonstrate the generative-UI hook: log any tool call the runtime emits.
        if (controller) {
          controller.el.addEventListener("chat:toolcall", (event) => {
            console.log("[chat-demo] tool call received:", event.detail);
          });
        }
        console.log("[chat-demo] initialization complete");
      }

      if (document.readyState === "loading") {
        document.addEventListener("DOMContentLoaded", initChat);
      } else {
        initChat();
      }
    </script>

    <script type="module" src="/app.js"></script>
{% include "footer" %}