aixyz 0.22.0 → 0.23.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/app/plugins/a2a.ts +60 -23
- package/package.json +4 -4
package/app/plugins/a2a.ts
CHANGED
|
@@ -10,17 +10,31 @@ import {
|
|
|
10
10
|
} from "@a2a-js/sdk/server";
|
|
11
11
|
import { AgentCard, Message, Task, TaskArtifactUpdateEvent, TaskStatusUpdateEvent, TextPart } from "@a2a-js/sdk";
|
|
12
12
|
import type { ToolLoopAgent, ToolSet } from "ai";
|
|
13
|
+
import { z } from "zod";
|
|
13
14
|
import { getAixyzConfigRuntime } from "../../config";
|
|
14
15
|
import { BasePlugin } from "../plugin";
|
|
15
16
|
import type { AixyzApp } from "../index";
|
|
16
17
|
import { Accepts, AcceptsScheme } from "../../accepts";
|
|
17
18
|
|
|
19
|
+
export const CapabilitiesSchema = z.object({
|
|
20
|
+
streaming: z.boolean().optional(),
|
|
21
|
+
pushNotifications: z.boolean().optional(),
|
|
22
|
+
stateTransitionHistory: z.boolean().optional(),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export type Capabilities = z.infer<typeof CapabilitiesSchema>;
|
|
26
|
+
|
|
27
|
+
const DEFAULT_CAPABILITIES: Capabilities = { streaming: true, pushNotifications: false };
|
|
28
|
+
|
|
18
29
|
/**
|
|
19
30
|
* Wraps a Vercel AI SDK ToolLoopAgent into the A2A AgentExecutor interface.
|
|
20
31
|
* Streams text chunks as artifact updates and publishes task lifecycle events.
|
|
21
32
|
*/
|
|
22
33
|
export class ToolLoopAgentExecutor<TOOLS extends ToolSet = ToolSet> implements AgentExecutor {
|
|
23
|
-
constructor(
|
|
34
|
+
constructor(
|
|
35
|
+
private agent: ToolLoopAgent<never, TOOLS>,
|
|
36
|
+
private streaming = true,
|
|
37
|
+
) {}
|
|
24
38
|
|
|
25
39
|
async execute(requestContext: RequestContext, eventBus: ExecutionEventBus): Promise<void> {
|
|
26
40
|
const { taskId, contextId, userMessage, task } = requestContext;
|
|
@@ -48,25 +62,41 @@ export class ToolLoopAgentExecutor<TOOLS extends ToolSet = ToolSet> implements A
|
|
|
48
62
|
};
|
|
49
63
|
eventBus.publish(workingUpdate);
|
|
50
64
|
|
|
51
|
-
const result = await this.agent.stream({ prompt });
|
|
52
65
|
const artifactId = randomUUID();
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
|
|
67
|
+
if (this.streaming) {
|
|
68
|
+
const result = await this.agent.stream({ prompt });
|
|
69
|
+
let firstChunk = true;
|
|
70
|
+
|
|
71
|
+
for await (const chunk of result.textStream) {
|
|
72
|
+
if (chunk) {
|
|
73
|
+
const artifactUpdate: TaskArtifactUpdateEvent = {
|
|
74
|
+
kind: "artifact-update",
|
|
75
|
+
taskId,
|
|
76
|
+
contextId,
|
|
77
|
+
artifact: {
|
|
78
|
+
artifactId,
|
|
79
|
+
parts: [{ kind: "text", text: chunk }],
|
|
80
|
+
},
|
|
81
|
+
append: !firstChunk,
|
|
82
|
+
};
|
|
83
|
+
eventBus.publish(artifactUpdate);
|
|
84
|
+
firstChunk = false;
|
|
85
|
+
}
|
|
69
86
|
}
|
|
87
|
+
} else {
|
|
88
|
+
const result = await this.agent.generate({ prompt });
|
|
89
|
+
const artifactUpdate: TaskArtifactUpdateEvent = {
|
|
90
|
+
kind: "artifact-update",
|
|
91
|
+
taskId,
|
|
92
|
+
contextId,
|
|
93
|
+
artifact: {
|
|
94
|
+
artifactId,
|
|
95
|
+
parts: [{ kind: "text", text: result.text }],
|
|
96
|
+
},
|
|
97
|
+
append: false,
|
|
98
|
+
};
|
|
99
|
+
eventBus.publish(artifactUpdate);
|
|
70
100
|
}
|
|
71
101
|
|
|
72
102
|
const completedUpdate: TaskStatusUpdateEvent = {
|
|
@@ -102,7 +132,7 @@ export class ToolLoopAgentExecutor<TOOLS extends ToolSet = ToolSet> implements A
|
|
|
102
132
|
}
|
|
103
133
|
|
|
104
134
|
/** Build an A2A AgentCard from the runtime config, pointing to the given agent endpoint path. */
|
|
105
|
-
export function getAgentCard(agentPath = "/agent"): AgentCard {
|
|
135
|
+
export function getAgentCard(agentPath = "/agent", capabilities?: Capabilities): AgentCard {
|
|
106
136
|
const config = getAixyzConfigRuntime();
|
|
107
137
|
return {
|
|
108
138
|
name: config.name,
|
|
@@ -110,7 +140,7 @@ export function getAgentCard(agentPath = "/agent"): AgentCard {
|
|
|
110
140
|
protocolVersion: "0.3.0",
|
|
111
141
|
version: config.version,
|
|
112
142
|
url: new URL(agentPath, config.url).toString(),
|
|
113
|
-
capabilities: {
|
|
143
|
+
capabilities: { ...DEFAULT_CAPABILITIES, ...capabilities },
|
|
114
144
|
defaultInputModes: ["text/plain"],
|
|
115
145
|
defaultOutputModes: ["text/plain"],
|
|
116
146
|
skills: config.skills,
|
|
@@ -126,7 +156,7 @@ export class A2APlugin<TOOLS extends ToolSet = ToolSet> extends BasePlugin {
|
|
|
126
156
|
readonly name = "a2a";
|
|
127
157
|
|
|
128
158
|
constructor(
|
|
129
|
-
private exports: { default: ToolLoopAgent<never, TOOLS>; accepts?: Accepts },
|
|
159
|
+
private exports: { default: ToolLoopAgent<never, TOOLS>; accepts?: Accepts; capabilities?: Capabilities },
|
|
130
160
|
private prefix?: string,
|
|
131
161
|
private taskStore: TaskStore = new InMemoryTaskStore(),
|
|
132
162
|
) {
|
|
@@ -140,13 +170,20 @@ export class A2APlugin<TOOLS extends ToolSet = ToolSet> extends BasePlugin {
|
|
|
140
170
|
return;
|
|
141
171
|
}
|
|
142
172
|
|
|
173
|
+
const parsed = this.exports.capabilities ? CapabilitiesSchema.safeParse(this.exports.capabilities) : undefined;
|
|
174
|
+
const capabilities = parsed?.success ? { ...DEFAULT_CAPABILITIES, ...parsed.data } : DEFAULT_CAPABILITIES;
|
|
175
|
+
|
|
143
176
|
const agentPath: `/${string}` = this.prefix ? `/${this.prefix}/agent` : "/agent";
|
|
144
177
|
const wellKnownPath: `/${string}` = this.prefix
|
|
145
178
|
? `/${this.prefix}/.well-known/agent-card.json`
|
|
146
179
|
: "/.well-known/agent-card.json";
|
|
147
180
|
|
|
148
|
-
const agentExecutor = new ToolLoopAgentExecutor(this.exports.default);
|
|
149
|
-
const requestHandler = new DefaultRequestHandler(
|
|
181
|
+
const agentExecutor = new ToolLoopAgentExecutor(this.exports.default, capabilities.streaming ?? true);
|
|
182
|
+
const requestHandler = new DefaultRequestHandler(
|
|
183
|
+
getAgentCard(agentPath, capabilities),
|
|
184
|
+
this.taskStore,
|
|
185
|
+
agentExecutor,
|
|
186
|
+
);
|
|
150
187
|
const jsonRpcTransport = new JsonRpcTransportHandler(requestHandler);
|
|
151
188
|
|
|
152
189
|
// Agent card — pure web-standard handler
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aixyz",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Payment-native SDK for AI Agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@a2a-js/sdk": "^0.3.10",
|
|
39
|
-
"@aixyz/cli": "0.
|
|
40
|
-
"@aixyz/config": "0.
|
|
41
|
-
"@aixyz/erc-8004": "0.
|
|
39
|
+
"@aixyz/cli": "0.23.0",
|
|
40
|
+
"@aixyz/config": "0.23.0",
|
|
41
|
+
"@aixyz/erc-8004": "0.23.0",
|
|
42
42
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
43
43
|
"@next/env": "^16.1.6",
|
|
44
44
|
"@x402/core": "^2.3.1",
|