@perkos/perkos-a2a 0.8.12 → 0.8.14
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 +167 -1
- package/bin/agent.ts +173 -0
- package/bin/relay.ts +20 -2
- package/dist/agent.d.ts +14 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +250 -0
- package/dist/agent.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +373 -168
- package/dist/index.js.map +4 -4
- package/dist/relay-client.js +1 -1
- package/dist/relay-client.js.map +1 -1
- package/dist/relay.d.ts +3 -1
- package/dist/relay.d.ts.map +1 -1
- package/dist/relay.js +14 -1
- package/dist/relay.js.map +1 -1
- package/dist/runtime-reply.d.ts +13 -0
- package/dist/runtime-reply.d.ts.map +1 -0
- package/dist/runtime-reply.js +114 -0
- package/dist/runtime-reply.js.map +1 -0
- package/dist/server.d.ts +4 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +74 -52
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +31 -6
- package/dist/types.d.ts.map +1 -1
- package/openclaw.plugin.json +121 -18
- package/package.json +13 -9
package/dist/relay-client.js
CHANGED
|
@@ -49,7 +49,7 @@ export class RelayClient {
|
|
|
49
49
|
from: this.options.agentName,
|
|
50
50
|
payload,
|
|
51
51
|
timestamp: new Date().toISOString(),
|
|
52
|
-
}, "task_response",
|
|
52
|
+
}, "task_response", Number(process.env.A2A_RELAY_RESPONSE_WAIT_MS || 60_000));
|
|
53
53
|
}
|
|
54
54
|
/** Discover agents connected to the relay */
|
|
55
55
|
async discover() {
|
package/dist/relay-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-client.js","sourceRoot":"","sources":["../src/relay-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAcpC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAC/B,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAChC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAErC,MAAM,OAAO,WAAW;IACd,EAAE,GAAqB,IAAI,CAAC;IAC5B,OAAO,CAAqB;IAC5B,MAAM,CAA8E;IACpF,WAAW,GAAG,gBAAgB,CAAC;IAC/B,cAAc,GAAyC,IAAI,CAAC;IAC5D,cAAc,GAA0C,IAAI,CAAC;IAC7D,SAAS,GAAG,KAAK,CAAC;IAClB,OAAO,GAAG,KAAK,CAAC;IAChB,gBAAgB,GAA6C,IAAI,GAAG,EAAE,CAAC;IAE/E,YAAY,OAA2B;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;IAC9E,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;YAC5C,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,iDAAiD;IACjD,KAAK,CAAC,QAAQ,CAAC,WAAmB,EAAE,OAAgC;QAClE,OAAO,IAAI,CAAC,WAAW,CAAC;YACtB,IAAI,EAAE,MAAM;YACZ,EAAE,EAAE,WAAW;YACf,EAAE,EAAE,UAAU,EAAE;YAChB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YAC5B,OAAO;YACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"relay-client.js","sourceRoot":"","sources":["../src/relay-client.ts"],"names":[],"mappings":"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"}
|
package/dist/relay.d.ts
CHANGED
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
import type { RelayAgentEntry } from "./types.js";
|
|
11
11
|
export interface RelayHubConfig {
|
|
12
12
|
port: number;
|
|
13
|
-
/** Accepted API keys. If empty, auth is disabled. */
|
|
13
|
+
/** Accepted API keys. If empty, auth is disabled. Prefer registeredAgents in production. */
|
|
14
14
|
apiKeys: string[];
|
|
15
|
+
/** Explicitly approved agents: agentName -> registration API key. */
|
|
16
|
+
registeredAgents: Record<string, string>;
|
|
15
17
|
/** Maximum queued messages per offline agent */
|
|
16
18
|
maxQueuePerAgent: number;
|
|
17
19
|
/** Rate limit: max messages per agent per minute */
|
package/dist/relay.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAgB,eAAe,EAAa,MAAM,YAAY,CAAC;AAgB3E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,
|
|
1
|
+
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAgB,eAAe,EAAa,MAAM,YAAY,CAAC;AAgB3E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,gDAAgD;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yCAAyC;IACzC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAYD,qBAAa,QAAQ;IACnB,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,YAAY,CAA2C;IAC/D,OAAO,CAAC,UAAU,CAAkE;IACpF,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,MAAM,CAA8E;gBAG1F,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,EAChC,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;KAAE;IAMtF,KAAK,IAAI,IAAI;IAab,IAAI,IAAI,IAAI;IAeZ,WAAW,IAAI,eAAe,EAAE;IAahC,OAAO,CAAC,gBAAgB;IAuDxB,OAAO,CAAC,cAAc;IAuDtB,OAAO,CAAC,YAAY;IAqCpB,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,SAAS;CAYlB"}
|
package/dist/relay.js
CHANGED
|
@@ -12,6 +12,7 @@ import { randomUUID } from "crypto";
|
|
|
12
12
|
const DEFAULT_CONFIG = {
|
|
13
13
|
port: 6060,
|
|
14
14
|
apiKeys: [],
|
|
15
|
+
registeredAgents: {},
|
|
15
16
|
maxQueuePerAgent: 200,
|
|
16
17
|
rateLimitPerMinute: 60,
|
|
17
18
|
heartbeatIntervalMs: 30_000,
|
|
@@ -120,7 +121,15 @@ export class RelayHub {
|
|
|
120
121
|
this.sendError(ws, "missing_name", "agentName is required for registration");
|
|
121
122
|
return null;
|
|
122
123
|
}
|
|
123
|
-
|
|
124
|
+
const approvedKey = this.config.registeredAgents[name];
|
|
125
|
+
if (Object.keys(this.config.registeredAgents).length > 0) {
|
|
126
|
+
if (!approvedKey || approvedKey !== apiKey) {
|
|
127
|
+
this.sendError(ws, "not_approved", "Agent is not approved for this relay or API key does not match");
|
|
128
|
+
ws.close(4001, "Agent not approved");
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else if (this.config.apiKeys.length > 0 && !this.config.apiKeys.includes(apiKey)) {
|
|
124
133
|
this.sendError(ws, "auth_failed", "Invalid API key");
|
|
125
134
|
ws.close(4001, "Authentication failed");
|
|
126
135
|
return null;
|
|
@@ -160,6 +169,10 @@ export class RelayHub {
|
|
|
160
169
|
}
|
|
161
170
|
msg.from = fromAgent;
|
|
162
171
|
msg.timestamp = new Date().toISOString();
|
|
172
|
+
if (Object.keys(this.config.registeredAgents).length > 0 && !(target in this.config.registeredAgents)) {
|
|
173
|
+
this.sendError(this.agents.get(fromAgent).ws, "target_not_approved", `Target agent ${target} is not approved on this relay`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
163
176
|
const targetAgent = this.agents.get(target);
|
|
164
177
|
if (targetAgent && targetAgent.ws.readyState === WebSocket.OPEN) {
|
|
165
178
|
targetAgent.ws.send(JSON.stringify(msg));
|
package/dist/relay.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay.js","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"relay.js","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { A2APluginConfig, Task } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generate a final task reply through PerkOS LLM when the local runtime accepts
|
|
4
|
+
* a task but does not expose a synchronous final answer API.
|
|
5
|
+
*
|
|
6
|
+
* This keeps A2A task state machine semantics intact: delivery/wake still
|
|
7
|
+
* happens, while the A2A caller receives a terminal task with a useful artifact
|
|
8
|
+
* instead of being left in `working` indefinitely.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateRuntimeReply(config: A2APluginConfig, text: string, marker: string): Promise<string>;
|
|
11
|
+
export declare function completeTaskWithReply(task: Task, finalText: string): void;
|
|
12
|
+
export declare function isTerminalTaskState(state: unknown): boolean;
|
|
13
|
+
//# sourceMappingURL=runtime-reply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-reply.d.ts","sourceRoot":"","sources":["../src/runtime-reply.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AA8BxD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAmEjB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAczE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE3D"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { randomUUID } from "crypto";
|
|
2
|
+
function env(name) {
|
|
3
|
+
const value = process.env[name];
|
|
4
|
+
return value && value.trim() ? value.trim() : undefined;
|
|
5
|
+
}
|
|
6
|
+
function stripTaskMarker(text, marker) {
|
|
7
|
+
const trimmed = text.trim();
|
|
8
|
+
if (!trimmed.includes(marker))
|
|
9
|
+
return trimmed;
|
|
10
|
+
return trimmed.slice(trimmed.indexOf(marker) + marker.length).trim();
|
|
11
|
+
}
|
|
12
|
+
function agentIdFor(config) {
|
|
13
|
+
return env("A2A_AGENT_ID")
|
|
14
|
+
|| env("HERMES_AGENT_ID")
|
|
15
|
+
|| config.agentName
|
|
16
|
+
|| "perkos-a2a-agent";
|
|
17
|
+
}
|
|
18
|
+
function llmSystemPrompt(config) {
|
|
19
|
+
const agentName = config.agentName || config.runtime?.kind || "PerkOS A2A agent";
|
|
20
|
+
return [
|
|
21
|
+
`You are ${agentName}, a PerkOS A2A agent.`,
|
|
22
|
+
"Reply concisely and directly.",
|
|
23
|
+
"If asked to confirm receipt, confirm that you received the task via PerkOS A2A and are using PerkOS LLM.",
|
|
24
|
+
"Do not mention implementation details unless asked.",
|
|
25
|
+
].join(" ");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generate a final task reply through PerkOS LLM when the local runtime accepts
|
|
29
|
+
* a task but does not expose a synchronous final answer API.
|
|
30
|
+
*
|
|
31
|
+
* This keeps A2A task state machine semantics intact: delivery/wake still
|
|
32
|
+
* happens, while the A2A caller receives a terminal task with a useful artifact
|
|
33
|
+
* instead of being left in `working` indefinitely.
|
|
34
|
+
*/
|
|
35
|
+
export async function generateRuntimeReply(config, text, marker) {
|
|
36
|
+
const runtimeKind = config.runtime?.kind || "openclaw";
|
|
37
|
+
const apiKey = env("PERKOS_LLM_API_KEY") || env("OPENAI_API_KEY") || env("OLLAMA_API_KEY");
|
|
38
|
+
if (!apiKey) {
|
|
39
|
+
throw new Error("No PerkOS LLM API key available in environment");
|
|
40
|
+
}
|
|
41
|
+
const headers = {
|
|
42
|
+
"content-type": "application/json",
|
|
43
|
+
authorization: `Bearer ${apiKey}`,
|
|
44
|
+
"x-agent-id": agentIdFor(config),
|
|
45
|
+
};
|
|
46
|
+
const system = llmSystemPrompt(config);
|
|
47
|
+
const user = [
|
|
48
|
+
text,
|
|
49
|
+
"",
|
|
50
|
+
"Return only the useful final answer.",
|
|
51
|
+
`Do not include ${marker}; the A2A bridge will attach the marker/task result.`,
|
|
52
|
+
].join("\n");
|
|
53
|
+
if (runtimeKind === "hermes") {
|
|
54
|
+
const base = (env("OPENAI_BASE_URL") || "https://api.llm.perkos.xyz/v1").replace(/\/+$/, "");
|
|
55
|
+
const model = env("HERMES_INFERENCE_MODEL") || env("OPENAI_MODEL") || "kimi-k2.6:cloud";
|
|
56
|
+
const response = await fetch(`${base}/chat/completions`, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers,
|
|
59
|
+
body: JSON.stringify({
|
|
60
|
+
model,
|
|
61
|
+
messages: [
|
|
62
|
+
{ role: "system", content: system },
|
|
63
|
+
{ role: "user", content: user },
|
|
64
|
+
],
|
|
65
|
+
temperature: 0.2,
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
const body = await response.text().catch(() => "");
|
|
70
|
+
throw new Error(`PerkOS LLM OpenAI-compatible call failed (${response.status}): ${body || response.statusText}`);
|
|
71
|
+
}
|
|
72
|
+
const data = await response.json();
|
|
73
|
+
return stripTaskMarker(data.choices?.[0]?.message?.content || "Task completed.", marker);
|
|
74
|
+
}
|
|
75
|
+
const base = (env("OLLAMA_BASE_URL") || "https://api.llm.perkos.xyz").replace(/\/+$/, "");
|
|
76
|
+
const model = env("OLLAMA_MODEL") || "kimi-k2.6:cloud";
|
|
77
|
+
const response = await fetch(`${base}/api/chat`, {
|
|
78
|
+
method: "POST",
|
|
79
|
+
headers,
|
|
80
|
+
body: JSON.stringify({
|
|
81
|
+
model,
|
|
82
|
+
stream: false,
|
|
83
|
+
messages: [
|
|
84
|
+
{ role: "system", content: system },
|
|
85
|
+
{ role: "user", content: user },
|
|
86
|
+
],
|
|
87
|
+
}),
|
|
88
|
+
});
|
|
89
|
+
if (!response.ok) {
|
|
90
|
+
const body = await response.text().catch(() => "");
|
|
91
|
+
throw new Error(`PerkOS LLM Ollama-compatible call failed (${response.status}): ${body || response.statusText}`);
|
|
92
|
+
}
|
|
93
|
+
const data = await response.json();
|
|
94
|
+
return stripTaskMarker(data.message?.content || data.response || "Task completed.", marker);
|
|
95
|
+
}
|
|
96
|
+
export function completeTaskWithReply(task, finalText) {
|
|
97
|
+
task.artifacts.push({
|
|
98
|
+
kind: "artifact",
|
|
99
|
+
artifactId: randomUUID(),
|
|
100
|
+
parts: [{ kind: "text", text: finalText }],
|
|
101
|
+
});
|
|
102
|
+
task.status = {
|
|
103
|
+
state: "completed",
|
|
104
|
+
timestamp: new Date().toISOString(),
|
|
105
|
+
message: {
|
|
106
|
+
role: "agent",
|
|
107
|
+
parts: [{ kind: "text", text: finalText }],
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function isTerminalTaskState(state) {
|
|
112
|
+
return state === "completed" || state === "failed" || state === "canceled";
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=runtime-reply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-reply.js","sourceRoot":"","sources":["../src/runtime-reply.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Integrates with the relay hub for NAT traversal when configured.
|
|
6
6
|
*/
|
|
7
7
|
import express from "express";
|
|
8
|
-
import type { AgentCard, Task, JsonRpcResponse, A2APluginConfig
|
|
8
|
+
import type { AgentCard, Task, JsonRpcResponse, A2APluginConfig } from "./types.js";
|
|
9
9
|
export type TaskResultHandler = (task: Task, text: string) => Promise<void> | void;
|
|
10
10
|
export type TaskFailureHandler = (task: Task, errorText: string) => Promise<void> | void;
|
|
11
11
|
/** Detect if the host is behind NAT by comparing public IP to local interfaces */
|
|
@@ -47,8 +47,10 @@ export declare class A2AServer {
|
|
|
47
47
|
private handleListTasks;
|
|
48
48
|
private handleCancelTask;
|
|
49
49
|
/** Send a task to a peer agent via A2A protocol (direct HTTP or relay) */
|
|
50
|
-
sendTask(targetAgent: string, messageText: string
|
|
50
|
+
sendTask(targetAgent: string, messageText: string): Promise<JsonRpcResponse>;
|
|
51
51
|
private sendTaskDirect;
|
|
52
|
+
private waitForRemoteTaskTerminal;
|
|
53
|
+
private waitForLocalTaskTerminal;
|
|
52
54
|
private sendTaskViaRelay;
|
|
53
55
|
/** Discover all peer agents (direct + relay) */
|
|
54
56
|
discoverPeers(): Promise<Record<string, {
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,OAAO,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,OAAO,MAAM,SAAS,CAAC;AAM9B,OAAO,KAAK,EACV,SAAS,EACT,IAAI,EAEJ,eAAe,EACf,eAAe,EAGhB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACnF,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAUzF,kFAAkF;AAClF,wBAAsB,gBAAgB,IAAI,OAAO,CAAC;IAChD,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC,CA8BD;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,MAAM,CAA8E;IAC5F,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,eAAe,CAA6E;IACpG,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,kBAAkB,CAAmC;gBAG3D,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;KAAE;IAsBtF,2EAA2E;IAC3E,kBAAkB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,IAAI;IAI9F,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAI7D,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,GAAG,IAAI;IAI/D,QAAQ,IAAI,gBAAgB,CAAC,IAAI,CAAC;IAIlC,YAAY,IAAI,OAAO;IAIvB,gBAAgB,IAAI,OAAO;IAI3B,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,WAAW;YAqEL,iBAAiB;YA8BjB,WAAW;IA+EzB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,gBAAgB;IAaxB,0EAA0E;IACpE,QAAQ,CACZ,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC;YA6Bb,cAAc;YAgDd,yBAAyB;YA2BzB,wBAAwB;YAgBxB,gBAAgB;IAuB9B,gDAAgD;IAC1C,aAAa,IAAI,OAAO,CAC5B,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC,CACrD;IAsCD,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,KAAK;IAIb,oDAAoD;IACpD,OAAO,CAAC,eAAe;IA0BvB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,aAAa;IAiBf,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyD5B,OAAO,CAAC,SAAS;IA8BjB,aAAa,IAAI,OAAO,CAAC,OAAO;CAGjC"}
|
package/dist/server.js
CHANGED
|
@@ -9,6 +9,7 @@ import { randomUUID } from "crypto";
|
|
|
9
9
|
import { homedir, networkInterfaces } from "os";
|
|
10
10
|
import { RelayClient } from "./relay-client.js";
|
|
11
11
|
import { RelayHub } from "./relay.js";
|
|
12
|
+
import { isTerminalTaskState } from "./runtime-reply.js";
|
|
12
13
|
function appendArtifact(task, text) {
|
|
13
14
|
task.artifacts.push({
|
|
14
15
|
kind: "artifact",
|
|
@@ -68,7 +69,7 @@ export class A2AServer {
|
|
|
68
69
|
description: `PerkOS agent: ${config.agentName}`,
|
|
69
70
|
protocolVersion: "0.3.0",
|
|
70
71
|
version: "1.0.0",
|
|
71
|
-
url: `http://localhost:${config.port}/a2a/jsonrpc`,
|
|
72
|
+
url: `${(config.publicUrl || `http://localhost:${config.port}`).replace(/\/+$/, "")}/a2a/jsonrpc`,
|
|
72
73
|
skills: config.skills || [],
|
|
73
74
|
capabilities: { pushNotifications: false },
|
|
74
75
|
defaultInputModes: ["text"],
|
|
@@ -180,7 +181,6 @@ export class A2AServer {
|
|
|
180
181
|
const message = params.message;
|
|
181
182
|
const taskId = randomUUID();
|
|
182
183
|
const contextId = message?.contextId || randomUUID();
|
|
183
|
-
const meta = (message?.metadata || {});
|
|
184
184
|
const task = {
|
|
185
185
|
kind: "task",
|
|
186
186
|
id: taskId,
|
|
@@ -189,10 +189,7 @@ export class A2AServer {
|
|
|
189
189
|
messages: [message],
|
|
190
190
|
artifacts: [],
|
|
191
191
|
metadata: {
|
|
192
|
-
fromAgent:
|
|
193
|
-
replyToTaskId: meta.replyToTaskId,
|
|
194
|
-
conversationId: meta.conversationId || contextId,
|
|
195
|
-
kind: meta.kind || "request",
|
|
192
|
+
fromAgent: message?.metadata?.fromAgent || "unknown",
|
|
196
193
|
},
|
|
197
194
|
sessionKeyHint: "agent:main",
|
|
198
195
|
};
|
|
@@ -210,34 +207,12 @@ export class A2AServer {
|
|
|
210
207
|
.map((p) => p.text)
|
|
211
208
|
.join("\n");
|
|
212
209
|
try {
|
|
213
|
-
if (task.metadata?.kind === "response" && task.metadata?.replyToTaskId) {
|
|
214
|
-
const original = this.tasks.get(String(task.metadata.replyToTaskId));
|
|
215
|
-
if (original) {
|
|
216
|
-
appendArtifact(original, textParts || "(empty response)");
|
|
217
|
-
original.status = {
|
|
218
|
-
state: "completed",
|
|
219
|
-
timestamp: new Date().toISOString(),
|
|
220
|
-
message: {
|
|
221
|
-
role: "agent",
|
|
222
|
-
parts: [{ kind: "text", text: textParts || "(empty response)" }],
|
|
223
|
-
},
|
|
224
|
-
};
|
|
225
|
-
this.tasks.set(original.id, structuredClone(original));
|
|
226
|
-
appendArtifact(task, `Response linked to original task ${original.id}`);
|
|
227
|
-
task.status = { state: "completed", timestamp: new Date().toISOString() };
|
|
228
|
-
this.tasks.set(task.id, structuredClone(task));
|
|
229
|
-
this.logger.info(`[perkos-a2a] Response task ${task.id} linked to original task ${original.id}`);
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
210
|
// Optional session injection for observability
|
|
234
211
|
if (this.messageInjector) {
|
|
235
212
|
this.messageInjector(textParts, {
|
|
236
213
|
source: "a2a",
|
|
237
214
|
fromAgent: task.metadata?.fromAgent,
|
|
238
215
|
taskId: task.id,
|
|
239
|
-
conversationId: task.metadata?.conversationId,
|
|
240
|
-
kind: task.metadata?.kind,
|
|
241
216
|
});
|
|
242
217
|
appendArtifact(task, "Task accepted and dispatched for execution");
|
|
243
218
|
this.tasks.set(task.id, structuredClone(task));
|
|
@@ -320,12 +295,12 @@ export class A2AServer {
|
|
|
320
295
|
return this.success(rpcId, task);
|
|
321
296
|
}
|
|
322
297
|
/** Send a task to a peer agent via A2A protocol (direct HTTP or relay) */
|
|
323
|
-
async sendTask(targetAgent, messageText
|
|
298
|
+
async sendTask(targetAgent, messageText) {
|
|
324
299
|
const targetUrl = this.config.peers[targetAgent];
|
|
325
300
|
// Try direct HTTP first if peer URL is configured
|
|
326
301
|
if (targetUrl) {
|
|
327
302
|
try {
|
|
328
|
-
return await this.sendTaskDirect(targetAgent, targetUrl, messageText
|
|
303
|
+
return await this.sendTaskDirect(targetAgent, targetUrl, messageText);
|
|
329
304
|
}
|
|
330
305
|
catch (err) {
|
|
331
306
|
// If relay is available, fall through to relay
|
|
@@ -337,12 +312,12 @@ export class A2AServer {
|
|
|
337
312
|
}
|
|
338
313
|
// Try relay
|
|
339
314
|
if (this.relayClient?.isConnected()) {
|
|
340
|
-
return this.sendTaskViaRelay(targetAgent, messageText
|
|
315
|
+
return this.sendTaskViaRelay(targetAgent, messageText);
|
|
341
316
|
}
|
|
342
317
|
throw new Error(`Cannot reach ${targetAgent}: no direct URL configured and relay not connected. ` +
|
|
343
318
|
`Known peers: ${Object.keys(this.config.peers).join(", ")}`);
|
|
344
319
|
}
|
|
345
|
-
async sendTaskDirect(targetAgent, targetUrl, messageText
|
|
320
|
+
async sendTaskDirect(targetAgent, targetUrl, messageText) {
|
|
346
321
|
const headers = { "Content-Type": "application/json" };
|
|
347
322
|
// Include auth token if peer has one configured
|
|
348
323
|
const peerAuth = this.config.peerAuth?.[targetAgent];
|
|
@@ -359,12 +334,7 @@ export class A2AServer {
|
|
|
359
334
|
messageId: randomUUID(),
|
|
360
335
|
role: "user",
|
|
361
336
|
parts: [{ kind: "text", text: messageText }],
|
|
362
|
-
metadata: {
|
|
363
|
-
fromAgent: this.config.agentName,
|
|
364
|
-
conversationId: metadata?.conversationId,
|
|
365
|
-
replyToTaskId: metadata?.replyToTaskId,
|
|
366
|
-
kind: metadata?.kind || "request",
|
|
367
|
-
},
|
|
337
|
+
metadata: { fromAgent: this.config.agentName },
|
|
368
338
|
},
|
|
369
339
|
},
|
|
370
340
|
};
|
|
@@ -373,9 +343,52 @@ export class A2AServer {
|
|
|
373
343
|
headers,
|
|
374
344
|
body: JSON.stringify(payload),
|
|
375
345
|
});
|
|
376
|
-
|
|
346
|
+
const initial = (await response.json());
|
|
347
|
+
const task = initial.result;
|
|
348
|
+
if (task?.id && !isTerminalTaskState(task.status?.state)) {
|
|
349
|
+
const terminal = await this.waitForRemoteTaskTerminal(targetUrl, headers, task.id).catch((err) => {
|
|
350
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
351
|
+
this.logger.info(`[perkos-a2a] Waiting for ${targetAgent} task ${task.id} terminal state failed: ${msg}`);
|
|
352
|
+
return null;
|
|
353
|
+
});
|
|
354
|
+
if (terminal)
|
|
355
|
+
return terminal;
|
|
356
|
+
}
|
|
357
|
+
return initial;
|
|
358
|
+
}
|
|
359
|
+
async waitForRemoteTaskTerminal(targetUrl, headers, taskId, timeoutMs = Number(process.env.A2A_SEND_WAIT_MS || 45_000), pollMs = Number(process.env.A2A_SEND_POLL_MS || 1_000)) {
|
|
360
|
+
const deadline = Date.now() + timeoutMs;
|
|
361
|
+
while (Date.now() < deadline) {
|
|
362
|
+
await new Promise((resolve) => setTimeout(resolve, pollMs));
|
|
363
|
+
const response = await fetch(`${targetUrl}/a2a/jsonrpc`, {
|
|
364
|
+
method: "POST",
|
|
365
|
+
headers,
|
|
366
|
+
body: JSON.stringify({
|
|
367
|
+
jsonrpc: "2.0",
|
|
368
|
+
method: "tasks/get",
|
|
369
|
+
id: randomUUID(),
|
|
370
|
+
params: { id: taskId },
|
|
371
|
+
}),
|
|
372
|
+
});
|
|
373
|
+
const json = (await response.json());
|
|
374
|
+
const task = json.result;
|
|
375
|
+
if (task && isTerminalTaskState(task.status?.state))
|
|
376
|
+
return json;
|
|
377
|
+
}
|
|
378
|
+
return null;
|
|
377
379
|
}
|
|
378
|
-
async
|
|
380
|
+
async waitForLocalTaskTerminal(taskId, timeoutMs = Number(process.env.A2A_RELAY_WAIT_MS || 45_000), pollMs = Number(process.env.A2A_RELAY_POLL_MS || 1_000)) {
|
|
381
|
+
const deadline = Date.now() + timeoutMs;
|
|
382
|
+
while (Date.now() < deadline) {
|
|
383
|
+
const task = this.tasks.get(taskId);
|
|
384
|
+
if (task && isTerminalTaskState(task.status?.state)) {
|
|
385
|
+
return this.success(randomUUID(), structuredClone(task));
|
|
386
|
+
}
|
|
387
|
+
await new Promise((resolve) => setTimeout(resolve, pollMs));
|
|
388
|
+
}
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
async sendTaskViaRelay(targetAgent, messageText) {
|
|
379
392
|
const rpcId = randomUUID();
|
|
380
393
|
const result = await this.relayClient.sendTask(targetAgent, {
|
|
381
394
|
jsonrpc: "2.0",
|
|
@@ -387,12 +400,7 @@ export class A2AServer {
|
|
|
387
400
|
messageId: randomUUID(),
|
|
388
401
|
role: "user",
|
|
389
402
|
parts: [{ kind: "text", text: messageText }],
|
|
390
|
-
metadata: {
|
|
391
|
-
fromAgent: this.config.agentName,
|
|
392
|
-
conversationId: metadata?.conversationId,
|
|
393
|
-
replyToTaskId: metadata?.replyToTaskId,
|
|
394
|
-
kind: metadata?.kind || "request",
|
|
395
|
-
},
|
|
403
|
+
metadata: { fromAgent: this.config.agentName },
|
|
396
404
|
},
|
|
397
405
|
},
|
|
398
406
|
});
|
|
@@ -447,7 +455,19 @@ export class A2AServer {
|
|
|
447
455
|
const payload = msg.payload;
|
|
448
456
|
const params = payload.params || payload;
|
|
449
457
|
const rpcId = payload.id || msg.id;
|
|
450
|
-
this.handleSendMessage(params, rpcId).then((response) => {
|
|
458
|
+
this.handleSendMessage(params, rpcId).then(async (response) => {
|
|
459
|
+
const task = response.result;
|
|
460
|
+
if (task?.id && !isTerminalTaskState(task.status?.state)) {
|
|
461
|
+
const terminal = await this.waitForLocalTaskTerminal(task.id).catch((err) => {
|
|
462
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
463
|
+
this.logger.info(`[perkos-a2a] Waiting for relay task ${task.id} terminal state failed: ${errMsg}`);
|
|
464
|
+
return null;
|
|
465
|
+
});
|
|
466
|
+
if (terminal) {
|
|
467
|
+
this.relayClient?.sendTaskResponse(msg, terminal);
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
451
471
|
this.relayClient?.sendTaskResponse(msg, response);
|
|
452
472
|
}).catch((err) => {
|
|
453
473
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -472,8 +492,9 @@ export class A2AServer {
|
|
|
472
492
|
startRelayHub() {
|
|
473
493
|
const relayConfig = this.config.relay;
|
|
474
494
|
this.relayHub = new RelayHub({
|
|
475
|
-
port: this.config.port,
|
|
476
|
-
apiKeys: this.config.auth?.apiKeys || [],
|
|
495
|
+
port: this.config.relay?.hubPort || this.config.port,
|
|
496
|
+
apiKeys: this.config.relay?.hubApiKeys || this.config.auth?.apiKeys || [],
|
|
497
|
+
registeredAgents: this.config.relay?.registeredAgents || {},
|
|
477
498
|
maxQueuePerAgent: 200,
|
|
478
499
|
rateLimitPerMinute: 60,
|
|
479
500
|
heartbeatIntervalMs: 30_000,
|
|
@@ -529,9 +550,10 @@ export class A2AServer {
|
|
|
529
550
|
tryListen(port, attempt = 1) {
|
|
530
551
|
const maxAttempts = 3;
|
|
531
552
|
try {
|
|
532
|
-
const
|
|
533
|
-
|
|
534
|
-
this.
|
|
553
|
+
const bindHost = this.config.bindHost || "0.0.0.0";
|
|
554
|
+
const srv = this.app.listen(port, bindHost, () => {
|
|
555
|
+
this.logger.info(`[perkos-a2a] ${this.config.agentName} server on ${bindHost}:${port}`);
|
|
556
|
+
this.agentCard.url = `${(this.config.publicUrl || `http://localhost:${port}`).replace(/\/+$/, "")}/a2a/jsonrpc`;
|
|
535
557
|
});
|
|
536
558
|
srv.on("error", (err) => {
|
|
537
559
|
if (err.code === "EADDRINUSE" && attempt < maxAttempts) {
|