opc-agent 2.0.0 → 2.0.2
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 +545 -365
- package/dist/channels/email.d.ts +32 -26
- package/dist/channels/email.js +239 -62
- package/dist/channels/feishu.d.ts +21 -6
- package/dist/channels/feishu.js +225 -126
- package/dist/channels/websocket.d.ts +46 -3
- package/dist/channels/websocket.js +306 -37
- package/dist/channels/wechat.d.ts +33 -13
- package/dist/channels/wechat.js +229 -42
- package/dist/cli.js +712 -11
- package/dist/core/a2a.d.ts +17 -0
- package/dist/core/a2a.js +43 -1
- package/dist/core/agent.d.ts +16 -0
- package/dist/core/agent.js +108 -0
- package/dist/core/runtime.d.ts +6 -0
- package/dist/core/runtime.js +161 -2
- package/dist/core/sandbox.d.ts +26 -0
- package/dist/core/sandbox.js +117 -0
- package/dist/core/workflow-graph.d.ts +93 -0
- package/dist/core/workflow-graph.js +247 -0
- package/dist/doctor.d.ts +15 -0
- package/dist/doctor.js +183 -0
- package/dist/eval/index.d.ts +65 -0
- package/dist/eval/index.js +191 -0
- package/dist/index.d.ts +32 -6
- package/dist/index.js +63 -4
- package/dist/plugins/content-filter.d.ts +7 -0
- package/dist/plugins/content-filter.js +25 -0
- package/dist/plugins/index.d.ts +42 -0
- package/dist/plugins/index.js +108 -2
- package/dist/plugins/logger.d.ts +6 -0
- package/dist/plugins/logger.js +20 -0
- package/dist/plugins/rate-limiter.d.ts +7 -0
- package/dist/plugins/rate-limiter.js +35 -0
- package/dist/protocols/a2a/client.d.ts +25 -0
- package/dist/protocols/a2a/client.js +115 -0
- package/dist/protocols/a2a/index.d.ts +6 -0
- package/dist/protocols/a2a/index.js +12 -0
- package/dist/protocols/a2a/server.d.ts +41 -0
- package/dist/protocols/a2a/server.js +295 -0
- package/dist/protocols/a2a/types.d.ts +91 -0
- package/dist/protocols/a2a/types.js +15 -0
- package/dist/protocols/a2a/utils.d.ts +6 -0
- package/dist/protocols/a2a/utils.js +47 -0
- package/dist/protocols/agui/client.d.ts +10 -0
- package/dist/protocols/agui/client.js +75 -0
- package/dist/protocols/agui/index.d.ts +4 -0
- package/dist/protocols/agui/index.js +25 -0
- package/dist/protocols/agui/server.d.ts +37 -0
- package/dist/protocols/agui/server.js +191 -0
- package/dist/protocols/agui/types.d.ts +107 -0
- package/dist/protocols/agui/types.js +17 -0
- package/dist/protocols/index.d.ts +2 -0
- package/dist/protocols/index.js +19 -0
- package/dist/protocols/mcp/agent-tools.d.ts +11 -0
- package/dist/protocols/mcp/agent-tools.js +129 -0
- package/dist/protocols/mcp/index.d.ts +5 -0
- package/dist/protocols/mcp/index.js +11 -0
- package/dist/protocols/mcp/server.d.ts +31 -0
- package/dist/protocols/mcp/server.js +248 -0
- package/dist/protocols/mcp/types.d.ts +92 -0
- package/dist/protocols/mcp/types.js +17 -0
- package/dist/publish/index.d.ts +45 -0
- package/dist/publish/index.js +350 -0
- package/dist/schema/oad.d.ts +682 -65
- package/dist/schema/oad.js +36 -3
- package/dist/security/approval.d.ts +36 -0
- package/dist/security/approval.js +113 -0
- package/dist/security/index.d.ts +4 -0
- package/dist/security/index.js +8 -0
- package/dist/security/keys.d.ts +16 -0
- package/dist/security/keys.js +117 -0
- package/dist/studio/server.d.ts +63 -0
- package/dist/studio/server.js +625 -0
- package/dist/studio-ui/index.html +662 -0
- package/dist/telemetry/index.d.ts +93 -0
- package/dist/telemetry/index.js +285 -0
- package/package.json +5 -3
- package/scripts/install.ps1 +31 -0
- package/scripts/install.sh +40 -0
- package/src/channels/email.ts +351 -177
- package/src/channels/feishu.ts +349 -236
- package/src/channels/websocket.ts +399 -87
- package/src/channels/wechat.ts +329 -149
- package/src/cli.ts +783 -12
- package/src/core/a2a.ts +60 -0
- package/src/core/agent.ts +125 -0
- package/src/core/runtime.ts +127 -0
- package/src/core/sandbox.ts +143 -0
- package/src/core/workflow-graph.ts +365 -0
- package/src/doctor.ts +156 -0
- package/src/eval/index.ts +211 -0
- package/src/eval/suites/basic.json +16 -0
- package/src/eval/suites/memory.json +12 -0
- package/src/eval/suites/safety.json +14 -0
- package/src/index.ts +58 -6
- package/src/plugins/content-filter.ts +23 -0
- package/src/plugins/index.ts +133 -2
- package/src/plugins/logger.ts +18 -0
- package/src/plugins/rate-limiter.ts +38 -0
- package/src/protocols/a2a/client.ts +132 -0
- package/src/protocols/a2a/index.ts +8 -0
- package/src/protocols/a2a/server.ts +333 -0
- package/src/protocols/a2a/types.ts +88 -0
- package/src/protocols/a2a/utils.ts +50 -0
- package/src/protocols/agui/client.ts +83 -0
- package/src/protocols/agui/index.ts +4 -0
- package/src/protocols/agui/server.ts +218 -0
- package/src/protocols/agui/types.ts +153 -0
- package/src/protocols/index.ts +2 -0
- package/src/protocols/mcp/agent-tools.ts +134 -0
- package/src/protocols/mcp/index.ts +8 -0
- package/src/protocols/mcp/server.ts +262 -0
- package/src/protocols/mcp/types.ts +69 -0
- package/src/publish/index.ts +376 -0
- package/src/schema/oad.ts +39 -2
- package/src/security/approval.ts +131 -0
- package/src/security/index.ts +3 -0
- package/src/security/keys.ts +87 -0
- package/src/studio/server.ts +629 -0
- package/src/studio-ui/index.html +662 -0
- package/src/telemetry/index.ts +324 -0
- package/src/types/agent-workstation.d.ts +2 -0
- package/tests/a2a-protocol.test.ts +285 -0
- package/tests/agui-protocol.test.ts +246 -0
- package/tests/channels/discord.test.ts +79 -0
- package/tests/channels/email.test.ts +148 -0
- package/tests/channels/feishu.test.ts +123 -0
- package/tests/channels/telegram.test.ts +129 -0
- package/tests/channels/websocket.test.ts +53 -0
- package/tests/channels/wechat.test.ts +170 -0
- package/tests/chat-cli.test.ts +160 -0
- package/tests/daemon.test.ts +135 -0
- package/tests/deepbrain-wire.test.ts +234 -0
- package/tests/doctor.test.ts +38 -0
- package/tests/eval.test.ts +173 -0
- package/tests/init-role.test.ts +124 -0
- package/tests/mcp-client.test.ts +92 -0
- package/tests/mcp-server.test.ts +178 -0
- package/tests/plugin-a2a-enhanced.test.ts +230 -0
- package/tests/publish.test.ts +231 -0
- package/tests/scheduler.test.ts +200 -0
- package/tests/security-enhanced.test.ts +233 -0
- package/tests/skill-learner.test.ts +161 -0
- package/tests/studio.test.ts +229 -0
- package/tests/subagent.test.ts +63 -0
- package/tests/telemetry.test.ts +186 -0
- package/tests/tools/builtin-extended.test.ts +138 -0
- package/tests/workflow-graph.test.ts +279 -0
- package/tutorial/customer-service-agent/README.md +612 -0
- package/tutorial/customer-service-agent/SOUL.md +26 -0
- package/tutorial/customer-service-agent/agent.yaml +63 -0
- package/tutorial/customer-service-agent/package.json +19 -0
- package/tutorial/customer-service-agent/src/index.ts +69 -0
- package/tutorial/customer-service-agent/src/skills/faq.ts +27 -0
- package/tutorial/customer-service-agent/src/skills/ticket.ts +22 -0
- package/tutorial/customer-service-agent/tsconfig.json +14 -0
package/dist/plugins/index.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.createRateLimitPlugin = createRateLimitPlugin;
|
|
|
7
7
|
const logger_1 = require("../core/logger");
|
|
8
8
|
class PluginManager {
|
|
9
9
|
plugins = new Map();
|
|
10
|
+
enhancedPlugins = new Map();
|
|
10
11
|
logger = new logger_1.Logger('plugins');
|
|
11
12
|
register(plugin) {
|
|
12
13
|
if (this.plugins.has(plugin.name)) {
|
|
@@ -15,19 +16,43 @@ class PluginManager {
|
|
|
15
16
|
this.plugins.set(plugin.name, plugin);
|
|
16
17
|
this.logger.info(`Plugin registered: ${plugin.name}@${plugin.version}`);
|
|
17
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Register an enhanced plugin with middleware support (v1.6.0).
|
|
21
|
+
*/
|
|
22
|
+
registerEnhanced(plugin) {
|
|
23
|
+
if (this.enhancedPlugins.has(plugin.name)) {
|
|
24
|
+
this.logger.warn(`Enhanced plugin "${plugin.name}" already registered, replacing`);
|
|
25
|
+
}
|
|
26
|
+
this.enhancedPlugins.set(plugin.name, plugin);
|
|
27
|
+
this.logger.info(`Enhanced plugin registered: ${plugin.name}@${plugin.version}`);
|
|
28
|
+
}
|
|
29
|
+
unregisterEnhanced(name) {
|
|
30
|
+
this.enhancedPlugins.delete(name);
|
|
31
|
+
}
|
|
32
|
+
getEnhanced(name) {
|
|
33
|
+
return this.enhancedPlugins.get(name);
|
|
34
|
+
}
|
|
35
|
+
listEnhanced() {
|
|
36
|
+
return Array.from(this.enhancedPlugins.values());
|
|
37
|
+
}
|
|
18
38
|
unregister(name) {
|
|
19
39
|
this.plugins.delete(name);
|
|
40
|
+
this.enhancedPlugins.delete(name);
|
|
20
41
|
}
|
|
21
42
|
get(name) {
|
|
22
43
|
return this.plugins.get(name);
|
|
23
44
|
}
|
|
24
45
|
list() {
|
|
25
|
-
|
|
46
|
+
const legacy = Array.from(this.plugins.values()).map(({ name, version, description }) => ({
|
|
47
|
+
name, version, description,
|
|
48
|
+
}));
|
|
49
|
+
const enhanced = Array.from(this.enhancedPlugins.values()).map(({ name, version, description }) => ({
|
|
26
50
|
name, version, description,
|
|
27
51
|
}));
|
|
52
|
+
return [...legacy, ...enhanced];
|
|
28
53
|
}
|
|
29
54
|
has(name) {
|
|
30
|
-
return this.plugins.has(name);
|
|
55
|
+
return this.plugins.has(name) || this.enhancedPlugins.has(name);
|
|
31
56
|
}
|
|
32
57
|
async runHook(hookName, ...args) {
|
|
33
58
|
for (const plugin of this.plugins.values()) {
|
|
@@ -45,6 +70,75 @@ class PluginManager {
|
|
|
45
70
|
}
|
|
46
71
|
}
|
|
47
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Initialize all plugins (legacy + enhanced).
|
|
75
|
+
*/
|
|
76
|
+
async initAll(runtime) {
|
|
77
|
+
await this.runOnInit();
|
|
78
|
+
for (const plugin of this.enhancedPlugins.values()) {
|
|
79
|
+
if (plugin.onInit) {
|
|
80
|
+
try {
|
|
81
|
+
await plugin.onInit(runtime);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
this.logger.error(`Enhanced plugin "${plugin.name}" onInit failed`, {
|
|
85
|
+
error: err instanceof Error ? err.message : String(err),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Shutdown all plugins (legacy + enhanced).
|
|
93
|
+
*/
|
|
94
|
+
async shutdownAll() {
|
|
95
|
+
await this.runOnShutdown();
|
|
96
|
+
for (const plugin of this.enhancedPlugins.values()) {
|
|
97
|
+
if (plugin.onShutdown) {
|
|
98
|
+
try {
|
|
99
|
+
await plugin.onShutdown();
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
this.logger.error(`Enhanced plugin "${plugin.name}" onShutdown failed`, {
|
|
103
|
+
error: err instanceof Error ? err.message : String(err),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Run message through enhanced plugin middleware chain.
|
|
111
|
+
* Each plugin calls next() to pass to the next plugin.
|
|
112
|
+
*/
|
|
113
|
+
async runMessageMiddleware(message) {
|
|
114
|
+
const plugins = Array.from(this.enhancedPlugins.values()).filter(p => p.onMessage);
|
|
115
|
+
if (plugins.length === 0)
|
|
116
|
+
return message;
|
|
117
|
+
let index = 0;
|
|
118
|
+
const next = async (msg) => {
|
|
119
|
+
if (index >= plugins.length)
|
|
120
|
+
return msg;
|
|
121
|
+
const plugin = plugins[index++];
|
|
122
|
+
return plugin.onMessage(msg, next);
|
|
123
|
+
};
|
|
124
|
+
return next(message);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Run response through enhanced plugin middleware chain.
|
|
128
|
+
*/
|
|
129
|
+
async runResponseMiddleware(response) {
|
|
130
|
+
const plugins = Array.from(this.enhancedPlugins.values()).filter(p => p.onResponse);
|
|
131
|
+
if (plugins.length === 0)
|
|
132
|
+
return response;
|
|
133
|
+
let index = 0;
|
|
134
|
+
const next = async (res) => {
|
|
135
|
+
if (index >= plugins.length)
|
|
136
|
+
return res;
|
|
137
|
+
const plugin = plugins[index++];
|
|
138
|
+
return plugin.onResponse(res, next);
|
|
139
|
+
};
|
|
140
|
+
return next(response);
|
|
141
|
+
}
|
|
48
142
|
async runOnInit() {
|
|
49
143
|
await this.runHook('onInit');
|
|
50
144
|
await this.runHook('beforeInit');
|
|
@@ -62,6 +156,8 @@ class PluginManager {
|
|
|
62
156
|
await plugin.hooks.beforeMessage({ content: msg.content });
|
|
63
157
|
}
|
|
64
158
|
}
|
|
159
|
+
// Also run enhanced middleware
|
|
160
|
+
msg = await this.runMessageMiddleware(msg);
|
|
65
161
|
return msg;
|
|
66
162
|
}
|
|
67
163
|
async runOnResponse(message, response) {
|
|
@@ -76,10 +172,20 @@ class PluginManager {
|
|
|
76
172
|
await plugin.hooks.afterMessage({ content: message.content }, { content: resp.content });
|
|
77
173
|
}
|
|
78
174
|
}
|
|
175
|
+
// Also run enhanced middleware
|
|
176
|
+
resp = await this.runResponseMiddleware(resp);
|
|
79
177
|
return resp;
|
|
80
178
|
}
|
|
81
179
|
async runOnError(error, context) {
|
|
82
180
|
await this.runHook('onError', error, context);
|
|
181
|
+
for (const plugin of this.enhancedPlugins.values()) {
|
|
182
|
+
if (plugin.onError) {
|
|
183
|
+
try {
|
|
184
|
+
plugin.onError(error);
|
|
185
|
+
}
|
|
186
|
+
catch (_) { /* ignore */ }
|
|
187
|
+
}
|
|
188
|
+
}
|
|
83
189
|
}
|
|
84
190
|
async runOnShutdown() {
|
|
85
191
|
await this.runHook('onShutdown');
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loggerPlugin = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Logger plugin — logs all messages and responses via middleware chain.
|
|
6
|
+
*/
|
|
7
|
+
exports.loggerPlugin = {
|
|
8
|
+
name: 'logger',
|
|
9
|
+
version: '1.0.0',
|
|
10
|
+
description: 'Log all messages and responses',
|
|
11
|
+
onMessage: async (msg, next) => {
|
|
12
|
+
console.log(`[${new Date().toISOString()}] IN: ${msg.content?.slice(0, 100)}`);
|
|
13
|
+
return next(msg);
|
|
14
|
+
},
|
|
15
|
+
onResponse: async (res, next) => {
|
|
16
|
+
console.log(`[${new Date().toISOString()}] OUT: ${res.content?.slice(0, 100)}`);
|
|
17
|
+
return next(res);
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Plugin } from './index';
|
|
2
|
+
/**
|
|
3
|
+
* Rate limiter plugin — limits messages per session using in-memory sliding window.
|
|
4
|
+
*/
|
|
5
|
+
export declare function createRateLimiterPlugin(maxPerMinute?: number): Plugin;
|
|
6
|
+
export declare const rateLimiterPlugin: Plugin;
|
|
7
|
+
//# sourceMappingURL=rate-limiter.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rateLimiterPlugin = void 0;
|
|
4
|
+
exports.createRateLimiterPlugin = createRateLimiterPlugin;
|
|
5
|
+
/**
|
|
6
|
+
* Rate limiter plugin — limits messages per session using in-memory sliding window.
|
|
7
|
+
*/
|
|
8
|
+
function createRateLimiterPlugin(maxPerMinute = 60) {
|
|
9
|
+
const sessionTimestamps = new Map();
|
|
10
|
+
return {
|
|
11
|
+
name: 'rate-limiter',
|
|
12
|
+
version: '1.0.0',
|
|
13
|
+
description: `Rate limit messages per session (${maxPerMinute}/min)`,
|
|
14
|
+
onMessage: async (msg, next) => {
|
|
15
|
+
const sessionId = msg.metadata?.sessionId || msg.id || 'default';
|
|
16
|
+
const now = Date.now();
|
|
17
|
+
const windowStart = now - 60_000;
|
|
18
|
+
if (!sessionTimestamps.has(sessionId)) {
|
|
19
|
+
sessionTimestamps.set(sessionId, []);
|
|
20
|
+
}
|
|
21
|
+
const timestamps = sessionTimestamps.get(sessionId);
|
|
22
|
+
// Remove expired timestamps
|
|
23
|
+
while (timestamps.length > 0 && timestamps[0] < windowStart) {
|
|
24
|
+
timestamps.shift();
|
|
25
|
+
}
|
|
26
|
+
if (timestamps.length >= maxPerMinute) {
|
|
27
|
+
throw new Error(`Rate limit exceeded: ${maxPerMinute} messages per minute`);
|
|
28
|
+
}
|
|
29
|
+
timestamps.push(now);
|
|
30
|
+
return next(msg);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
exports.rateLimiterPlugin = createRateLimiterPlugin(60);
|
|
35
|
+
//# sourceMappingURL=rate-limiter.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { A2AAgentCard, A2ATask, A2AMessage } from './types';
|
|
2
|
+
export declare class A2AClient {
|
|
3
|
+
private agentUrl;
|
|
4
|
+
private auth?;
|
|
5
|
+
constructor(agentUrl: string, auth?: {
|
|
6
|
+
scheme: string;
|
|
7
|
+
token: string;
|
|
8
|
+
});
|
|
9
|
+
private getHeaders;
|
|
10
|
+
private rpc;
|
|
11
|
+
getAgentCard(): Promise<A2AAgentCard>;
|
|
12
|
+
sendTask(message: A2AMessage, options?: {
|
|
13
|
+
taskId?: string;
|
|
14
|
+
sessionId?: string;
|
|
15
|
+
}): Promise<A2ATask>;
|
|
16
|
+
sendTaskSubscribe(message: A2AMessage, onEvent: (event: any) => void, options?: {
|
|
17
|
+
taskId?: string;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
getTask(taskId: string): Promise<A2ATask>;
|
|
20
|
+
cancelTask(taskId: string): Promise<A2ATask>;
|
|
21
|
+
sendText(text: string, options?: {
|
|
22
|
+
taskId?: string;
|
|
23
|
+
}): Promise<string>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.A2AClient = void 0;
|
|
4
|
+
class A2AClient {
|
|
5
|
+
agentUrl;
|
|
6
|
+
auth;
|
|
7
|
+
constructor(agentUrl, auth) {
|
|
8
|
+
this.agentUrl = agentUrl.endsWith('/') ? agentUrl.slice(0, -1) : agentUrl;
|
|
9
|
+
this.auth = auth;
|
|
10
|
+
}
|
|
11
|
+
getHeaders() {
|
|
12
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
13
|
+
if (this.auth) {
|
|
14
|
+
if (this.auth.scheme === 'bearer') {
|
|
15
|
+
headers['Authorization'] = `Bearer ${this.auth.token}`;
|
|
16
|
+
}
|
|
17
|
+
else if (this.auth.scheme === 'apiKey') {
|
|
18
|
+
headers['X-API-Key'] = this.auth.token;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return headers;
|
|
22
|
+
}
|
|
23
|
+
async rpc(method, params) {
|
|
24
|
+
const body = JSON.stringify({
|
|
25
|
+
jsonrpc: '2.0',
|
|
26
|
+
id: `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
27
|
+
method,
|
|
28
|
+
params,
|
|
29
|
+
});
|
|
30
|
+
const res = await fetch(this.agentUrl, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: this.getHeaders(),
|
|
33
|
+
body,
|
|
34
|
+
});
|
|
35
|
+
const json = await res.json();
|
|
36
|
+
if (json.error) {
|
|
37
|
+
const err = new Error(json.error.message);
|
|
38
|
+
err.code = json.error.code;
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
return json.result;
|
|
42
|
+
}
|
|
43
|
+
async getAgentCard() {
|
|
44
|
+
const res = await fetch(`${this.agentUrl}/.well-known/agent.json`, {
|
|
45
|
+
headers: this.getHeaders(),
|
|
46
|
+
});
|
|
47
|
+
if (!res.ok)
|
|
48
|
+
throw new Error(`Failed to fetch agent card: ${res.status}`);
|
|
49
|
+
return res.json();
|
|
50
|
+
}
|
|
51
|
+
async sendTask(message, options) {
|
|
52
|
+
return this.rpc('tasks/send', {
|
|
53
|
+
id: options?.taskId || `task_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
54
|
+
sessionId: options?.sessionId,
|
|
55
|
+
message,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async sendTaskSubscribe(message, onEvent, options) {
|
|
59
|
+
const body = JSON.stringify({
|
|
60
|
+
jsonrpc: '2.0',
|
|
61
|
+
id: `${Date.now()}`,
|
|
62
|
+
method: 'tasks/sendSubscribe',
|
|
63
|
+
params: {
|
|
64
|
+
id: options?.taskId || `task_${Date.now()}`,
|
|
65
|
+
message,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
const res = await fetch(this.agentUrl, {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: this.getHeaders(),
|
|
71
|
+
body,
|
|
72
|
+
});
|
|
73
|
+
if (!res.ok || !res.body)
|
|
74
|
+
throw new Error(`SSE failed: ${res.status}`);
|
|
75
|
+
const reader = res.body.getReader();
|
|
76
|
+
const decoder = new TextDecoder();
|
|
77
|
+
let buffer = '';
|
|
78
|
+
while (true) {
|
|
79
|
+
const { done, value } = await reader.read();
|
|
80
|
+
if (done)
|
|
81
|
+
break;
|
|
82
|
+
buffer += decoder.decode(value, { stream: true });
|
|
83
|
+
const lines = buffer.split('\n');
|
|
84
|
+
buffer = lines.pop() || '';
|
|
85
|
+
for (const line of lines) {
|
|
86
|
+
if (line.startsWith('data: ')) {
|
|
87
|
+
try {
|
|
88
|
+
onEvent(JSON.parse(line.slice(6)));
|
|
89
|
+
}
|
|
90
|
+
catch { /* skip malformed */ }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async getTask(taskId) {
|
|
96
|
+
return this.rpc('tasks/get', { id: taskId });
|
|
97
|
+
}
|
|
98
|
+
async cancelTask(taskId) {
|
|
99
|
+
return this.rpc('tasks/cancel', { id: taskId });
|
|
100
|
+
}
|
|
101
|
+
async sendText(text, options) {
|
|
102
|
+
const task = await this.sendTask({ role: 'user', parts: [{ type: 'text', text }] }, options);
|
|
103
|
+
// Extract text from last agent message
|
|
104
|
+
const agentMessages = task.history.filter(m => m.role === 'agent');
|
|
105
|
+
const last = agentMessages[agentMessages.length - 1];
|
|
106
|
+
if (!last)
|
|
107
|
+
return '';
|
|
108
|
+
return last.parts
|
|
109
|
+
.filter(p => p.type === 'text')
|
|
110
|
+
.map(p => p.text)
|
|
111
|
+
.join('\n');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.A2AClient = A2AClient;
|
|
115
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { A2AAgentCard, A2AAgentSkill, A2ATask, A2ATaskStatus, A2ATaskState, A2AMessage, A2AMessagePart, A2AArtifact, JsonRpcRequest, JsonRpcResponse, } from './types';
|
|
2
|
+
export { JSON_RPC_ERRORS } from './types';
|
|
3
|
+
export { A2AServer } from './server';
|
|
4
|
+
export { A2AClient } from './client';
|
|
5
|
+
export { oadToAgentCard } from './utils';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.oadToAgentCard = exports.A2AClient = exports.A2AServer = exports.JSON_RPC_ERRORS = void 0;
|
|
4
|
+
var types_1 = require("./types");
|
|
5
|
+
Object.defineProperty(exports, "JSON_RPC_ERRORS", { enumerable: true, get: function () { return types_1.JSON_RPC_ERRORS; } });
|
|
6
|
+
var server_1 = require("./server");
|
|
7
|
+
Object.defineProperty(exports, "A2AServer", { enumerable: true, get: function () { return server_1.A2AServer; } });
|
|
8
|
+
var client_1 = require("./client");
|
|
9
|
+
Object.defineProperty(exports, "A2AClient", { enumerable: true, get: function () { return client_1.A2AClient; } });
|
|
10
|
+
var utils_1 = require("./utils");
|
|
11
|
+
Object.defineProperty(exports, "oadToAgentCard", { enumerable: true, get: function () { return utils_1.oadToAgentCard; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
+
import type { A2AAgentCard, A2ATask, A2AMessage } from './types';
|
|
3
|
+
export declare class A2AServer {
|
|
4
|
+
private tasks;
|
|
5
|
+
private agent;
|
|
6
|
+
private card;
|
|
7
|
+
private server;
|
|
8
|
+
private taskHandler?;
|
|
9
|
+
constructor(agent: any, config?: {
|
|
10
|
+
card?: Partial<A2AAgentCard>;
|
|
11
|
+
oad?: any;
|
|
12
|
+
port?: number;
|
|
13
|
+
});
|
|
14
|
+
/** Set custom handler for processing tasks */
|
|
15
|
+
onTask(handler: (task: A2ATask) => Promise<A2ATask>): void;
|
|
16
|
+
getAgentCard(): A2AAgentCard;
|
|
17
|
+
getTasks(): A2ATask[];
|
|
18
|
+
/** Mount A2A routes on an existing HTTP server handler */
|
|
19
|
+
mount(handleRequest: (req: IncomingMessage, res: ServerResponse) => void): (req: IncomingMessage, res: ServerResponse) => void;
|
|
20
|
+
start(port: number): Promise<void>;
|
|
21
|
+
stop(): Promise<void>;
|
|
22
|
+
private handleHTTP;
|
|
23
|
+
private handleRPC;
|
|
24
|
+
tasksSend(params: {
|
|
25
|
+
id: string;
|
|
26
|
+
sessionId?: string;
|
|
27
|
+
message: A2AMessage;
|
|
28
|
+
metadata?: any;
|
|
29
|
+
}): Promise<A2ATask>;
|
|
30
|
+
tasksSendSubscribe(params: any, onEvent: (event: any) => void): Promise<void>;
|
|
31
|
+
tasksGet(params: {
|
|
32
|
+
id: string;
|
|
33
|
+
historyLength?: number;
|
|
34
|
+
}): Promise<A2ATask>;
|
|
35
|
+
tasksCancel(params: {
|
|
36
|
+
id: string;
|
|
37
|
+
}): Promise<A2ATask>;
|
|
38
|
+
private rpcError;
|
|
39
|
+
private readBody;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=server.d.ts.map
|