AI Display components

Five vanilla-ES-module display components for the tool-call runtime. Each file lives at site/frontend/ai/components/display/<name>.js and exports a single def object the runtime collects automatically.


Component contract

export const def = {
  name: "<snake_case id>",   // unique id used by the runtime
  category: "Display",
  title: "<Human Title>",
  match(payload) { /* return true iff payload fits this component */ },
  render(payload, ctx) { /* return an HTMLElement */ },
  example: { /* realistic preset payload */ },
};

All components are XSS-safe: text is set via textContent; no untrusted string is ever passed to innerHTML. Zero dependencies — pure DOM, no imports.


citation

File: site/frontend/ai/components/display/citation.js

A compact cited-source card with favicon, domain, linked title, and a text snippet.

Payload shape

{
  title:   string;   // page / article title
  url:     string;   // canonical URL — used for the link and domain display
  snippet: string;   // 1–3 sentence excerpt
  favicon?: string;  // optional favicon URL; falls back to first-letter badge
}

Example

{
  "title": "From-scratch SQL engine — AkurAI-Framework",
  "url": "https://github.com/olibuijr/AkurAI-Framework",
  "snippet": "A pure-Rust zero-runtime-dep full-stack framework with a built-in SQL engine, native ESM frontend, and semantic search.",
  "favicon": "https://github.com/favicon.ico"
}

link_preview

File: site/frontend/ai/components/display/link_preview.js

OpenGraph-style preview card: optional hero image, domain badge, bold title, and description. The entire card is a navigable <a>.

Payload shape

{
  url:         string;  // destination
  title:       string;  // OG title
  description: string;  // OG description
  image?:      string;  // OG image URL — omit to render text-only card
}

Example

{
  "url": "https://akurai.is",
  "title": "AkurAI — AI for Icelandic businesses",
  "description": "AI solutions, automation, and training built specifically for Icelandic companies. Up to 90% training reimbursement via vocational funds.",
  "image": "https://akurai.is/og-image.png"
}

stats_display

File: site/frontend/ai/components/display/stats_display.js

A responsive stat grid. Reuses .stat, .stat-value, and .stat-label from the design system. Optional delta strings are coloured green (up) or red (down) based on their leading sign.

Payload shape

{
  stats: Array<{
    label: string;
    value: string | number;
    delta?: string | null;  // e.g. "+18%" or "-0.3 s"; null = omit
  }>;
}

Example

{
  "stats": [
    { "label": "Monthly revenue",   "value": "ISK 1.2M", "delta": "+18%"  },
    { "label": "Active customers",  "value": 34,          "delta": "+3"    },
    { "label": "Avg response time", "value": "1.4 s",     "delta": "-0.3 s" },
    { "label": "Uptime",            "value": "99.97%",    "delta": null    }
  ]
}

terminal

File: site/frontend/ai/components/display/terminal.js

A styled terminal block with a macOS-style title bar (traffic-light dots), a prompt line, output lines, and an optional exit-code indicator (red when non-zero).

Payload shape

{
  command:    string;    // command that was run (shown after the prompt)
  lines:      string[];  // output lines (stdout / stderr)
  exit_code?: number;    // optional; omit to hide; non-zero renders in red
}

Example

{
  "command": "bun run build",
  "lines": [
    "  Building routes...",
    "  Compiled 42 pages in 180ms",
    "  Static assets copied: 7 files",
    "  Done."
  ],
  "exit_code": 0
}

weather_widget

File: site/frontend/ai/components/display/weather_widget.js

A weather card with current temperature, condition (mapped to emoji — no image assets), hi/lo range, and an optional scrollable hourly strip.

Payload shape

{
  location:  string;   // display name, e.g. "Akureyri, Iceland"
  temp:      number;   // current temperature
  unit?:     "C" | "F";  // default "C"
  condition: string;   // free-text, e.g. "Partly cloudy"
  hi:        number;   // daily high
  lo:        number;   // daily low
  hourly?:   Array<{
    time:      string;  // display label, e.g. "14:00" or "Now"
    temp:      number;
    condition: string;
  }>;
}

Example

{
  "location": "Akureyri, Iceland",
  "temp": 9,
  "unit": "C",
  "condition": "Partly cloudy",
  "hi": 12,
  "lo": 5,
  "hourly": [
    { "time": "Now",   "temp": 9,  "condition": "Partly cloudy" },
    { "time": "13:00", "temp": 10, "condition": "Partly cloudy" },
    { "time": "14:00", "temp": 11, "condition": "Sunny"         },
    { "time": "15:00", "temp": 12, "condition": "Sunny"         },
    { "time": "16:00", "temp": 11, "condition": "Cloudy"        },
    { "time": "17:00", "temp": 10, "condition": "Rain"          },
    { "time": "18:00", "temp": 8,  "condition": "Rain"          },
    { "time": "19:00", "temp": 7,  "condition": "Cloudy"        }
  ]
}