import { defineCatalog } from "@json-render/core"; import { schema } from "@json-render/react/schema"; import { z } from "zod"; const shortText = z.string().max(200); const text = z.string().max(4000); const optionalText = shortText.nullable(); const featureId = z.string().min(1).max(128); /** This is the source of the generated Agent contract, not a remotely hosted registry. */ export const answerUiCatalog = defineCatalog(schema, { actions: {}, components: { Stack: { props: z .object({ columns: z.enum(["one", "two"]), gap: z.enum(["compact", "normal"]) }) .strict(), slots: ["default"], description: "组织内容;双列在窄面板自动改为单列。" }, Section: { props: z.object({ title: shortText, description: text.nullable() }).strict(), slots: ["default"], description: "带标题的资料分区,保留真实内容层级。" }, Text: { props: z.object({ text, tone: z.enum(["neutral", "info", "warning"]) }).strict(), description: "简短说明、判断边界或资料缺口。" }, Metric: { props: z .object({ label: shortText, value: shortText, unit: optionalText, source: optionalText }) .strict(), description: "展示真实指标及其单位、来源;不能臆造读数。" }, Table: { props: z .object({ title: shortText, columns: z.array(shortText).min(1).max(8), rows: z.array(z.array(z.string().max(1000)).max(8)).max(50) }) .strict(), description: "按相同字段比较资料,避免无法比较的指标混列。" }, Chart: { props: z .object({ title: shortText, chart_type: z.enum(["line", "bar"]), x_data: z.array(shortText).min(1).max(100), series: z .array( z .object({ name: shortText, data: z.array(z.number().finite()).min(1).max(100) }) .strict() ) .min(1) .max(8), source: text }) .strict(), description: "展示查询或用户提供的真实数据;series 必须与 x_data 对齐。浏览者可切换图形与数据表。" }, Evidence: { props: z .object({ title: shortText, summary: text, source: shortText, evidence_id: optionalText, observed_at: optionalText, kind: z.enum(["observed", "human_input", "inference", "demo"]) }) .strict(), description: "展示证据依据;明确区分查询记录、用户事实、推断和演练数据。" }, MapLocation: { props: z .object({ label: shortText, layer: z.enum(["junctions", "pipes", "valves", "pumps", "tanks", "reservoirs", "scada"]), feature_ids: z.array(featureId).min(1).max(100), source: shortText }) .strict(), description: "用户点击后定位已有要素;ID 必须来自查询或用户明确提供,不绘制臆测影响范围。" }, FollowUpForm: { props: z .object({ title: shortText, description: text, fields: z .array( z .object({ name: z.string().regex(/^[a-z][a-z0-9_]{0,39}$/), label: shortText, kind: z.enum(["text", "datetime", "number"]), required: z.boolean() }) .strict() ) .min(1) .max(12) }) .strict(), description: "让用户主动填写并提交补充资料;无默认事实。提交产生用户消息,是否写入业务证据由现有 Agent 工具处理。" } } }); export const ANSWER_UI_VERSION = "answer-ui@1" as const;