vercel-labs / vercel-labs/json-render
feat: Filter components in `catalog.prompt()` via `PromptOptions`
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 16.8k
- Forks
- 901
- Avg merge
- 3h 14m
- Merged PRs (30d)
- 4
Description
Problem
When building a general-purpose Agent Chat UI, the full component catalog is injected into the LLM system prompt on every request. As the catalog grows, this creates two issues:
- Token waste — components irrelevant to the current intent are included every time.
- Output quality degradation — a larger component list increases the chance the LLM picks an inappropriate component or hallucinates props.
Currently, PromptOptions can't filter which components go into the generated prompt. The only workaround is to define multiple separate catalogs and swap between them at the call site — which is brittle and doesn't scale.
Proposed Solution
Add an include (and optionally exclude) option to PromptOptions.
export interface PromptOptions {
// ...existing options...
/**
* If provided, only components whose names appear in this list are included
* in the generated prompt. Useful for dynamically scoping the LLM's component
* vocabulary to the current request context.
*/
include?: string[];
}
Usage example:
// Classify user intent first (e.g. via a lightweight model or keyword match)
const tags = await classifyIntent(userMessage); // e.g. ["data", "chart"]
const relevantComponents = resolveComponentsForTags(tags);
// → ["Metric", "Table", "BarChart", "LineChart"]
const instructions = BASE_INSTRUCTIONS + catalog.prompt({
mode: "inline",
include: relevantComponents,
});
Motivation
This enables a common pattern for agent chat UIs:
User input
↓
Lightweight intent classifier → ["data", "3d", "form", ...]
↓
Filter catalog by resolved component names
↓
Inject only relevant component docs into LLM system prompt
Without this, building a scalable generative UI agent requires maintaining multiple
hand-crafted sub-catalogs, which duplicates schema definitions and is hard to keep
in sync as the catalog evolves.
Acceptance Criteria
- catalog.prompt({ include: ["Card", "Metric"] }) only documents Card and Metric in the output, even if the catalog contains 30+ components.
- catalog.prompt({ exclude: ["Scene3D", "Sphere", "Box"] }) omits all listed components.
- include and exclude are mutually exclusive or include takes precedence when both are provided (behavior should be documented).
- Components referenced in include/exclude that don't exist in the catalog produce a warning (not a hard error).
No breaking change to existing catalog.prompt() calls without options.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the catalog.prompt() implementation and the PromptOptions definition. Add tests covering include, exclude, unknown component names, and their interaction, then verify existing calls without options remain unchanged. Done means generated prompts contain only the requested components, document the include/exclude behavior, and warn rather than fail for unknown names.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- ai
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100