Parse a versioned result, not arbitrary JSX props
Ask the model for a constrained object with version, kind, view data, provenance, validation issues, and suggested commands. Validate the complete object or validated stream chunks before mapping allowed fields to Ace Grid props. Ace Grid schema documents use a version field; application envelopes may add their own result identifier and generation timestamp.
Render every state deliberately
Show progress while rows stream, preserve a text fallback, report schema errors without discarding raw output, and keep citations available beside the grid. Do not let partial columns or changing row IDs corrupt selection and editing.
Separate display from mutation
Rendering an answer can be automatic after validation. Applying commands should require policy checks, current authorization, user approval, and a server-side mutation. Return per-row outcomes so the grid can show partial success or failure.
Handle streaming without corrupting identity
If rows arrive incrementally, assign stable IDs and avoid replacing column definitions after users begin interacting. Buffer incomplete objects until they validate. Preserve selection and scroll when appending results. If the model revises an existing row, make that update explicit and retain provenance. Streaming convenience should not make the visible result internally inconsistent.
Test adversarial and malformed output
Send missing IDs, duplicate columns, unknown commands, oversized payloads, invalid values, stale citations, and prompt-injected instructions. Confirm validation rejects unsafe shapes and the UI falls back without applying actions. Limit row, column, text, and command sizes before rendering. Treat model output as untrusted external data even when the model is hosted internally.
Never apply generated commands directly
An LLM result can suggest actions, but the application must map them to allow-listed commands, require user approval when needed, and send them to a server that rechecks authorization and row versions. The grid can display suggested actions and outcomes, but model output is not permission. This is the safety distinction that makes Ace Grid relevant for serious LLM table output.
Product evidence
Validated schema application
@ace-grid/schema-ai can create an AI result schema, validate the document, and apply it through grid actions after validation succeeds.
Validate before rendering an LLM table result
import { Grid } from "@ace-grid/enterprise";
import { validateGridSchemaDocument } from "@ace-grid/schema-ai";
export function AssistantGridResult({ result }) {
const validation = validateGridSchemaDocument(result);
if (!validation.valid) {
return (
<section role="alert">
<h3>The assistant result could not be rendered</h3>
<pre>{JSON.stringify(validation.issues, null, 2)}</pre>
</section>
);
}
const view = validation.value.kind === "view"
? validation.value
: validation.value.view;
if (!view?.data?.rows || !view.data.columnDefs) {
return <p>The assistant returned no table data.</p>;
}
return (
<Grid
data={{ rows: view.data.rows, columns: view.data.columnDefs }}
layout={{ width: 1200, height: 420 }}
columns={{ columnWidths: {}, fillWidth: true }}
/>
);
}
Limitations and tradeoffs
- Use prose or a simple semantic table for small answers that do not need interaction or mutation.
- Never map unvalidated model output directly into JSX, grid props, or executable callbacks.
Common questions
Should the model generate React components?
No. Have the model return a versioned, allow-listed document, validate it, and map approved fields into application-owned components.
How should streaming rows be identified?
Use stable row IDs from the result contract and update existing records by identity rather than by arrival position.