Skip to content

Commit 813533a

Browse files
authored
feat(ui): allow multiple citations in CitationMetadata (#1008)
Signed-off-by: Petr Bulánek <bulanek.petr@gmail.com>
1 parent d0bf92c commit 813533a

File tree

3 files changed

+15
-10
lines changed

3 files changed

+15
-10
lines changed

apps/beeai-ui/src/api/a2a/extensions/citation.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type { A2AExtension } from './types';
99

1010
const URI = 'https://a2a-extensions.beeai.dev/ui/citation/v1';
1111

12-
const schema = z
12+
const citationSchema = z
1313
.object({
1414
url: z.string(),
1515
start_index: z.number(),
@@ -19,8 +19,14 @@ const schema = z
1919
})
2020
.partial();
2121

22+
const schema = z.object({
23+
citations: z.array(citationSchema),
24+
});
25+
2226
export type CitationMetadata = z.infer<typeof schema>;
2327

28+
export type Citation = z.infer<typeof citationSchema>;
29+
2430
export const citationExtension: A2AExtension<typeof URI, CitationMetadata> = {
2531
getSchema: () => z.object({ [URI]: schema }).partial(),
2632
getUri: () => URI,

apps/beeai-ui/src/api/a2a/part-processors.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { v4 as uuid } from 'uuid';
88

99
import type { UIFilePart, UIMessagePart } from '#modules/messages/types.ts';
1010
import { UIMessagePartKind } from '#modules/messages/types.ts';
11+
import { isNotNull } from '#utils/helpers.ts';
1112

1213
import {
1314
createSourcePart,
@@ -20,16 +21,14 @@ import {
2021

2122
export function processMessageMetadata(message: Message): UIMessagePart[] {
2223
const trajectory = extractTrajectory(message.metadata);
23-
const citation = extractCitation(message.metadata);
24+
const citations = extractCitation(message.metadata)?.citations;
2425

2526
if (trajectory) {
2627
return [createTrajectoryPart(trajectory)];
27-
} else if (citation) {
28-
const sourcePart = createSourcePart(citation, message.taskId);
28+
} else if (citations) {
29+
const sourceParts = citations.map((citation) => createSourcePart(citation, message.taskId)).filter(isNotNull);
2930

30-
if (sourcePart) {
31-
return [sourcePart];
32-
}
31+
return [...sourceParts];
3332
}
3433

3534
return [];

apps/beeai-ui/src/api/a2a/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { UIMessagePartKind } from '#modules/messages/types.ts';
1818
import type { ContextId, TaskId } from '#modules/tasks/api/types.ts';
1919
import { isNotNull } from '#utils/helpers.ts';
2020

21-
import type { CitationMetadata } from './extensions/citation';
21+
import type { Citation } from './extensions/citation';
2222
import { citationExtension } from './extensions/citation';
2323
import type { TrajectoryMetadata } from './extensions/trajectory';
2424
import { trajectoryExtension } from './extensions/trajectory';
@@ -101,8 +101,8 @@ export function getFileUri(file: FilePart['file']): string {
101101
return `data:${mimeType};base64,${bytes}`;
102102
}
103103

104-
export function createSourcePart(metadata: CitationMetadata, messageId: string | undefined): UISourcePart | null {
105-
const { url, start_index, end_index, title, description } = metadata;
104+
export function createSourcePart(citation: Citation, messageId: string | undefined): UISourcePart | null {
105+
const { url, start_index, end_index, title, description } = citation;
106106

107107
if (!url || !messageId) {
108108
return null;

0 commit comments

Comments
 (0)