const A2UI_ACTION_KEYS = [
"beginRendering" ,
"surfaceUpdate" ,
"dataModelUpdate" ,
"deleteSurface" ,
"createSurface" ,
] as const ;
export type A2UIVersion = "v0.8" | "v0.9" ;
export function buildA2UITextJsonl(text: string) {
const surfaceId = "main" ;
const rootId = "root" ;
const textId = "text" ;
const payloads = [
{
surfaceUpdate: {
surfaceId,
components: [
{
id: rootId,
component: { Column: { children: { explicitList: [textId] } } },
},
{
id: textId,
component: {
Text: { text: { literalString: text }, usageHint: "body" },
},
},
],
},
},
{ beginRendering: { surfaceId, root: rootId } },
];
return payloads.map((payload) => JSON.stringify(payload)).join("\n" );
}
export function validateA2UIJsonl(jsonl: string) {
const lines = jsonl.split(/\r?\n/);
const errors: string[] = [];
let sawV08 = false ;
let sawV09 = false ;
let messageCount = 0 ;
lines.forEach((line, idx) => {
const trimmed = line.trim();
if (!trimmed) {
return ;
}
messageCount += 1 ;
let obj: unknown;
try {
obj = JSON.parse(trimmed) as unknown;
} catch (err) {
errors.push(`line ${idx + 1 }: ${String(err)}`);
return ;
}
if (!obj || typeof obj !== "object" || Array.isArray(obj)) {
errors.push(`line ${idx + 1 }: expected JSON object`);
return ;
}
const record = obj as Record<string, unknown>;
const actionKeys = A2UI_ACTION_KEYS.filter((key) => key in record);
if (actionKeys.length !== 1 ) {
errors.push(
`line ${idx + 1 }: expected exactly one action key (${A2UI_ACTION_KEYS.join(", " )})`,
);
return ;
}
if (actionKeys[0 ] === "createSurface" ) {
sawV09 = true ;
} else {
sawV08 = true ;
}
});
if (messageCount === 0 ) {
errors.push("no JSONL messages found" );
}
if (sawV08 && sawV09) {
errors.push("mixed A2UI v0.8 and v0.9 messages in one file" );
}
if (errors.length > 0 ) {
throw new Error(`Invalid A2UI JSONL:\n- ${errors.join("\n- " )}`);
}
const version: A2UIVersion = sawV09 ? "v0.9" : "v0.8" ;
return { version, messageCount };
}
Messung V0.5 in Prozent C=100 H=98 G=98
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland