@botbotgo/agent-harness 0.0.270 → 0.0.272
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 +2 -1
- package/README.zh.md +2 -1
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/protocol/a2a/http.d.ts +20 -0
- package/dist/protocol/a2a/http.js +94 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1059,8 +1059,9 @@ ACP transport notes:
|
|
|
1059
1059
|
- `serveAcpStdio(runtime)` exposes newline-delimited JSON-RPC over stdio for local IDE, CLI, or subprocess clients.
|
|
1060
1060
|
- `serveAcpHttp(runtime)` exposes JSON-RPC over HTTP plus SSE runtime events so remote operator surfaces can connect without importing the runtime in-process.
|
|
1061
1061
|
- ACP transport validation now covers the reference-client core flow: capability discovery, request submit, session lookup, request lookup, invalid-JSON handling, notification calls without response ids, stdio JSON-RPC, and HTTP plus SSE runtime notifications.
|
|
1062
|
+
- Cross-protocol conformance now has an explicit regression gate as well: ACP submission, A2A task lookup and continuation, and runtime MCP inspection must all project the same persisted `sessionId` / `requestId` runtime records instead of drifting into surface-specific identifiers or side stores.
|
|
1062
1063
|
- For the thinnest editor or CLI starter, begin with `agent-harness acp serve --workspace . --transport stdio` and mirror the `examples/protocol-hello-world/app/acp-stdio-hello-world.mjs` wire shape. Applications that want an in-process reference client can use `createAcpStdioClient(...)` to issue JSON-RPC requests and route runtime notifications without hand-rolling line parsing.
|
|
1063
|
-
- `serveA2aHttp(runtime)` exposes an A2A-compatible HTTP JSON-RPC bridge plus agent card discovery, mapping both existing methods such as `message/send` and A2A v1.0 PascalCase methods such as `SendMessage`, `SendStreamingMessage`, `GetTask`, `ListTasks`, `CancelTask`, `SubscribeToTask`, `GetAgentCard`, `GetExtendedAgentCard`, and task push-notification config methods onto the existing session/request runtime surface. The bridge now advertises both `1.0` and `0.3` JSON-RPC interfaces, answers `HEAD` / `OPTIONS` discovery on the agent-card path, sets supported-version discovery headers, validates `A2A-Version`, records `A2A-Extensions` into runtime invocation metadata, publishes `TASK_STATE_*` statuses plus the `{ task }` `SendMessage` wrapper, streams an initial `{ task }` snapshot plus later `{ statusUpdate }` payloads over SSE for v1 streaming methods, and can send best-effort webhook task snapshots for configured push notification receivers.
|
|
1064
|
+
- `serveA2aHttp(runtime)` exposes an A2A-compatible HTTP JSON-RPC bridge plus agent card discovery, mapping both existing methods such as `message/send` and A2A v1.0 PascalCase methods such as `SendMessage`, `SendStreamingMessage`, `GetTask`, `ListTasks`, `CancelTask`, `SubscribeToTask`, `GetAgentCard`, `GetExtendedAgentCard`, and task push-notification config methods onto the existing session/request runtime surface. The bridge now advertises both `1.0` and `0.3` JSON-RPC interfaces, answers `HEAD` / `OPTIONS` discovery on the agent-card path, sets supported-version discovery headers, can optionally expose registry URLs plus detached signed-card metadata for surrounding discovery systems, validates `A2A-Version`, records `A2A-Extensions` into runtime invocation metadata, publishes `TASK_STATE_*` statuses plus the `{ task }` `SendMessage` wrapper, streams an initial `{ task }` snapshot plus later `{ statusUpdate }` payloads over SSE for v1 streaming methods, and can send best-effort webhook task snapshots for configured push notification receivers.
|
|
1064
1065
|
- `serveAgUiHttp(runtime)` exposes an AG-UI-compatible HTTP SSE bridge that projects runtime lifecycle, text output, upstream thinking, step progress, and tool calls onto `RUN_*`, `TEXT_MESSAGE_*`, `THINKING_TEXT_MESSAGE_*`, `STEP_*`, and `TOOL_CALL_*` events for UI clients.
|
|
1065
1066
|
- `createRuntimeMcpServer(runtime)` and `serveRuntimeMcpOverStdio(runtime)` expose the persisted runtime control surface itself as MCP tools, including sessions, requests, approvals, artifacts, events, and package export helpers.
|
|
1066
1067
|
- `listRequestEvents(...)`, `listRequestTraceItems(...)`, and `exportRequestPackage(...)` are the request-first inspection helpers.
|
package/README.zh.md
CHANGED
|
@@ -1016,8 +1016,9 @@ ACP transport 说明:
|
|
|
1016
1016
|
- `serveAcpStdio(runtime)` 提供基于 stdio 的 newline-delimited JSON-RPC,适合本地 IDE、CLI 或子进程客户端。
|
|
1017
1017
|
- `serveAcpHttp(runtime)` 提供基于 HTTP 的 JSON-RPC 与 SSE runtime events,适合远程界面或独立控制面接入。
|
|
1018
1018
|
- ACP transport 现已覆盖核心参考客户端流程验证:capability discovery、request submit、session lookup、request lookup、invalid JSON 处理、无 id notification 不返回响应,以及 stdio JSON-RPC 与 HTTP + SSE runtime notifications。
|
|
1019
|
+
- 现在还额外有一条跨协议一致性回归门:ACP 发起的 request、A2A 读取或继续的 task,以及 runtime MCP 暴露的检查结果,必须始终指向同一组持久化 `sessionId` / `requestId` 运行时记录,不能漂移成各协议各自维护的标识体系。
|
|
1019
1020
|
- 如果要从最薄的一层 editor / CLI starter 开始,优先用 `agent-harness acp serve --workspace . --transport stdio`,并直接参考 `examples/protocol-hello-world/app/acp-stdio-hello-world.mjs` 的 wire shape。需要在应用内使用 reference client 时,可直接用 `createAcpStdioClient(...)` 发起 JSON-RPC 请求并分流 runtime notifications,避免每个 sidecar 自己重写 line parsing。
|
|
1020
|
-
- `serveA2aHttp(runtime)` 提供 A2A HTTP JSON-RPC bridge 与 agent card discovery,同时兼容 `message/send` 这类旧方法,以及 `SendMessage`、`SendStreamingMessage`、`GetTask`、`ListTasks`、`CancelTask`、`SubscribeToTask`、`GetAgentCard`、`GetExtendedAgentCard` 与 task push-notification config 这类 A2A v1.0 方法,并统一映射到现有 session/request 运行记录。bridge 现在会同时声明 `1.0` 与 `0.3` 两个 JSON-RPC interface、在 agent card 路径上响应 `HEAD` / `OPTIONS` discovery、写出支持版本的 discovery headers
|
|
1021
|
+
- `serveA2aHttp(runtime)` 提供 A2A HTTP JSON-RPC bridge 与 agent card discovery,同时兼容 `message/send` 这类旧方法,以及 `SendMessage`、`SendStreamingMessage`、`GetTask`、`ListTasks`、`CancelTask`、`SubscribeToTask`、`GetAgentCard`、`GetExtendedAgentCard` 与 task push-notification config 这类 A2A v1.0 方法,并统一映射到现有 session/request 运行记录。bridge 现在会同时声明 `1.0` 与 `0.3` 两个 JSON-RPC interface、在 agent card 路径上响应 `HEAD` / `OPTIONS` discovery、写出支持版本的 discovery headers、可选暴露 registry URL 与 detached signed-card metadata 供外围发现系统使用、校验 `A2A-Version`、把 `A2A-Extensions` 记录进 runtime invocation metadata、发布 `TASK_STATE_*` 状态与 `SendMessage` 的 `{ task }` wrapper、在 v1 streaming 方法上先通过 SSE 输出 `{ task }` 初始快照,再输出 `{ statusUpdate }` 增量状态,并可向已配置的 webhook receiver 发送 best-effort task push notifications。
|
|
1021
1022
|
- `serveAgUiHttp(runtime)` 提供 AG-UI HTTP SSE bridge,把 runtime 生命周期、文本输出、upstream thinking、step 进度与 tool call 投影成 `RUN_*`、`TEXT_MESSAGE_*`、`THINKING_TEXT_MESSAGE_*`、`STEP_*` 与 `TOOL_CALL_*` 事件,便于 UI 客户端直接接入。
|
|
1022
1023
|
- `createRuntimeMcpServer(runtime)` 与 `serveRuntimeMcpOverStdio(runtime)` 会把持久化 runtime 控制面本身暴露成 MCP tools,包括 sessions、requests、approvals、artifacts、events 与 package export helpers。
|
|
1023
1024
|
- `listRequestEvents(...)`、`listRequestTraceItems(...)` 与 `exportRequestPackage(...)` 是 request-first 的检查 helper。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.271";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.271";
|
|
@@ -12,6 +12,20 @@ export type A2aHttpServerOptions = {
|
|
|
12
12
|
url?: string;
|
|
13
13
|
};
|
|
14
14
|
defaultAgentId?: string;
|
|
15
|
+
registryUrls?: string[];
|
|
16
|
+
agentCardSignature?: {
|
|
17
|
+
algorithm: string;
|
|
18
|
+
signature: string;
|
|
19
|
+
keyId?: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
type A2aAgentCardDiscoveryMetadata = {
|
|
23
|
+
registryUrls?: string[];
|
|
24
|
+
signedAgentCard?: {
|
|
25
|
+
algorithm: string;
|
|
26
|
+
signature: string;
|
|
27
|
+
keyId?: string;
|
|
28
|
+
};
|
|
15
29
|
};
|
|
16
30
|
export type A2aAgentCard = {
|
|
17
31
|
name: string;
|
|
@@ -45,6 +59,11 @@ export type A2aAgentCard = {
|
|
|
45
59
|
tags: string[];
|
|
46
60
|
examples: string[];
|
|
47
61
|
}>;
|
|
62
|
+
metadata?: {
|
|
63
|
+
agentHarness?: {
|
|
64
|
+
discovery?: A2aAgentCardDiscoveryMetadata;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
48
67
|
};
|
|
49
68
|
export type A2aExtendedAgentCard = A2aAgentCard & {
|
|
50
69
|
metadata: {
|
|
@@ -59,6 +78,7 @@ export type A2aExtendedAgentCard = A2aAgentCard & {
|
|
|
59
78
|
agentCount: number;
|
|
60
79
|
subagentCount: number;
|
|
61
80
|
};
|
|
81
|
+
discovery?: A2aAgentCardDiscoveryMetadata;
|
|
62
82
|
agents: Array<{
|
|
63
83
|
id: string;
|
|
64
84
|
name: string;
|
|
@@ -15,6 +15,50 @@ function writeA2aDiscoveryHeaders(response) {
|
|
|
15
15
|
response.setHeader("A2A-Version", "1.0");
|
|
16
16
|
response.setHeader("A2A-Supported-Versions", SUPPORTED_A2A_VERSIONS.join(", "));
|
|
17
17
|
}
|
|
18
|
+
function normalizeNonEmptyStringArray(value) {
|
|
19
|
+
if (!Array.isArray(value)) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const items = value.map((item) => item.trim()).filter((item) => item.length > 0);
|
|
23
|
+
return items.length > 0 ? items : undefined;
|
|
24
|
+
}
|
|
25
|
+
function buildDiscoveryMetadata(options) {
|
|
26
|
+
const registryUrls = normalizeNonEmptyStringArray(options.registryUrls);
|
|
27
|
+
const signature = options.agentCardSignature?.signature?.trim();
|
|
28
|
+
const algorithm = options.agentCardSignature?.algorithm?.trim();
|
|
29
|
+
const keyId = options.agentCardSignature?.keyId?.trim();
|
|
30
|
+
if (!registryUrls && (!signature || !algorithm)) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
...(registryUrls ? { registryUrls } : {}),
|
|
35
|
+
...(signature && algorithm
|
|
36
|
+
? {
|
|
37
|
+
signedAgentCard: {
|
|
38
|
+
algorithm,
|
|
39
|
+
signature,
|
|
40
|
+
...(keyId ? { keyId } : {}),
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
: {}),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function writeOptionalAgentCardIntegrityHeaders(response, options) {
|
|
47
|
+
const registryUrls = normalizeNonEmptyStringArray(options.registryUrls);
|
|
48
|
+
if (registryUrls) {
|
|
49
|
+
response.setHeader("X-A2A-Registry-Urls", registryUrls.join(", "));
|
|
50
|
+
}
|
|
51
|
+
const signature = options.agentCardSignature?.signature?.trim();
|
|
52
|
+
const algorithm = options.agentCardSignature?.algorithm?.trim();
|
|
53
|
+
const keyId = options.agentCardSignature?.keyId?.trim();
|
|
54
|
+
if (signature && algorithm) {
|
|
55
|
+
response.setHeader("X-A2A-Agent-Card-Signature", signature);
|
|
56
|
+
response.setHeader("X-A2A-Agent-Card-Alg", algorithm);
|
|
57
|
+
if (keyId) {
|
|
58
|
+
response.setHeader("X-A2A-Agent-Card-Key-Id", keyId);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
18
62
|
function writeSseHeaders(response) {
|
|
19
63
|
response.statusCode = 200;
|
|
20
64
|
response.setHeader("content-type", "text/event-stream; charset=utf-8");
|
|
@@ -562,6 +606,21 @@ function buildAgentCard(runtime, options) {
|
|
|
562
606
|
defaultInputModes: ["text/plain"],
|
|
563
607
|
defaultOutputModes: ["text/plain"],
|
|
564
608
|
skills,
|
|
609
|
+
...(buildDiscoveryMetadata({
|
|
610
|
+
registryUrls: options.registryUrls,
|
|
611
|
+
agentCardSignature: options.agentCardSignature,
|
|
612
|
+
})
|
|
613
|
+
? {
|
|
614
|
+
metadata: {
|
|
615
|
+
agentHarness: {
|
|
616
|
+
discovery: buildDiscoveryMetadata({
|
|
617
|
+
registryUrls: options.registryUrls,
|
|
618
|
+
agentCardSignature: options.agentCardSignature,
|
|
619
|
+
}),
|
|
620
|
+
},
|
|
621
|
+
},
|
|
622
|
+
}
|
|
623
|
+
: {}),
|
|
565
624
|
...(options.documentationUrl ? { documentationUrl: options.documentationUrl } : {}),
|
|
566
625
|
...(options.provider ? { provider: options.provider } : {}),
|
|
567
626
|
...(options.defaultAgentId ? { defaultAgentId: options.defaultAgentId } : {}),
|
|
@@ -584,6 +643,17 @@ function buildExtendedAgentCard(runtime, options) {
|
|
|
584
643
|
agentCount: inventory.agents.length,
|
|
585
644
|
subagentCount: inventory.agents.filter((agent) => Boolean(agent.parentAgentId)).length,
|
|
586
645
|
},
|
|
646
|
+
...(buildDiscoveryMetadata({
|
|
647
|
+
registryUrls: options.registryUrls,
|
|
648
|
+
agentCardSignature: options.agentCardSignature,
|
|
649
|
+
})
|
|
650
|
+
? {
|
|
651
|
+
discovery: buildDiscoveryMetadata({
|
|
652
|
+
registryUrls: options.registryUrls,
|
|
653
|
+
agentCardSignature: options.agentCardSignature,
|
|
654
|
+
}),
|
|
655
|
+
}
|
|
656
|
+
: {}),
|
|
587
657
|
agents: inventory.agents.map((agent) => ({
|
|
588
658
|
id: agent.id,
|
|
589
659
|
name: agent.id,
|
|
@@ -846,6 +916,8 @@ export async function serveA2aOverHttp(runtime, options = {}) {
|
|
|
846
916
|
...(options.documentationUrl ? { documentationUrl: options.documentationUrl } : {}),
|
|
847
917
|
...(options.provider ? { provider: options.provider } : {}),
|
|
848
918
|
...(options.defaultAgentId ? { defaultAgentId: options.defaultAgentId } : {}),
|
|
919
|
+
...(options.registryUrls ? { registryUrls: options.registryUrls } : {}),
|
|
920
|
+
...(options.agentCardSignature ? { agentCardSignature: options.agentCardSignature } : {}),
|
|
849
921
|
});
|
|
850
922
|
const pushConfigsByTask = new Map();
|
|
851
923
|
const registerPushNotificationConfig = (taskId, config) => {
|
|
@@ -919,18 +991,32 @@ export async function serveA2aOverHttp(runtime, options = {}) {
|
|
|
919
991
|
}
|
|
920
992
|
writeA2aDiscoveryHeaders(response);
|
|
921
993
|
if (request.method === "OPTIONS" && (requestUrl.pathname === rpcPath || requestUrl.pathname === agentCardPath || requestUrl.pathname === "/.well-known/agent.json")) {
|
|
994
|
+
if (requestUrl.pathname === agentCardPath || requestUrl.pathname === "/.well-known/agent.json") {
|
|
995
|
+
writeOptionalAgentCardIntegrityHeaders(response, {
|
|
996
|
+
registryUrls: options.registryUrls,
|
|
997
|
+
agentCardSignature: options.agentCardSignature,
|
|
998
|
+
});
|
|
999
|
+
}
|
|
922
1000
|
response.statusCode = 204;
|
|
923
1001
|
response.setHeader("Allow", "GET,HEAD,POST,OPTIONS");
|
|
924
1002
|
response.end();
|
|
925
1003
|
return;
|
|
926
1004
|
}
|
|
927
1005
|
if (request.method === "HEAD" && (requestUrl.pathname === agentCardPath || requestUrl.pathname === "/.well-known/agent.json")) {
|
|
1006
|
+
writeOptionalAgentCardIntegrityHeaders(response, {
|
|
1007
|
+
registryUrls: options.registryUrls,
|
|
1008
|
+
agentCardSignature: options.agentCardSignature,
|
|
1009
|
+
});
|
|
928
1010
|
response.statusCode = 200;
|
|
929
1011
|
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
930
1012
|
response.end();
|
|
931
1013
|
return;
|
|
932
1014
|
}
|
|
933
1015
|
if (request.method === "GET" && (requestUrl.pathname === agentCardPath || requestUrl.pathname === "/.well-known/agent.json")) {
|
|
1016
|
+
writeOptionalAgentCardIntegrityHeaders(response, {
|
|
1017
|
+
registryUrls: options.registryUrls,
|
|
1018
|
+
agentCardSignature: options.agentCardSignature,
|
|
1019
|
+
});
|
|
934
1020
|
writeJson(response, 200, buildAgentCard(runtime, buildCardOptions()));
|
|
935
1021
|
return;
|
|
936
1022
|
}
|
|
@@ -968,6 +1054,10 @@ export async function serveA2aOverHttp(runtime, options = {}) {
|
|
|
968
1054
|
return;
|
|
969
1055
|
}
|
|
970
1056
|
if (payload.method === "GetAgentCard") {
|
|
1057
|
+
writeOptionalAgentCardIntegrityHeaders(response, {
|
|
1058
|
+
registryUrls: options.registryUrls,
|
|
1059
|
+
agentCardSignature: options.agentCardSignature,
|
|
1060
|
+
});
|
|
971
1061
|
writeJson(response, 200, toSuccess(payload.id ?? null, buildAgentCard(runtime, buildCardOptions())));
|
|
972
1062
|
return;
|
|
973
1063
|
}
|
|
@@ -1093,6 +1183,10 @@ export async function serveA2aOverHttp(runtime, options = {}) {
|
|
|
1093
1183
|
return;
|
|
1094
1184
|
}
|
|
1095
1185
|
if (payload.method === "GetExtendedAgentCard") {
|
|
1186
|
+
writeOptionalAgentCardIntegrityHeaders(response, {
|
|
1187
|
+
registryUrls: options.registryUrls,
|
|
1188
|
+
agentCardSignature: options.agentCardSignature,
|
|
1189
|
+
});
|
|
1096
1190
|
writeJson(response, 200, toSuccess(payload.id ?? null, buildExtendedAgentCard(runtime, buildCardOptions())));
|
|
1097
1191
|
return;
|
|
1098
1192
|
}
|