Generate Lynx OpenUI Programs
Generate valid OpenUI Lang v0.5 consumed by
<OpenUiRenderer response={...}>. Produce declarative DSL, not application
code.
Read The References
- Always read components.md before generating a
program. Treat caller-supplied component signatures as authoritative
extensions or replacements.
- Read runtime.md when the request involves state,
tools, live data, mutations, actions, repeated query data, or edits.
- Read examples.md for a non-trivial layout or tool
workflow. Adapt patterns; do not copy irrelevant content.
Workflow
- Identify the requested UI, supplied component catalog, available tool
schemas, media URLs, and whether the host supports full programs or
mergeStatements patches.
- Choose the data mode:
- Use static values for self-contained content and when no tool exists.
- Use
Query only for an actual read tool supplied by the caller or host.
- Use
Mutation only for an actual write tool and trigger it from an
explicit Action.
- Select only components and positional arguments allowed by the active
catalog.
- Write a streaming-friendly graph. For a complete program, put the root
first, followed by state, queries or mutations, structural components, and
leaf content. For an edit-mode patch, return only changed statements.
- Validate syntax, references, reachability, component names, argument order,
tool names, and action targets before returning the program.
Output Contract
- Return only OpenUI Lang. Do not return Markdown, code fences, prose, JSON,
XML, HTML, JavaScript, TypeScript, JSX, or CSS.
- Put one assignment statement on each line.
- For a complete program, make the first non-empty line
root = Stack(...).
- Return a complete program by default. When the caller explicitly says the
host uses edit mode or
mergeStatements, return only changed statements and
include root only when the root graph changes.
- If a request needs an unavailable component or capability, render a concise
explanation with supported OpenUI components instead of inventing syntax.
Syntax Rules
- Use
identifier = Expression for ordinary declarations and
$identifier = defaultValue for mutable state.
- Pass component arguments positionally. Never use named arguments such as
gap: "m".
- Omit optional arguments only from the end. When setting a later argument,
provide valid values for every earlier position.
- Use double-quoted strings and escape embedded quotes and backslashes.
- Use references or inline components. Prefer references for the root and
major sections so streaming reveals the structure progressively.
- Ensure every referenced identifier is defined. Ensure every declaration
other than
root is reachable from root, an expression reachable from
root, or an action reachable from root.
- Use only documented operators, built-ins, components, and action steps.
Correct positional layout:
root = Stack([header, content], "column", false, "l", "stretch", "start")
Incorrect positional layout:
root = Stack([header, content], "column", "l", "stretch")
The incorrect form passes a string into wrap and shifts every later prop.
Data And Interaction Rules
- Do not invent tool names. If no tool schema is supplied, use static data or
an explanatory supported UI.
- Give every
Query a representative default result matching the real tool
shape so the UI renders before the request resolves.
- Keep
Query and Mutation declarations on ordinary identifiers, never
$identifiers.
- Use
@Each for query-backed repeated UI. Keep its loop-dependent component
inline inside @Each.
- Put write operations on a submit or confirmation
Button. Do not attach a
mutation to an input's change action.
- When an input must update a
$variable, use the same-key name pattern in
runtime.md. Do not invent an event-value variable.
- Execute multi-step actions in deliberate order. Remember that a failed
mutation stops the remaining steps.
- Use
@ToAssistant for conversational continuation and @OpenUrl only with
a caller-provided or trustworthy URL.
- Use caller-provided media URLs. Do not fabricate CDN URLs or assume the host
resolves image-search strings.
Lynx UI Rules
- Prefer compact, mobile-first layouts with a shallow component tree.
- Use
Stack or Column for ordinary vertical structure, Row for small
horizontal groups, and List for grouped or repeated content.
- Prefer explicit
Image variants so the Lynx renderer has concrete sizing.
- Keep readable text in
Text or TextContent; do not emit raw Lynx elements.
- Use
Tabs for alternate views and Modal for tap-to-open details. Pass a
modal trigger first and content second; do not also render the trigger as a
sibling.
Final Verification
Before returning, verify all of the following:
- A complete program starts with
root = Stack(...). An edit-mode patch omits
root unless the root graph changes. The response contains only OpenUI Lang.
- Every component exists in the active catalog and every argument matches its
positional schema.
- No
Form, Input, Select, SelectItem, FormControl, table, or chart is
used unless the caller supplied that custom component.
- Every reference resolves and no declaration is orphaned.
- Every
Query or Mutation uses a real supplied tool and is referenced by
visible UI or a visible action.
- Every
$variable participates in visible UI, a query argument, or an action.
- Every
@Each loop variable stays inside its inline template expression.
- No working dynamic list relies on
TemplateChildren in the built-in Lynx
renderer.
- If a parser is available, parsing finishes with a root, no validation errors,
no unresolved references, and no orphaned statements.
1---2name: lynx-openui3description: Generate valid OpenUI Lang v0.5 functional-notation programs for the Lynx OpenUI renderer. Use when Codex must turn a natural-language UI request into raw OpenUI DSL for OpenUiRenderer, including static mobile UI, $state, Query/Mutation tool flows, Action plans, streaming-friendly output, or catalog-constrained revisions. Do not use for JSX, HTML, CSS, A2UI JSON, or implementing new ReactLynx components.4---5
6# Generate Lynx OpenUI Programs
7
8Generate valid OpenUI Lang v0.5 consumed by
9`<OpenUiRenderer response={...}>`. Produce declarative DSL, not application
10code.
11
12## Read The References
13
14- Always read [components.md](references/components.md) before generating a
15 program. Treat caller-supplied component signatures as authoritative
16 extensions or replacements.
17- Read [runtime.md](references/runtime.md) when the request involves state,
18 tools, live data, mutations, actions, repeated query data, or edits.
19- Read [examples.md](references/examples.md) for a non-trivial layout or tool
20 workflow. Adapt patterns; do not copy irrelevant content.
21
22## Workflow
23
241. Identify the requested UI, supplied component catalog, available tool
25 schemas, media URLs, and whether the host supports full programs or
26 `mergeStatements` patches.
272. Choose the data mode:
28 - Use static values for self-contained content and when no tool exists.
29 - Use `Query` only for an actual read tool supplied by the caller or host.
30 - Use `Mutation` only for an actual write tool and trigger it from an
31 explicit `Action`.
323. Select only components and positional arguments allowed by the active
33 catalog.
344. Write a streaming-friendly graph. For a complete program, put the root
35 first, followed by state, queries or mutations, structural components, and
36 leaf content. For an edit-mode patch, return only changed statements.
375. Validate syntax, references, reachability, component names, argument order,
38 tool names, and action targets before returning the program.
39
40## Output Contract
41
42- Return only OpenUI Lang. Do not return Markdown, code fences, prose, JSON,
43 XML, HTML, JavaScript, TypeScript, JSX, or CSS.
44- Put one assignment statement on each line.
45- For a complete program, make the first non-empty line `root = Stack(...)`.
46- Return a complete program by default. When the caller explicitly says the
47 host uses edit mode or `mergeStatements`, return only changed statements and
48 include `root` only when the root graph changes.
49- If a request needs an unavailable component or capability, render a concise
50 explanation with supported OpenUI components instead of inventing syntax.
51
52## Syntax Rules
53
54- Use `identifier = Expression` for ordinary declarations and
55 `$identifier = defaultValue` for mutable state.
56- Pass component arguments positionally. Never use named arguments such as
57 `gap: "m"`.
58- Omit optional arguments only from the end. When setting a later argument,
59 provide valid values for every earlier position.
60- Use double-quoted strings and escape embedded quotes and backslashes.
61- Use references or inline components. Prefer references for the root and
62 major sections so streaming reveals the structure progressively.
63- Ensure every referenced identifier is defined. Ensure every declaration
64 other than `root` is reachable from `root`, an expression reachable from
65 `root`, or an action reachable from `root`.
66- Use only documented operators, built-ins, components, and action steps.
67
68Correct positional layout:
69
70```text
71root = Stack([header, content], "column", false, "l", "stretch", "start")
72```
73
74Incorrect positional layout:
75
76```text
77root = Stack([header, content], "column", "l", "stretch")
78```
79
80The incorrect form passes a string into `wrap` and shifts every later prop.
81
82## Data And Interaction Rules
83
84- Do not invent tool names. If no tool schema is supplied, use static data or
85 an explanatory supported UI.
86- Give every `Query` a representative default result matching the real tool
87 shape so the UI renders before the request resolves.
88- Keep `Query` and `Mutation` declarations on ordinary identifiers, never
89 `$identifiers`.
90- Use `@Each` for query-backed repeated UI. Keep its loop-dependent component
91 inline inside `@Each`.
92- Put write operations on a submit or confirmation `Button`. Do not attach a
93 mutation to an input's change action.
94- When an input must update a `$variable`, use the same-key `name` pattern in
95 [runtime.md](references/runtime.md). Do not invent an event-value variable.
96- Execute multi-step actions in deliberate order. Remember that a failed
97 mutation stops the remaining steps.
98- Use `@ToAssistant` for conversational continuation and `@OpenUrl` only with
99 a caller-provided or trustworthy URL.
100- Use caller-provided media URLs. Do not fabricate CDN URLs or assume the host
101 resolves image-search strings.
102
103## Lynx UI Rules
104
105- Prefer compact, mobile-first layouts with a shallow component tree.
106- Use `Stack` or `Column` for ordinary vertical structure, `Row` for small
107 horizontal groups, and `List` for grouped or repeated content.
108- Prefer explicit `Image` variants so the Lynx renderer has concrete sizing.
109- Keep readable text in `Text` or `TextContent`; do not emit raw Lynx elements.
110- Use `Tabs` for alternate views and `Modal` for tap-to-open details. Pass a
111 modal trigger first and content second; do not also render the trigger as a
112 sibling.
113
114## Final Verification
115
116Before returning, verify all of the following:
117
118- A complete program starts with `root = Stack(...)`. An edit-mode patch omits
119 `root` unless the root graph changes. The response contains only OpenUI Lang.
120- Every component exists in the active catalog and every argument matches its
121 positional schema.
122- No `Form`, `Input`, `Select`, `SelectItem`, `FormControl`, table, or chart is
123 used unless the caller supplied that custom component.
124- Every reference resolves and no declaration is orphaned.
125- Every `Query` or `Mutation` uses a real supplied tool and is referenced by
126 visible UI or a visible action.
127- Every `$variable` participates in visible UI, a query argument, or an action.
128- Every `@Each` loop variable stays inside its inline template expression.
129- No working dynamic list relies on `TemplateChildren` in the built-in Lynx
130 renderer.
131- If a parser is available, parsing finishes with a root, no validation errors,
132 no unresolved references, and no orphaned statements.