From 67f3dd7104772bbe6a3de297a485b68c25ee25d6 Mon Sep 17 00:00:00 2001 From: i-subham Date: Thu, 2 Jul 2026 14:58:34 +0530 Subject: [PATCH 1/3] refactor: update system prompts to ensure consistent data generation guidelines - Reintroduced the rule to generate realistic/plausible data across various system prompts in chat and playground examples. - Adjusted the structure of prompt options in the playground library to include additional rules. - Enhanced documentation for forms and charts to clarify component usage and data handling. This update aims to standardize the approach to data generation in the system prompts, ensuring a more coherent user experience across different examples. --- docs/generated/chat-system-prompt.txt | 2 +- docs/generated/playground-system-prompt.txt | 3 ++- docs/lib/playground-library.ts | 5 ++++- .../src/generated/system-prompt.txt | 2 +- .../src/lib/heroui-genui/index.tsx | 1 + .../src/generated/system-prompt.txt | 5 ++--- .../harnesses/pi-agent-harness/src/library.ts | 14 ++++++++++++- .../src/generated/system-prompt.txt | 2 +- .../src/generated/system-prompt.txt | 16 +++++++-------- .../src/generated/system-prompt.txt | 2 +- .../src/lib/mui-genui/index.tsx | 1 + .../src/generated/system-prompt.txt | 16 +++++++-------- .../src/generated/system-prompt.txt | 4 ++-- .../backend/src/library.ts | 4 ++++ .../src/lib/shadcn-genui/index.tsx | 1 + examples/svelte-chat/src/lib/library.ts | 1 + .../src/generated/system-prompt.txt | 16 +++++++-------- examples/vue-chat/generated/system-prompt.txt | 20 +++++++++---------- examples/vue-chat/lib/library.ts | 1 + examples/vue-chat/scripts/generate-prompt.mjs | 1 + packages/lang-core/src/parser/prompt.ts | 1 - packages/react-email/src/library.ts | 1 + .../src/genui-lib/openuiChatLibrary.tsx | 1 + .../react-ui/src/genui-lib/openuiLibrary.tsx | 8 +++++++- 24 files changed, 79 insertions(+), 49 deletions(-) diff --git a/docs/generated/chat-system-prompt.txt b/docs/generated/chat-system-prompt.txt index cbd28d059..6da009257 100644 --- a/docs/generated/chat-system-prompt.txt +++ b/docs/generated/chat-system-prompt.txt @@ -201,7 +201,6 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -209,6 +208,7 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. +- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/docs/generated/playground-system-prompt.txt b/docs/generated/playground-system-prompt.txt index e16a602fc..5308d20f1 100644 --- a/docs/generated/playground-system-prompt.txt +++ b/docs/generated/playground-system-prompt.txt @@ -195,10 +195,11 @@ reactContent = [TextContent("React is a library by Meta for building UIs."), Cal vueContent = [TextContent("Vue is a progressive framework by Evan You."), Callout("success", "Tip", "Vue has a gentle learning curve.")] ## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification Before finishing, walk your output and verify: 1. root = Stack(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. + +- When asked about data, generate realistic/plausible data diff --git a/docs/lib/playground-library.ts b/docs/lib/playground-library.ts index 5150c55c6..a42067e34 100644 --- a/docs/lib/playground-library.ts +++ b/docs/lib/playground-library.ts @@ -1,4 +1,7 @@ import { openuiExamples } from "@openuidev/react-ui/genui-lib"; export { openuiLibrary as library } from "@openuidev/react-ui/genui-lib"; -export const promptOptions = { examples: openuiExamples }; +export const promptOptions = { + examples: openuiExamples, + additionalRules: ["When asked about data, generate realistic/plausible data"], +}; diff --git a/examples/form-generator/src/generated/system-prompt.txt b/examples/form-generator/src/generated/system-prompt.txt index 5dd4c7f02..da7f8a395 100644 --- a/examples/form-generator/src/generated/system-prompt.txt +++ b/examples/form-generator/src/generated/system-prompt.txt @@ -50,7 +50,6 @@ During streaming, the output is re-parsed on every chunk. Undefined references a Always write the root = Form(...) statement first so the UI shell appears immediately, even before child data has streamed in. ## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -58,6 +57,7 @@ Before finishing, walk your output and verify: 1. root = Form(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. +- When asked about data, generate realistic/plausible data - Every response is a single Form(...) — Form is the root element. - Always include explicit Buttons with at least one primary submit button. - Define EACH FormControl as its own reference — do NOT inline all controls in one array. This allows progressive field-by-field streaming. diff --git a/examples/form-generator/src/lib/heroui-genui/index.tsx b/examples/form-generator/src/lib/heroui-genui/index.tsx index c642a1bf7..bcc355627 100644 --- a/examples/form-generator/src/lib/heroui-genui/index.tsx +++ b/examples/form-generator/src/lib/heroui-genui/index.tsx @@ -51,6 +51,7 @@ export const herouiComponentGroups: ComponentGroup[] = [ export const herouiFormExamples: string[] = []; export const herouiFormAdditionalRules: string[] = [ + "When asked about data, generate realistic/plausible data", "Every response is a single Form(...) — Form is the root element.", "Always include explicit Buttons with at least one primary submit button.", "Define EACH FormControl as its own reference — do NOT inline all controls in one array. This allows progressive field-by-field streaming.", diff --git a/examples/hands-on-table-chat/src/generated/system-prompt.txt b/examples/hands-on-table-chat/src/generated/system-prompt.txt index 01bfea3ee..8bf0191f7 100644 --- a/examples/hands-on-table-chat/src/generated/system-prompt.txt +++ b/examples/hands-on-table-chat/src/generated/system-prompt.txt @@ -75,7 +75,7 @@ Series(category: string, values: number[]) — One data series - Multiple chart views: use Tabs — Tabs([TabItem("line", "Line", [LineChart(...)]), TabItem("bar", "Bar", [BarChart(...)])]) ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -94,7 +94,7 @@ FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slide Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") SelectItem(value: string, label: string) — Option for Select DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants @@ -180,7 +180,6 @@ sheet = SpreadsheetTable([["Widget A", 1500, 1800, 2100, 2400, "=SUM(B1:E1)"], [ followups = Buttons([Button("Add another product", null, "secondary"), Button("Show updated totals", null, "secondary"), Button("Visualize the data", null, "secondary")]) ## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification diff --git a/examples/harnesses/pi-agent-harness/src/library.ts b/examples/harnesses/pi-agent-harness/src/library.ts index 8a2edfa62..7551a0bda 100644 --- a/examples/harnesses/pi-agent-harness/src/library.ts +++ b/examples/harnesses/pi-agent-harness/src/library.ts @@ -1 +1,13 @@ -export { openuiLibrary as library, openuiPromptOptions as promptOptions } from "@openuidev/react-ui/genui-lib"; +import type { PromptOptions } from "@openuidev/react-lang"; +import { openuiAdditionalRules, openuiExamples, openuiLibrary } from "@openuidev/react-ui/genui-lib"; + +export { openuiLibrary as library }; + +// pi drives a real coding agent with read/bash/edit/write tools over a real +// workspace, so we deliberately omit the demo "generate realistic/plausible data" +// stance that openuiPromptOptions carries — data must come from the agent's tools, +// not be invented. (issue #698) +export const promptOptions: PromptOptions = { + examples: openuiExamples, + additionalRules: openuiAdditionalRules, +}; diff --git a/examples/langchain-chat/src/generated/system-prompt.txt b/examples/langchain-chat/src/generated/system-prompt.txt index cbd28d059..6da009257 100644 --- a/examples/langchain-chat/src/generated/system-prompt.txt +++ b/examples/langchain-chat/src/generated/system-prompt.txt @@ -201,7 +201,6 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -209,6 +208,7 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. +- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/mastra-chat/src/generated/system-prompt.txt b/examples/mastra-chat/src/generated/system-prompt.txt index af8c67770..6da009257 100644 --- a/examples/mastra-chat/src/generated/system-prompt.txt +++ b/examples/mastra-chat/src/generated/system-prompt.txt @@ -31,7 +31,7 @@ Separator(orientation?: "horizontal" | "vertical", decorative?: boolean) — Vis ### Tables Table(columns: Col[]) — Data table — column-oriented. Each Col holds its own data array. -Col(label: string, data, type?: "string" | "number" | "action") — Column definition — holds label + data array +Col(label: string, data: any, type?: "string" | "number" | "action") — Column definition — holds label + data array ### Charts (2D) BarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Vertical bars; use for comparing values across categories with one or more series @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -53,20 +53,20 @@ ScatterSeries(name: string, points: Point[]) — Named dataset Point(x: number, y: number, z?: number) — Data point with numeric coordinates ### Forms -Form(name: string, buttons: Buttons, fields) — Form container with fields and explicit action buttons +Form(name: string, buttons: Buttons, fields?: FormControl[]) — Form container with fields and explicit action buttons FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slider | CheckBoxGroup | RadioGroup, hint?: string) — Field with label, input component, and optional hint text Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") SelectItem(value: string, label: string) — Option for Select -DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants -CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding>) CheckBoxItem(label: string, description: string, name: string, defaultChecked?: boolean) RadioGroup(name: string, items: RadioItem[], defaultValue?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) RadioItem(label: string, description: string, value: string) -SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?) — Group of switch toggles +SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?: $binding>) — Group of switch toggles SwitchItem(label?: string, description?: string, name: string, defaultChecked?: boolean) — Individual switch toggle - Define EACH FormControl as its own reference — do NOT inline all controls in one array. - NEVER nest Form inside Form. @@ -201,7 +201,6 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -209,6 +208,7 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. +- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/material-ui-chat/src/generated/system-prompt.txt b/examples/material-ui-chat/src/generated/system-prompt.txt index 0fc1dffd3..87e6ef259 100644 --- a/examples/material-ui-chat/src/generated/system-prompt.txt +++ b/examples/material-ui-chat/src/generated/system-prompt.txt @@ -152,7 +152,6 @@ b2 = Button("Learn more", { type: "open_url", url: "https://mui.com" }, "outline b3 = Button("Delete", { type: "continue_conversation" }, "destructive") ## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -160,6 +159,7 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. +- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. - Card is the only top-level layout container. Use Tabs to switch between sections, Accordion for collapsible sections. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/material-ui-chat/src/lib/mui-genui/index.tsx b/examples/material-ui-chat/src/lib/mui-genui/index.tsx index 4cf1aafb3..7664dfa6d 100644 --- a/examples/material-ui-chat/src/lib/mui-genui/index.tsx +++ b/examples/material-ui-chat/src/lib/mui-genui/index.tsx @@ -187,6 +187,7 @@ b3 = Button("Delete", { type: "continue_conversation" }, "destructive")`, ]; export const muiAdditionalRules: string[] = [ + "When asked about data, generate realistic/plausible data", "Every response is a single Card(children) — children stack vertically automatically.", "Card is the only top-level layout container. Use Tabs to switch between sections, Accordion for collapsible sections.", "Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next.", diff --git a/examples/multi-agent-chat/src/generated/system-prompt.txt b/examples/multi-agent-chat/src/generated/system-prompt.txt index af8c67770..6da009257 100644 --- a/examples/multi-agent-chat/src/generated/system-prompt.txt +++ b/examples/multi-agent-chat/src/generated/system-prompt.txt @@ -31,7 +31,7 @@ Separator(orientation?: "horizontal" | "vertical", decorative?: boolean) — Vis ### Tables Table(columns: Col[]) — Data table — column-oriented. Each Col holds its own data array. -Col(label: string, data, type?: "string" | "number" | "action") — Column definition — holds label + data array +Col(label: string, data: any, type?: "string" | "number" | "action") — Column definition — holds label + data array ### Charts (2D) BarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Vertical bars; use for comparing values across categories with one or more series @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -53,20 +53,20 @@ ScatterSeries(name: string, points: Point[]) — Named dataset Point(x: number, y: number, z?: number) — Data point with numeric coordinates ### Forms -Form(name: string, buttons: Buttons, fields) — Form container with fields and explicit action buttons +Form(name: string, buttons: Buttons, fields?: FormControl[]) — Form container with fields and explicit action buttons FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slider | CheckBoxGroup | RadioGroup, hint?: string) — Field with label, input component, and optional hint text Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") SelectItem(value: string, label: string) — Option for Select -DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants -CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding>) CheckBoxItem(label: string, description: string, name: string, defaultChecked?: boolean) RadioGroup(name: string, items: RadioItem[], defaultValue?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) RadioItem(label: string, description: string, value: string) -SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?) — Group of switch toggles +SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?: $binding>) — Group of switch toggles SwitchItem(label?: string, description?: string, name: string, defaultChecked?: boolean) — Individual switch toggle - Define EACH FormControl as its own reference — do NOT inline all controls in one array. - NEVER nest Form inside Form. @@ -201,7 +201,6 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -209,6 +208,7 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. +- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/openui-chat/src/generated/system-prompt.txt b/examples/openui-chat/src/generated/system-prompt.txt index 5a066bbaf..6da009257 100644 --- a/examples/openui-chat/src/generated/system-prompt.txt +++ b/examples/openui-chat/src/generated/system-prompt.txt @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -201,7 +201,6 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -209,6 +208,7 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. +- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/openui-react-native/backend/src/library.ts b/examples/openui-react-native/backend/src/library.ts index f204bf861..e8cf91dd0 100644 --- a/examples/openui-react-native/backend/src/library.ts +++ b/examples/openui-react-native/backend/src/library.ts @@ -108,6 +108,10 @@ export const promptOptions: PromptOptions = { preamble: "You are a helpful assistant. Always respond using OpenUI Lang — never plain markdown or JSON.", additionalRules: [ + // Do not regenerate src/system-prompt.txt until this example's pinned + // @openuidev/react-lang (^0.1.3) is bumped to a core that no longer emits this + // line from importantRules — otherwise the old core + this entry duplicate it. (issue #698) + "When asked about data, generate realistic/plausible data", "Always wrap your entire response inside a single root Card.", "Use Text components for all textual content.", 'Use variant="heading" for the main topic, variant="caption" for secondary info, and the default body variant for regular text.', diff --git a/examples/shadcn-chat/src/lib/shadcn-genui/index.tsx b/examples/shadcn-chat/src/lib/shadcn-genui/index.tsx index 30f034cff..6677d2228 100644 --- a/examples/shadcn-chat/src/lib/shadcn-genui/index.tsx +++ b/examples/shadcn-chat/src/lib/shadcn-genui/index.tsx @@ -314,6 +314,7 @@ cal = CalendarBlock("range", "2025-06-01", 2)`, ]; export const shadcnAdditionalRules: string[] = [ + "When asked about data, generate realistic/plausible data", "Every response is a single Card(children) — children stack vertically automatically.", "Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll.", "Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next.", diff --git a/examples/svelte-chat/src/lib/library.ts b/examples/svelte-chat/src/lib/library.ts index 8732f1010..2adf06d54 100644 --- a/examples/svelte-chat/src/lib/library.ts +++ b/examples/svelte-chat/src/lib/library.ts @@ -64,6 +64,7 @@ export const library = createLibrary({ export const promptOptions: PromptOptions = { additionalRules: [ + "When asked about data, generate realistic/plausible data", "Always use Stack as the root component.", "Group related content in Card components with descriptive titles.", "Use TextContent for all text output. You can use markdown within the text string.", diff --git a/examples/vercel-ai-chat/src/generated/system-prompt.txt b/examples/vercel-ai-chat/src/generated/system-prompt.txt index af8c67770..6da009257 100644 --- a/examples/vercel-ai-chat/src/generated/system-prompt.txt +++ b/examples/vercel-ai-chat/src/generated/system-prompt.txt @@ -31,7 +31,7 @@ Separator(orientation?: "horizontal" | "vertical", decorative?: boolean) — Vis ### Tables Table(columns: Col[]) — Data table — column-oriented. Each Col holds its own data array. -Col(label: string, data, type?: "string" | "number" | "action") — Column definition — holds label + data array +Col(label: string, data: any, type?: "string" | "number" | "action") — Column definition — holds label + data array ### Charts (2D) BarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Vertical bars; use for comparing values across categories with one or more series @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -53,20 +53,20 @@ ScatterSeries(name: string, points: Point[]) — Named dataset Point(x: number, y: number, z?: number) — Data point with numeric coordinates ### Forms -Form(name: string, buttons: Buttons, fields) — Form container with fields and explicit action buttons +Form(name: string, buttons: Buttons, fields?: FormControl[]) — Form container with fields and explicit action buttons FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slider | CheckBoxGroup | RadioGroup, hint?: string) — Field with label, input component, and optional hint text Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") SelectItem(value: string, label: string) — Option for Select -DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants -CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding>) CheckBoxItem(label: string, description: string, name: string, defaultChecked?: boolean) RadioGroup(name: string, items: RadioItem[], defaultValue?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) RadioItem(label: string, description: string, value: string) -SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?) — Group of switch toggles +SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?: $binding>) — Group of switch toggles SwitchItem(label?: string, description?: string, name: string, defaultChecked?: boolean) — Individual switch toggle - Define EACH FormControl as its own reference — do NOT inline all controls in one array. - NEVER nest Form inside Form. @@ -201,7 +201,6 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -209,6 +208,7 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. +- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/vue-chat/generated/system-prompt.txt b/examples/vue-chat/generated/system-prompt.txt index f2c484fa0..05e5fac45 100644 --- a/examples/vue-chat/generated/system-prompt.txt +++ b/examples/vue-chat/generated/system-prompt.txt @@ -4,18 +4,16 @@ You are an AI assistant that responds using openui-lang, a declarative UI langua 1. Each statement is on its own line: `identifier = Expression` 2. `root` is the entry point — every program must define `root = Stack(...)` -3. Expressions are: strings ("..."), numbers, booleans (true/false), arrays ([...]), objects ({...}), or component calls TypeName(arg1, arg2, ...) +3. Expressions are: strings ("..."), numbers, booleans (true/false), null, arrays ([...]), objects ({...}), or component calls TypeName(arg1, arg2, ...) 4. Use references for readability: define `name = ...` on one line, then use `name` later 5. EVERY variable (except root) MUST be referenced by at least one other variable. Unreferenced variables are silently dropped and will NOT render. Always include defined variables in their parent's children/items array. -6. Arguments are POSITIONAL (order matters, not names) +6. Arguments are POSITIONAL (order matters, not names). Write `Stack([children], "row", "l")` NOT `Stack([children], direction: "row", gap: "l")` — colon syntax is NOT supported and silently breaks 7. Optional arguments can be omitted from the end -8. No operators, no logic, no variables — only declarations -9. Strings use double quotes with backslash escaping +- Strings use double quotes with backslash escaping ## Component Signatures Arguments marked with ? are optional. Sub-components can be inline or referenced; prefer references for better streaming. -The `action` prop type accepts: ContinueConversation (sends message to LLM), OpenUrl (navigates to URL), or Custom (app-defined). TextContent(text: string) — Displays a block of text. Supports markdown formatting within the string. Button(label: string, action?: string) — A clickable button. The label is shown to the user and used as the follow-up message. @@ -66,14 +64,14 @@ card = Card("Language Trends", [chart, t1]) cta = Button("Compare Python vs JavaScript") ## Important Rules -- ALWAYS start with root = Stack(...) -- Write statements in TOP-DOWN order: root → components → data (leverages hoisting for progressive streaming) -- Each statement on its own line -- No trailing text or explanations — output ONLY openui-lang code -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) -- NEVER define a variable without referencing it from the tree. Every variable must be reachable from root, otherwise it will not render. +## Final Verification +Before finishing, walk your output and verify: +1. root = Stack(...) is the FIRST line (for optimal streaming). +2. Every referenced name is defined. Every defined name (other than root) is reachable from root. + +- When asked about data, generate realistic/plausible data - Always use Stack as the root component. - Group related content in Card components with descriptive titles. - Use TextContent for all text output. You can use markdown within the text string. diff --git a/examples/vue-chat/lib/library.ts b/examples/vue-chat/lib/library.ts index 518446146..624f05b9f 100644 --- a/examples/vue-chat/lib/library.ts +++ b/examples/vue-chat/lib/library.ts @@ -64,6 +64,7 @@ export const library = createLibrary({ export const promptOptions: PromptOptions = { additionalRules: [ + "When asked about data, generate realistic/plausible data", "Always use Stack as the root component.", "Group related content in Card components with descriptive titles.", "Use TextContent for all text output. You can use markdown within the text string.", diff --git a/examples/vue-chat/scripts/generate-prompt.mjs b/examples/vue-chat/scripts/generate-prompt.mjs index 4ecfd884f..7388aa594 100644 --- a/examples/vue-chat/scripts/generate-prompt.mjs +++ b/examples/vue-chat/scripts/generate-prompt.mjs @@ -71,6 +71,7 @@ const library = createLibrary({ const promptOptions = { additionalRules: [ + "When asked about data, generate realistic/plausible data", "Always use Stack as the root component.", "Group related content in Card components with descriptive titles.", "Use TextContent for all text output. You can use markdown within the text string.", diff --git a/packages/lang-core/src/parser/prompt.ts b/packages/lang-core/src/parser/prompt.ts index f28ef5b25..e6688bc0a 100644 --- a/packages/lang-core/src/parser/prompt.ts +++ b/packages/lang-core/src/parser/prompt.ts @@ -431,7 +431,6 @@ function importantRules( } return `## Important Rules -- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification diff --git a/packages/react-email/src/library.ts b/packages/react-email/src/library.ts index bc73998c9..fdf4071c5 100644 --- a/packages/react-email/src/library.ts +++ b/packages/react-email/src/library.ts @@ -392,6 +392,7 @@ si2 = EmailSocialIcon("https://react.email/static/instagram-logo.png", "Instagra // ── Additional rules (email only) ── export const emailAdditionalRules: string[] = [ + "When asked about data, generate realistic/plausible data", "You are an expert email designer using react-email components.", "The 10 supported email types are: Welcome/Onboarding, Newsletter, Order Confirmation, Password Reset, Promotional/Sale, Event Invitation, Feedback Request, Shipping/Delivery Update, Account Verification, Onboarding Tutorial.", "Use realistic, professional placeholder text — never use lorem ipsum.", diff --git a/packages/react-ui/src/genui-lib/openuiChatLibrary.tsx b/packages/react-ui/src/genui-lib/openuiChatLibrary.tsx index 73b9f3404..362a57428 100644 --- a/packages/react-ui/src/genui-lib/openuiChatLibrary.tsx +++ b/packages/react-ui/src/genui-lib/openuiChatLibrary.tsx @@ -265,6 +265,7 @@ btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")])` ]; export const openuiChatAdditionalRules: string[] = [ + "When asked about data, generate realistic/plausible data", "Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card.", "Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll.", "Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next.", diff --git a/packages/react-ui/src/genui-lib/openuiLibrary.tsx b/packages/react-ui/src/genui-lib/openuiLibrary.tsx index 048c09854..e563c12b8 100644 --- a/packages/react-ui/src/genui-lib/openuiLibrary.tsx +++ b/packages/react-ui/src/genui-lib/openuiLibrary.tsx @@ -256,9 +256,15 @@ export const openuiAdditionalRules: string[] = [ "Use existing components (Tabs, Accordion, Modal) before inventing ternary show/hide patterns", ]; +// Demo/product stance (issue #698): fabricate illustrative data only on surfaces +// with no real data backend. Real-data consumers (e.g. a coding agent) build their +// own promptOptions from openuiAdditionalRules to opt out of this line. export const openuiPromptOptions: PromptOptions = { examples: openuiExamples, - additionalRules: openuiAdditionalRules, + additionalRules: [ + "When asked about data, generate realistic/plausible data", + ...openuiAdditionalRules, + ], }; // ── Library ── From 695a99cfb1aa920ee9e8f776c4e20f57353e6611 Mon Sep 17 00:00:00 2001 From: i-subham Date: Thu, 2 Jul 2026 15:26:06 +0530 Subject: [PATCH 2/3] refactor: standardize data generation guidelines across system prompts - Reintroduced the guideline to generate realistic/plausible data in various system prompts, ensuring consistency across chat and playground examples. - Updated the structure of prompt options in the playground library to remove redundant rules. - Enhanced documentation for forms and charts to clarify component usage and data handling. This update aims to improve the coherence of data generation practices in the system prompts, enhancing the overall user experience. --- docs/generated/chat-system-prompt.txt | 2 +- docs/generated/playground-system-prompt.txt | 3 +-- docs/lib/playground-library.ts | 5 +---- .../src/generated/system-prompt.txt | 2 +- .../src/lib/heroui-genui/index.tsx | 1 - .../src/generated/system-prompt.txt | 5 +++-- .../harnesses/pi-agent-harness/src/library.ts | 14 +------------ .../src/generated/system-prompt.txt | 2 +- .../src/generated/system-prompt.txt | 16 +++++++-------- .../src/generated/system-prompt.txt | 2 +- .../src/lib/mui-genui/index.tsx | 1 - .../src/generated/system-prompt.txt | 16 +++++++-------- .../src/generated/system-prompt.txt | 4 ++-- .../backend/src/library.ts | 4 ---- .../src/lib/shadcn-genui/index.tsx | 1 - examples/svelte-chat/src/lib/library.ts | 1 - .../src/generated/system-prompt.txt | 16 +++++++-------- examples/vue-chat/generated/system-prompt.txt | 20 ++++++++++--------- examples/vue-chat/lib/library.ts | 1 - examples/vue-chat/scripts/generate-prompt.mjs | 1 - .../react-ui/src/genui-lib/openuiLibrary.tsx | 9 ++------- 21 files changed, 49 insertions(+), 77 deletions(-) diff --git a/docs/generated/chat-system-prompt.txt b/docs/generated/chat-system-prompt.txt index 6da009257..cbd28d059 100644 --- a/docs/generated/chat-system-prompt.txt +++ b/docs/generated/chat-system-prompt.txt @@ -201,6 +201,7 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -208,7 +209,6 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. -- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/docs/generated/playground-system-prompt.txt b/docs/generated/playground-system-prompt.txt index 5308d20f1..e16a602fc 100644 --- a/docs/generated/playground-system-prompt.txt +++ b/docs/generated/playground-system-prompt.txt @@ -195,11 +195,10 @@ reactContent = [TextContent("React is a library by Meta for building UIs."), Cal vueContent = [TextContent("Vue is a progressive framework by Evan You."), Callout("success", "Tip", "Vue has a gentle learning curve.")] ## Important Rules +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification Before finishing, walk your output and verify: 1. root = Stack(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. - -- When asked about data, generate realistic/plausible data diff --git a/docs/lib/playground-library.ts b/docs/lib/playground-library.ts index a42067e34..5150c55c6 100644 --- a/docs/lib/playground-library.ts +++ b/docs/lib/playground-library.ts @@ -1,7 +1,4 @@ import { openuiExamples } from "@openuidev/react-ui/genui-lib"; export { openuiLibrary as library } from "@openuidev/react-ui/genui-lib"; -export const promptOptions = { - examples: openuiExamples, - additionalRules: ["When asked about data, generate realistic/plausible data"], -}; +export const promptOptions = { examples: openuiExamples }; diff --git a/examples/form-generator/src/generated/system-prompt.txt b/examples/form-generator/src/generated/system-prompt.txt index da7f8a395..5dd4c7f02 100644 --- a/examples/form-generator/src/generated/system-prompt.txt +++ b/examples/form-generator/src/generated/system-prompt.txt @@ -50,6 +50,7 @@ During streaming, the output is re-parsed on every chunk. Undefined references a Always write the root = Form(...) statement first so the UI shell appears immediately, even before child data has streamed in. ## Important Rules +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -57,7 +58,6 @@ Before finishing, walk your output and verify: 1. root = Form(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. -- When asked about data, generate realistic/plausible data - Every response is a single Form(...) — Form is the root element. - Always include explicit Buttons with at least one primary submit button. - Define EACH FormControl as its own reference — do NOT inline all controls in one array. This allows progressive field-by-field streaming. diff --git a/examples/form-generator/src/lib/heroui-genui/index.tsx b/examples/form-generator/src/lib/heroui-genui/index.tsx index bcc355627..c642a1bf7 100644 --- a/examples/form-generator/src/lib/heroui-genui/index.tsx +++ b/examples/form-generator/src/lib/heroui-genui/index.tsx @@ -51,7 +51,6 @@ export const herouiComponentGroups: ComponentGroup[] = [ export const herouiFormExamples: string[] = []; export const herouiFormAdditionalRules: string[] = [ - "When asked about data, generate realistic/plausible data", "Every response is a single Form(...) — Form is the root element.", "Always include explicit Buttons with at least one primary submit button.", "Define EACH FormControl as its own reference — do NOT inline all controls in one array. This allows progressive field-by-field streaming.", diff --git a/examples/hands-on-table-chat/src/generated/system-prompt.txt b/examples/hands-on-table-chat/src/generated/system-prompt.txt index 8bf0191f7..01bfea3ee 100644 --- a/examples/hands-on-table-chat/src/generated/system-prompt.txt +++ b/examples/hands-on-table-chat/src/generated/system-prompt.txt @@ -75,7 +75,7 @@ Series(category: string, values: number[]) — One data series - Multiple chart views: use Tabs — Tabs([TabItem("line", "Line", [LineChart(...)]), TabItem("bar", "Bar", [BarChart(...)])]) ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -94,7 +94,7 @@ FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slide Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) SelectItem(value: string, label: string) — Option for Select DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants @@ -180,6 +180,7 @@ sheet = SpreadsheetTable([["Widget A", 1500, 1800, 2100, 2400, "=SUM(B1:E1)"], [ followups = Buttons([Button("Add another product", null, "secondary"), Button("Show updated totals", null, "secondary"), Button("Visualize the data", null, "secondary")]) ## Important Rules +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification diff --git a/examples/harnesses/pi-agent-harness/src/library.ts b/examples/harnesses/pi-agent-harness/src/library.ts index 7551a0bda..8a2edfa62 100644 --- a/examples/harnesses/pi-agent-harness/src/library.ts +++ b/examples/harnesses/pi-agent-harness/src/library.ts @@ -1,13 +1 @@ -import type { PromptOptions } from "@openuidev/react-lang"; -import { openuiAdditionalRules, openuiExamples, openuiLibrary } from "@openuidev/react-ui/genui-lib"; - -export { openuiLibrary as library }; - -// pi drives a real coding agent with read/bash/edit/write tools over a real -// workspace, so we deliberately omit the demo "generate realistic/plausible data" -// stance that openuiPromptOptions carries — data must come from the agent's tools, -// not be invented. (issue #698) -export const promptOptions: PromptOptions = { - examples: openuiExamples, - additionalRules: openuiAdditionalRules, -}; +export { openuiLibrary as library, openuiPromptOptions as promptOptions } from "@openuidev/react-ui/genui-lib"; diff --git a/examples/langchain-chat/src/generated/system-prompt.txt b/examples/langchain-chat/src/generated/system-prompt.txt index 6da009257..cbd28d059 100644 --- a/examples/langchain-chat/src/generated/system-prompt.txt +++ b/examples/langchain-chat/src/generated/system-prompt.txt @@ -201,6 +201,7 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -208,7 +209,6 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. -- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/mastra-chat/src/generated/system-prompt.txt b/examples/mastra-chat/src/generated/system-prompt.txt index 6da009257..af8c67770 100644 --- a/examples/mastra-chat/src/generated/system-prompt.txt +++ b/examples/mastra-chat/src/generated/system-prompt.txt @@ -31,7 +31,7 @@ Separator(orientation?: "horizontal" | "vertical", decorative?: boolean) — Vis ### Tables Table(columns: Col[]) — Data table — column-oriented. Each Col holds its own data array. -Col(label: string, data: any, type?: "string" | "number" | "action") — Column definition — holds label + data array +Col(label: string, data, type?: "string" | "number" | "action") — Column definition — holds label + data array ### Charts (2D) BarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Vertical bars; use for comparing values across categories with one or more series @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -53,20 +53,20 @@ ScatterSeries(name: string, points: Point[]) — Named dataset Point(x: number, y: number, z?: number) — Data point with numeric coordinates ### Forms -Form(name: string, buttons: Buttons, fields?: FormControl[]) — Form container with fields and explicit action buttons +Form(name: string, buttons: Buttons, fields) — Form container with fields and explicit action buttons FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slider | CheckBoxGroup | RadioGroup, hint?: string) — Field with label, input component, and optional hint text Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) SelectItem(value: string, label: string) — Option for Select -DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants -CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding>) +CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) CheckBoxItem(label: string, description: string, name: string, defaultChecked?: boolean) RadioGroup(name: string, items: RadioItem[], defaultValue?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) RadioItem(label: string, description: string, value: string) -SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?: $binding>) — Group of switch toggles +SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?) — Group of switch toggles SwitchItem(label?: string, description?: string, name: string, defaultChecked?: boolean) — Individual switch toggle - Define EACH FormControl as its own reference — do NOT inline all controls in one array. - NEVER nest Form inside Form. @@ -201,6 +201,7 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -208,7 +209,6 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. -- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/material-ui-chat/src/generated/system-prompt.txt b/examples/material-ui-chat/src/generated/system-prompt.txt index 87e6ef259..0fc1dffd3 100644 --- a/examples/material-ui-chat/src/generated/system-prompt.txt +++ b/examples/material-ui-chat/src/generated/system-prompt.txt @@ -152,6 +152,7 @@ b2 = Button("Learn more", { type: "open_url", url: "https://mui.com" }, "outline b3 = Button("Delete", { type: "continue_conversation" }, "destructive") ## Important Rules +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -159,7 +160,6 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. -- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. - Card is the only top-level layout container. Use Tabs to switch between sections, Accordion for collapsible sections. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/material-ui-chat/src/lib/mui-genui/index.tsx b/examples/material-ui-chat/src/lib/mui-genui/index.tsx index 7664dfa6d..4cf1aafb3 100644 --- a/examples/material-ui-chat/src/lib/mui-genui/index.tsx +++ b/examples/material-ui-chat/src/lib/mui-genui/index.tsx @@ -187,7 +187,6 @@ b3 = Button("Delete", { type: "continue_conversation" }, "destructive")`, ]; export const muiAdditionalRules: string[] = [ - "When asked about data, generate realistic/plausible data", "Every response is a single Card(children) — children stack vertically automatically.", "Card is the only top-level layout container. Use Tabs to switch between sections, Accordion for collapsible sections.", "Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next.", diff --git a/examples/multi-agent-chat/src/generated/system-prompt.txt b/examples/multi-agent-chat/src/generated/system-prompt.txt index 6da009257..af8c67770 100644 --- a/examples/multi-agent-chat/src/generated/system-prompt.txt +++ b/examples/multi-agent-chat/src/generated/system-prompt.txt @@ -31,7 +31,7 @@ Separator(orientation?: "horizontal" | "vertical", decorative?: boolean) — Vis ### Tables Table(columns: Col[]) — Data table — column-oriented. Each Col holds its own data array. -Col(label: string, data: any, type?: "string" | "number" | "action") — Column definition — holds label + data array +Col(label: string, data, type?: "string" | "number" | "action") — Column definition — holds label + data array ### Charts (2D) BarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Vertical bars; use for comparing values across categories with one or more series @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -53,20 +53,20 @@ ScatterSeries(name: string, points: Point[]) — Named dataset Point(x: number, y: number, z?: number) — Data point with numeric coordinates ### Forms -Form(name: string, buttons: Buttons, fields?: FormControl[]) — Form container with fields and explicit action buttons +Form(name: string, buttons: Buttons, fields) — Form container with fields and explicit action buttons FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slider | CheckBoxGroup | RadioGroup, hint?: string) — Field with label, input component, and optional hint text Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) SelectItem(value: string, label: string) — Option for Select -DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants -CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding>) +CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) CheckBoxItem(label: string, description: string, name: string, defaultChecked?: boolean) RadioGroup(name: string, items: RadioItem[], defaultValue?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) RadioItem(label: string, description: string, value: string) -SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?: $binding>) — Group of switch toggles +SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?) — Group of switch toggles SwitchItem(label?: string, description?: string, name: string, defaultChecked?: boolean) — Individual switch toggle - Define EACH FormControl as its own reference — do NOT inline all controls in one array. - NEVER nest Form inside Form. @@ -201,6 +201,7 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -208,7 +209,6 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. -- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/openui-chat/src/generated/system-prompt.txt b/examples/openui-chat/src/generated/system-prompt.txt index 6da009257..5a066bbaf 100644 --- a/examples/openui-chat/src/generated/system-prompt.txt +++ b/examples/openui-chat/src/generated/system-prompt.txt @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -201,6 +201,7 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -208,7 +209,6 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. -- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/openui-react-native/backend/src/library.ts b/examples/openui-react-native/backend/src/library.ts index e8cf91dd0..f204bf861 100644 --- a/examples/openui-react-native/backend/src/library.ts +++ b/examples/openui-react-native/backend/src/library.ts @@ -108,10 +108,6 @@ export const promptOptions: PromptOptions = { preamble: "You are a helpful assistant. Always respond using OpenUI Lang — never plain markdown or JSON.", additionalRules: [ - // Do not regenerate src/system-prompt.txt until this example's pinned - // @openuidev/react-lang (^0.1.3) is bumped to a core that no longer emits this - // line from importantRules — otherwise the old core + this entry duplicate it. (issue #698) - "When asked about data, generate realistic/plausible data", "Always wrap your entire response inside a single root Card.", "Use Text components for all textual content.", 'Use variant="heading" for the main topic, variant="caption" for secondary info, and the default body variant for regular text.', diff --git a/examples/shadcn-chat/src/lib/shadcn-genui/index.tsx b/examples/shadcn-chat/src/lib/shadcn-genui/index.tsx index 6677d2228..30f034cff 100644 --- a/examples/shadcn-chat/src/lib/shadcn-genui/index.tsx +++ b/examples/shadcn-chat/src/lib/shadcn-genui/index.tsx @@ -314,7 +314,6 @@ cal = CalendarBlock("range", "2025-06-01", 2)`, ]; export const shadcnAdditionalRules: string[] = [ - "When asked about data, generate realistic/plausible data", "Every response is a single Card(children) — children stack vertically automatically.", "Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll.", "Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next.", diff --git a/examples/svelte-chat/src/lib/library.ts b/examples/svelte-chat/src/lib/library.ts index 2adf06d54..8732f1010 100644 --- a/examples/svelte-chat/src/lib/library.ts +++ b/examples/svelte-chat/src/lib/library.ts @@ -64,7 +64,6 @@ export const library = createLibrary({ export const promptOptions: PromptOptions = { additionalRules: [ - "When asked about data, generate realistic/plausible data", "Always use Stack as the root component.", "Group related content in Card components with descriptive titles.", "Use TextContent for all text output. You can use markdown within the text string.", diff --git a/examples/vercel-ai-chat/src/generated/system-prompt.txt b/examples/vercel-ai-chat/src/generated/system-prompt.txt index 6da009257..af8c67770 100644 --- a/examples/vercel-ai-chat/src/generated/system-prompt.txt +++ b/examples/vercel-ai-chat/src/generated/system-prompt.txt @@ -31,7 +31,7 @@ Separator(orientation?: "horizontal" | "vertical", decorative?: boolean) — Vis ### Tables Table(columns: Col[]) — Data table — column-oriented. Each Col holds its own data array. -Col(label: string, data: any, type?: "string" | "number" | "action") — Column definition — holds label + data array +Col(label: string, data, type?: "string" | "number" | "action") — Column definition — holds label + data array ### Charts (2D) BarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Vertical bars; use for comparing values across categories with one or more series @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -53,20 +53,20 @@ ScatterSeries(name: string, points: Point[]) — Named dataset Point(x: number, y: number, z?: number) — Data point with numeric coordinates ### Forms -Form(name: string, buttons: Buttons, fields?: FormControl[]) — Form container with fields and explicit action buttons +Form(name: string, buttons: Buttons, fields) — Form container with fields and explicit action buttons FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slider | CheckBoxGroup | RadioGroup, hint?: string) — Field with label, input component, and optional hint text Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) SelectItem(value: string, label: string) — Option for Select -DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants -CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding>) +CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) CheckBoxItem(label: string, description: string, name: string, defaultChecked?: boolean) RadioGroup(name: string, items: RadioItem[], defaultValue?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) RadioItem(label: string, description: string, value: string) -SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?: $binding>) — Group of switch toggles +SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?) — Group of switch toggles SwitchItem(label?: string, description?: string, name: string, defaultChecked?: boolean) — Individual switch toggle - Define EACH FormControl as its own reference — do NOT inline all controls in one array. - NEVER nest Form inside Form. @@ -201,6 +201,7 @@ msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { re btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) ## Important Rules +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) ## Final Verification @@ -208,7 +209,6 @@ Before finishing, walk your output and verify: 1. root = Card(...) is the FIRST line (for optimal streaming). 2. Every referenced name is defined. Every defined name (other than root) is reachable from root. -- When asked about data, generate realistic/plausible data - Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. - Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. - Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. diff --git a/examples/vue-chat/generated/system-prompt.txt b/examples/vue-chat/generated/system-prompt.txt index 05e5fac45..f2c484fa0 100644 --- a/examples/vue-chat/generated/system-prompt.txt +++ b/examples/vue-chat/generated/system-prompt.txt @@ -4,16 +4,18 @@ You are an AI assistant that responds using openui-lang, a declarative UI langua 1. Each statement is on its own line: `identifier = Expression` 2. `root` is the entry point — every program must define `root = Stack(...)` -3. Expressions are: strings ("..."), numbers, booleans (true/false), null, arrays ([...]), objects ({...}), or component calls TypeName(arg1, arg2, ...) +3. Expressions are: strings ("..."), numbers, booleans (true/false), arrays ([...]), objects ({...}), or component calls TypeName(arg1, arg2, ...) 4. Use references for readability: define `name = ...` on one line, then use `name` later 5. EVERY variable (except root) MUST be referenced by at least one other variable. Unreferenced variables are silently dropped and will NOT render. Always include defined variables in their parent's children/items array. -6. Arguments are POSITIONAL (order matters, not names). Write `Stack([children], "row", "l")` NOT `Stack([children], direction: "row", gap: "l")` — colon syntax is NOT supported and silently breaks +6. Arguments are POSITIONAL (order matters, not names) 7. Optional arguments can be omitted from the end -- Strings use double quotes with backslash escaping +8. No operators, no logic, no variables — only declarations +9. Strings use double quotes with backslash escaping ## Component Signatures Arguments marked with ? are optional. Sub-components can be inline or referenced; prefer references for better streaming. +The `action` prop type accepts: ContinueConversation (sends message to LLM), OpenUrl (navigates to URL), or Custom (app-defined). TextContent(text: string) — Displays a block of text. Supports markdown formatting within the string. Button(label: string, action?: string) — A clickable button. The label is shown to the user and used as the follow-up message. @@ -64,14 +66,14 @@ card = Card("Language Trends", [chart, t1]) cta = Button("Compare Python vs JavaScript") ## Important Rules +- ALWAYS start with root = Stack(...) +- Write statements in TOP-DOWN order: root → components → data (leverages hoisting for progressive streaming) +- Each statement on its own line +- No trailing text or explanations — output ONLY openui-lang code +- When asked about data, generate realistic/plausible data - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) +- NEVER define a variable without referencing it from the tree. Every variable must be reachable from root, otherwise it will not render. -## Final Verification -Before finishing, walk your output and verify: -1. root = Stack(...) is the FIRST line (for optimal streaming). -2. Every referenced name is defined. Every defined name (other than root) is reachable from root. - -- When asked about data, generate realistic/plausible data - Always use Stack as the root component. - Group related content in Card components with descriptive titles. - Use TextContent for all text output. You can use markdown within the text string. diff --git a/examples/vue-chat/lib/library.ts b/examples/vue-chat/lib/library.ts index 624f05b9f..518446146 100644 --- a/examples/vue-chat/lib/library.ts +++ b/examples/vue-chat/lib/library.ts @@ -64,7 +64,6 @@ export const library = createLibrary({ export const promptOptions: PromptOptions = { additionalRules: [ - "When asked about data, generate realistic/plausible data", "Always use Stack as the root component.", "Group related content in Card components with descriptive titles.", "Use TextContent for all text output. You can use markdown within the text string.", diff --git a/examples/vue-chat/scripts/generate-prompt.mjs b/examples/vue-chat/scripts/generate-prompt.mjs index 7388aa594..4ecfd884f 100644 --- a/examples/vue-chat/scripts/generate-prompt.mjs +++ b/examples/vue-chat/scripts/generate-prompt.mjs @@ -71,7 +71,6 @@ const library = createLibrary({ const promptOptions = { additionalRules: [ - "When asked about data, generate realistic/plausible data", "Always use Stack as the root component.", "Group related content in Card components with descriptive titles.", "Use TextContent for all text output. You can use markdown within the text string.", diff --git a/packages/react-ui/src/genui-lib/openuiLibrary.tsx b/packages/react-ui/src/genui-lib/openuiLibrary.tsx index e563c12b8..f456d389e 100644 --- a/packages/react-ui/src/genui-lib/openuiLibrary.tsx +++ b/packages/react-ui/src/genui-lib/openuiLibrary.tsx @@ -246,6 +246,7 @@ vueContent = [TextContent("Vue is a progressive framework by Evan You."), Callou ]; export const openuiAdditionalRules: string[] = [ + "When asked about data, generate realistic/plausible data", 'For grid-like layouts, use Stack with direction "row" and wrap=true. Avoid justify="between" unless you specifically want large gutters.', "For forms, define one FormControl reference per field so controls can stream progressively.", "For forms, always provide the second Form argument with Buttons(...) actions: Form(name, buttons, fields).", @@ -256,15 +257,9 @@ export const openuiAdditionalRules: string[] = [ "Use existing components (Tabs, Accordion, Modal) before inventing ternary show/hide patterns", ]; -// Demo/product stance (issue #698): fabricate illustrative data only on surfaces -// with no real data backend. Real-data consumers (e.g. a coding agent) build their -// own promptOptions from openuiAdditionalRules to opt out of this line. export const openuiPromptOptions: PromptOptions = { examples: openuiExamples, - additionalRules: [ - "When asked about data, generate realistic/plausible data", - ...openuiAdditionalRules, - ], + additionalRules: openuiAdditionalRules, }; // ── Library ── From 8d64d2163a41e39e667c185188d2e3f1d1dc9fec Mon Sep 17 00:00:00 2001 From: i-subham Date: Thu, 2 Jul 2026 15:52:23 +0530 Subject: [PATCH 3/3] refactor: enhance system prompt documentation for forms and charts - Updated the system prompt files across multiple examples to improve clarity and consistency in the documentation of form and chart components. - Added optional parameters to various components, including `Col`, `PieChart`, `Form`, `Select`, `DatePicker`, `CheckBoxGroup`, and `SwitchGroup`, to enhance flexibility in usage. - Ensured that all changes align with the recent standardization efforts in data generation guidelines, contributing to a more coherent user experience across examples. --- .../mastra-chat/src/generated/system-prompt.txt | 14 +++++++------- .../src/generated/system-prompt.txt | 14 +++++++------- .../openui-chat/src/generated/system-prompt.txt | 2 +- .../vercel-ai-chat/src/generated/system-prompt.txt | 14 +++++++------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/mastra-chat/src/generated/system-prompt.txt b/examples/mastra-chat/src/generated/system-prompt.txt index af8c67770..cbd28d059 100644 --- a/examples/mastra-chat/src/generated/system-prompt.txt +++ b/examples/mastra-chat/src/generated/system-prompt.txt @@ -31,7 +31,7 @@ Separator(orientation?: "horizontal" | "vertical", decorative?: boolean) — Vis ### Tables Table(columns: Col[]) — Data table — column-oriented. Each Col holds its own data array. -Col(label: string, data, type?: "string" | "number" | "action") — Column definition — holds label + data array +Col(label: string, data: any, type?: "string" | "number" | "action") — Column definition — holds label + data array ### Charts (2D) BarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Vertical bars; use for comparing values across categories with one or more series @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -53,20 +53,20 @@ ScatterSeries(name: string, points: Point[]) — Named dataset Point(x: number, y: number, z?: number) — Data point with numeric coordinates ### Forms -Form(name: string, buttons: Buttons, fields) — Form container with fields and explicit action buttons +Form(name: string, buttons: Buttons, fields?: FormControl[]) — Form container with fields and explicit action buttons FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slider | CheckBoxGroup | RadioGroup, hint?: string) — Field with label, input component, and optional hint text Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") SelectItem(value: string, label: string) — Option for Select -DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants -CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding>) CheckBoxItem(label: string, description: string, name: string, defaultChecked?: boolean) RadioGroup(name: string, items: RadioItem[], defaultValue?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) RadioItem(label: string, description: string, value: string) -SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?) — Group of switch toggles +SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?: $binding>) — Group of switch toggles SwitchItem(label?: string, description?: string, name: string, defaultChecked?: boolean) — Individual switch toggle - Define EACH FormControl as its own reference — do NOT inline all controls in one array. - NEVER nest Form inside Form. diff --git a/examples/multi-agent-chat/src/generated/system-prompt.txt b/examples/multi-agent-chat/src/generated/system-prompt.txt index af8c67770..cbd28d059 100644 --- a/examples/multi-agent-chat/src/generated/system-prompt.txt +++ b/examples/multi-agent-chat/src/generated/system-prompt.txt @@ -31,7 +31,7 @@ Separator(orientation?: "horizontal" | "vertical", decorative?: boolean) — Vis ### Tables Table(columns: Col[]) — Data table — column-oriented. Each Col holds its own data array. -Col(label: string, data, type?: "string" | "number" | "action") — Column definition — holds label + data array +Col(label: string, data: any, type?: "string" | "number" | "action") — Column definition — holds label + data array ### Charts (2D) BarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Vertical bars; use for comparing values across categories with one or more series @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -53,20 +53,20 @@ ScatterSeries(name: string, points: Point[]) — Named dataset Point(x: number, y: number, z?: number) — Data point with numeric coordinates ### Forms -Form(name: string, buttons: Buttons, fields) — Form container with fields and explicit action buttons +Form(name: string, buttons: Buttons, fields?: FormControl[]) — Form container with fields and explicit action buttons FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slider | CheckBoxGroup | RadioGroup, hint?: string) — Field with label, input component, and optional hint text Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") SelectItem(value: string, label: string) — Option for Select -DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants -CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding>) CheckBoxItem(label: string, description: string, name: string, defaultChecked?: boolean) RadioGroup(name: string, items: RadioItem[], defaultValue?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) RadioItem(label: string, description: string, value: string) -SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?) — Group of switch toggles +SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?: $binding>) — Group of switch toggles SwitchItem(label?: string, description?: string, name: string, defaultChecked?: boolean) — Individual switch toggle - Define EACH FormControl as its own reference — do NOT inline all controls in one array. - NEVER nest Form inside Form. diff --git a/examples/openui-chat/src/generated/system-prompt.txt b/examples/openui-chat/src/generated/system-prompt.txt index 5a066bbaf..cbd28d059 100644 --- a/examples/openui-chat/src/generated/system-prompt.txt +++ b/examples/openui-chat/src/generated/system-prompt.txt @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value diff --git a/examples/vercel-ai-chat/src/generated/system-prompt.txt b/examples/vercel-ai-chat/src/generated/system-prompt.txt index af8c67770..cbd28d059 100644 --- a/examples/vercel-ai-chat/src/generated/system-prompt.txt +++ b/examples/vercel-ai-chat/src/generated/system-prompt.txt @@ -31,7 +31,7 @@ Separator(orientation?: "horizontal" | "vertical", decorative?: boolean) — Vis ### Tables Table(columns: Col[]) — Data table — column-oriented. Each Col holds its own data array. -Col(label: string, data, type?: "string" | "number" | "action") — Column definition — holds label + data array +Col(label: string, data: any, type?: "string" | "number" | "action") — Column definition — holds label + data array ### Charts (2D) BarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Vertical bars; use for comparing values across categories with one or more series @@ -42,7 +42,7 @@ HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "st Series(category: string, values: number[]) — One data series ### Charts (1D) -PieChart(labels: string[], values: number[], variant?: "pie" | "donut") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) Slice(category: string, value: number) — One slice with label and numeric value @@ -53,20 +53,20 @@ ScatterSeries(name: string, points: Point[]) — Named dataset Point(x: number, y: number, z?: number) — Data point with numeric coordinates ### Forms -Form(name: string, buttons: Buttons, fields) — Form container with fields and explicit action buttons +Form(name: string, buttons: Buttons, fields?: FormControl[]) — Form container with fields and explicit action buttons FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slider | CheckBoxGroup | RadioGroup, hint?: string) — Field with label, input component, and optional hint text Label(text: string) — Text label Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) -Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") SelectItem(value: string, label: string) — Option for Select -DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants -CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?) +CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding>) CheckBoxItem(label: string, description: string, name: string, defaultChecked?: boolean) RadioGroup(name: string, items: RadioItem[], defaultValue?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) RadioItem(label: string, description: string, value: string) -SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?) — Group of switch toggles +SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?: $binding>) — Group of switch toggles SwitchItem(label?: string, description?: string, name: string, defaultChecked?: boolean) — Individual switch toggle - Define EACH FormControl as its own reference — do NOT inline all controls in one array. - NEVER nest Form inside Form.