Enforce restricted action slots (follow-up to #1298) the parser keeps `@OpenUrl` and the prompt still teaches it

Open
#1,467 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
react, typescript

Research direction

Start with the restricted action slot refs and parser checks in lang-core, then inspect actionSection() and builtinSteps() for prompt generation and runChatAction in react-ui for runtime handling. Reproduce with the supplied createParser example and review related issues #1298, #663, and #633. Done means disallowed steps are reported and dropped, the prompt lists only allowed steps, and apps can veto URL opening.

Written by the indexing model from the issue text.

Description

Describe the bug

#1298 (shipped in 1.0 via #1348) added restricted action slots for the prompt and schema and left enforcement as a follow-up. I couldn't find an issue tracking it, so here is one with a repro.

lang-core exports steps.OpenUrl.ref / steps.ToAssistant.ref for restricted action slots, and the generated prompt says "Props typed like @OpenUrl | @ToAssistant accept only the steps listed." With action: z.union([steps.ToAssistant.ref]).optional():

  1. Parser: @OpenUrl(...) in that slot, bare or inside Action([...]), parses with meta.errors == [] and stays in the action plan. An unknown step (@Frobnicate) does get unknown-function, so steps are checked, but not against the slot's union.
  2. Prompt: actionSection() still lists @OpenUrl under "Available steps", uses it in the intro (Action([@OpenUrl(...), @ToAssistant(...)])) and the "simple nav" example, and the signatures line says (@ToAssistant, @OpenUrl), though no slot accepts it. builtinSteps() filters only Run/Set/Reset.
  3. Runtime: react-ui's runChatAction handles open_url itself (window.open(url, "_blank")) and forwards only other events to onAction, so an AgentInterface app can't veto it.

To Reproduce

// Button.action = z.union([steps.ToAssistant.ref]).optional()
createParser(spec.schema, spec.root)
  .parse('root = Card([b])\nb = Button("Go", @OpenUrl("https://x"))')
  .meta.errors; // []

Expected behavior
A step outside the slot's union is reported (e.g. code: "step-not-allowed") and dropped from the plan; the prompt advertises only steps some slot accepts.

Actual behavior
The step is kept silently, taught to the model, and a click opens the URL.

Desktop (the parser part reproduces in Node, no browser)
Versions: @openuidev/lang-core 1.0.1, @openuidev/react-lang 1.0.1, @openuidev/react-ui 0.18.1

Additional context
Possible fixes:

  • Parser: check step membership against the slot's union, next to the existing unknown-function check.
  • Prompt: derive the step list from the library's slots and omit the @OpenUrl intro/example when no slot accepts it (or a PromptOptions.steps override).
  • Runtime: pass open_url through onAction (or let it override the default) so apps can veto navigation.

Apps that must never open model-written URLs (strict CSP, a screen that rejects URLs) currently wrap each action-bearing component to filter steps themselves.

Related: #663 (custom action steps), #633 (prompt allow-list for components).

Dominant language
TypeScript
Stars
10k
Forks
698
Avg merge
1d 6h
Merged PRs (30d)
148

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from thesysdev/openui

All issues in thesysdev/openui

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.