@botbotgo/agent-harness 0.0.213 → 0.0.214

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 CHANGED
@@ -126,7 +126,7 @@ The public API spans a full product runtime—persistent records, memory and evi
126
126
 
127
127
  - **Core runtime API:** `createAgentHarness`, `request`, `subscribe`, `resolveApproval`, inspection helpers, and stable persisted runtime records for `requests`, `sessions`, `approvals`, `events`, and artifacts.
128
128
  - **Runtime memory and evidence:** `memorize`, `recall`, `listMemories`, memory policy hooks, `listArtifacts`, `getArtifact`, `exportEvaluationBundle`, `replayEvaluationBundle`, and request/session evidence export helpers.
129
- - **Protocol and transport surfaces:** `createAcpServer`, `serveAcpStdio`, `serveAcpHttp`, `serveA2aHttp`, `serveAgUiHttp`, and `createRuntimeMcpServer` / `serveRuntimeMcpOverStdio`.
129
+ - **Protocol and transport surfaces:** `createAcpServer`, `createAcpStdioClient`, `serveAcpStdio`, `serveAcpHttp`, `serveA2aHttp`, `serveAgUiHttp`, and `createRuntimeMcpServer` / `serveRuntimeMcpOverStdio`.
130
130
  - **Governed workspace runtime:** YAML-owned routing, concurrency, maintenance, MCP policy, runtime governance bundles, and approval defaults for sensitive memory or write-like MCP side effects.
131
131
 
132
132
  If you integrate external clients, treat `deepagents-acp` as the primary protocol direction: clients connect through that surface while `agent-harness` keeps persistence, recovery, approvals, and operator control on the runtime side.
@@ -992,6 +992,7 @@ Primary exports:
992
992
  - `exportEvaluationBundle`
993
993
  - `replayEvaluationBundle`
994
994
  - `createAcpServer`
995
+ - `createAcpStdioClient`
995
996
  - `serveAcpHttp`
996
997
  - `serveAcpStdio`
997
998
  - `serveA2aHttp`
@@ -1020,7 +1021,7 @@ ACP transport notes:
1020
1021
  - `serveAcpStdio(runtime)` exposes newline-delimited JSON-RPC over stdio for local IDE, CLI, or subprocess clients.
1021
1022
  - `serveAcpHttp(runtime)` exposes JSON-RPC over HTTP plus SSE runtime events so remote operator surfaces can connect without importing the runtime in-process.
1022
1023
  - 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.
1023
- - 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.
1024
+ - 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.
1024
1025
  - `serveA2aHttp(runtime)` exposes an A2A-compatible HTTP JSON-RPC bridge plus agent card discovery, mapping both existing methods such as `message/send` and newer aliases such as `SendMessage`, `GetTask`, `ListTasks`, `CancelTask`, and `SubscribeToTask` onto the existing session/request runtime surface.
1025
1026
  - `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.
1026
1027
  - `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.
package/README.zh.md CHANGED
@@ -122,7 +122,7 @@ try {
122
122
 
123
123
  - **核心 runtime API:** `createAgentHarness`、`request`、`subscribe`、`resolveApproval`、各类查询与检查辅助 API,以及稳定持久化的 `requests`、`sessions`、`approvals`、`events` 与 artifacts 记录。
124
124
  - **运行时 memory 与证据能力:** `memorize`、`recall`、`listMemories`、memory policy hooks、`listArtifacts`、`getArtifact`、`exportEvaluationBundle`、`replayEvaluationBundle`,以及 request / session 级证据导出辅助函数。
125
- - **协议与传输层:** `createAcpServer`、`serveAcpStdio`、`serveAcpHttp`、`serveA2aHttp`、`serveAgUiHttp`,以及 `createRuntimeMcpServer` / `serveRuntimeMcpOverStdio`。
125
+ - **协议与传输层:** `createAcpServer`、`createAcpStdioClient`、`serveAcpStdio`、`serveAcpHttp`、`serveA2aHttp`、`serveAgUiHttp`,以及 `createRuntimeMcpServer` / `serveRuntimeMcpOverStdio`。
126
126
  - **受治理的工作区运行时:** 由 YAML 持有的路由、并发、维护、MCP 策略、runtime governance bundles,以及针对敏感 memory 或写类 MCP 副作用的默认审批门槛。
127
127
 
128
128
  若你的产品需要对接外部客户端,可从本节理解边界:`deepagents-acp` 是主要的外部协议接入方向;持久化、恢复、审批与运行控制仍由 `agent-harness` 在运行时侧承担。
@@ -950,6 +950,7 @@ spec:
950
950
  - `exportEvaluationBundle`
951
951
  - `replayEvaluationBundle`
952
952
  - `createAcpServer`
953
+ - `createAcpStdioClient`
953
954
  - `serveAcpHttp`
954
955
  - `serveAcpStdio`
955
956
  - `serveA2aHttp`
@@ -978,7 +979,7 @@ ACP transport 说明:
978
979
  - `serveAcpStdio(runtime)` 提供基于 stdio 的 newline-delimited JSON-RPC,适合本地 IDE、CLI 或子进程客户端。
979
980
  - `serveAcpHttp(runtime)` 提供基于 HTTP 的 JSON-RPC 与 SSE runtime events,适合远程界面或独立控制面接入。
980
981
  - ACP transport 现已覆盖核心参考客户端流程验证:capability discovery、request submit、session lookup、request lookup、invalid JSON 处理、无 id notification 不返回响应,以及 stdio JSON-RPC 与 HTTP + SSE runtime notifications。
981
- - 如果要从最薄的一层 editor / CLI starter 开始,优先用 `agent-harness acp serve --workspace . --transport stdio`,并直接参考 `examples/protocol-hello-world/app/acp-stdio-hello-world.mjs` 的 wire shape。
982
+ - 如果要从最薄的一层 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
982
983
  - `serveA2aHttp(runtime)` 提供 A2A HTTP JSON-RPC bridge 与 agent card discovery,同时兼容 `message/send` 这类旧方法,以及 `SendMessage`、`GetTask`、`ListTasks`、`CancelTask`、`SubscribeToTask` 这类更新的方法别名,并统一映射到现有 session/request 运行记录。
983
984
  - `serveAgUiHttp(runtime)` 提供 AG-UI HTTP SSE bridge,把 runtime 生命周期、文本输出、upstream thinking、step 进度与 tool call 投影成 `RUN_*`、`TEXT_MESSAGE_*`、`THINKING_TEXT_MESSAGE_*`、`STEP_*` 与 `TOOL_CALL_*` 事件,便于 UI 客户端直接接入。
984
985
  - `createRuntimeMcpServer(runtime)` 与 `serveRuntimeMcpOverStdio(runtime)` 会把持久化 runtime 控制面本身暴露成 MCP tools,包括 sessions、requests、approvals、artifacts、events 与 package export helpers。
package/dist/acp.d.ts CHANGED
@@ -84,4 +84,5 @@ export declare class AgentHarnessAcpServer {
84
84
  private dispatch;
85
85
  }
86
86
  export declare function createAcpServer(runtime: AgentHarnessRuntime): AgentHarnessAcpServer;
87
- export {};
87
+ export { createAcpStdioClient } from "./protocol/acp/client.js";
88
+ export type { AcpStdioClient, AcpStdioClientOptions } from "./protocol/acp/client.js";
package/dist/acp.js CHANGED
@@ -206,3 +206,4 @@ export class AgentHarnessAcpServer {
206
206
  export function createAcpServer(runtime) {
207
207
  return new AgentHarnessAcpServer(runtime);
208
208
  }
209
+ export { createAcpStdioClient } from "./protocol/acp/client.js";
package/dist/api.d.ts CHANGED
@@ -4,12 +4,14 @@ import type { InventoryAgentRecord, InventorySkillRecord } from "./runtime/harne
4
4
  import type { RequirementAssessmentOptions } from "./runtime/harness/system/skill-requirements.js";
5
5
  import type { RuntimeMcpServerOptions, ToolMcpServerOptions } from "./mcp.js";
6
6
  export { AgentHarnessAcpServer, createAcpServer } from "./acp.js";
7
+ export { createAcpStdioClient } from "./protocol/acp/client.js";
7
8
  export type { AcpApproval, AcpArtifact, AcpEventNotification, AcpJsonRpcError, AcpJsonRpcRequest, AcpJsonRpcResponse, AcpJsonRpcSuccess, AcpRequestRecord, AcpRunRequestParams, AcpServerCapabilities, AcpSessionRecord, } from "./acp.js";
8
9
  export { AgentHarnessRuntime } from "./runtime/harness.js";
9
10
  export { buildFlowGraph, exportFlowGraphToMermaid, exportFlowGraphToSequenceMermaid } from "./flow/index.js";
10
11
  export { createUpstreamTimelineReducer } from "./upstream-events.js";
11
12
  export type { ListMemoriesInput, ListMemoriesResult, MemoryDecision, MemoryKind, MemoryRecord, MemoryScope, MemorizeInput, MemorizeResult, RecallInput, RecallResult, RemoveMemoryInput, RuntimeEvaluationExport, RuntimeEvaluationExportInput, RuntimeEvaluationReplayInput, RuntimeSessionPackageInput, RuntimeSessionPackage, UpdateMemoryInput, } from "./contracts/types.js";
12
13
  export type { AcpHttpServer, AcpHttpServerOptions } from "./protocol/acp/http.js";
14
+ export type { AcpStdioClient, AcpStdioClientOptions } from "./protocol/acp/client.js";
13
15
  export type { A2aAgentCard, A2aHttpServer, A2aHttpServerOptions, A2aTask, A2aTaskState } from "./protocol/a2a/http.js";
14
16
  export type { AcpStdioServer, AcpStdioServerOptions } from "./protocol/acp/stdio.js";
15
17
  export type { AgUiEvent, AgUiHttpServer, AgUiHttpServerOptions, AgUiRunAgentInput } from "./protocol/ag-ui/http.js";
package/dist/api.js CHANGED
@@ -6,6 +6,7 @@ import { serveAcpOverStdio } from "./protocol/acp/stdio.js";
6
6
  import { normalizeMessageContent } from "./utils/message-content.js";
7
7
  import { loadWorkspace } from "./workspace/compile.js";
8
8
  export { AgentHarnessAcpServer, createAcpServer } from "./acp.js";
9
+ export { createAcpStdioClient } from "./protocol/acp/client.js";
9
10
  export { AgentHarnessRuntime } from "./runtime/harness.js";
10
11
  export { buildFlowGraph, exportFlowGraphToMermaid, exportFlowGraphToSequenceMermaid } from "./flow/index.js";
11
12
  export { createUpstreamTimelineReducer } from "./upstream-events.js";
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { AgentHarnessAcpServer, AgentHarnessRuntime, buildFlowGraph, cancelRun, createAgentHarness, createAcpServer, createRuntimeMcpServer, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, exportEvaluationBundle, exportRequestPackage, exportSessionPackage, replayEvaluationBundle, getArtifact, getAgent, getApproval, getOperatorOverview, getRequest, getHealth, listMemories, getSession, listAgentSkills, listArtifacts, listApprovals, listRequests, listRequestEvents, listSessions, memorize, normalizeUserChatInput, request, recall, removeMemory, resolveApproval, serveA2aHttp, serveAcpHttp, serveAcpStdio, serveAgUiHttp, serveRuntimeMcpOverStdio, serveToolsOverStdio, subscribe, stop, updateMemory, exportFlowGraphToMermaid, exportFlowGraphToSequenceMermaid, } from "./api.js";
2
- export type { AcpApproval, AcpArtifact, AcpEventNotification, AcpJsonRpcError, AcpJsonRpcRequest, AcpJsonRpcResponse, AcpJsonRpcSuccess, AcpRequestRecord, AcpRunRequestParams, AcpServerCapabilities, AcpSessionRecord, } from "./acp.js";
1
+ export { AgentHarnessAcpServer, AgentHarnessRuntime, buildFlowGraph, cancelRun, createAgentHarness, createAcpServer, createAcpStdioClient, createRuntimeMcpServer, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, exportEvaluationBundle, exportRequestPackage, exportSessionPackage, replayEvaluationBundle, getArtifact, getAgent, getApproval, getOperatorOverview, getRequest, getHealth, listMemories, getSession, listAgentSkills, listArtifacts, listApprovals, listRequests, listRequestEvents, listSessions, memorize, normalizeUserChatInput, request, recall, removeMemory, resolveApproval, serveA2aHttp, serveAcpHttp, serveAcpStdio, serveAgUiHttp, serveRuntimeMcpOverStdio, serveToolsOverStdio, subscribe, stop, updateMemory, exportFlowGraphToMermaid, exportFlowGraphToSequenceMermaid, } from "./api.js";
2
+ export type { AcpApproval, AcpArtifact, AcpEventNotification, AcpJsonRpcError, AcpJsonRpcRequest, AcpJsonRpcResponse, AcpJsonRpcSuccess, AcpRequestRecord, AcpRunRequestParams, AcpServerCapabilities, AcpSessionRecord, AcpStdioClient, AcpStdioClientOptions, } from "./acp.js";
3
3
  export type { Approval, ListMemoriesInput, ListMemoriesResult, MemoryDecision, MemoryKind, MemoryRecord, MemoryScope, MemorizeInput, MemorizeResult, NormalizeUserChatInputOptions, OperatorOverview, PublicRunListeners, RequestArtifactListing, RequestEvent, RequestEventType, RequestPackage, RequestPackageInput, RequestResult, RequestUpstreamEventItem, RecallInput, RecallResult, RemoveMemoryInput, RuntimeEvaluationExport, RuntimeEvaluationExportInput, RuntimeEvaluationReplayInput, RuntimeEvaluationReplayResult, RuntimeSessionPackage, RuntimeSessionPackageInput, UpdateMemoryInput, UserChatInput, UserChatMessage, } from "./api.js";
4
4
  export type { BuildFlowGraphInput, FlowEdge, FlowEdgeKind, FlowGraph, FlowGraphMermaidOptions, FlowGraphSequenceMermaidOptions, FlowGroup, FlowGroupKind, FlowNode, FlowNodeKind, FlowNodeLayer, FlowNodeStatus, } from "./flow/index.js";
5
5
  export type { A2aAgentCard, A2aHttpServer, A2aHttpServerOptions, A2aTask, A2aTaskState, AcpHttpServer, AcpHttpServerOptions, AcpStdioServer, AcpStdioServerOptions, AgUiEvent, AgUiHttpServer, AgUiHttpServerOptions, AgUiRunAgentInput, } from "./api.js";
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { AgentHarnessAcpServer, AgentHarnessRuntime, buildFlowGraph, cancelRun, createAgentHarness, createAcpServer, createRuntimeMcpServer, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, exportEvaluationBundle, exportRequestPackage, exportSessionPackage, replayEvaluationBundle, getArtifact, getAgent, getApproval, getOperatorOverview, getRequest, getHealth, listMemories, getSession, listAgentSkills, listArtifacts, listApprovals, listRequests, listRequestEvents, listSessions, memorize, normalizeUserChatInput, request, recall, removeMemory, resolveApproval, serveA2aHttp, serveAcpHttp, serveAcpStdio, serveAgUiHttp, serveRuntimeMcpOverStdio, serveToolsOverStdio, subscribe, stop, updateMemory, exportFlowGraphToMermaid, exportFlowGraphToSequenceMermaid, } from "./api.js";
1
+ export { AgentHarnessAcpServer, AgentHarnessRuntime, buildFlowGraph, cancelRun, createAgentHarness, createAcpServer, createAcpStdioClient, createRuntimeMcpServer, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, exportEvaluationBundle, exportRequestPackage, exportSessionPackage, replayEvaluationBundle, getArtifact, getAgent, getApproval, getOperatorOverview, getRequest, getHealth, listMemories, getSession, listAgentSkills, listArtifacts, listApprovals, listRequests, listRequestEvents, listSessions, memorize, normalizeUserChatInput, request, recall, removeMemory, resolveApproval, serveA2aHttp, serveAcpHttp, serveAcpStdio, serveAgUiHttp, serveRuntimeMcpOverStdio, serveToolsOverStdio, subscribe, stop, updateMemory, exportFlowGraphToMermaid, exportFlowGraphToSequenceMermaid, } from "./api.js";
2
2
  export { tool } from "./tools.js";
@@ -1 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.212";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.213";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.212";
1
+ export const AGENT_HARNESS_VERSION = "0.0.213";
@@ -0,0 +1,14 @@
1
+ import type { Readable, Writable } from "node:stream";
2
+ import type { AcpEventNotification, AcpJsonRpcSuccess } from "../../acp.js";
3
+ export type AcpStdioClientOptions = {
4
+ input: Writable;
5
+ output: Readable;
6
+ idPrefix?: string;
7
+ };
8
+ export type AcpStdioClient = {
9
+ request: (method: string, params?: unknown) => Promise<AcpJsonRpcSuccess["result"]>;
10
+ notify: (method: string, params?: unknown) => Promise<void>;
11
+ subscribe: (listener: (notification: AcpEventNotification) => void) => () => void;
12
+ close: () => Promise<void>;
13
+ };
14
+ export declare function createAcpStdioClient(options: AcpStdioClientOptions): AcpStdioClient;
@@ -0,0 +1,140 @@
1
+ import { createInterface } from "node:readline";
2
+ class AcpClientError extends Error {
3
+ error;
4
+ constructor(error) {
5
+ super(error.message);
6
+ this.error = error;
7
+ this.name = "AcpClientError";
8
+ }
9
+ }
10
+ function writeJsonLine(output, payload) {
11
+ return new Promise((resolve, reject) => {
12
+ output.write(`${JSON.stringify(payload)}\n`, (error) => {
13
+ if (error) {
14
+ reject(error);
15
+ return;
16
+ }
17
+ resolve();
18
+ });
19
+ });
20
+ }
21
+ function isResponse(value) {
22
+ return typeof value === "object"
23
+ && value !== null
24
+ && !Array.isArray(value)
25
+ && value.jsonrpc === "2.0"
26
+ && Object.hasOwn(value, "id");
27
+ }
28
+ function isNotification(value) {
29
+ return typeof value === "object"
30
+ && value !== null
31
+ && !Array.isArray(value)
32
+ && value.jsonrpc === "2.0"
33
+ && typeof value.method === "string"
34
+ && !Object.hasOwn(value, "id");
35
+ }
36
+ export function createAcpStdioClient(options) {
37
+ const idPrefix = options.idPrefix?.trim() || "acp";
38
+ let sequence = 0;
39
+ let closed = false;
40
+ const pending = new Map();
41
+ const listeners = new Set();
42
+ const reader = createInterface({
43
+ input: options.output,
44
+ crlfDelay: Infinity,
45
+ });
46
+ const completed = (async () => {
47
+ try {
48
+ for await (const line of reader) {
49
+ const trimmed = line.trim();
50
+ if (!trimmed) {
51
+ continue;
52
+ }
53
+ const parsed = JSON.parse(trimmed);
54
+ if (isNotification(parsed)) {
55
+ for (const listener of Array.from(listeners)) {
56
+ listener(parsed);
57
+ }
58
+ continue;
59
+ }
60
+ if (!isResponse(parsed)) {
61
+ continue;
62
+ }
63
+ const request = pending.get(parsed.id);
64
+ if (!request) {
65
+ continue;
66
+ }
67
+ pending.delete(parsed.id);
68
+ if ("error" in parsed) {
69
+ request.reject(new AcpClientError(parsed.error));
70
+ }
71
+ else {
72
+ request.resolve(parsed.result);
73
+ }
74
+ }
75
+ }
76
+ catch (error) {
77
+ closed = true;
78
+ for (const request of pending.values()) {
79
+ request.reject(error);
80
+ }
81
+ pending.clear();
82
+ }
83
+ })();
84
+ return {
85
+ async request(method, params) {
86
+ if (closed) {
87
+ throw new Error("ACP stdio client is closed.");
88
+ }
89
+ const id = `${idPrefix}-${++sequence}`;
90
+ const payload = {
91
+ jsonrpc: "2.0",
92
+ id,
93
+ method,
94
+ ...(params === undefined ? {} : { params }),
95
+ };
96
+ const result = new Promise((resolve, reject) => {
97
+ pending.set(id, { resolve, reject });
98
+ });
99
+ try {
100
+ await writeJsonLine(options.input, payload);
101
+ }
102
+ catch (error) {
103
+ pending.delete(id);
104
+ throw error;
105
+ }
106
+ return result;
107
+ },
108
+ async notify(method, params) {
109
+ if (closed) {
110
+ throw new Error("ACP stdio client is closed.");
111
+ }
112
+ await writeJsonLine(options.input, {
113
+ jsonrpc: "2.0",
114
+ method,
115
+ ...(params === undefined ? {} : { params }),
116
+ });
117
+ },
118
+ subscribe(listener) {
119
+ listeners.add(listener);
120
+ return () => {
121
+ listeners.delete(listener);
122
+ };
123
+ },
124
+ async close() {
125
+ closed = true;
126
+ reader.close();
127
+ if (typeof options.output.destroy === "function") {
128
+ options.output.destroy();
129
+ }
130
+ if (typeof options.input.end === "function") {
131
+ options.input.end();
132
+ }
133
+ await completed.catch(() => undefined);
134
+ for (const request of pending.values()) {
135
+ request.reject(new Error("ACP stdio client closed before response."));
136
+ }
137
+ pending.clear();
138
+ },
139
+ };
140
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.213",
3
+ "version": "0.0.214",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "license": "MIT",
6
6
  "type": "module",