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:
@@ -31,6 +31,15 @@ const PROBE_TIMEOUT_MS = 3000
|
||||
// "Available actions" in the system prompt only lists what's on screen NOW;
|
||||
// this catalog tells the model what exists elsewhere so it can plan
|
||||
// multi-step flows (navigate → wait_for → fill → click) in a single block.
|
||||
// Rich-output protocol: typed fenced blocks the chat renderer turns into UI
|
||||
// from @crema/*-ui. The system prompt only carries a thin INDEX (kind →
|
||||
// one-line purpose) — full schemas live in app/lib/block-schemas.ts and are
|
||||
// fetched on demand via the get_block_schema tool. Adding a new block kind
|
||||
// = edit block-schemas.ts + the renderer; no prompt edit required.
|
||||
import { blockIndexForPrompt } from "~/lib/block-schemas"
|
||||
const RICH_OUTPUT_PREFACE = blockIndexForPrompt()
|
||||
|
||||
|
||||
const UI_CONTROL_PREFACE = `You are the operator's assistant inside Arcadia Admin — the platform-admin web app for the Arcadia multi-tenant SaaS backend (Phoenix, /api/v1). The signed-in user is a platform administrator. Help them inspect and manage tenants, users, billing, audit logs, feature flags, and other platform surfaces.
|
||||
|
||||
You can both answer factual questions about the current state (use the "Admin context" block below) and drive the UI. A virtual cursor is shown to the user — every step should target an element so the cursor visibly moves.
|
||||
@@ -104,6 +113,7 @@ function buildAdminPreface(activeAgent: Agent | undefined, uiControl: boolean):
|
||||
const ctx = formatAdminContextForPrompt()
|
||||
const parts = [
|
||||
"You are the operator's assistant inside Arcadia Admin. Be precise and direct. You have native function tools attached to this conversation — call them whenever the user asks about live platform state (counts, statuses, listings, lookups). Never invent tenant slugs, user counts, or statuses; if you need data, call a tool.",
|
||||
RICH_OUTPUT_PREFACE,
|
||||
ARCADIA_KNOWLEDGE,
|
||||
persona,
|
||||
ctx,
|
||||
|
||||
Reference in New Issue
Block a user