ai: rich-output blocks via lazy-fetched typed-fence protocol

Assistant replies can now emit typed fenced blocks that render as
@crema/*-ui components inline at their position in the reply.

- message-body.tsx: segmented rendering — alternating prose chunks and
  block dispatch (was: all blocks appended at end). Renderers for kpi,
  table, chart-bar/-line/-donut/-spark, code, diff, flowchart, orgchart,
  steps, checklist, welcome, hint, plus the legacy card kinds.
- block-schemas.ts: single source of truth — BLOCK_INDEX (one-line
  purpose per kind, always in prompt) + SCHEMAS (full JSON shape +
  example, fetched on demand).
- admin-tools.ts: new get_block_schema(kind) tool the model calls once
  per kind per thread to fetch the exact schema. Keeps the always-on
  prompt small (~110 tokens vs ~400 inline).
- assistant.tsx: replaces the inline schema dump with the generated
  thin index.
- ai.tsx: empty-state preview button injects a synthetic assistant
  message exercising every block, for renderer/theme smoke-testing.
- console.css + ai.tsx: shrink ATLAS headline so it doesn't slip under
  the composer with the added preview button.
- tsconfig.json + app.css: wire lib-data-ui, lib-code-ui, lib-diagram-ui,
  lib-onboarding-ui as siblings.

Adding a new block kind = add the lib paths, add a renderer case, add
a schema entry. No prompt edits required.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
jules
2026-05-02 22:47:36 +10:00
parent cdb96499be
commit 9cbe921db7
8 changed files with 966 additions and 143 deletions

View File

@@ -187,10 +187,10 @@
/* Empty-state oversize text — letter-spacing tracking is the whole point */
[data-theme="console"] .console-empty-headline {
font-family: var(--console-font-mono);
font-size: clamp(2.25rem, 5.5vw, 4.5rem);
font-size: clamp(1.5rem, 3.2vw, 2.5rem);
font-weight: 500;
letter-spacing: 0.02em;
line-height: 0.95;
line-height: 1;
color: var(--console-text);
}
@@ -325,10 +325,18 @@
color: var(--console-muted-2);
}
/* Header strip — session card */
/* Header strip — session card. Solid background so messages scrolling past
* don't bleed through the sticky bar. */
[data-theme="console"] .console-header {
border-bottom: 1px solid var(--console-rule-soft);
background: linear-gradient(to bottom, oklch(0.16 0.02 240 / 0.6), transparent);
background: var(--console-ink);
-webkit-backdrop-filter: blur(12px) saturate(140%);
backdrop-filter: blur(12px) saturate(140%);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
[data-theme="console"] .console-header {
background: oklch(0.13 0.02 240 / 0.82);
}
}
[data-theme="console"] .console-session-id {
font-family: var(--console-font-mono);