Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/genui/a2ui-prompt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ package.
Build a prompt with the built-in A2UI basic catalog:

```ts
import { buildA2UISystemPrompt } from '@lynx-js/genui/a2ui-prompt';
import { buildA2UISystemPromptAsync } from '@lynx-js/genui/a2ui-prompt';

const prompt = buildA2UISystemPrompt();
const prompt = await buildA2UISystemPromptAsync();
```

Read generated catalog artifacts and build a prompt for a custom catalog:
Expand All @@ -42,11 +42,11 @@ Use `genui a2ui generate catalog` to create those artifacts.
## Exports

- `buildA2UISystemPrompt`
- `A2UI_SYSTEM_PROMPT`
- `BASIC_CATALOG`
- `BASIC_CATALOG_ID`
- `renderCatalogReference`
- `createA2UICatalogFromManifests`
- `loadBasicCatalog`
- `buildA2UISystemPromptAsync`
- `readA2UICatalogFromDirectory`

## Local Development
Expand Down
27 changes: 14 additions & 13 deletions packages/genui/a2ui-prompt/etc/genui-a2ui-prompt.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@
// @public (undocumented)
export const A2UI_PROTOCOL_VERSION = "v0.9";

// Warning: (ae-missing-release-tag) "A2UI_SYSTEM_PROMPT" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const A2UI_SYSTEM_PROMPT: string;

// Warning: (ae-missing-release-tag) "A2UICatalog" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand Down Expand Up @@ -94,11 +89,6 @@ export interface A2UIFunctionSpec {
returnType: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'any' | 'void';
}

// Warning: (ae-missing-release-tag) "BASIC_CATALOG" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const BASIC_CATALOG: A2UICatalog;

// Warning: (ae-missing-release-tag) "BASIC_CATALOG_EXAMPLES" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand All @@ -107,12 +97,17 @@ export const BASIC_CATALOG_EXAMPLES: A2UIExample[];
// Warning: (ae-missing-release-tag) "BASIC_CATALOG_ID" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const BASIC_CATALOG_ID = "https://a2ui.org/specification/v0_9/basic_catalog.json";
export const BASIC_CATALOG_ID = "https://unpkg.com/@lynx-js/genui/a2ui/dist/catalog/catalog.json";

// Warning: (ae-missing-release-tag) "buildA2UISystemPrompt" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function buildA2UISystemPrompt(opts?: BuildSystemPromptOptions): string;
export function buildA2UISystemPrompt(opts: BuildSystemPromptOptions): string;

// Warning: (ae-missing-release-tag) "buildA2UISystemPromptAsync" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function buildA2UISystemPromptAsync(opts?: BuildSystemPromptOptions): Promise<string>;

// Warning: (ae-missing-release-tag) "BuildSystemPromptOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
Expand All @@ -129,7 +124,8 @@ export interface BuildSystemPromptOptions {
// @public (undocumented)
export function createA2UICatalogFromManifests(options: {
catalogId: string;
componentManifests: Record<string, JsonSchema>[];
componentManifests?: Record<string, JsonSchema>[];
components?: Record<string, JsonSchema>;
examples?: A2UIExample[];
extraRules?: string[];
functions?: A2UIFunctionSpec[];
Expand Down Expand Up @@ -159,6 +155,11 @@ export interface JsonSchema {
type?: string;
}

// Warning: (ae-missing-release-tag) "loadBasicCatalog" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function loadBasicCatalog(): Promise<A2UICatalog>;

// Warning: (ae-missing-release-tag) "ReadA2UICatalogDirectoryOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand Down
1 change: 1 addition & 0 deletions packages/genui/a2ui-prompt/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"include": [
"src",
"../server/agent/a2ui-catalog-id.ts",
"../server/agent/a2ui-catalog.ts",
"../server/agent/a2ui-examples.ts",
"../server/agent/a2ui-prompt.ts",
Expand Down
1 change: 1 addition & 0 deletions packages/genui/a2ui-prompt/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"include": [
"src",
"rslib.config.ts",
"../server/agent/a2ui-catalog-id.ts",
"../server/agent/a2ui-catalog.ts",
"../server/agent/a2ui-examples.ts",
"../server/agent/a2ui-prompt.ts",
Expand Down
2 changes: 2 additions & 0 deletions packages/genui/a2ui-prompt/turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
],
"inputs": [
"src/**",
"../server/agent/a2ui-catalog-id.ts",
"../server/agent/a2ui-catalog.ts",
"../server/agent/a2ui-examples.ts",
"../server/agent/a2ui-prompt.ts",
Expand All @@ -27,6 +28,7 @@
"dependsOn": [],
"inputs": [
"src/**",
"../server/agent/a2ui-catalog-id.ts",
"../server/agent/a2ui-catalog.ts",
"../server/agent/a2ui-examples.ts",
"../server/agent/a2ui-prompt.ts",
Expand Down
12 changes: 8 additions & 4 deletions packages/genui/cli/bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,10 @@ async function runGeneratePromptCli(args, cwd, cliOptions) {
}

const {
BASIC_CATALOG,
BASIC_CATALOG_ID,
buildA2UISystemPrompt,
buildA2UISystemPromptAsync,
loadBasicCatalog,
readA2UICatalogFromDirectory,
} = await import('../../a2ui-prompt/dist/index.js');
const catalog = options.catalogDir
Expand All @@ -185,17 +186,20 @@ async function runGeneratePromptCli(args, cwd, cliOptions) {
cwd,
})
: (options.catalogId
? { ...BASIC_CATALOG, id: options.catalogId }
? { ...(await loadBasicCatalog()), id: options.catalogId }
: undefined);
if (options.catalogDir && catalog && isEmptyCatalog(catalog)) {
throw new Error(
`[${programName}] No components or functions found in generated catalog directory: ${options.catalogDir}`,
);
}
const systemPrompt = buildA2UISystemPrompt({
const promptOptions = {
...(catalog ? { catalog } : {}),
...(options.appendix ? { appendix: options.appendix } : {}),
});
};
const systemPrompt = catalog
? buildA2UISystemPrompt(promptOptions)
: await buildA2UISystemPromptAsync(promptOptions);

if (options.out) {
const outPath = path.resolve(cwd, options.out);
Expand Down
29 changes: 16 additions & 13 deletions packages/genui/etc/genui.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ export const A2UI: MemoExoticComponent<typeof A2UIImpl>;
// @public (undocumented)
export const A2UI_PROTOCOL_VERSION = "v0.9";

// Warning: (ae-missing-release-tag) "A2UI_SYSTEM_PROMPT" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const A2UI_SYSTEM_PROMPT: string;

// Warning: (ae-missing-release-tag) "A2UIClientEventMessage" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand Down Expand Up @@ -197,11 +192,6 @@ export interface ActionProps {
surfaceId: string;
}

// Warning: (ae-missing-release-tag) "BASIC_CATALOG" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const BASIC_CATALOG: A2UIPromptCatalog;

// Warning: (ae-missing-release-tag) "BASIC_CATALOG_EXAMPLES" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand All @@ -210,7 +200,7 @@ export const BASIC_CATALOG_EXAMPLES: A2UIExample[];
// Warning: (ae-missing-release-tag) "BASIC_CATALOG_ID" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const BASIC_CATALOG_ID = "https://a2ui.org/specification/v0_9/basic_catalog.json";
export const BASIC_CATALOG_ID = "https://unpkg.com/@lynx-js/genui/a2ui/dist/catalog/catalog.json";

// Warning: (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
Expand All @@ -225,7 +215,12 @@ export const basicFunctions: readonly CatalogFunctionEntry[];
// Warning: (ae-missing-release-tag) "buildA2UISystemPrompt" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function buildA2UISystemPrompt(opts?: BuildSystemPromptOptions): string;
export function buildA2UISystemPrompt(opts: BuildSystemPromptOptions): string;

// Warning: (ae-missing-release-tag) "buildA2UISystemPromptAsync" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function buildA2UISystemPromptAsync(opts?: BuildSystemPromptOptions): Promise<string>;

// Warning: (ae-missing-release-tag) "BuildSystemPromptOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
Expand Down Expand Up @@ -306,7 +301,8 @@ export function createA2UICatalog(options: {
// @public (undocumented)
export function createA2UICatalogFromManifests(options: {
catalogId: string;
componentManifests: Record<string, A2UIPromptJsonSchema>[];
componentManifests?: Record<string, A2UIPromptJsonSchema>[];
components?: Record<string, A2UIPromptJsonSchema>;
examples?: A2UIExample[];
extraRules?: string[];
functions?: A2UIFunctionSpec[];
Expand Down Expand Up @@ -593,6 +589,11 @@ export type LibraryDefinition = LibraryDefinition_2<ComponentRenderer<any>>;

export { LibraryJSONSchema }

// Warning: (ae-missing-release-tag) "loadBasicCatalog" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export function loadBasicCatalog(): Promise<A2UIPromptCatalog>;

// Warning: (ae-missing-release-tag) "MessageProcessor" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand Down Expand Up @@ -1029,6 +1030,8 @@ export function writeCatalogFunctions(functions: CatalogFunction[], options: {
//
// @public (undocumented)
export interface WriteComponentCatalogOptions extends ExtractCatalogOptions {
// (undocumented)
catalogId?: string;
// (undocumented)
outDir: string;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/genui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ export {
export * from '@lynx-js/genui/openui';
export {
A2UI_PROTOCOL_VERSION,
A2UI_SYSTEM_PROMPT,
BASIC_CATALOG,
BASIC_CATALOG_EXAMPLES,
BASIC_CATALOG_ID,
buildA2UISystemPrompt,
buildA2UISystemPromptAsync,
createA2UICatalogFromManifests,
loadBasicCatalog,
readA2UICatalogFromDirectory,
renderCatalogReference,
} from '@lynx-js/genui/a2ui-prompt';
Expand Down
6 changes: 3 additions & 3 deletions packages/genui/server/agent/a2ui-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

import { Agent } from '@mastra/core/agent';

import { BASIC_CATALOG } from './a2ui-catalog';
import type { A2UICatalog } from './a2ui-catalog';
import { loadBasicCatalog } from './a2ui-catalog';
import { buildA2UISystemPrompt } from './a2ui-prompt';
import { createLLMProvider } from './openai-provider';
import type { OpenAIProviderOptions } from './openai-provider';
Expand All @@ -30,10 +30,10 @@ export interface A2UIAgent {
) => unknown;
}

export function createA2UIAgent(opts: A2UIAgentOptions = {}) {
export async function createA2UIAgent(opts: A2UIAgentOptions = {}) {
const { buildModel, model } = createLLMProvider(opts);

const catalog = opts.catalog ?? BASIC_CATALOG;
const catalog = opts.catalog ?? await loadBasicCatalog();
const promptOptions = {
catalog,
...(opts.systemAppendix === undefined
Expand Down
6 changes: 6 additions & 0 deletions packages/genui/server/agent/a2ui-catalog-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright 2026 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.

export const BASIC_CATALOG_ID =
'https://unpkg.com/@lynx-js/genui/a2ui/dist/catalog/catalog.json';
Comment on lines +5 to +6
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pin BASIC_CATALOG_ID to an immutable artifact.

This URL tracks the latest published @lynx-js/genui package on unpkg, so a future release can change the basic catalog without any server deploy. That breaks the contract between the shipped prompt/examples code and the remotely loaded schema. Please point this at a versioned asset (or another immutable same-build artifact) instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/genui/server/agent/a2ui-catalog-id.ts` around lines 5 - 6,
BASIC_CATALOG_ID currently points to an unversioned unpkg URL that will move as
new `@lynx-js/genui` releases are published; change BASIC_CATALOG_ID to reference
a versioned immutable asset (for example the same unpkg URL but including the
package version like
'https://unpkg.com/@lynx-js/genui@<version>/a2ui/dist/catalog/catalog.json' or a
build-time substituted artifact URL from your CI/artifacts store) so the shipped
server always loads the catalog that matches the shipped code; update the
constant BASIC_CATALOG_ID accordingly and, if applicable, wire it to read the
package version (package.json) or a build environment variable used during
release to ensure it is pinned per build.

Loading
Loading