@assistant-ui/react-a2a 0.2.5 → 0.2.7
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/README.md +47 -1
- package/dist/A2AClient.d.ts +43 -0
- package/dist/A2AClient.d.ts.map +1 -0
- package/dist/A2AClient.js +358 -0
- package/dist/A2AClient.js.map +1 -0
- package/dist/A2AThreadRuntimeCore.d.ts +75 -0
- package/dist/A2AThreadRuntimeCore.d.ts.map +1 -0
- package/dist/A2AThreadRuntimeCore.js +483 -0
- package/dist/A2AThreadRuntimeCore.js.map +1 -0
- package/dist/conversions.d.ts +14 -0
- package/dist/conversions.d.ts.map +1 -0
- package/dist/conversions.js +92 -0
- package/dist/conversions.js.map +1 -0
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +228 -84
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -9
- package/dist/types.js.map +1 -1
- package/dist/useA2ARuntime.d.ts +35 -48
- package/dist/useA2ARuntime.d.ts.map +1 -1
- package/dist/useA2ARuntime.js +126 -172
- package/dist/useA2ARuntime.js.map +1 -1
- package/package.json +9 -9
- package/src/A2AClient.test.ts +773 -0
- package/src/A2AClient.ts +519 -0
- package/src/A2AThreadRuntimeCore.test.ts +692 -0
- package/src/A2AThreadRuntimeCore.ts +633 -0
- package/src/conversions.test.ts +276 -0
- package/src/conversions.ts +115 -0
- package/src/index.ts +66 -6
- package/src/types.ts +276 -95
- package/src/useA2ARuntime.ts +204 -296
- package/dist/A2AMessageAccumulator.d.ts +0 -16
- package/dist/A2AMessageAccumulator.d.ts.map +0 -1
- package/dist/A2AMessageAccumulator.js +0 -29
- package/dist/A2AMessageAccumulator.js.map +0 -1
- package/dist/appendA2AChunk.d.ts +0 -3
- package/dist/appendA2AChunk.d.ts.map +0 -1
- package/dist/appendA2AChunk.js +0 -110
- package/dist/appendA2AChunk.js.map +0 -1
- package/dist/convertA2AMessages.d.ts +0 -64
- package/dist/convertA2AMessages.d.ts.map +0 -1
- package/dist/convertA2AMessages.js +0 -90
- package/dist/convertA2AMessages.js.map +0 -1
- package/dist/testUtils.d.ts +0 -4
- package/dist/testUtils.d.ts.map +0 -1
- package/dist/testUtils.js +0 -6
- package/dist/testUtils.js.map +0 -1
- package/dist/useA2AMessages.d.ts +0 -25
- package/dist/useA2AMessages.d.ts.map +0 -1
- package/dist/useA2AMessages.js +0 -122
- package/dist/useA2AMessages.js.map +0 -1
- package/src/A2AMessageAccumulator.ts +0 -48
- package/src/appendA2AChunk.ts +0 -121
- package/src/convertA2AMessages.ts +0 -108
- package/src/testUtils.ts +0 -11
- package/src/useA2AMessages.ts +0 -180
package/dist/appendA2AChunk.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { parsePartialJsonObject } from "assistant-stream/utils";
|
|
2
|
-
export const appendA2AChunk = (prev, curr) => {
|
|
3
|
-
// If no previous message or different message type, return current as-is
|
|
4
|
-
if (!prev || prev.role !== curr.role || prev.id !== curr.id) {
|
|
5
|
-
return curr;
|
|
6
|
-
}
|
|
7
|
-
// For assistant messages, we need to handle streaming content and tool calls
|
|
8
|
-
if (curr.role === "assistant") {
|
|
9
|
-
const newContent = Array.isArray(prev.content)
|
|
10
|
-
? [...prev.content]
|
|
11
|
-
: typeof prev.content === "string"
|
|
12
|
-
? [{ type: "text", text: prev.content }]
|
|
13
|
-
: [];
|
|
14
|
-
// Append new content chunks
|
|
15
|
-
if (typeof curr.content === "string") {
|
|
16
|
-
const lastIndex = newContent.length - 1;
|
|
17
|
-
const lastPart = newContent[lastIndex];
|
|
18
|
-
if (lastPart?.type === "text") {
|
|
19
|
-
// Append to existing text part
|
|
20
|
-
lastPart.text += curr.content;
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
// Create new text part
|
|
24
|
-
newContent.push({ type: "text", text: curr.content });
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
else if (Array.isArray(curr.content)) {
|
|
28
|
-
for (const contentPart of curr.content) {
|
|
29
|
-
const lastIndex = newContent.length - 1;
|
|
30
|
-
const lastPart = newContent[lastIndex];
|
|
31
|
-
if (contentPart.type === "text" && lastPart?.type === "text") {
|
|
32
|
-
// Append to existing text part
|
|
33
|
-
lastPart.text += contentPart.text;
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
// Add new content part
|
|
37
|
-
newContent.push(contentPart);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
// Merge tool calls - A2A typically sends complete tool calls rather than chunks
|
|
42
|
-
const newToolCalls = [...(prev.tool_calls ?? [])];
|
|
43
|
-
if (curr.tool_calls) {
|
|
44
|
-
for (const toolCall of curr.tool_calls) {
|
|
45
|
-
const existingIndex = newToolCalls.findIndex((tc) => tc.id === toolCall.id);
|
|
46
|
-
if (existingIndex >= 0) {
|
|
47
|
-
// Update existing tool call (merge args if needed)
|
|
48
|
-
const existing = newToolCalls[existingIndex];
|
|
49
|
-
newToolCalls[existingIndex] = {
|
|
50
|
-
...existing,
|
|
51
|
-
...toolCall,
|
|
52
|
-
// If argsText is provided in chunks, concatenate it
|
|
53
|
-
argsText: (existing.argsText || "") + (toolCall.argsText || ""),
|
|
54
|
-
// Try to parse merged args, fallback to existing or new args
|
|
55
|
-
args: parsePartialJsonObject((existing.argsText || "") + (toolCall.argsText || "")) ||
|
|
56
|
-
toolCall.args ||
|
|
57
|
-
existing.args,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
// Add new tool call
|
|
62
|
-
newToolCalls.push(toolCall);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
// Merge artifacts
|
|
67
|
-
const newArtifacts = [...(prev.artifacts ?? [])];
|
|
68
|
-
if (curr.artifacts) {
|
|
69
|
-
for (const artifact of curr.artifacts) {
|
|
70
|
-
const existingIndex = newArtifacts.findIndex((a) => a.name === artifact.name);
|
|
71
|
-
if (existingIndex >= 0) {
|
|
72
|
-
// Merge artifact parts
|
|
73
|
-
const existingArtifact = newArtifacts[existingIndex];
|
|
74
|
-
newArtifacts[existingIndex] = {
|
|
75
|
-
name: existingArtifact.name,
|
|
76
|
-
parts: [...existingArtifact.parts, ...artifact.parts],
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
// Add new artifact
|
|
81
|
-
newArtifacts.push(artifact);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
const result = {
|
|
86
|
-
...prev,
|
|
87
|
-
content: newContent,
|
|
88
|
-
};
|
|
89
|
-
const newStatus = curr.status || prev.status;
|
|
90
|
-
if (newStatus)
|
|
91
|
-
result.status = newStatus;
|
|
92
|
-
if (newToolCalls.length > 0)
|
|
93
|
-
result.tool_calls = newToolCalls;
|
|
94
|
-
if (newArtifacts.length > 0)
|
|
95
|
-
result.artifacts = newArtifacts;
|
|
96
|
-
return result;
|
|
97
|
-
}
|
|
98
|
-
// For other message types (user, system, tool), just return the current message
|
|
99
|
-
// as they typically don't stream in chunks
|
|
100
|
-
const result = {
|
|
101
|
-
...prev,
|
|
102
|
-
...curr,
|
|
103
|
-
};
|
|
104
|
-
// Preserve any existing artifacts and merge with new ones
|
|
105
|
-
if (curr.artifacts || prev.artifacts) {
|
|
106
|
-
result.artifacts = [...(prev.artifacts ?? []), ...(curr.artifacts ?? [])];
|
|
107
|
-
}
|
|
108
|
-
return result;
|
|
109
|
-
};
|
|
110
|
-
//# sourceMappingURL=appendA2AChunk.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"appendA2AChunk.js","sourceRoot":"","sources":["../src/appendA2AChunk.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { A2AMessage } from "./types.js";
|
|
2
|
-
import { ToolCallMessagePart } from "@assistant-ui/react";
|
|
3
|
-
export declare const convertA2AMessage: (message: A2AMessage) => {
|
|
4
|
-
id: string | undefined;
|
|
5
|
-
role: "system";
|
|
6
|
-
content: {
|
|
7
|
-
type: "text";
|
|
8
|
-
text: string;
|
|
9
|
-
}[];
|
|
10
|
-
status?: never;
|
|
11
|
-
} | {
|
|
12
|
-
id: string | undefined;
|
|
13
|
-
role: "user";
|
|
14
|
-
content: NonNullable<import("@assistant-ui/core").ThreadUserMessagePart | null>[];
|
|
15
|
-
status?: never;
|
|
16
|
-
} | {
|
|
17
|
-
id: string | undefined;
|
|
18
|
-
role: "assistant";
|
|
19
|
-
content: (NonNullable<import("@assistant-ui/core").ThreadUserMessagePart | null> | ToolCallMessagePart)[];
|
|
20
|
-
status: import("@assistant-ui/core").MessageStatus | undefined;
|
|
21
|
-
} | {
|
|
22
|
-
id: string | undefined;
|
|
23
|
-
role: "user";
|
|
24
|
-
content: {
|
|
25
|
-
type: "tool-call";
|
|
26
|
-
toolCallId: string;
|
|
27
|
-
toolName: string;
|
|
28
|
-
result: any;
|
|
29
|
-
isError: boolean;
|
|
30
|
-
}[];
|
|
31
|
-
status?: never;
|
|
32
|
-
};
|
|
33
|
-
export declare const convertA2AMessages: (messages: A2AMessage[]) => ({
|
|
34
|
-
id: string | undefined;
|
|
35
|
-
role: "system";
|
|
36
|
-
content: {
|
|
37
|
-
type: "text";
|
|
38
|
-
text: string;
|
|
39
|
-
}[];
|
|
40
|
-
status?: never;
|
|
41
|
-
} | {
|
|
42
|
-
id: string | undefined;
|
|
43
|
-
role: "user";
|
|
44
|
-
content: NonNullable<import("@assistant-ui/core").ThreadUserMessagePart | null>[];
|
|
45
|
-
status?: never;
|
|
46
|
-
} | {
|
|
47
|
-
id: string | undefined;
|
|
48
|
-
role: "assistant";
|
|
49
|
-
content: (NonNullable<import("@assistant-ui/core").ThreadUserMessagePart | null> | ToolCallMessagePart)[];
|
|
50
|
-
status: import("@assistant-ui/core").MessageStatus | undefined;
|
|
51
|
-
} | {
|
|
52
|
-
id: string | undefined;
|
|
53
|
-
role: "user";
|
|
54
|
-
content: {
|
|
55
|
-
type: "tool-call";
|
|
56
|
-
toolCallId: string;
|
|
57
|
-
toolName: string;
|
|
58
|
-
result: any;
|
|
59
|
-
isError: boolean;
|
|
60
|
-
}[];
|
|
61
|
-
status?: never;
|
|
62
|
-
})[];
|
|
63
|
-
export declare const useA2AMessageConverter: (messages: A2AMessage[], isRunning: boolean) => import("@assistant-ui/core").ThreadMessage[];
|
|
64
|
-
//# sourceMappingURL=convertA2AMessages.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"convertA2AMessages.d.ts","sourceRoot":"","sources":["../src/convertA2AMessages.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,mBAAgB;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAkC1D,eAAO,MAAM,iBAAiB,GAAI,SAAS,UAAU;;;;;cAOe,MAAM;;;;;;;;;;;;;;;;;;;;;;;;CAiDzE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,UAAU,UAAU,EAAE;;;;;cAnDW,MAAM;;;;;;;;;;;;;;;;;;;;;;;;IAoDzC,CAAC;AAElC,eAAO,MAAM,sBAAsB,GACjC,UAAU,UAAU,EAAE,EACtB,WAAW,OAAO,iDAMhB,CAAC"}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useExternalMessageConverter } from "@assistant-ui/react";
|
|
3
|
-
const contentToParts = (content) => {
|
|
4
|
-
if (typeof content === "string")
|
|
5
|
-
return [{ type: "text", text: content }];
|
|
6
|
-
return content
|
|
7
|
-
.map((part) => {
|
|
8
|
-
const type = part.type;
|
|
9
|
-
switch (type) {
|
|
10
|
-
case "text":
|
|
11
|
-
return { type: "text", text: part.text };
|
|
12
|
-
case "image_url":
|
|
13
|
-
if (typeof part.image_url === "string") {
|
|
14
|
-
return { type: "image", image: part.image_url };
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
return {
|
|
18
|
-
type: "image",
|
|
19
|
-
image: part.image_url.url,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
case "data":
|
|
23
|
-
// Convert data parts to text representation for display
|
|
24
|
-
return {
|
|
25
|
-
type: "text",
|
|
26
|
-
text: `[Data: ${JSON.stringify(part.data)}]`,
|
|
27
|
-
};
|
|
28
|
-
default:
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
})
|
|
32
|
-
.filter((part) => part !== null);
|
|
33
|
-
};
|
|
34
|
-
export const convertA2AMessage = (message) => {
|
|
35
|
-
const role = message.role;
|
|
36
|
-
switch (role) {
|
|
37
|
-
case "system":
|
|
38
|
-
return {
|
|
39
|
-
id: message.id,
|
|
40
|
-
role: "system",
|
|
41
|
-
content: [{ type: "text", text: message.content }],
|
|
42
|
-
};
|
|
43
|
-
case "user":
|
|
44
|
-
return {
|
|
45
|
-
id: message.id,
|
|
46
|
-
role: "user",
|
|
47
|
-
content: contentToParts(message.content),
|
|
48
|
-
};
|
|
49
|
-
case "assistant": {
|
|
50
|
-
const toolCallParts = message.tool_calls?.map((toolCall) => ({
|
|
51
|
-
type: "tool-call",
|
|
52
|
-
toolCallId: toolCall.id,
|
|
53
|
-
toolName: toolCall.name,
|
|
54
|
-
args: toolCall.args,
|
|
55
|
-
argsText: toolCall.argsText ?? JSON.stringify(toolCall.args),
|
|
56
|
-
})) ?? [];
|
|
57
|
-
return {
|
|
58
|
-
id: message.id,
|
|
59
|
-
role: "assistant",
|
|
60
|
-
content: [...contentToParts(message.content), ...toolCallParts],
|
|
61
|
-
status: message.status,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
case "tool":
|
|
65
|
-
return {
|
|
66
|
-
id: message.id,
|
|
67
|
-
role: "user",
|
|
68
|
-
content: [
|
|
69
|
-
{
|
|
70
|
-
type: "tool-call",
|
|
71
|
-
toolCallId: message.tool_call_id,
|
|
72
|
-
toolName: "", // A2A doesn't store tool name in tool messages
|
|
73
|
-
result: JSON.parse(message.content),
|
|
74
|
-
isError: message.status?.type === "incomplete" &&
|
|
75
|
-
message.status?.reason === "error",
|
|
76
|
-
},
|
|
77
|
-
],
|
|
78
|
-
};
|
|
79
|
-
default:
|
|
80
|
-
const _exhaustiveCheck = role;
|
|
81
|
-
throw new Error(`Unknown message role: ${_exhaustiveCheck}`);
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
export const convertA2AMessages = (messages) => messages.map(convertA2AMessage);
|
|
85
|
-
export const useA2AMessageConverter = (messages, isRunning) => useExternalMessageConverter({
|
|
86
|
-
callback: convertA2AMessage,
|
|
87
|
-
messages,
|
|
88
|
-
isRunning,
|
|
89
|
-
});
|
|
90
|
-
//# sourceMappingURL=convertA2AMessages.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"convertA2AMessages.js","sourceRoot":"","sources":["../src/convertA2AMessages.ts"],"names":[],"mappings":"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"}
|
package/dist/testUtils.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { A2AMessage } from "./types.js";
|
|
2
|
-
import { A2AMessagesEvent } from "./useA2AMessages.js";
|
|
3
|
-
export declare const mockStreamCallbackFactory: (events: Array<A2AMessagesEvent<A2AMessage>>) => () => AsyncGenerator<import("./types").A2AEvent, void, unknown>;
|
|
4
|
-
//# sourceMappingURL=testUtils.d.ts.map
|
package/dist/testUtils.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,mBAAgB;AACrC,OAAO,EAAE,gBAAgB,EAAE,4BAAyB;AAEpD,eAAO,MAAM,yBAAyB,GACpC,QAAQ,KAAK,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,oEAM1C,CAAC"}
|
package/dist/testUtils.js
DELETED
package/dist/testUtils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"testUtils.js","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,MAA2C,EAC3C,EAAE,CACF,KAAK,SAAS,CAAC;IACb,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
|
package/dist/useA2AMessages.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { A2AEvent, A2ATaskState, A2AArtifact, A2ASendMessageConfig, A2AStreamCallback, OnTaskUpdateEventCallback, OnArtifactsEventCallback, OnErrorEventCallback, OnStateUpdateEventCallback, OnCustomEventCallback } from "./types.js";
|
|
2
|
-
export type A2AMessagesEvent<_TMessage> = A2AEvent;
|
|
3
|
-
export declare const useA2AMessages: <TMessage extends {
|
|
4
|
-
id?: string;
|
|
5
|
-
}>({ stream, appendMessage, eventHandlers, }: {
|
|
6
|
-
stream: A2AStreamCallback<TMessage>;
|
|
7
|
-
appendMessage?: (prev: TMessage | undefined, curr: TMessage) => TMessage;
|
|
8
|
-
eventHandlers?: {
|
|
9
|
-
onTaskUpdate?: OnTaskUpdateEventCallback;
|
|
10
|
-
onArtifacts?: OnArtifactsEventCallback;
|
|
11
|
-
onError?: OnErrorEventCallback;
|
|
12
|
-
onStateUpdate?: OnStateUpdateEventCallback;
|
|
13
|
-
onCustomEvent?: OnCustomEventCallback;
|
|
14
|
-
};
|
|
15
|
-
}) => {
|
|
16
|
-
messages: TMessage[];
|
|
17
|
-
artifacts: A2AArtifact[];
|
|
18
|
-
taskState: A2ATaskState | undefined;
|
|
19
|
-
sendMessage: (newMessages: TMessage[], config: A2ASendMessageConfig) => Promise<void>;
|
|
20
|
-
cancel: () => void;
|
|
21
|
-
setMessages: import("react").Dispatch<import("react").SetStateAction<TMessage[]>>;
|
|
22
|
-
setArtifacts: import("react").Dispatch<import("react").SetStateAction<A2AArtifact[]>>;
|
|
23
|
-
setTaskState: import("react").Dispatch<import("react").SetStateAction<A2ATaskState | undefined>>;
|
|
24
|
-
};
|
|
25
|
-
//# sourceMappingURL=useA2AMessages.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useA2AMessages.d.ts","sourceRoot":"","sources":["../src/useA2AMessages.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,QAAQ,EAER,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,EACtB,mBAAgB;AAEjB,MAAM,MAAM,gBAAgB,CAAC,SAAS,IAAI,QAAQ,CAAC;AAOnD,eAAO,MAAM,cAAc,GAAI,QAAQ,SAAS;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,2CAI9D;IACD,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACpC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE,IAAI,EAAE,QAAQ,KAAK,QAAQ,CAAC;IACzE,aAAa,CAAC,EAAE;QACd,YAAY,CAAC,EAAE,yBAAyB,CAAC;QACzC,WAAW,CAAC,EAAE,wBAAwB,CAAC;QACvC,OAAO,CAAC,EAAE,oBAAoB,CAAC;QAC/B,aAAa,CAAC,EAAE,0BAA0B,CAAC;QAC3C,aAAa,CAAC,EAAE,qBAAqB,CAAC;KACvC,CAAC;CACH;;;;+BAUuB,QAAQ,EAAE,UAAU,oBAAoB;;;;;CAmI/D,CAAC"}
|
package/dist/useA2AMessages.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { useState, useCallback, useRef, useMemo } from "react";
|
|
2
|
-
import { v4 as uuidv4 } from "uuid";
|
|
3
|
-
import { A2AMessageAccumulator } from "./A2AMessageAccumulator.js";
|
|
4
|
-
import { A2AKnownEventTypes, } from "./types.js";
|
|
5
|
-
const DEFAULT_APPEND_MESSAGE = (_, curr) => curr;
|
|
6
|
-
export const useA2AMessages = ({ stream, appendMessage = DEFAULT_APPEND_MESSAGE, eventHandlers, }) => {
|
|
7
|
-
const [messages, setMessages] = useState([]);
|
|
8
|
-
const [taskState, setTaskState] = useState();
|
|
9
|
-
const [artifacts, setArtifacts] = useState([]);
|
|
10
|
-
const abortControllerRef = useRef(null);
|
|
11
|
-
const { onTaskUpdate, onArtifacts, onError, onStateUpdate, onCustomEvent } = useMemo(() => eventHandlers ?? {}, [eventHandlers]);
|
|
12
|
-
const sendMessage = useCallback(async (newMessages, config) => {
|
|
13
|
-
// ensure all messages have an ID
|
|
14
|
-
const newMessagesWithId = newMessages.map((m) => m.id ? m : { ...m, id: uuidv4() });
|
|
15
|
-
const accumulator = new A2AMessageAccumulator({
|
|
16
|
-
initialMessages: messages,
|
|
17
|
-
appendMessage,
|
|
18
|
-
});
|
|
19
|
-
setMessages(accumulator.addMessages(newMessagesWithId));
|
|
20
|
-
const abortController = new AbortController();
|
|
21
|
-
abortControllerRef.current = abortController;
|
|
22
|
-
const response = await stream(newMessagesWithId, {
|
|
23
|
-
...config,
|
|
24
|
-
abortSignal: abortController.signal,
|
|
25
|
-
});
|
|
26
|
-
for await (const event of response) {
|
|
27
|
-
switch (event.event) {
|
|
28
|
-
case A2AKnownEventTypes.TaskUpdate:
|
|
29
|
-
const taskData = event.data;
|
|
30
|
-
setTaskState(taskData);
|
|
31
|
-
onTaskUpdate?.(taskData);
|
|
32
|
-
break;
|
|
33
|
-
case A2AKnownEventTypes.TaskComplete:
|
|
34
|
-
// Extract messages and artifacts from completed task
|
|
35
|
-
const { messages: taskMessages, artifacts: taskArtifacts } = event.data;
|
|
36
|
-
if (taskMessages) {
|
|
37
|
-
setMessages(accumulator.addMessages(taskMessages));
|
|
38
|
-
}
|
|
39
|
-
if (taskArtifacts) {
|
|
40
|
-
setArtifacts(taskArtifacts);
|
|
41
|
-
onArtifacts?.(taskArtifacts);
|
|
42
|
-
}
|
|
43
|
-
// Clear task state on completion
|
|
44
|
-
setTaskState(undefined);
|
|
45
|
-
break;
|
|
46
|
-
case A2AKnownEventTypes.TaskFailed:
|
|
47
|
-
onError?.(event.data);
|
|
48
|
-
// Update task state to failed
|
|
49
|
-
if (taskState) {
|
|
50
|
-
setTaskState({
|
|
51
|
-
...taskState,
|
|
52
|
-
state: "failed",
|
|
53
|
-
message: event.data?.message,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
break;
|
|
57
|
-
case A2AKnownEventTypes.Artifacts:
|
|
58
|
-
const artifactData = event.data;
|
|
59
|
-
setArtifacts(artifactData);
|
|
60
|
-
onArtifacts?.(artifactData);
|
|
61
|
-
break;
|
|
62
|
-
case A2AKnownEventTypes.StateUpdate:
|
|
63
|
-
onStateUpdate?.(event.data);
|
|
64
|
-
break;
|
|
65
|
-
case A2AKnownEventTypes.Error:
|
|
66
|
-
onError?.(event.data);
|
|
67
|
-
// Update the last assistant message with error status if available
|
|
68
|
-
const messages = accumulator.getMessages();
|
|
69
|
-
const lastAssistantMessage = messages.findLast((m) => m != null &&
|
|
70
|
-
"role" in m &&
|
|
71
|
-
m.role === "assistant" &&
|
|
72
|
-
m.id != null);
|
|
73
|
-
if (lastAssistantMessage) {
|
|
74
|
-
const errorMessage = {
|
|
75
|
-
...lastAssistantMessage,
|
|
76
|
-
status: {
|
|
77
|
-
type: "incomplete",
|
|
78
|
-
reason: "error",
|
|
79
|
-
error: event.data,
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
setMessages(accumulator.addMessages([errorMessage]));
|
|
83
|
-
}
|
|
84
|
-
break;
|
|
85
|
-
default:
|
|
86
|
-
if (onCustomEvent) {
|
|
87
|
-
onCustomEvent(event.event, event.data);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
console.warn("Unhandled A2A event received:", event.event, event.data);
|
|
91
|
-
}
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}, [
|
|
96
|
-
messages,
|
|
97
|
-
appendMessage,
|
|
98
|
-
stream,
|
|
99
|
-
onTaskUpdate,
|
|
100
|
-
onArtifacts,
|
|
101
|
-
onError,
|
|
102
|
-
onStateUpdate,
|
|
103
|
-
onCustomEvent,
|
|
104
|
-
taskState,
|
|
105
|
-
]);
|
|
106
|
-
const cancel = useCallback(() => {
|
|
107
|
-
if (abortControllerRef.current) {
|
|
108
|
-
abortControllerRef.current.abort();
|
|
109
|
-
}
|
|
110
|
-
}, []);
|
|
111
|
-
return {
|
|
112
|
-
messages,
|
|
113
|
-
artifacts,
|
|
114
|
-
taskState,
|
|
115
|
-
sendMessage,
|
|
116
|
-
cancel,
|
|
117
|
-
setMessages,
|
|
118
|
-
setArtifacts,
|
|
119
|
-
setTaskState,
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
//# sourceMappingURL=useA2AMessages.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useA2AMessages.js","sourceRoot":"","sources":["../src/useA2AMessages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC/D,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,mCAAgC;AAChE,OAAO,EAEL,kBAAkB,GAUnB,mBAAgB;AAIjB,MAAM,sBAAsB,GAAG,CAC7B,CAAuB,EACvB,IAAc,EACd,EAAE,CAAC,IAAI,CAAC;AAEV,MAAM,CAAC,MAAM,cAAc,GAAG,CAAmC,EAC/D,MAAM,EACN,aAAa,GAAG,sBAAsB,EACtC,aAAa,GAWd,EAAE,EAAE;IACH,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAa,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,EAA4B,CAAC;IACvE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAgB,EAAE,CAAC,CAAC;IAC9D,MAAM,kBAAkB,GAAG,MAAM,CAAyB,IAAI,CAAC,CAAC;IAEhE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,GACxE,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEtD,MAAM,WAAW,GAAG,WAAW,CAC7B,KAAK,EAAE,WAAuB,EAAE,MAA4B,EAAE,EAAE;QAC9D,iCAAiC;QACjC,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,CAClC,CAAC;QAEF,MAAM,WAAW,GAAG,IAAI,qBAAqB,CAAC;YAC5C,eAAe,EAAE,QAAQ;YACzB,aAAa;SACd,CAAC,CAAC;QACH,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAExD,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAC9C,kBAAkB,CAAC,OAAO,GAAG,eAAe,CAAC;QAC7C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,iBAAiB,EAAE;YAC/C,GAAG,MAAM;YACT,WAAW,EAAE,eAAe,CAAC,MAAM;SACpC,CAAC,CAAC;QAEH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YACnC,QAAQ,KAAK,CAAC,KAAK,EAAE,CAAC;gBACpB,KAAK,kBAAkB,CAAC,UAAU;oBAChC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAoB,CAAC;oBAC5C,YAAY,CAAC,QAAQ,CAAC,CAAC;oBACvB,YAAY,EAAE,CAAC,QAAQ,CAAC,CAAC;oBACzB,MAAM;gBAER,KAAK,kBAAkB,CAAC,YAAY;oBAClC,qDAAqD;oBACrD,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,GACxD,KAAK,CAAC,IAAI,CAAC;oBACb,IAAI,YAAY,EAAE,CAAC;wBACjB,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC;oBACrD,CAAC;oBACD,IAAI,aAAa,EAAE,CAAC;wBAClB,YAAY,CAAC,aAAa,CAAC,CAAC;wBAC5B,WAAW,EAAE,CAAC,aAAa,CAAC,CAAC;oBAC/B,CAAC;oBACD,iCAAiC;oBACjC,YAAY,CAAC,SAAS,CAAC,CAAC;oBACxB,MAAM;gBAER,KAAK,kBAAkB,CAAC,UAAU;oBAChC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACtB,8BAA8B;oBAC9B,IAAI,SAAS,EAAE,CAAC;wBACd,YAAY,CAAC;4BACX,GAAG,SAAS;4BACZ,KAAK,EAAE,QAAQ;4BACf,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO;yBAC7B,CAAC,CAAC;oBACL,CAAC;oBACD,MAAM;gBAER,KAAK,kBAAkB,CAAC,SAAS;oBAC/B,MAAM,YAAY,GAAG,KAAK,CAAC,IAAqB,CAAC;oBACjD,YAAY,CAAC,YAAY,CAAC,CAAC;oBAC3B,WAAW,EAAE,CAAC,YAAY,CAAC,CAAC;oBAC5B,MAAM;gBAER,KAAK,kBAAkB,CAAC,WAAW;oBACjC,aAAa,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC5B,MAAM;gBAER,KAAK,kBAAkB,CAAC,KAAK;oBAC3B,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACtB,mEAAmE;oBACnE,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;oBAC3C,MAAM,oBAAoB,GAAG,QAAQ,CAAC,QAAQ,CAC5C,CAAC,CAAC,EAAgD,EAAE,CAClD,CAAC,IAAI,IAAI;wBACT,MAAM,IAAI,CAAC;wBACX,CAAC,CAAC,IAAI,KAAK,WAAW;wBACtB,CAAC,CAAC,EAAE,IAAI,IAAI,CACf,CAAC;oBACF,IAAI,oBAAoB,EAAE,CAAC;wBACzB,MAAM,YAAY,GAAG;4BACnB,GAAG,oBAAoB;4BACvB,MAAM,EAAE;gCACN,IAAI,EAAE,YAAqB;gCAC3B,MAAM,EAAE,OAAgB;gCACxB,KAAK,EAAE,KAAK,CAAC,IAAI;6BAClB;yBACF,CAAC;wBACF,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBACvD,CAAC;oBACD,MAAM;gBAER;oBACE,IAAI,aAAa,EAAE,CAAC;wBAClB,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBACzC,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,IAAI,CACV,+BAA+B,EAC/B,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,IAAI,CACX,CAAC;oBACJ,CAAC;oBACD,MAAM;YACV,CAAC;QACH,CAAC;IACH,CAAC,EACD;QACE,QAAQ;QACR,aAAa;QACb,MAAM;QACN,YAAY;QACZ,WAAW;QACX,OAAO;QACP,aAAa;QACb,aAAa;QACb,SAAS;KACV,CACF,CAAC;IAEF,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9B,IAAI,kBAAkB,CAAC,OAAO,EAAE,CAAC;YAC/B,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrC,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,QAAQ;QACR,SAAS;QACT,SAAS;QACT,WAAW;QACX,MAAM;QACN,WAAW;QACX,YAAY;QACZ,YAAY;KACb,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from "uuid";
|
|
2
|
-
|
|
3
|
-
export type A2AStateAccumulatorConfig<TMessage> = {
|
|
4
|
-
initialMessages?: TMessage[];
|
|
5
|
-
appendMessage?: (prev: TMessage | undefined, curr: TMessage) => TMessage;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export class A2AMessageAccumulator<TMessage extends { id?: string }> {
|
|
9
|
-
private messagesMap = new Map<string, TMessage>();
|
|
10
|
-
private appendMessage: (
|
|
11
|
-
prev: TMessage | undefined,
|
|
12
|
-
curr: TMessage,
|
|
13
|
-
) => TMessage;
|
|
14
|
-
|
|
15
|
-
constructor({
|
|
16
|
-
initialMessages = [],
|
|
17
|
-
appendMessage = ((_: TMessage | undefined, curr: TMessage) => curr) as (
|
|
18
|
-
prev: TMessage | undefined,
|
|
19
|
-
curr: TMessage,
|
|
20
|
-
) => TMessage,
|
|
21
|
-
}: A2AStateAccumulatorConfig<TMessage> = {}) {
|
|
22
|
-
this.appendMessage = appendMessage;
|
|
23
|
-
this.addMessages(initialMessages);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
private ensureMessageId(message: TMessage): TMessage {
|
|
27
|
-
return message.id ? message : { ...message, id: uuidv4() };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public addMessages(newMessages: TMessage[]) {
|
|
31
|
-
if (newMessages.length === 0) return this.getMessages();
|
|
32
|
-
|
|
33
|
-
for (const message of newMessages.map(this.ensureMessageId)) {
|
|
34
|
-
const messageId = message.id!; // ensureMessageId guarantees id exists
|
|
35
|
-
const previous = this.messagesMap.get(messageId);
|
|
36
|
-
this.messagesMap.set(messageId, this.appendMessage(previous, message));
|
|
37
|
-
}
|
|
38
|
-
return this.getMessages();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public getMessages(): TMessage[] {
|
|
42
|
-
return [...this.messagesMap.values()];
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
public clear() {
|
|
46
|
-
this.messagesMap.clear();
|
|
47
|
-
}
|
|
48
|
-
}
|
package/src/appendA2AChunk.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import { A2AMessage } from "./types";
|
|
2
|
-
import { parsePartialJsonObject } from "assistant-stream/utils";
|
|
3
|
-
|
|
4
|
-
export const appendA2AChunk = (
|
|
5
|
-
prev: A2AMessage | undefined,
|
|
6
|
-
curr: A2AMessage,
|
|
7
|
-
): A2AMessage => {
|
|
8
|
-
// If no previous message or different message type, return current as-is
|
|
9
|
-
if (!prev || prev.role !== curr.role || prev.id !== curr.id) {
|
|
10
|
-
return curr;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// For assistant messages, we need to handle streaming content and tool calls
|
|
14
|
-
if (curr.role === "assistant") {
|
|
15
|
-
const newContent = Array.isArray(prev.content)
|
|
16
|
-
? [...prev.content]
|
|
17
|
-
: typeof prev.content === "string"
|
|
18
|
-
? [{ type: "text" as const, text: prev.content }]
|
|
19
|
-
: [];
|
|
20
|
-
|
|
21
|
-
// Append new content chunks
|
|
22
|
-
if (typeof curr.content === "string") {
|
|
23
|
-
const lastIndex = newContent.length - 1;
|
|
24
|
-
const lastPart = newContent[lastIndex];
|
|
25
|
-
|
|
26
|
-
if (lastPart?.type === "text") {
|
|
27
|
-
// Append to existing text part
|
|
28
|
-
(lastPart as { type: "text"; text: string }).text += curr.content;
|
|
29
|
-
} else {
|
|
30
|
-
// Create new text part
|
|
31
|
-
newContent.push({ type: "text", text: curr.content });
|
|
32
|
-
}
|
|
33
|
-
} else if (Array.isArray(curr.content)) {
|
|
34
|
-
for (const contentPart of curr.content) {
|
|
35
|
-
const lastIndex = newContent.length - 1;
|
|
36
|
-
const lastPart = newContent[lastIndex];
|
|
37
|
-
|
|
38
|
-
if (contentPart.type === "text" && lastPart?.type === "text") {
|
|
39
|
-
// Append to existing text part
|
|
40
|
-
(lastPart as { type: "text"; text: string }).text += contentPart.text;
|
|
41
|
-
} else {
|
|
42
|
-
// Add new content part
|
|
43
|
-
newContent.push(contentPart);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Merge tool calls - A2A typically sends complete tool calls rather than chunks
|
|
49
|
-
const newToolCalls = [...(prev.tool_calls ?? [])];
|
|
50
|
-
if (curr.tool_calls) {
|
|
51
|
-
for (const toolCall of curr.tool_calls) {
|
|
52
|
-
const existingIndex = newToolCalls.findIndex(
|
|
53
|
-
(tc) => tc.id === toolCall.id,
|
|
54
|
-
);
|
|
55
|
-
if (existingIndex >= 0) {
|
|
56
|
-
// Update existing tool call (merge args if needed)
|
|
57
|
-
const existing = newToolCalls[existingIndex]!;
|
|
58
|
-
newToolCalls[existingIndex] = {
|
|
59
|
-
...existing,
|
|
60
|
-
...toolCall,
|
|
61
|
-
// If argsText is provided in chunks, concatenate it
|
|
62
|
-
argsText: (existing.argsText || "") + (toolCall.argsText || ""),
|
|
63
|
-
// Try to parse merged args, fallback to existing or new args
|
|
64
|
-
args:
|
|
65
|
-
parsePartialJsonObject(
|
|
66
|
-
(existing.argsText || "") + (toolCall.argsText || ""),
|
|
67
|
-
) ||
|
|
68
|
-
toolCall.args ||
|
|
69
|
-
existing.args,
|
|
70
|
-
};
|
|
71
|
-
} else {
|
|
72
|
-
// Add new tool call
|
|
73
|
-
newToolCalls.push(toolCall);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Merge artifacts
|
|
79
|
-
const newArtifacts = [...(prev.artifacts ?? [])];
|
|
80
|
-
if (curr.artifacts) {
|
|
81
|
-
for (const artifact of curr.artifacts) {
|
|
82
|
-
const existingIndex = newArtifacts.findIndex(
|
|
83
|
-
(a) => a.name === artifact.name,
|
|
84
|
-
);
|
|
85
|
-
if (existingIndex >= 0) {
|
|
86
|
-
// Merge artifact parts
|
|
87
|
-
const existingArtifact = newArtifacts[existingIndex]!;
|
|
88
|
-
newArtifacts[existingIndex] = {
|
|
89
|
-
name: existingArtifact.name,
|
|
90
|
-
parts: [...existingArtifact.parts, ...artifact.parts],
|
|
91
|
-
};
|
|
92
|
-
} else {
|
|
93
|
-
// Add new artifact
|
|
94
|
-
newArtifacts.push(artifact);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const result: A2AMessage = {
|
|
100
|
-
...prev,
|
|
101
|
-
content: newContent,
|
|
102
|
-
};
|
|
103
|
-
const newStatus = curr.status || prev.status;
|
|
104
|
-
if (newStatus) result.status = newStatus;
|
|
105
|
-
if (newToolCalls.length > 0) result.tool_calls = newToolCalls;
|
|
106
|
-
if (newArtifacts.length > 0) result.artifacts = newArtifacts;
|
|
107
|
-
return result;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// For other message types (user, system, tool), just return the current message
|
|
111
|
-
// as they typically don't stream in chunks
|
|
112
|
-
const result: A2AMessage = {
|
|
113
|
-
...prev,
|
|
114
|
-
...curr,
|
|
115
|
-
};
|
|
116
|
-
// Preserve any existing artifacts and merge with new ones
|
|
117
|
-
if (curr.artifacts || prev.artifacts) {
|
|
118
|
-
result.artifacts = [...(prev.artifacts ?? []), ...(curr.artifacts ?? [])];
|
|
119
|
-
}
|
|
120
|
-
return result;
|
|
121
|
-
};
|