@genkit-ai/a2ui 0.5.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +314 -0
- package/lib/catalog.d.mts +70 -0
- package/lib/catalog.d.ts +70 -0
- package/lib/catalog.js +285 -0
- package/lib/catalog.js.map +1 -0
- package/lib/catalog.mjs +256 -0
- package/lib/catalog.mjs.map +1 -0
- package/lib/client.d.mts +59 -0
- package/lib/client.d.ts +59 -0
- package/lib/client.js +82 -0
- package/lib/client.js.map +1 -0
- package/lib/client.mjs +55 -0
- package/lib/client.mjs.map +1 -0
- package/lib/index.d.mts +8 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +62 -0
- package/lib/index.js.map +1 -0
- package/lib/index.mjs +36 -0
- package/lib/index.mjs.map +1 -0
- package/lib/loader.d.mts +70 -0
- package/lib/loader.d.ts +70 -0
- package/lib/loader.js +92 -0
- package/lib/loader.js.map +1 -0
- package/lib/loader.mjs +61 -0
- package/lib/loader.mjs.map +1 -0
- package/lib/middleware.d.mts +112 -0
- package/lib/middleware.d.ts +112 -0
- package/lib/middleware.js +259 -0
- package/lib/middleware.js.map +1 -0
- package/lib/middleware.mjs +240 -0
- package/lib/middleware.mjs.map +1 -0
- package/lib/parser.d.mts +132 -0
- package/lib/parser.d.ts +132 -0
- package/lib/parser.js +282 -0
- package/lib/parser.js.map +1 -0
- package/lib/parser.mjs +260 -0
- package/lib/parser.mjs.map +1 -0
- package/lib/part.d.mts +56 -0
- package/lib/part.d.ts +56 -0
- package/lib/part.js +52 -0
- package/lib/part.js.map +1 -0
- package/lib/part.mjs +26 -0
- package/lib/part.mjs.map +1 -0
- package/lib/types.d.mts +153 -0
- package/lib/types.d.ts +153 -0
- package/lib/types.js +38 -0
- package/lib/types.js.map +1 -0
- package/lib/types.mjs +11 -0
- package/lib/types.mjs.map +1 -0
- package/package.json +80 -0
package/lib/client.d.mts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { A2uiEnvelope, A2uiClientAction, A2uiPart } from './types.mjs';
|
|
2
|
+
export { A2UI_MIME_TYPE, A2UI_VERSION, A2uiComponent, BASIC_CATALOG_ID } from './types.mjs';
|
|
3
|
+
export { a2uiEnvelopesFromParts, a2uiPart, isA2uiPart } from './part.mjs';
|
|
4
|
+
import 'genkit';
|
|
5
|
+
|
|
6
|
+
/** A single event yielded while streaming an A2UI agent turn. */
|
|
7
|
+
type A2uiStreamEvent = {
|
|
8
|
+
type: 'text';
|
|
9
|
+
text: string;
|
|
10
|
+
} | {
|
|
11
|
+
type: 'envelopes';
|
|
12
|
+
envelopes: A2uiEnvelope[];
|
|
13
|
+
};
|
|
14
|
+
/** Options for {@link streamA2uiAgent}. */
|
|
15
|
+
interface StreamA2uiAgentOptions {
|
|
16
|
+
/** URL of the Genkit agent/flow endpoint (e.g. `/uiAgent`). */
|
|
17
|
+
url: string;
|
|
18
|
+
/** The user message to send (Genkit message data or a plain string). */
|
|
19
|
+
message: string | Record<string, unknown>;
|
|
20
|
+
/** Server-managed session id (a UUID). */
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
/** Extra HTTP headers. */
|
|
23
|
+
headers?: Record<string, string>;
|
|
24
|
+
/** Abort signal to cancel the request. */
|
|
25
|
+
abortSignal?: AbortSignal;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Streams an A2UI-enabled Genkit agent, yielding prose text deltas and complete
|
|
29
|
+
* A2UI envelope batches in the order they arrive. Feed the envelopes to your
|
|
30
|
+
* renderer's message processor.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { MessageProcessor } from '@a2ui/web_core/v0_9';
|
|
35
|
+
* import { basicCatalog } from '@a2ui/lit/v0_9';
|
|
36
|
+
* import { streamA2uiAgent } from '@genkit-ai/a2ui/client';
|
|
37
|
+
*
|
|
38
|
+
* const processor = new MessageProcessor([basicCatalog]);
|
|
39
|
+
* for await (const ev of streamA2uiAgent({ url: '/uiAgent', message: 'weather in Tokyo' })) {
|
|
40
|
+
* if (ev.type === 'text') appendProse(ev.text);
|
|
41
|
+
* else processor.processMessages(ev.envelopes);
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
declare function streamA2uiAgent(options: StreamA2uiAgentOptions): AsyncGenerator<A2uiStreamEvent, void, unknown>;
|
|
46
|
+
/**
|
|
47
|
+
* Builds the agent input for sending a rendered surface's user action back to
|
|
48
|
+
* the agent as the next turn. The action's `name` becomes the user message so
|
|
49
|
+
* the agent can react to it; the full action object is attached as an a2ui data
|
|
50
|
+
* part for richer handling.
|
|
51
|
+
*/
|
|
52
|
+
declare function actionToMessage(action: A2uiClientAction): {
|
|
53
|
+
role: string;
|
|
54
|
+
content: (A2uiPart | {
|
|
55
|
+
text: string;
|
|
56
|
+
})[];
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export { A2uiClientAction, A2uiEnvelope, A2uiPart, type A2uiStreamEvent, type StreamA2uiAgentOptions, actionToMessage, streamA2uiAgent };
|
package/lib/client.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { A2uiEnvelope, A2uiClientAction, A2uiPart } from './types.js';
|
|
2
|
+
export { A2UI_MIME_TYPE, A2UI_VERSION, A2uiComponent, BASIC_CATALOG_ID } from './types.js';
|
|
3
|
+
export { a2uiEnvelopesFromParts, a2uiPart, isA2uiPart } from './part.js';
|
|
4
|
+
import 'genkit';
|
|
5
|
+
|
|
6
|
+
/** A single event yielded while streaming an A2UI agent turn. */
|
|
7
|
+
type A2uiStreamEvent = {
|
|
8
|
+
type: 'text';
|
|
9
|
+
text: string;
|
|
10
|
+
} | {
|
|
11
|
+
type: 'envelopes';
|
|
12
|
+
envelopes: A2uiEnvelope[];
|
|
13
|
+
};
|
|
14
|
+
/** Options for {@link streamA2uiAgent}. */
|
|
15
|
+
interface StreamA2uiAgentOptions {
|
|
16
|
+
/** URL of the Genkit agent/flow endpoint (e.g. `/uiAgent`). */
|
|
17
|
+
url: string;
|
|
18
|
+
/** The user message to send (Genkit message data or a plain string). */
|
|
19
|
+
message: string | Record<string, unknown>;
|
|
20
|
+
/** Server-managed session id (a UUID). */
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
/** Extra HTTP headers. */
|
|
23
|
+
headers?: Record<string, string>;
|
|
24
|
+
/** Abort signal to cancel the request. */
|
|
25
|
+
abortSignal?: AbortSignal;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Streams an A2UI-enabled Genkit agent, yielding prose text deltas and complete
|
|
29
|
+
* A2UI envelope batches in the order they arrive. Feed the envelopes to your
|
|
30
|
+
* renderer's message processor.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { MessageProcessor } from '@a2ui/web_core/v0_9';
|
|
35
|
+
* import { basicCatalog } from '@a2ui/lit/v0_9';
|
|
36
|
+
* import { streamA2uiAgent } from '@genkit-ai/a2ui/client';
|
|
37
|
+
*
|
|
38
|
+
* const processor = new MessageProcessor([basicCatalog]);
|
|
39
|
+
* for await (const ev of streamA2uiAgent({ url: '/uiAgent', message: 'weather in Tokyo' })) {
|
|
40
|
+
* if (ev.type === 'text') appendProse(ev.text);
|
|
41
|
+
* else processor.processMessages(ev.envelopes);
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
declare function streamA2uiAgent(options: StreamA2uiAgentOptions): AsyncGenerator<A2uiStreamEvent, void, unknown>;
|
|
46
|
+
/**
|
|
47
|
+
* Builds the agent input for sending a rendered surface's user action back to
|
|
48
|
+
* the agent as the next turn. The action's `name` becomes the user message so
|
|
49
|
+
* the agent can react to it; the full action object is attached as an a2ui data
|
|
50
|
+
* part for richer handling.
|
|
51
|
+
*/
|
|
52
|
+
declare function actionToMessage(action: A2uiClientAction): {
|
|
53
|
+
role: string;
|
|
54
|
+
content: (A2uiPart | {
|
|
55
|
+
text: string;
|
|
56
|
+
})[];
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export { A2uiClientAction, A2uiEnvelope, A2uiPart, type A2uiStreamEvent, type StreamA2uiAgentOptions, actionToMessage, streamA2uiAgent };
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var client_exports = {};
|
|
20
|
+
__export(client_exports, {
|
|
21
|
+
A2UI_MIME_TYPE: () => import_types.A2UI_MIME_TYPE,
|
|
22
|
+
A2UI_VERSION: () => import_types.A2UI_VERSION,
|
|
23
|
+
BASIC_CATALOG_ID: () => import_types.BASIC_CATALOG_ID,
|
|
24
|
+
a2uiEnvelopesFromParts: () => import_part2.a2uiEnvelopesFromParts,
|
|
25
|
+
a2uiPart: () => import_part2.a2uiPart,
|
|
26
|
+
actionToMessage: () => actionToMessage,
|
|
27
|
+
isA2uiPart: () => import_part2.isA2uiPart,
|
|
28
|
+
streamA2uiAgent: () => streamA2uiAgent
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(client_exports);
|
|
31
|
+
var import_client = require("genkit/beta/client");
|
|
32
|
+
var import_part = require("./part.js");
|
|
33
|
+
var import_part2 = require("./part.js");
|
|
34
|
+
var import_types = require("./types.js");
|
|
35
|
+
function toMessage(message) {
|
|
36
|
+
if (typeof message === "string") {
|
|
37
|
+
return { role: "user", content: [{ text: message }] };
|
|
38
|
+
}
|
|
39
|
+
return message;
|
|
40
|
+
}
|
|
41
|
+
async function* streamA2uiAgent(options) {
|
|
42
|
+
const agent = (0, import_client.remoteAgent)({ url: options.url, headers: options.headers });
|
|
43
|
+
const chat = agent.chat(
|
|
44
|
+
options.sessionId ? { sessionId: options.sessionId } : void 0
|
|
45
|
+
);
|
|
46
|
+
const turn = chat.sendStream(
|
|
47
|
+
{ message: toMessage(options.message) },
|
|
48
|
+
{ abortSignal: options.abortSignal }
|
|
49
|
+
);
|
|
50
|
+
for await (const chunk of turn.stream) {
|
|
51
|
+
if (chunk.text) {
|
|
52
|
+
yield { type: "text", text: chunk.text };
|
|
53
|
+
}
|
|
54
|
+
const envelopes = (0, import_part.a2uiEnvelopesFromParts)(chunk.raw.modelChunk?.content);
|
|
55
|
+
if (envelopes.length > 0) {
|
|
56
|
+
yield { type: "envelopes", envelopes };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
await turn.response;
|
|
60
|
+
}
|
|
61
|
+
function actionToMessage(action) {
|
|
62
|
+
if (!action) {
|
|
63
|
+
throw new Error("actionToMessage: action is required");
|
|
64
|
+
}
|
|
65
|
+
const summary = `User interacted with the UI (surface "${action.surfaceId}"): action "${action.name}"` + (action.context && Object.keys(action.context).length ? ` with context ${JSON.stringify(action.context)}` : "") + ".";
|
|
66
|
+
return {
|
|
67
|
+
role: "user",
|
|
68
|
+
content: [{ text: summary }, (0, import_part.a2uiPart)([{ action }])]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
72
|
+
0 && (module.exports = {
|
|
73
|
+
A2UI_MIME_TYPE,
|
|
74
|
+
A2UI_VERSION,
|
|
75
|
+
BASIC_CATALOG_ID,
|
|
76
|
+
a2uiEnvelopesFromParts,
|
|
77
|
+
a2uiPart,
|
|
78
|
+
actionToMessage,
|
|
79
|
+
isA2uiPart,
|
|
80
|
+
streamA2uiAgent
|
|
81
|
+
});
|
|
82
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["/**\n * Copyright 2026 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Browser-safe client helpers for consuming an A2UI-enabled Genkit agent.\n *\n * This module has NO Node dependencies. It builds on Genkit's agent client\n * (`remoteAgent` from `genkit/beta/client`), filters A2UI parts out of the\n * agent stream, and hands whole envelopes to whatever renderer you use (e.g.\n * `@a2ui/web_core`'s `MessageProcessor`).\n *\n * @module\n */\n\nimport { remoteAgent } from 'genkit/beta/client';\nimport { a2uiEnvelopesFromParts, a2uiPart } from './part.js';\nimport type { A2uiClientAction, A2uiEnvelope } from './types.js';\n\nexport { a2uiEnvelopesFromParts, a2uiPart, isA2uiPart } from './part.js';\nexport {\n A2UI_MIME_TYPE,\n A2UI_VERSION,\n BASIC_CATALOG_ID,\n type A2uiClientAction,\n type A2uiComponent,\n type A2uiEnvelope,\n type A2uiPart,\n} from './types.js';\n\n/** A single event yielded while streaming an A2UI agent turn. */\nexport type A2uiStreamEvent =\n | { type: 'text'; text: string }\n | { type: 'envelopes'; envelopes: A2uiEnvelope[] };\n\n/** Options for {@link streamA2uiAgent}. */\nexport interface StreamA2uiAgentOptions {\n /** URL of the Genkit agent/flow endpoint (e.g. `/uiAgent`). */\n url: string;\n /** The user message to send (Genkit message data or a plain string). */\n message: string | Record<string, unknown>;\n /** Server-managed session id (a UUID). */\n sessionId?: string;\n /** Extra HTTP headers. */\n headers?: Record<string, string>;\n /** Abort signal to cancel the request. */\n abortSignal?: AbortSignal;\n}\n\n/** Normalizes a string message into a Genkit user message. */\nfunction toMessage(message: string | Record<string, unknown>) {\n if (typeof message === 'string') {\n return { role: 'user', content: [{ text: message }] };\n }\n return message;\n}\n\n/**\n * Streams an A2UI-enabled Genkit agent, yielding prose text deltas and complete\n * A2UI envelope batches in the order they arrive. Feed the envelopes to your\n * renderer's message processor.\n *\n * @example\n * ```ts\n * import { MessageProcessor } from '@a2ui/web_core/v0_9';\n * import { basicCatalog } from '@a2ui/lit/v0_9';\n * import { streamA2uiAgent } from '@genkit-ai/a2ui/client';\n *\n * const processor = new MessageProcessor([basicCatalog]);\n * for await (const ev of streamA2uiAgent({ url: '/uiAgent', message: 'weather in Tokyo' })) {\n * if (ev.type === 'text') appendProse(ev.text);\n * else processor.processMessages(ev.envelopes);\n * }\n * ```\n */\nexport async function* streamA2uiAgent(\n options: StreamA2uiAgentOptions\n): AsyncGenerator<A2uiStreamEvent, void, unknown> {\n const agent = remoteAgent({ url: options.url, headers: options.headers });\n // A server-managed session id (when provided) attaches this turn to an\n // existing conversation; otherwise the agent starts a fresh session.\n const chat = agent.chat(\n options.sessionId ? { sessionId: options.sessionId } : undefined\n );\n\n const turn = chat.sendStream(\n { message: toMessage(options.message) } as Parameters<\n typeof chat.sendStream\n >[0],\n { abortSignal: options.abortSignal }\n );\n\n for await (const chunk of turn.stream) {\n if (chunk.text) {\n yield { type: 'text', text: chunk.text };\n }\n // A2UI rides as data parts on the raw chunk; extract whole envelopes.\n const envelopes = a2uiEnvelopesFromParts(chunk.raw.modelChunk?.content);\n if (envelopes.length > 0) {\n yield { type: 'envelopes', envelopes };\n }\n }\n // Surface any server error / finalize the turn.\n await turn.response;\n}\n\n/**\n * Builds the agent input for sending a rendered surface's user action back to\n * the agent as the next turn. The action's `name` becomes the user message so\n * the agent can react to it; the full action object is attached as an a2ui data\n * part for richer handling.\n */\nexport function actionToMessage(action: A2uiClientAction) {\n if (!action) {\n throw new Error('actionToMessage: action is required');\n }\n const summary =\n `User interacted with the UI (surface \"${action.surfaceId}\"): ` +\n `action \"${action.name}\"` +\n (action.context && Object.keys(action.context).length\n ? ` with context ${JSON.stringify(action.context)}`\n : '') +\n '.';\n return {\n role: 'user',\n content: [{ text: summary }, a2uiPart([{ action }])],\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BA,oBAA4B;AAC5B,kBAAiD;AAGjD,IAAAA,eAA6D;AAC7D,mBAQO;AAsBP,SAAS,UAAU,SAA2C;AAC5D,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO,EAAE,MAAM,QAAQ,SAAS,CAAC,EAAE,MAAM,QAAQ,CAAC,EAAE;AAAA,EACtD;AACA,SAAO;AACT;AAoBA,gBAAuB,gBACrB,SACgD;AAChD,QAAM,YAAQ,2BAAY,EAAE,KAAK,QAAQ,KAAK,SAAS,QAAQ,QAAQ,CAAC;AAGxE,QAAM,OAAO,MAAM;AAAA,IACjB,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI;AAAA,EACzD;AAEA,QAAM,OAAO,KAAK;AAAA,IAChB,EAAE,SAAS,UAAU,QAAQ,OAAO,EAAE;AAAA,IAGtC,EAAE,aAAa,QAAQ,YAAY;AAAA,EACrC;AAEA,mBAAiB,SAAS,KAAK,QAAQ;AACrC,QAAI,MAAM,MAAM;AACd,YAAM,EAAE,MAAM,QAAQ,MAAM,MAAM,KAAK;AAAA,IACzC;AAEA,UAAM,gBAAY,oCAAuB,MAAM,IAAI,YAAY,OAAO;AACtE,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,EAAE,MAAM,aAAa,UAAU;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,KAAK;AACb;AAQO,SAAS,gBAAgB,QAA0B;AACxD,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,qCAAqC;AAAA,EACvD;AACA,QAAM,UACJ,yCAAyC,OAAO,SAAS,eAC9C,OAAO,IAAI,OACrB,OAAO,WAAW,OAAO,KAAK,OAAO,OAAO,EAAE,SAC3C,iBAAiB,KAAK,UAAU,OAAO,OAAO,CAAC,KAC/C,MACJ;AACF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,CAAC,EAAE,MAAM,QAAQ,OAAG,sBAAS,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAAA,EACrD;AACF;","names":["import_part"]}
|
package/lib/client.mjs
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { remoteAgent } from "genkit/beta/client";
|
|
2
|
+
import { a2uiEnvelopesFromParts, a2uiPart } from "./part.mjs";
|
|
3
|
+
import { a2uiEnvelopesFromParts as a2uiEnvelopesFromParts2, a2uiPart as a2uiPart2, isA2uiPart } from "./part.mjs";
|
|
4
|
+
import {
|
|
5
|
+
A2UI_MIME_TYPE,
|
|
6
|
+
A2UI_VERSION,
|
|
7
|
+
BASIC_CATALOG_ID
|
|
8
|
+
} from "./types.mjs";
|
|
9
|
+
function toMessage(message) {
|
|
10
|
+
if (typeof message === "string") {
|
|
11
|
+
return { role: "user", content: [{ text: message }] };
|
|
12
|
+
}
|
|
13
|
+
return message;
|
|
14
|
+
}
|
|
15
|
+
async function* streamA2uiAgent(options) {
|
|
16
|
+
const agent = remoteAgent({ url: options.url, headers: options.headers });
|
|
17
|
+
const chat = agent.chat(
|
|
18
|
+
options.sessionId ? { sessionId: options.sessionId } : void 0
|
|
19
|
+
);
|
|
20
|
+
const turn = chat.sendStream(
|
|
21
|
+
{ message: toMessage(options.message) },
|
|
22
|
+
{ abortSignal: options.abortSignal }
|
|
23
|
+
);
|
|
24
|
+
for await (const chunk of turn.stream) {
|
|
25
|
+
if (chunk.text) {
|
|
26
|
+
yield { type: "text", text: chunk.text };
|
|
27
|
+
}
|
|
28
|
+
const envelopes = a2uiEnvelopesFromParts(chunk.raw.modelChunk?.content);
|
|
29
|
+
if (envelopes.length > 0) {
|
|
30
|
+
yield { type: "envelopes", envelopes };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
await turn.response;
|
|
34
|
+
}
|
|
35
|
+
function actionToMessage(action) {
|
|
36
|
+
if (!action) {
|
|
37
|
+
throw new Error("actionToMessage: action is required");
|
|
38
|
+
}
|
|
39
|
+
const summary = `User interacted with the UI (surface "${action.surfaceId}"): action "${action.name}"` + (action.context && Object.keys(action.context).length ? ` with context ${JSON.stringify(action.context)}` : "") + ".";
|
|
40
|
+
return {
|
|
41
|
+
role: "user",
|
|
42
|
+
content: [{ text: summary }, a2uiPart([{ action }])]
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
A2UI_MIME_TYPE,
|
|
47
|
+
A2UI_VERSION,
|
|
48
|
+
BASIC_CATALOG_ID,
|
|
49
|
+
a2uiEnvelopesFromParts2 as a2uiEnvelopesFromParts,
|
|
50
|
+
a2uiPart2 as a2uiPart,
|
|
51
|
+
actionToMessage,
|
|
52
|
+
isA2uiPart,
|
|
53
|
+
streamA2uiAgent
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["/**\n * Copyright 2026 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Browser-safe client helpers for consuming an A2UI-enabled Genkit agent.\n *\n * This module has NO Node dependencies. It builds on Genkit's agent client\n * (`remoteAgent` from `genkit/beta/client`), filters A2UI parts out of the\n * agent stream, and hands whole envelopes to whatever renderer you use (e.g.\n * `@a2ui/web_core`'s `MessageProcessor`).\n *\n * @module\n */\n\nimport { remoteAgent } from 'genkit/beta/client';\nimport { a2uiEnvelopesFromParts, a2uiPart } from './part.mjs';\nimport type { A2uiClientAction, A2uiEnvelope } from './types.mjs';\n\nexport { a2uiEnvelopesFromParts, a2uiPart, isA2uiPart } from './part.mjs';\nexport {\n A2UI_MIME_TYPE,\n A2UI_VERSION,\n BASIC_CATALOG_ID,\n type A2uiClientAction,\n type A2uiComponent,\n type A2uiEnvelope,\n type A2uiPart,\n} from './types.mjs';\n\n/** A single event yielded while streaming an A2UI agent turn. */\nexport type A2uiStreamEvent =\n | { type: 'text'; text: string }\n | { type: 'envelopes'; envelopes: A2uiEnvelope[] };\n\n/** Options for {@link streamA2uiAgent}. */\nexport interface StreamA2uiAgentOptions {\n /** URL of the Genkit agent/flow endpoint (e.g. `/uiAgent`). */\n url: string;\n /** The user message to send (Genkit message data or a plain string). */\n message: string | Record<string, unknown>;\n /** Server-managed session id (a UUID). */\n sessionId?: string;\n /** Extra HTTP headers. */\n headers?: Record<string, string>;\n /** Abort signal to cancel the request. */\n abortSignal?: AbortSignal;\n}\n\n/** Normalizes a string message into a Genkit user message. */\nfunction toMessage(message: string | Record<string, unknown>) {\n if (typeof message === 'string') {\n return { role: 'user', content: [{ text: message }] };\n }\n return message;\n}\n\n/**\n * Streams an A2UI-enabled Genkit agent, yielding prose text deltas and complete\n * A2UI envelope batches in the order they arrive. Feed the envelopes to your\n * renderer's message processor.\n *\n * @example\n * ```ts\n * import { MessageProcessor } from '@a2ui/web_core/v0_9';\n * import { basicCatalog } from '@a2ui/lit/v0_9';\n * import { streamA2uiAgent } from '@genkit-ai/a2ui/client';\n *\n * const processor = new MessageProcessor([basicCatalog]);\n * for await (const ev of streamA2uiAgent({ url: '/uiAgent', message: 'weather in Tokyo' })) {\n * if (ev.type === 'text') appendProse(ev.text);\n * else processor.processMessages(ev.envelopes);\n * }\n * ```\n */\nexport async function* streamA2uiAgent(\n options: StreamA2uiAgentOptions\n): AsyncGenerator<A2uiStreamEvent, void, unknown> {\n const agent = remoteAgent({ url: options.url, headers: options.headers });\n // A server-managed session id (when provided) attaches this turn to an\n // existing conversation; otherwise the agent starts a fresh session.\n const chat = agent.chat(\n options.sessionId ? { sessionId: options.sessionId } : undefined\n );\n\n const turn = chat.sendStream(\n { message: toMessage(options.message) } as Parameters<\n typeof chat.sendStream\n >[0],\n { abortSignal: options.abortSignal }\n );\n\n for await (const chunk of turn.stream) {\n if (chunk.text) {\n yield { type: 'text', text: chunk.text };\n }\n // A2UI rides as data parts on the raw chunk; extract whole envelopes.\n const envelopes = a2uiEnvelopesFromParts(chunk.raw.modelChunk?.content);\n if (envelopes.length > 0) {\n yield { type: 'envelopes', envelopes };\n }\n }\n // Surface any server error / finalize the turn.\n await turn.response;\n}\n\n/**\n * Builds the agent input for sending a rendered surface's user action back to\n * the agent as the next turn. The action's `name` becomes the user message so\n * the agent can react to it; the full action object is attached as an a2ui data\n * part for richer handling.\n */\nexport function actionToMessage(action: A2uiClientAction) {\n if (!action) {\n throw new Error('actionToMessage: action is required');\n }\n const summary =\n `User interacted with the UI (surface \"${action.surfaceId}\"): ` +\n `action \"${action.name}\"` +\n (action.context && Object.keys(action.context).length\n ? ` with context ${JSON.stringify(action.context)}`\n : '') +\n '.';\n return {\n role: 'user',\n content: [{ text: summary }, a2uiPart([{ action }])],\n };\n}\n"],"mappings":"AA2BA,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB,gBAAgB;AAGjD,SAAS,0BAAAA,yBAAwB,YAAAC,WAAU,kBAAkB;AAC7D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AAsBP,SAAS,UAAU,SAA2C;AAC5D,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO,EAAE,MAAM,QAAQ,SAAS,CAAC,EAAE,MAAM,QAAQ,CAAC,EAAE;AAAA,EACtD;AACA,SAAO;AACT;AAoBA,gBAAuB,gBACrB,SACgD;AAChD,QAAM,QAAQ,YAAY,EAAE,KAAK,QAAQ,KAAK,SAAS,QAAQ,QAAQ,CAAC;AAGxE,QAAM,OAAO,MAAM;AAAA,IACjB,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI;AAAA,EACzD;AAEA,QAAM,OAAO,KAAK;AAAA,IAChB,EAAE,SAAS,UAAU,QAAQ,OAAO,EAAE;AAAA,IAGtC,EAAE,aAAa,QAAQ,YAAY;AAAA,EACrC;AAEA,mBAAiB,SAAS,KAAK,QAAQ;AACrC,QAAI,MAAM,MAAM;AACd,YAAM,EAAE,MAAM,QAAQ,MAAM,MAAM,KAAK;AAAA,IACzC;AAEA,UAAM,YAAY,uBAAuB,MAAM,IAAI,YAAY,OAAO;AACtE,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,EAAE,MAAM,aAAa,UAAU;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,KAAK;AACb;AAQO,SAAS,gBAAgB,QAA0B;AACxD,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,qCAAqC;AAAA,EACvD;AACA,QAAM,UACJ,yCAAyC,OAAO,SAAS,eAC9C,OAAO,IAAI,OACrB,OAAO,WAAW,OAAO,KAAK,OAAO,OAAO,EAAE,SAC3C,iBAAiB,KAAK,UAAU,OAAO,OAAO,CAAC,KAC/C,MACJ;AACF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,CAAC,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAAA,EACrD;AACF;","names":["a2uiEnvelopesFromParts","a2uiPart"]}
|
package/lib/index.d.mts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { A2UI_CATALOG_VALUE_TYPE, A2uiCatalog, A2uiCatalogComponent, DEFAULT_CATALOG_ID, SURFACE_ID_PLACEHOLDER, basicCatalog, renderCatalogInstructions } from './catalog.mjs';
|
|
2
|
+
export { LoadCatalogOptions, loadCatalog } from './loader.mjs';
|
|
3
|
+
export { A2uiOptions, A2uiOptionsSchema, a2ui } from './middleware.mjs';
|
|
4
|
+
export { A2uiParserOptions, A2uiStreamParser, ParseResult } from './parser.mjs';
|
|
5
|
+
export { a2uiEnvelopesFromParts, a2uiPart, isA2uiPart } from './part.mjs';
|
|
6
|
+
export { A2UI_MIME_TYPE, A2UI_VERSION, A2uiClientAction, A2uiComponent, A2uiEnvelope, A2uiPart, BASIC_CATALOG_ID, CreateSurfaceEnvelope, DeleteSurfaceEnvelope, UpdateComponentsEnvelope, UpdateDataModelEnvelope } from './types.mjs';
|
|
7
|
+
import 'genkit/registry';
|
|
8
|
+
import 'genkit';
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { A2UI_CATALOG_VALUE_TYPE, A2uiCatalog, A2uiCatalogComponent, DEFAULT_CATALOG_ID, SURFACE_ID_PLACEHOLDER, basicCatalog, renderCatalogInstructions } from './catalog.js';
|
|
2
|
+
export { LoadCatalogOptions, loadCatalog } from './loader.js';
|
|
3
|
+
export { A2uiOptions, A2uiOptionsSchema, a2ui } from './middleware.js';
|
|
4
|
+
export { A2uiParserOptions, A2uiStreamParser, ParseResult } from './parser.js';
|
|
5
|
+
export { a2uiEnvelopesFromParts, a2uiPart, isA2uiPart } from './part.js';
|
|
6
|
+
export { A2UI_MIME_TYPE, A2UI_VERSION, A2uiClientAction, A2uiComponent, A2uiEnvelope, A2uiPart, BASIC_CATALOG_ID, CreateSurfaceEnvelope, DeleteSurfaceEnvelope, UpdateComponentsEnvelope, UpdateDataModelEnvelope } from './types.js';
|
|
7
|
+
import 'genkit/registry';
|
|
8
|
+
import 'genkit';
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var index_exports = {};
|
|
20
|
+
__export(index_exports, {
|
|
21
|
+
A2UI_CATALOG_VALUE_TYPE: () => import_catalog.A2UI_CATALOG_VALUE_TYPE,
|
|
22
|
+
A2UI_MIME_TYPE: () => import_types.A2UI_MIME_TYPE,
|
|
23
|
+
A2UI_VERSION: () => import_types.A2UI_VERSION,
|
|
24
|
+
A2uiOptionsSchema: () => import_middleware.A2uiOptionsSchema,
|
|
25
|
+
A2uiStreamParser: () => import_parser.A2uiStreamParser,
|
|
26
|
+
BASIC_CATALOG_ID: () => import_types.BASIC_CATALOG_ID,
|
|
27
|
+
DEFAULT_CATALOG_ID: () => import_catalog.DEFAULT_CATALOG_ID,
|
|
28
|
+
SURFACE_ID_PLACEHOLDER: () => import_catalog.SURFACE_ID_PLACEHOLDER,
|
|
29
|
+
a2ui: () => import_middleware.a2ui,
|
|
30
|
+
a2uiEnvelopesFromParts: () => import_part.a2uiEnvelopesFromParts,
|
|
31
|
+
a2uiPart: () => import_part.a2uiPart,
|
|
32
|
+
basicCatalog: () => import_catalog.basicCatalog,
|
|
33
|
+
isA2uiPart: () => import_part.isA2uiPart,
|
|
34
|
+
loadCatalog: () => import_loader.loadCatalog,
|
|
35
|
+
renderCatalogInstructions: () => import_catalog.renderCatalogInstructions
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
var import_catalog = require("./catalog.js");
|
|
39
|
+
var import_loader = require("./loader.js");
|
|
40
|
+
var import_middleware = require("./middleware.js");
|
|
41
|
+
var import_parser = require("./parser.js");
|
|
42
|
+
var import_part = require("./part.js");
|
|
43
|
+
var import_types = require("./types.js");
|
|
44
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
45
|
+
0 && (module.exports = {
|
|
46
|
+
A2UI_CATALOG_VALUE_TYPE,
|
|
47
|
+
A2UI_MIME_TYPE,
|
|
48
|
+
A2UI_VERSION,
|
|
49
|
+
A2uiOptionsSchema,
|
|
50
|
+
A2uiStreamParser,
|
|
51
|
+
BASIC_CATALOG_ID,
|
|
52
|
+
DEFAULT_CATALOG_ID,
|
|
53
|
+
SURFACE_ID_PLACEHOLDER,
|
|
54
|
+
a2ui,
|
|
55
|
+
a2uiEnvelopesFromParts,
|
|
56
|
+
a2uiPart,
|
|
57
|
+
basicCatalog,
|
|
58
|
+
isA2uiPart,
|
|
59
|
+
loadCatalog,
|
|
60
|
+
renderCatalogInstructions
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Copyright 2026 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * `@genkit-ai/a2ui` — A2UI (Agent-to-UI) streaming UI protocol support for\n * Genkit agents.\n *\n * The whole server-side integration is the {@link a2ui} model middleware; add it\n * to `defineAgent({ use: [...] })` or `ai.generate({ use: [...] })`. Pair it with\n * {@link basicCatalog} (or your own catalog) and render on the client with the\n * `@a2ui/lit` renderer plus the helpers in `@genkit-ai/a2ui/client`.\n *\n * @module\n */\n\nexport {\n A2UI_CATALOG_VALUE_TYPE,\n DEFAULT_CATALOG_ID,\n SURFACE_ID_PLACEHOLDER,\n basicCatalog,\n renderCatalogInstructions,\n type A2uiCatalog,\n type A2uiCatalogComponent,\n} from './catalog.js';\nexport { loadCatalog, type LoadCatalogOptions } from './loader.js';\nexport { A2uiOptionsSchema, a2ui, type A2uiOptions } from './middleware.js';\nexport {\n A2uiStreamParser,\n type A2uiParserOptions,\n type ParseResult,\n} from './parser.js';\nexport { a2uiEnvelopesFromParts, a2uiPart, isA2uiPart } from './part.js';\nexport {\n A2UI_MIME_TYPE,\n A2UI_VERSION,\n BASIC_CATALOG_ID,\n type A2uiClientAction,\n type A2uiComponent,\n type A2uiEnvelope,\n type A2uiPart,\n type CreateSurfaceEnvelope,\n type DeleteSurfaceEnvelope,\n type UpdateComponentsEnvelope,\n type UpdateDataModelEnvelope,\n} from './types.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BA,qBAQO;AACP,oBAAqD;AACrD,wBAA0D;AAC1D,oBAIO;AACP,kBAA6D;AAC7D,mBAYO;","names":[]}
|
package/lib/index.mjs
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
A2UI_CATALOG_VALUE_TYPE,
|
|
3
|
+
DEFAULT_CATALOG_ID,
|
|
4
|
+
SURFACE_ID_PLACEHOLDER,
|
|
5
|
+
basicCatalog,
|
|
6
|
+
renderCatalogInstructions
|
|
7
|
+
} from "./catalog.mjs";
|
|
8
|
+
import { loadCatalog } from "./loader.mjs";
|
|
9
|
+
import { A2uiOptionsSchema, a2ui } from "./middleware.mjs";
|
|
10
|
+
import {
|
|
11
|
+
A2uiStreamParser
|
|
12
|
+
} from "./parser.mjs";
|
|
13
|
+
import { a2uiEnvelopesFromParts, a2uiPart, isA2uiPart } from "./part.mjs";
|
|
14
|
+
import {
|
|
15
|
+
A2UI_MIME_TYPE,
|
|
16
|
+
A2UI_VERSION,
|
|
17
|
+
BASIC_CATALOG_ID
|
|
18
|
+
} from "./types.mjs";
|
|
19
|
+
export {
|
|
20
|
+
A2UI_CATALOG_VALUE_TYPE,
|
|
21
|
+
A2UI_MIME_TYPE,
|
|
22
|
+
A2UI_VERSION,
|
|
23
|
+
A2uiOptionsSchema,
|
|
24
|
+
A2uiStreamParser,
|
|
25
|
+
BASIC_CATALOG_ID,
|
|
26
|
+
DEFAULT_CATALOG_ID,
|
|
27
|
+
SURFACE_ID_PLACEHOLDER,
|
|
28
|
+
a2ui,
|
|
29
|
+
a2uiEnvelopesFromParts,
|
|
30
|
+
a2uiPart,
|
|
31
|
+
basicCatalog,
|
|
32
|
+
isA2uiPart,
|
|
33
|
+
loadCatalog,
|
|
34
|
+
renderCatalogInstructions
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Copyright 2026 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * `@genkit-ai/a2ui` — A2UI (Agent-to-UI) streaming UI protocol support for\n * Genkit agents.\n *\n * The whole server-side integration is the {@link a2ui} model middleware; add it\n * to `defineAgent({ use: [...] })` or `ai.generate({ use: [...] })`. Pair it with\n * {@link basicCatalog} (or your own catalog) and render on the client with the\n * `@a2ui/lit` renderer plus the helpers in `@genkit-ai/a2ui/client`.\n *\n * @module\n */\n\nexport {\n A2UI_CATALOG_VALUE_TYPE,\n DEFAULT_CATALOG_ID,\n SURFACE_ID_PLACEHOLDER,\n basicCatalog,\n renderCatalogInstructions,\n type A2uiCatalog,\n type A2uiCatalogComponent,\n} from './catalog.mjs';\nexport { loadCatalog, type LoadCatalogOptions } from './loader.mjs';\nexport { A2uiOptionsSchema, a2ui, type A2uiOptions } from './middleware.mjs';\nexport {\n A2uiStreamParser,\n type A2uiParserOptions,\n type ParseResult,\n} from './parser.mjs';\nexport { a2uiEnvelopesFromParts, a2uiPart, isA2uiPart } from './part.mjs';\nexport {\n A2UI_MIME_TYPE,\n A2UI_VERSION,\n BASIC_CATALOG_ID,\n type A2uiClientAction,\n type A2uiComponent,\n type A2uiEnvelope,\n type A2uiPart,\n type CreateSurfaceEnvelope,\n type DeleteSurfaceEnvelope,\n type UpdateComponentsEnvelope,\n type UpdateDataModelEnvelope,\n} from './types.mjs';\n"],"mappings":"AA4BA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,mBAA4C;AACrD,SAAS,mBAAmB,YAA8B;AAC1D;AAAA,EACE;AAAA,OAGK;AACP,SAAS,wBAAwB,UAAU,kBAAkB;AAC7D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OASK;","names":[]}
|
package/lib/loader.d.mts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { HasRegistry } from 'genkit/registry';
|
|
2
|
+
import { A2uiCatalog } from './catalog.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Copyright 2026 Google LLC
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Catalog loading helpers.
|
|
21
|
+
*
|
|
22
|
+
* The {@link a2ui} middleware references catalogs by id and looks them up in the
|
|
23
|
+
* Genkit registry (value type {@link A2UI_CATALOG_VALUE_TYPE}). {@link loadCatalog}
|
|
24
|
+
* registers a catalog under an id so the middleware — and, in the future, Genkit
|
|
25
|
+
* tooling — can find it. Provide the catalog inline, or load it from a JSON file.
|
|
26
|
+
*
|
|
27
|
+
* This module uses Node's `fs` for the `file` variant, so it is server-only (it
|
|
28
|
+
* is exported from the main `@genkit-ai/a2ui` entry, not `@genkit-ai/a2ui/client`).
|
|
29
|
+
*
|
|
30
|
+
* @module
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/** Options for {@link loadCatalog}. Provide either `catalog` or `file`. */
|
|
34
|
+
type LoadCatalogOptions = {
|
|
35
|
+
/** The id to register the catalog under (referenced by `a2ui({ catalog })`). */
|
|
36
|
+
id: string;
|
|
37
|
+
} & ({
|
|
38
|
+
/** An in-memory catalog to register. */
|
|
39
|
+
catalog: A2uiCatalog;
|
|
40
|
+
file?: never;
|
|
41
|
+
} | {
|
|
42
|
+
/** Path to a JSON file containing a catalog. */
|
|
43
|
+
file: string;
|
|
44
|
+
catalog?: never;
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* Registers an A2UI catalog under an id so the {@link a2ui} middleware can look
|
|
48
|
+
* it up (via `a2ui({ catalog: id })`).
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* // From an in-memory object:
|
|
53
|
+
* await loadCatalog(ai, { id: 'my-catalog', catalog: myCatalog });
|
|
54
|
+
*
|
|
55
|
+
* // From a JSON file:
|
|
56
|
+
* await loadCatalog(ai, { id: 'my-catalog', file: './my-catalog.json' });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @returns The registered catalog (with its `id` set to the given id).
|
|
60
|
+
*/
|
|
61
|
+
declare function loadCatalog(ai: HasRegistry, options: LoadCatalogOptions): Promise<A2uiCatalog>;
|
|
62
|
+
/**
|
|
63
|
+
* Resolves a catalog by id from the registry, falling back to the bundled
|
|
64
|
+
* {@link basicCatalog} for the default id. Used by the {@link a2ui} middleware.
|
|
65
|
+
*
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
declare function resolveCatalog(ai: HasRegistry, id: string): Promise<A2uiCatalog>;
|
|
69
|
+
|
|
70
|
+
export { type LoadCatalogOptions, loadCatalog, resolveCatalog };
|
package/lib/loader.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { HasRegistry } from 'genkit/registry';
|
|
2
|
+
import { A2uiCatalog } from './catalog.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Copyright 2026 Google LLC
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Catalog loading helpers.
|
|
21
|
+
*
|
|
22
|
+
* The {@link a2ui} middleware references catalogs by id and looks them up in the
|
|
23
|
+
* Genkit registry (value type {@link A2UI_CATALOG_VALUE_TYPE}). {@link loadCatalog}
|
|
24
|
+
* registers a catalog under an id so the middleware — and, in the future, Genkit
|
|
25
|
+
* tooling — can find it. Provide the catalog inline, or load it from a JSON file.
|
|
26
|
+
*
|
|
27
|
+
* This module uses Node's `fs` for the `file` variant, so it is server-only (it
|
|
28
|
+
* is exported from the main `@genkit-ai/a2ui` entry, not `@genkit-ai/a2ui/client`).
|
|
29
|
+
*
|
|
30
|
+
* @module
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/** Options for {@link loadCatalog}. Provide either `catalog` or `file`. */
|
|
34
|
+
type LoadCatalogOptions = {
|
|
35
|
+
/** The id to register the catalog under (referenced by `a2ui({ catalog })`). */
|
|
36
|
+
id: string;
|
|
37
|
+
} & ({
|
|
38
|
+
/** An in-memory catalog to register. */
|
|
39
|
+
catalog: A2uiCatalog;
|
|
40
|
+
file?: never;
|
|
41
|
+
} | {
|
|
42
|
+
/** Path to a JSON file containing a catalog. */
|
|
43
|
+
file: string;
|
|
44
|
+
catalog?: never;
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* Registers an A2UI catalog under an id so the {@link a2ui} middleware can look
|
|
48
|
+
* it up (via `a2ui({ catalog: id })`).
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* // From an in-memory object:
|
|
53
|
+
* await loadCatalog(ai, { id: 'my-catalog', catalog: myCatalog });
|
|
54
|
+
*
|
|
55
|
+
* // From a JSON file:
|
|
56
|
+
* await loadCatalog(ai, { id: 'my-catalog', file: './my-catalog.json' });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @returns The registered catalog (with its `id` set to the given id).
|
|
60
|
+
*/
|
|
61
|
+
declare function loadCatalog(ai: HasRegistry, options: LoadCatalogOptions): Promise<A2uiCatalog>;
|
|
62
|
+
/**
|
|
63
|
+
* Resolves a catalog by id from the registry, falling back to the bundled
|
|
64
|
+
* {@link basicCatalog} for the default id. Used by the {@link a2ui} middleware.
|
|
65
|
+
*
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
declare function resolveCatalog(ai: HasRegistry, id: string): Promise<A2uiCatalog>;
|
|
69
|
+
|
|
70
|
+
export { type LoadCatalogOptions, loadCatalog, resolveCatalog };
|
package/lib/loader.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var loader_exports = {};
|
|
30
|
+
__export(loader_exports, {
|
|
31
|
+
loadCatalog: () => loadCatalog,
|
|
32
|
+
resolveCatalog: () => resolveCatalog
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(loader_exports);
|
|
35
|
+
var import_catalog = require("./catalog.js");
|
|
36
|
+
async function loadCatalog(ai, options) {
|
|
37
|
+
const { id } = options;
|
|
38
|
+
if (!id) {
|
|
39
|
+
throw new Error("loadCatalog(): `id` is required.");
|
|
40
|
+
}
|
|
41
|
+
let catalog;
|
|
42
|
+
if (options.file !== void 0) {
|
|
43
|
+
catalog = await readCatalogFile(options.file);
|
|
44
|
+
} else if (options.catalog !== void 0) {
|
|
45
|
+
catalog = options.catalog;
|
|
46
|
+
} else {
|
|
47
|
+
throw new Error("loadCatalog(): provide either `catalog` or `file`.");
|
|
48
|
+
}
|
|
49
|
+
if (!catalog || !Array.isArray(catalog.components)) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`loadCatalog(): catalog "${id}" must have a "components" array.`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
const registered = { ...catalog, id: catalog.id || id };
|
|
55
|
+
ai.registry.registerValue(import_catalog.A2UI_CATALOG_VALUE_TYPE, id, registered);
|
|
56
|
+
return registered;
|
|
57
|
+
}
|
|
58
|
+
async function readCatalogFile(file) {
|
|
59
|
+
const { readFile } = await import("node:fs/promises");
|
|
60
|
+
let raw;
|
|
61
|
+
try {
|
|
62
|
+
raw = await readFile(file, "utf8");
|
|
63
|
+
} catch (e) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`loadCatalog(): failed to read catalog file "${file}": ${e.message}`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
return JSON.parse(raw);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`loadCatalog(): catalog file "${file}" is not valid JSON: ${e.message}`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function resolveCatalog(ai, id) {
|
|
77
|
+
const found = await ai.registry.lookupValue(
|
|
78
|
+
import_catalog.A2UI_CATALOG_VALUE_TYPE,
|
|
79
|
+
id
|
|
80
|
+
);
|
|
81
|
+
if (found) return found;
|
|
82
|
+
if (id === import_catalog.DEFAULT_CATALOG_ID) return import_catalog.basicCatalog;
|
|
83
|
+
throw new Error(
|
|
84
|
+
`a2ui(): no catalog registered under id "${id}". Register one with loadCatalog(ai, { id: "${id}", catalog }) or use the default "${import_catalog.DEFAULT_CATALOG_ID}" catalog.`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
88
|
+
0 && (module.exports = {
|
|
89
|
+
loadCatalog,
|
|
90
|
+
resolveCatalog
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=loader.js.map
|