@botbotgo/agent-harness 0.0.160 → 0.0.162
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 +11 -0
- package/README.zh.md +11 -0
- package/dist/api.d.ts +10 -2
- package/dist/api.js +13 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +47 -10
- package/dist/contracts/runtime.d.ts +32 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/protocol/acp/http.d.ts +20 -0
- package/dist/protocol/acp/http.js +130 -0
- package/dist/runtime/harness/run/governance.js +56 -2
- package/dist/runtime/harness/system/policy-engine.js +69 -0
- package/dist/runtime/harness.d.ts +3 -1
- package/dist/runtime/harness.js +44 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -881,9 +881,13 @@ Primary exports:
|
|
|
881
881
|
- `getApproval`
|
|
882
882
|
- `listArtifacts`
|
|
883
883
|
- `getArtifact`
|
|
884
|
+
- `listRunEvents`
|
|
885
|
+
- `exportRunPackage`
|
|
886
|
+
- `exportSessionPackage`
|
|
884
887
|
- `exportEvaluationBundle`
|
|
885
888
|
- `replayEvaluationBundle`
|
|
886
889
|
- `createAcpServer`
|
|
890
|
+
- `serveAcpHttp`
|
|
887
891
|
- `serveAcpStdio`
|
|
888
892
|
- `createToolMcpServer`
|
|
889
893
|
- `serveToolsOverStdio`
|
|
@@ -901,3 +905,10 @@ Inspection helpers:
|
|
|
901
905
|
- `exportFlowGraphToSequenceMermaid(...)` renders the same inspection graph as a Mermaid sequence diagram. By default it emits only user-defined participants and calls, while `view: "debug"` includes runtime participants and lifecycle messages.
|
|
902
906
|
|
|
903
907
|
These helpers are visualization and inspection utilities. They do not introduce a canonical harness-owned execution protocol.
|
|
908
|
+
|
|
909
|
+
ACP transport notes:
|
|
910
|
+
|
|
911
|
+
- `serveAcpStdio(runtime)` exposes newline-delimited JSON-RPC over stdio for local IDE, CLI, or subprocess clients.
|
|
912
|
+
- `serveAcpHttp(runtime)` exposes JSON-RPC over HTTP plus SSE runtime events so remote operator surfaces can connect without importing the runtime in-process.
|
|
913
|
+
- `exportRunPackage(...)` and `exportSessionPackage(...)` package stable runtime records, transcript, approvals, events, and artifacts for operator tooling without reaching into persistence internals.
|
|
914
|
+
- `runtime/default.governance.remoteMcp` can now deny or allow specific MCP servers, raise approval requirements by transport, and stamp transport-based risk tiers into runtime governance bundles.
|
package/README.zh.md
CHANGED
|
@@ -840,9 +840,13 @@ spec:
|
|
|
840
840
|
- `getApproval`
|
|
841
841
|
- `listArtifacts`
|
|
842
842
|
- `getArtifact`
|
|
843
|
+
- `listRunEvents`
|
|
844
|
+
- `exportRunPackage`
|
|
845
|
+
- `exportSessionPackage`
|
|
843
846
|
- `exportEvaluationBundle`
|
|
844
847
|
- `replayEvaluationBundle`
|
|
845
848
|
- `createAcpServer`
|
|
849
|
+
- `serveAcpHttp`
|
|
846
850
|
- `serveAcpStdio`
|
|
847
851
|
- `createToolMcpServer`
|
|
848
852
|
- `serveToolsOverStdio`
|
|
@@ -860,3 +864,10 @@ Inspection 辅助工具:
|
|
|
860
864
|
- `exportFlowGraphToSequenceMermaid(...)` 可把同一份 inspection graph 导出为 Mermaid sequence diagram。默认只输出用户定义的参与者与调用;传 `view: "debug"` 才会包含 runtime participant 与生命周期消息。
|
|
861
865
|
|
|
862
866
|
这些 helper 只用于可视化与检查,不代表新的 harness 官方执行协议。
|
|
867
|
+
|
|
868
|
+
ACP transport 说明:
|
|
869
|
+
|
|
870
|
+
- `serveAcpStdio(runtime)` 提供基于 stdio 的 newline-delimited JSON-RPC,适合本地 IDE、CLI 或子进程客户端。
|
|
871
|
+
- `serveAcpHttp(runtime)` 提供基于 HTTP 的 JSON-RPC 与 SSE runtime events,适合远程 operator surface 或独立控制面接入。
|
|
872
|
+
- `exportRunPackage(...)` 与 `exportSessionPackage(...)` 可把稳定 runtime 记录、transcript、approvals、events 和 artifacts 打包给 operator tooling,而不必直接访问 persistence 内部实现。
|
|
873
|
+
- `runtime/default.governance.remoteMcp` 现在可以按 MCP server 或 transport 做 allow/deny、审批升级,并把 transport 风险等级写进 runtime governance bundles。
|
package/dist/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ArtifactListing, CancelOptions, InvocationEnvelope, ListMemoriesInput, ListMemoriesResult, MemoryRecord, MemorizeInput, MemorizeResult, MessageContent, RecallInput, RecallResult, RemoveMemoryInput, RequestRecord, RequestSummary, ResumeOptions, RunDecisionOptions, RunResult, RunStartOptions, RuntimeHealthSnapshot, RuntimeAdapterOptions, RuntimeEvaluationExport, RuntimeEvaluationExportInput, RuntimeEvaluationReplayInput, RuntimeEvaluationReplayResult, SessionRecord, SessionSummary, UpdateMemoryInput, WorkspaceLoadOptions } from "./contracts/types.js";
|
|
1
|
+
import type { ArtifactListing, CancelOptions, InvocationEnvelope, ListMemoriesInput, ListMemoriesResult, MemoryRecord, MemorizeInput, MemorizeResult, MessageContent, RecallInput, RecallResult, RemoveMemoryInput, RequestRecord, RequestSummary, ResumeOptions, RunDecisionOptions, RunResult, RunStartOptions, RuntimeHealthSnapshot, RuntimeAdapterOptions, RuntimeEvaluationExport, RuntimeEvaluationExportInput, RuntimeEvaluationReplayInput, RuntimeEvaluationReplayResult, RuntimeRunPackage, RuntimeRunPackageInput, RuntimeSessionPackage, RuntimeSessionPackageInput, SessionRecord, SessionSummary, UpdateMemoryInput, WorkspaceLoadOptions } from "./contracts/types.js";
|
|
2
2
|
import { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
3
3
|
import type { InventoryAgentRecord, InventorySkillRecord } from "./runtime/harness/system/inventory.js";
|
|
4
4
|
import type { RequirementAssessmentOptions } from "./runtime/harness/system/skill-requirements.js";
|
|
@@ -8,7 +8,8 @@ export type { AcpApproval, AcpArtifact, AcpEventNotification, AcpJsonRpcError, A
|
|
|
8
8
|
export { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
9
9
|
export { buildFlowGraph, exportFlowGraphToMermaid, exportFlowGraphToSequenceMermaid } from "./flow/index.js";
|
|
10
10
|
export { createUpstreamTimelineReducer } from "./upstream-events.js";
|
|
11
|
-
export type { ListMemoriesInput, ListMemoriesResult, MemoryDecision, MemoryKind, MemoryRecord, MemoryScope, MemorizeInput, MemorizeResult, RecallInput, RecallResult, RemoveMemoryInput, RuntimeEvaluationExport, RuntimeEvaluationExportInput, RuntimeEvaluationReplayInput, RuntimeEvaluationReplayResult, UpdateMemoryInput, } from "./contracts/types.js";
|
|
11
|
+
export type { ListMemoriesInput, ListMemoriesResult, MemoryDecision, MemoryKind, MemoryRecord, MemoryScope, MemorizeInput, MemorizeResult, RecallInput, RecallResult, RemoveMemoryInput, RuntimeEvaluationExport, RuntimeEvaluationExportInput, RuntimeEvaluationReplayInput, RuntimeEvaluationReplayResult, RuntimeRunPackage, RuntimeRunPackageInput, RuntimeSessionPackage, RuntimeSessionPackageInput, UpdateMemoryInput, } from "./contracts/types.js";
|
|
12
|
+
export type { AcpHttpServer, AcpHttpServerOptions } from "./protocol/acp/http.js";
|
|
12
13
|
export type { AcpStdioServer, AcpStdioServerOptions } from "./protocol/acp/stdio.js";
|
|
13
14
|
type PublicApprovalRecord = {
|
|
14
15
|
approvalId: string;
|
|
@@ -85,10 +86,17 @@ export declare function getArtifact(runtime: AgentHarnessRuntime, input: {
|
|
|
85
86
|
requestId: string;
|
|
86
87
|
artifactPath: string;
|
|
87
88
|
}): Promise<unknown>;
|
|
89
|
+
export declare function listRunEvents(runtime: AgentHarnessRuntime, input: {
|
|
90
|
+
sessionId: string;
|
|
91
|
+
requestId: string;
|
|
92
|
+
}): Promise<import("./contracts/runtime.js").HarnessEvent[]>;
|
|
88
93
|
export declare function getHealth(runtime: AgentHarnessRuntime): Promise<RuntimeHealthSnapshot>;
|
|
94
|
+
export declare function exportRunPackage(runtime: AgentHarnessRuntime, input: RuntimeRunPackageInput): Promise<RuntimeRunPackage>;
|
|
95
|
+
export declare function exportSessionPackage(runtime: AgentHarnessRuntime, input: RuntimeSessionPackageInput): Promise<RuntimeSessionPackage>;
|
|
89
96
|
export declare function exportEvaluationBundle(runtime: AgentHarnessRuntime, input: RuntimeEvaluationExportInput): Promise<RuntimeEvaluationExport>;
|
|
90
97
|
export declare function replayEvaluationBundle(runtime: AgentHarnessRuntime, input: RuntimeEvaluationReplayInput): Promise<RuntimeEvaluationReplayResult>;
|
|
91
98
|
export declare function serveAcpStdio(runtime: AgentHarnessRuntime, options?: import("./protocol/acp/stdio.js").AcpStdioServerOptions): import("./protocol/acp/stdio.js").AcpStdioServer;
|
|
99
|
+
export declare function serveAcpHttp(runtime: AgentHarnessRuntime, options?: import("./protocol/acp/http.js").AcpHttpServerOptions): Promise<import("./protocol/acp/http.js").AcpHttpServer>;
|
|
92
100
|
export declare function listAgentSkills(runtime: AgentHarnessRuntime, agentId: string, options?: RequirementAssessmentOptions): InventorySkillRecord[];
|
|
93
101
|
export declare function getAgent(runtime: AgentHarnessRuntime, agentId: string, options?: RequirementAssessmentOptions): InventoryAgentRecord | null;
|
|
94
102
|
export declare function describeInventory(runtime: AgentHarnessRuntime, options?: RequirementAssessmentOptions): {
|
package/dist/api.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AgentHarnessRuntime } from "./runtime/harness.js";
|
|
2
|
+
import { serveAcpOverHttp } from "./protocol/acp/http.js";
|
|
2
3
|
import { serveAcpOverStdio } from "./protocol/acp/stdio.js";
|
|
3
4
|
import { normalizeMessageContent } from "./utils/message-content.js";
|
|
4
5
|
import { loadWorkspace } from "./workspace/compile.js";
|
|
@@ -187,9 +188,18 @@ export async function listArtifacts(runtime, input) {
|
|
|
187
188
|
export async function getArtifact(runtime, input) {
|
|
188
189
|
return runtime.readArtifact(input.sessionId, input.requestId, input.artifactPath);
|
|
189
190
|
}
|
|
191
|
+
export async function listRunEvents(runtime, input) {
|
|
192
|
+
return runtime.listRunEvents(input.sessionId, input.requestId);
|
|
193
|
+
}
|
|
190
194
|
export async function getHealth(runtime) {
|
|
191
195
|
return runtime.getHealth();
|
|
192
196
|
}
|
|
197
|
+
export async function exportRunPackage(runtime, input) {
|
|
198
|
+
return runtime.exportRunPackage(input);
|
|
199
|
+
}
|
|
200
|
+
export async function exportSessionPackage(runtime, input) {
|
|
201
|
+
return runtime.exportSessionPackage(input);
|
|
202
|
+
}
|
|
193
203
|
export async function exportEvaluationBundle(runtime, input) {
|
|
194
204
|
return runtime.exportEvaluationBundle(input);
|
|
195
205
|
}
|
|
@@ -199,6 +209,9 @@ export async function replayEvaluationBundle(runtime, input) {
|
|
|
199
209
|
export function serveAcpStdio(runtime, options) {
|
|
200
210
|
return serveAcpOverStdio(runtime, options);
|
|
201
211
|
}
|
|
212
|
+
export async function serveAcpHttp(runtime, options) {
|
|
213
|
+
return serveAcpOverHttp(runtime, options);
|
|
214
|
+
}
|
|
202
215
|
export function listAgentSkills(runtime, agentId, options) {
|
|
203
216
|
return runtime.listAgentSkills(agentId, options);
|
|
204
217
|
}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createAgentHarness } from "./api.js";
|
|
3
|
+
import { serveAcpOverHttp } from "./protocol/acp/http.js";
|
|
3
4
|
import { serveAcpOverStdio } from "./protocol/acp/stdio.js";
|
|
4
5
|
type CliIo = {
|
|
5
6
|
cwd?: string;
|
|
@@ -8,6 +9,7 @@ type CliIo = {
|
|
|
8
9
|
};
|
|
9
10
|
type CliDeps = {
|
|
10
11
|
createAgentHarness?: typeof createAgentHarness;
|
|
12
|
+
serveAcpOverHttp?: typeof serveAcpOverHttp;
|
|
11
13
|
serveAcpOverStdio?: typeof serveAcpOverStdio;
|
|
12
14
|
};
|
|
13
15
|
export declare function runCli(argv: string[], io?: CliIo, deps?: CliDeps): Promise<number>;
|
package/dist/cli.js
CHANGED
|
@@ -3,11 +3,12 @@ import path from "node:path";
|
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { createAgentHarness } from "./api.js";
|
|
5
5
|
import { initProject } from "./init-project.js";
|
|
6
|
+
import { serveAcpOverHttp } from "./protocol/acp/http.js";
|
|
6
7
|
import { serveAcpOverStdio } from "./protocol/acp/stdio.js";
|
|
7
8
|
function renderUsage() {
|
|
8
9
|
return `Usage:
|
|
9
10
|
agent-harness init <project-name> [--template deep-research|single-agent] [--provider <provider>] [--model <model>] [--with-web-search|--no-web-search]
|
|
10
|
-
agent-harness acp serve [--workspace <path>] [--transport stdio]
|
|
11
|
+
agent-harness acp serve [--workspace <path>] [--transport stdio|http] [--host <hostname>] [--port <port>]
|
|
11
12
|
`;
|
|
12
13
|
}
|
|
13
14
|
function isTemplate(value) {
|
|
@@ -52,6 +53,8 @@ function parseInitOptions(args) {
|
|
|
52
53
|
function parseAcpServeOptions(args) {
|
|
53
54
|
let workspaceRoot;
|
|
54
55
|
let transport = "stdio";
|
|
56
|
+
let hostname;
|
|
57
|
+
let port;
|
|
55
58
|
for (let index = 0; index < args.length; index += 1) {
|
|
56
59
|
const arg = args[index];
|
|
57
60
|
if (arg === "--workspace") {
|
|
@@ -66,18 +69,40 @@ function parseAcpServeOptions(args) {
|
|
|
66
69
|
if (arg === "--transport") {
|
|
67
70
|
const value = args[index + 1];
|
|
68
71
|
if (!value) {
|
|
69
|
-
return { transport, error: "Missing value for --transport" };
|
|
72
|
+
return { transport, hostname, port, error: "Missing value for --transport" };
|
|
70
73
|
}
|
|
71
|
-
if (value !== "stdio") {
|
|
72
|
-
return { transport, error: `Unsupported ACP transport: ${value}` };
|
|
74
|
+
if (value !== "stdio" && value !== "http") {
|
|
75
|
+
return { transport, hostname, port, error: `Unsupported ACP transport: ${value}` };
|
|
73
76
|
}
|
|
74
|
-
transport =
|
|
77
|
+
transport = value;
|
|
75
78
|
index += 1;
|
|
76
79
|
continue;
|
|
77
80
|
}
|
|
78
|
-
|
|
81
|
+
if (arg === "--host") {
|
|
82
|
+
const value = args[index + 1];
|
|
83
|
+
if (!value) {
|
|
84
|
+
return { transport, hostname, port, error: "Missing value for --host" };
|
|
85
|
+
}
|
|
86
|
+
hostname = value;
|
|
87
|
+
index += 1;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (arg === "--port") {
|
|
91
|
+
const value = args[index + 1];
|
|
92
|
+
if (!value) {
|
|
93
|
+
return { transport, hostname, port, error: "Missing value for --port" };
|
|
94
|
+
}
|
|
95
|
+
const parsedPort = Number.parseInt(value, 10);
|
|
96
|
+
if (!Number.isFinite(parsedPort) || parsedPort < 0) {
|
|
97
|
+
return { transport, hostname, port, error: `Invalid ACP port: ${value}` };
|
|
98
|
+
}
|
|
99
|
+
port = parsedPort;
|
|
100
|
+
index += 1;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
return { transport, hostname, port, error: `Unknown option: ${arg}` };
|
|
79
104
|
}
|
|
80
|
-
return { workspaceRoot, transport };
|
|
105
|
+
return { workspaceRoot, transport, hostname, port };
|
|
81
106
|
}
|
|
82
107
|
export async function runCli(argv, io = {}, deps = {}) {
|
|
83
108
|
const cwd = io.cwd ?? process.cwd();
|
|
@@ -85,6 +110,7 @@ export async function runCli(argv, io = {}, deps = {}) {
|
|
|
85
110
|
const stderr = io.stderr ?? ((message) => process.stderr.write(message));
|
|
86
111
|
const [command, projectName, ...rest] = argv;
|
|
87
112
|
const createHarness = deps.createAgentHarness ?? createAgentHarness;
|
|
113
|
+
const serveAcpHttp = deps.serveAcpOverHttp ?? serveAcpOverHttp;
|
|
88
114
|
const serveAcp = deps.serveAcpOverStdio ?? serveAcpOverStdio;
|
|
89
115
|
if (command === "init") {
|
|
90
116
|
if (!projectName?.trim()) {
|
|
@@ -130,9 +156,20 @@ export async function runCli(argv, io = {}, deps = {}) {
|
|
|
130
156
|
}
|
|
131
157
|
try {
|
|
132
158
|
const runtime = await createHarness(path.resolve(cwd, parsed.workspaceRoot ?? "."));
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
159
|
+
const workspacePath = path.resolve(cwd, parsed.workspaceRoot ?? ".");
|
|
160
|
+
if (parsed.transport === "http") {
|
|
161
|
+
const server = await serveAcpHttp(runtime, {
|
|
162
|
+
hostname: parsed.hostname,
|
|
163
|
+
port: parsed.port,
|
|
164
|
+
});
|
|
165
|
+
stderr(`Serving ACP over http from ${workspacePath} at ${server.rpcUrl} (events ${server.eventsUrl})\n`);
|
|
166
|
+
await server.completed;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
stderr(`Serving ACP over stdio from ${workspacePath}\n`);
|
|
170
|
+
const server = serveAcp(runtime);
|
|
171
|
+
await server.completed;
|
|
172
|
+
}
|
|
136
173
|
await runtime.stop();
|
|
137
174
|
return 0;
|
|
138
175
|
}
|
|
@@ -102,6 +102,8 @@ export type RuntimeGovernanceToolPolicy = {
|
|
|
102
102
|
toolId: string;
|
|
103
103
|
toolType: string;
|
|
104
104
|
category: "local" | "backend" | "mcp" | "provider-native";
|
|
105
|
+
mcpServerRef?: string;
|
|
106
|
+
mcpTransport?: string;
|
|
105
107
|
risk: RuntimeGovernanceRiskLevel;
|
|
106
108
|
requiresApproval: boolean;
|
|
107
109
|
approvalPolicy: "explicit-hitl" | "runtime-default" | "none";
|
|
@@ -626,6 +628,36 @@ export type RuntimeEvaluationReplayResult = {
|
|
|
626
628
|
expectedOutputMatched?: boolean;
|
|
627
629
|
};
|
|
628
630
|
};
|
|
631
|
+
export type RuntimeRunPackageInput = {
|
|
632
|
+
sessionId: string;
|
|
633
|
+
requestId: string;
|
|
634
|
+
includeArtifacts?: boolean;
|
|
635
|
+
includeArtifactContents?: boolean;
|
|
636
|
+
includeRuntimeHealth?: boolean;
|
|
637
|
+
};
|
|
638
|
+
export type RuntimeRunPackage = {
|
|
639
|
+
session: SessionRecord | null;
|
|
640
|
+
request: RequestRecord | null;
|
|
641
|
+
approvals: ApprovalRecord[];
|
|
642
|
+
transcript: TranscriptMessage[];
|
|
643
|
+
events: HarnessEvent[];
|
|
644
|
+
artifacts: RuntimeEvaluationArtifact[];
|
|
645
|
+
runtimeHealth?: RuntimeHealthSnapshot;
|
|
646
|
+
};
|
|
647
|
+
export type RuntimeSessionPackageInput = {
|
|
648
|
+
sessionId: string;
|
|
649
|
+
includeArtifacts?: boolean;
|
|
650
|
+
includeArtifactContents?: boolean;
|
|
651
|
+
includeRuntimeHealth?: boolean;
|
|
652
|
+
};
|
|
653
|
+
export type RuntimeSessionPackage = {
|
|
654
|
+
session: SessionRecord | null;
|
|
655
|
+
requests: RequestRecord[];
|
|
656
|
+
approvals: ApprovalRecord[];
|
|
657
|
+
transcript: TranscriptMessage[];
|
|
658
|
+
runs: RuntimeRunPackage[];
|
|
659
|
+
runtimeHealth?: RuntimeHealthSnapshot;
|
|
660
|
+
};
|
|
629
661
|
export type RuntimeInventoryContext = {
|
|
630
662
|
workspace: WorkspaceBundle;
|
|
631
663
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { AgentHarnessAcpServer, AgentHarnessRuntime, buildFlowGraph, cancelRun, createAgentHarness, createAcpServer, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, exportEvaluationBundle, replayEvaluationBundle, getArtifact, getAgent, getApproval, getRequest, getHealth, listMemories, getSession, listAgentSkills, listArtifacts, listApprovals, listRequests, listSessions, memorize, normalizeUserChatInput, recall, removeMemory, resolveApproval, run, serveAcpStdio, serveToolsOverStdio, subscribe, stop, updateMemory, exportFlowGraphToMermaid, exportFlowGraphToSequenceMermaid, } from "./api.js";
|
|
1
|
+
export { AgentHarnessAcpServer, AgentHarnessRuntime, buildFlowGraph, cancelRun, createAgentHarness, createAcpServer, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, exportEvaluationBundle, exportRunPackage, exportSessionPackage, replayEvaluationBundle, getArtifact, getAgent, getApproval, getRequest, getHealth, listMemories, listRunEvents, getSession, listAgentSkills, listArtifacts, listApprovals, listRequests, listSessions, memorize, normalizeUserChatInput, recall, removeMemory, resolveApproval, run, serveAcpHttp, serveAcpStdio, serveToolsOverStdio, subscribe, stop, updateMemory, exportFlowGraphToMermaid, exportFlowGraphToSequenceMermaid, } from "./api.js";
|
|
2
2
|
export type { AcpApproval, AcpArtifact, AcpEventNotification, AcpJsonRpcError, AcpJsonRpcRequest, AcpJsonRpcResponse, AcpJsonRpcSuccess, AcpRequestRecord, AcpRunRequestParams, AcpServerCapabilities, AcpSessionRecord, } from "./acp.js";
|
|
3
|
-
export type { ListMemoriesInput, ListMemoriesResult, MemoryDecision, MemoryKind, MemoryRecord, MemoryScope, MemorizeInput, MemorizeResult, NormalizeUserChatInputOptions, RecallInput, RecallResult, RemoveMemoryInput, RuntimeEvaluationExport, RuntimeEvaluationExportInput, RuntimeEvaluationReplayInput, RuntimeEvaluationReplayResult, UpdateMemoryInput, UserChatInput, UserChatMessage, } from "./api.js";
|
|
3
|
+
export type { ListMemoriesInput, ListMemoriesResult, MemoryDecision, MemoryKind, MemoryRecord, MemoryScope, MemorizeInput, MemorizeResult, NormalizeUserChatInputOptions, RecallInput, RecallResult, RemoveMemoryInput, RuntimeEvaluationExport, RuntimeEvaluationExportInput, RuntimeEvaluationReplayInput, RuntimeEvaluationReplayResult, RuntimeRunPackage, RuntimeRunPackageInput, 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
|
-
export type { AcpStdioServer, AcpStdioServerOptions } from "./api.js";
|
|
5
|
+
export type { AcpHttpServer, AcpHttpServerOptions, AcpStdioServer, AcpStdioServerOptions } from "./api.js";
|
|
6
6
|
export type { ToolMcpServerOptions } from "./mcp.js";
|
|
7
7
|
export { tool } from "./tools.js";
|
|
8
8
|
export type { UpstreamTimelineProjection, UpstreamTimelineReducer } from "./upstream-events.js";
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { AgentHarnessAcpServer, AgentHarnessRuntime, buildFlowGraph, cancelRun, createAgentHarness, createAcpServer, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, exportEvaluationBundle, replayEvaluationBundle, getArtifact, getAgent, getApproval, getRequest, getHealth, listMemories, getSession, listAgentSkills, listArtifacts, listApprovals, listRequests, listSessions, memorize, normalizeUserChatInput, recall, removeMemory, resolveApproval, run, serveAcpStdio, serveToolsOverStdio, subscribe, stop, updateMemory, exportFlowGraphToMermaid, exportFlowGraphToSequenceMermaid, } from "./api.js";
|
|
1
|
+
export { AgentHarnessAcpServer, AgentHarnessRuntime, buildFlowGraph, cancelRun, createAgentHarness, createAcpServer, createUpstreamTimelineReducer, createToolMcpServer, deleteSession, describeInventory, exportEvaluationBundle, exportRunPackage, exportSessionPackage, replayEvaluationBundle, getArtifact, getAgent, getApproval, getRequest, getHealth, listMemories, listRunEvents, getSession, listAgentSkills, listArtifacts, listApprovals, listRequests, listSessions, memorize, normalizeUserChatInput, recall, removeMemory, resolveApproval, run, serveAcpHttp, serveAcpStdio, 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.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.161";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.161";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Server } from "node:http";
|
|
2
|
+
import type { AgentHarnessRuntime } from "../../runtime/harness.js";
|
|
3
|
+
export type AcpHttpServerOptions = {
|
|
4
|
+
hostname?: string;
|
|
5
|
+
port?: number;
|
|
6
|
+
rpcPath?: string;
|
|
7
|
+
eventsPath?: string;
|
|
8
|
+
};
|
|
9
|
+
export type AcpHttpServer = {
|
|
10
|
+
hostname: string;
|
|
11
|
+
port: number;
|
|
12
|
+
rpcPath: string;
|
|
13
|
+
eventsPath: string;
|
|
14
|
+
rpcUrl: string;
|
|
15
|
+
eventsUrl: string;
|
|
16
|
+
completed: Promise<void>;
|
|
17
|
+
close: () => Promise<void>;
|
|
18
|
+
};
|
|
19
|
+
export declare function serveAcpOverHttp(runtime: AgentHarnessRuntime, options?: AcpHttpServerOptions): Promise<AcpHttpServer>;
|
|
20
|
+
export type { Server as AcpHttpNodeServer };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { createAcpServer } from "../../acp.js";
|
|
3
|
+
function normalizePath(value, fallback) {
|
|
4
|
+
const source = typeof value === "string" && value.trim().length > 0 ? value.trim() : fallback;
|
|
5
|
+
return source.startsWith("/") ? source : `/${source}`;
|
|
6
|
+
}
|
|
7
|
+
function writeJson(response, statusCode, payload) {
|
|
8
|
+
response.statusCode = statusCode;
|
|
9
|
+
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
10
|
+
response.end(JSON.stringify(payload));
|
|
11
|
+
}
|
|
12
|
+
function readRequestBody(request) {
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
const chunks = [];
|
|
15
|
+
request.on("data", (chunk) => {
|
|
16
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
17
|
+
});
|
|
18
|
+
request.on("end", () => {
|
|
19
|
+
resolve(Buffer.concat(chunks).toString("utf8"));
|
|
20
|
+
});
|
|
21
|
+
request.on("error", reject);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
export async function serveAcpOverHttp(runtime, options = {}) {
|
|
25
|
+
const hostname = options.hostname?.trim() || "127.0.0.1";
|
|
26
|
+
const port = typeof options.port === "number" && Number.isFinite(options.port) ? options.port : 0;
|
|
27
|
+
const rpcPath = normalizePath(options.rpcPath, "/rpc");
|
|
28
|
+
const eventsPath = normalizePath(options.eventsPath, "/events");
|
|
29
|
+
const server = createAcpServer(runtime);
|
|
30
|
+
const eventSubscribers = new Set();
|
|
31
|
+
const unsubscribe = server.subscribe((notification) => {
|
|
32
|
+
const payload = `data: ${JSON.stringify(notification)}\n\n`;
|
|
33
|
+
for (const response of Array.from(eventSubscribers)) {
|
|
34
|
+
if (response.writableEnded || response.destroyed) {
|
|
35
|
+
eventSubscribers.delete(response);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
response.write(payload);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const httpServer = createServer(async (request, response) => {
|
|
42
|
+
try {
|
|
43
|
+
const requestUrl = new URL(request.url ?? "/", `http://${hostname}`);
|
|
44
|
+
if (request.method === "GET" && requestUrl.pathname === eventsPath) {
|
|
45
|
+
response.statusCode = 200;
|
|
46
|
+
response.setHeader("content-type", "text/event-stream; charset=utf-8");
|
|
47
|
+
response.setHeader("cache-control", "no-cache, no-transform");
|
|
48
|
+
response.setHeader("connection", "keep-alive");
|
|
49
|
+
response.write(": connected\n\n");
|
|
50
|
+
eventSubscribers.add(response);
|
|
51
|
+
request.on("close", () => {
|
|
52
|
+
eventSubscribers.delete(response);
|
|
53
|
+
response.end();
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (request.method === "POST" && requestUrl.pathname === rpcPath) {
|
|
58
|
+
const body = await readRequestBody(request);
|
|
59
|
+
let payload;
|
|
60
|
+
try {
|
|
61
|
+
payload = JSON.parse(body);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
writeJson(response, 400, {
|
|
65
|
+
jsonrpc: "2.0",
|
|
66
|
+
id: null,
|
|
67
|
+
error: {
|
|
68
|
+
code: -32700,
|
|
69
|
+
message: "Invalid JSON payload.",
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const rpcResponse = await server.handle(payload);
|
|
75
|
+
if (!rpcResponse) {
|
|
76
|
+
response.statusCode = 204;
|
|
77
|
+
response.end();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
writeJson(response, 200, rpcResponse);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
writeJson(response, 404, {
|
|
84
|
+
error: "Not Found",
|
|
85
|
+
rpcPath,
|
|
86
|
+
eventsPath,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
writeJson(response, 500, {
|
|
91
|
+
error: error instanceof Error ? error.message : "ACP HTTP transport failed.",
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
const completed = new Promise((resolve, reject) => {
|
|
96
|
+
httpServer.once("close", resolve);
|
|
97
|
+
httpServer.once("error", reject);
|
|
98
|
+
});
|
|
99
|
+
await new Promise((resolve, reject) => {
|
|
100
|
+
httpServer.listen(port, hostname, () => resolve());
|
|
101
|
+
httpServer.once("error", reject);
|
|
102
|
+
});
|
|
103
|
+
const address = httpServer.address();
|
|
104
|
+
const resolvedPort = typeof address === "object" && address ? address.port : port;
|
|
105
|
+
return {
|
|
106
|
+
hostname,
|
|
107
|
+
port: resolvedPort,
|
|
108
|
+
rpcPath,
|
|
109
|
+
eventsPath,
|
|
110
|
+
rpcUrl: `http://${hostname}:${resolvedPort}${rpcPath}`,
|
|
111
|
+
eventsUrl: `http://${hostname}:${resolvedPort}${eventsPath}`,
|
|
112
|
+
completed,
|
|
113
|
+
close: async () => {
|
|
114
|
+
unsubscribe();
|
|
115
|
+
for (const response of Array.from(eventSubscribers)) {
|
|
116
|
+
response.end();
|
|
117
|
+
}
|
|
118
|
+
eventSubscribers.clear();
|
|
119
|
+
await new Promise((resolve, reject) => {
|
|
120
|
+
httpServer.close((error) => {
|
|
121
|
+
if (error) {
|
|
122
|
+
reject(error);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
resolve();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -57,6 +57,25 @@ function readRisk(value) {
|
|
|
57
57
|
function readApprovalPolicy(value) {
|
|
58
58
|
return value === "explicit-hitl" || value === "runtime-default" || value === "none" ? value : undefined;
|
|
59
59
|
}
|
|
60
|
+
function normalizeServerRef(value) {
|
|
61
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
const trimmed = value.trim();
|
|
65
|
+
return trimmed.startsWith("mcp/") ? trimmed : `mcp/${trimmed}`;
|
|
66
|
+
}
|
|
67
|
+
function readRemoteMcpMetadata(tool) {
|
|
68
|
+
const config = asObject(tool.config);
|
|
69
|
+
const mcpReference = asObject(config?.mcp);
|
|
70
|
+
const inlineServer = asObject(config?.mcpServer);
|
|
71
|
+
const transport = typeof inlineServer?.transport === "string" && inlineServer.transport.trim().length > 0
|
|
72
|
+
? inlineServer.transport.trim()
|
|
73
|
+
: undefined;
|
|
74
|
+
return {
|
|
75
|
+
...(normalizeServerRef(mcpReference?.serverRef) ? { serverRef: normalizeServerRef(mcpReference?.serverRef) } : {}),
|
|
76
|
+
...(transport ? { transport } : {}),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
60
79
|
function matchesToolPolicy(rule, policy) {
|
|
61
80
|
const match = asObject(rule.match) ?? rule;
|
|
62
81
|
const toolName = typeof match.toolName === "string" ? match.toolName.trim() : undefined;
|
|
@@ -102,14 +121,49 @@ function applyGovernanceOverrides(binding, policies) {
|
|
|
102
121
|
return merged;
|
|
103
122
|
});
|
|
104
123
|
}
|
|
124
|
+
function applyRemoteMcpGovernance(binding, policies) {
|
|
125
|
+
const governance = asObject(binding.harnessRuntime.governance);
|
|
126
|
+
const remoteMcp = asObject(governance?.remoteMcp);
|
|
127
|
+
if (!remoteMcp) {
|
|
128
|
+
return policies;
|
|
129
|
+
}
|
|
130
|
+
const requireApprovalTransports = new Set(readStringArray(remoteMcp.requireApprovalTransports));
|
|
131
|
+
const riskByTransport = asObject(remoteMcp.riskByTransport);
|
|
132
|
+
const inputRiskHintsByTransport = asObject(remoteMcp.inputRiskHintsByTransport);
|
|
133
|
+
return policies.map((policy) => {
|
|
134
|
+
if (policy.category !== "mcp") {
|
|
135
|
+
return policy;
|
|
136
|
+
}
|
|
137
|
+
const merged = { ...policy };
|
|
138
|
+
const transport = merged.mcpTransport;
|
|
139
|
+
if (transport && requireApprovalTransports.has(transport)) {
|
|
140
|
+
merged.requiresApproval = true;
|
|
141
|
+
if (merged.approvalPolicy === "none") {
|
|
142
|
+
merged.approvalPolicy = "runtime-default";
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const transportRisk = transport ? readRisk(riskByTransport?.[transport]) : undefined;
|
|
146
|
+
if (transportRisk) {
|
|
147
|
+
merged.risk = transportRisk;
|
|
148
|
+
}
|
|
149
|
+
const transportHints = transport ? readStringArray(inputRiskHintsByTransport?.[transport]) : [];
|
|
150
|
+
if (transportHints.length > 0) {
|
|
151
|
+
merged.inputRiskHints = Array.from(new Set([...merged.inputRiskHints, ...transportHints]));
|
|
152
|
+
}
|
|
153
|
+
return merged;
|
|
154
|
+
});
|
|
155
|
+
}
|
|
105
156
|
export function buildRuntimeGovernanceBundles(binding) {
|
|
106
|
-
const toolPolicies = applyGovernanceOverrides(binding, getBindingPrimaryTools(binding).map((tool) => {
|
|
157
|
+
const toolPolicies = applyGovernanceOverrides(binding, applyRemoteMcpGovernance(binding, getBindingPrimaryTools(binding).map((tool) => {
|
|
107
158
|
const requiresApproval = toolRequiresRuntimeApproval(tool);
|
|
159
|
+
const remoteMcp = readRemoteMcpMetadata(tool);
|
|
108
160
|
return {
|
|
109
161
|
toolName: tool.name,
|
|
110
162
|
toolId: tool.id,
|
|
111
163
|
toolType: tool.type,
|
|
112
164
|
category: toCategory(tool.type),
|
|
165
|
+
...(remoteMcp.serverRef ? { mcpServerRef: remoteMcp.serverRef } : {}),
|
|
166
|
+
...(remoteMcp.transport ? { mcpTransport: remoteMcp.transport } : {}),
|
|
113
167
|
risk: classifyRisk({
|
|
114
168
|
toolType: tool.type,
|
|
115
169
|
requiresApproval,
|
|
@@ -122,7 +176,7 @@ export function buildRuntimeGovernanceBundles(binding) {
|
|
|
122
176
|
hasInputSchema: typeof tool.inputSchemaRef === "string" && tool.inputSchemaRef.trim().length > 0,
|
|
123
177
|
inputRiskHints: inputHints(binding, tool),
|
|
124
178
|
};
|
|
125
|
-
}));
|
|
179
|
+
})));
|
|
126
180
|
if (toolPolicies.length === 0) {
|
|
127
181
|
return [];
|
|
128
182
|
}
|
|
@@ -12,6 +12,9 @@ export class PolicyEngine {
|
|
|
12
12
|
const governance = typeof binding.harnessRuntime.governance === "object" && binding.harnessRuntime.governance
|
|
13
13
|
? binding.harnessRuntime.governance
|
|
14
14
|
: undefined;
|
|
15
|
+
const remoteMcp = typeof governance?.remoteMcp === "object" && governance.remoteMcp
|
|
16
|
+
? governance.remoteMcp
|
|
17
|
+
: undefined;
|
|
15
18
|
const denyConfig = typeof governance?.deny === "object" && governance.deny
|
|
16
19
|
? governance.deny
|
|
17
20
|
: undefined;
|
|
@@ -38,6 +41,72 @@ export class PolicyEngine {
|
|
|
38
41
|
reasons.push(`runtime governance denied tool access: ${blocked.map((tool) => tool.name).join(", ")}`);
|
|
39
42
|
}
|
|
40
43
|
}
|
|
44
|
+
if (remoteMcp) {
|
|
45
|
+
const normalizeServerRef = (value) => {
|
|
46
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
const trimmed = value.trim();
|
|
50
|
+
return trimmed.startsWith("mcp/") ? trimmed : `mcp/${trimmed}`;
|
|
51
|
+
};
|
|
52
|
+
const allowServerRefs = new Set(Array.isArray(remoteMcp.allowServerRefs)
|
|
53
|
+
? remoteMcp.allowServerRefs
|
|
54
|
+
.map((item) => normalizeServerRef(item))
|
|
55
|
+
.filter((item) => Boolean(item))
|
|
56
|
+
: []);
|
|
57
|
+
const denyServerRefs = new Set(Array.isArray(remoteMcp.denyServerRefs)
|
|
58
|
+
? remoteMcp.denyServerRefs
|
|
59
|
+
.map((item) => normalizeServerRef(item))
|
|
60
|
+
.filter((item) => Boolean(item))
|
|
61
|
+
: []);
|
|
62
|
+
const denyTransports = new Set(Array.isArray(remoteMcp.denyTransports)
|
|
63
|
+
? remoteMcp.denyTransports.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim())
|
|
64
|
+
: []);
|
|
65
|
+
const tools = binding.execution?.params?.tools ?? binding.langchainAgentParams?.tools ?? binding.deepAgentParams?.tools ?? [];
|
|
66
|
+
const deniedRemoteTools = tools.flatMap((tool) => {
|
|
67
|
+
if (tool.type !== "mcp") {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
const config = typeof tool.config === "object" && tool.config && !Array.isArray(tool.config)
|
|
71
|
+
? tool.config
|
|
72
|
+
: undefined;
|
|
73
|
+
const mcpRef = typeof config?.mcp === "object" && config.mcp && !Array.isArray(config.mcp)
|
|
74
|
+
? config.mcp
|
|
75
|
+
: undefined;
|
|
76
|
+
const inlineMcpServer = typeof config?.mcpServer === "object" && config.mcpServer && !Array.isArray(config.mcpServer)
|
|
77
|
+
? config.mcpServer
|
|
78
|
+
: undefined;
|
|
79
|
+
const serverRef = normalizeServerRef(mcpRef?.serverRef);
|
|
80
|
+
const transport = typeof inlineMcpServer?.transport === "string" && inlineMcpServer.transport.trim().length > 0
|
|
81
|
+
? inlineMcpServer.transport.trim()
|
|
82
|
+
: undefined;
|
|
83
|
+
const serverDenied = serverRef ? denyServerRefs.has(serverRef) || (allowServerRefs.size > 0 && !allowServerRefs.has(serverRef)) : false;
|
|
84
|
+
const transportDenied = transport ? denyTransports.has(transport) : false;
|
|
85
|
+
return serverDenied || transportDenied
|
|
86
|
+
? [{
|
|
87
|
+
toolName: tool.name,
|
|
88
|
+
...(serverRef ? { serverRef } : {}),
|
|
89
|
+
...(transport ? { transport } : {}),
|
|
90
|
+
}]
|
|
91
|
+
: [];
|
|
92
|
+
});
|
|
93
|
+
if (deniedRemoteTools.length > 0) {
|
|
94
|
+
allowed = false;
|
|
95
|
+
const details = deniedRemoteTools.map((tool) => {
|
|
96
|
+
if (tool.serverRef && tool.transport) {
|
|
97
|
+
return `${tool.toolName} (${tool.serverRef}, ${tool.transport})`;
|
|
98
|
+
}
|
|
99
|
+
if (tool.serverRef) {
|
|
100
|
+
return `${tool.toolName} (${tool.serverRef})`;
|
|
101
|
+
}
|
|
102
|
+
if (tool.transport) {
|
|
103
|
+
return `${tool.toolName} (${tool.transport})`;
|
|
104
|
+
}
|
|
105
|
+
return tool.toolName;
|
|
106
|
+
});
|
|
107
|
+
reasons.push(`runtime governance denied remote MCP access: ${details.join(", ")}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
41
110
|
for (const evaluator of getPolicyEvaluators()) {
|
|
42
111
|
const decision = evaluator.evaluate(binding);
|
|
43
112
|
if (!decision) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ApprovalRecord, ArtifactListing, CancelOptions, HarnessEvent, HarnessStreamItem, RuntimeHealthSnapshot, ListMemoriesInput, ListMemoriesResult, MessageContent, RemoveMemoryInput, RunRecord, RunStartOptions, RestartConversationOptions, RuntimeAdapterOptions, RuntimeEvaluationExport, RuntimeEvaluationExportInput, RuntimeEvaluationReplayInput, RuntimeEvaluationReplayResult, ResumeOptions, RunOptions, RunResult, RunSummary, MemoryRecord, MemorizeInput, MemorizeResult, RecallInput, RecallResult, UpdateMemoryInput, ThreadSummary, ThreadRecord, WorkspaceBundle } from "../contracts/types.js";
|
|
1
|
+
import type { ApprovalRecord, ArtifactListing, CancelOptions, HarnessEvent, HarnessStreamItem, RuntimeHealthSnapshot, ListMemoriesInput, ListMemoriesResult, MessageContent, RemoveMemoryInput, RunRecord, RunStartOptions, RestartConversationOptions, RuntimeAdapterOptions, RuntimeEvaluationExport, RuntimeEvaluationExportInput, RuntimeEvaluationReplayInput, RuntimeEvaluationReplayResult, RuntimeRunPackage, RuntimeRunPackageInput, RuntimeSessionPackage, RuntimeSessionPackageInput, ResumeOptions, RunOptions, RunResult, RunSummary, MemoryRecord, MemorizeInput, MemorizeResult, RecallInput, RecallResult, UpdateMemoryInput, ThreadSummary, ThreadRecord, WorkspaceBundle } from "../contracts/types.js";
|
|
2
2
|
import { type ToolMcpServerOptions } from "../mcp.js";
|
|
3
3
|
import { type InventoryAgentRecord, type InventorySkillRecord } from "./harness/system/inventory.js";
|
|
4
4
|
import type { RequirementAssessmentOptions } from "./harness/system/skill-requirements.js";
|
|
@@ -85,6 +85,8 @@ export declare class AgentHarnessRuntime {
|
|
|
85
85
|
listArtifacts(threadId: string, runId: string): Promise<ArtifactListing>;
|
|
86
86
|
readArtifact(threadId: string, runId: string, artifactPath: string): Promise<unknown>;
|
|
87
87
|
listRunEvents(threadId: string, runId: string): Promise<HarnessEvent[]>;
|
|
88
|
+
exportRunPackage(input: RuntimeRunPackageInput): Promise<RuntimeRunPackage>;
|
|
89
|
+
exportSessionPackage(input: RuntimeSessionPackageInput): Promise<RuntimeSessionPackage>;
|
|
88
90
|
exportEvaluationBundle(input: RuntimeEvaluationExportInput): Promise<RuntimeEvaluationExport>;
|
|
89
91
|
replayEvaluationBundle(input: RuntimeEvaluationReplayInput): Promise<RuntimeEvaluationReplayResult>;
|
|
90
92
|
listAgentSkills(agentId: string, options?: RequirementAssessmentOptions): InventorySkillRecord[];
|
package/dist/runtime/harness.js
CHANGED
|
@@ -484,6 +484,50 @@ export class AgentHarnessRuntime {
|
|
|
484
484
|
async listRunEvents(threadId, runId) {
|
|
485
485
|
return this.persistence.listRunEvents(threadId, runId);
|
|
486
486
|
}
|
|
487
|
+
async exportRunPackage(input) {
|
|
488
|
+
const thread = await this.getThread(input.sessionId);
|
|
489
|
+
const run = await this.getRun(input.requestId);
|
|
490
|
+
const approvals = await this.listApprovals({ threadId: input.sessionId, runId: input.requestId });
|
|
491
|
+
const transcript = await this.persistence.listThreadMessages(input.sessionId, 500);
|
|
492
|
+
const events = await this.persistence.listRunEvents(input.sessionId, input.requestId);
|
|
493
|
+
const artifactsListing = input.includeArtifacts === false
|
|
494
|
+
? { items: [] }
|
|
495
|
+
: await this.persistence.listArtifacts(input.sessionId, input.requestId);
|
|
496
|
+
const artifacts = await Promise.all(artifactsListing.items.map(async (artifact) => ({
|
|
497
|
+
...artifact,
|
|
498
|
+
...(input.includeArtifactContents === true
|
|
499
|
+
? { content: await this.persistence.readArtifact(input.sessionId, input.requestId, artifact.path) }
|
|
500
|
+
: {}),
|
|
501
|
+
})));
|
|
502
|
+
return {
|
|
503
|
+
session: thread ? toSessionRecord(thread) : null,
|
|
504
|
+
request: run ? toRequestRecord(run) : null,
|
|
505
|
+
approvals,
|
|
506
|
+
transcript,
|
|
507
|
+
events,
|
|
508
|
+
artifacts,
|
|
509
|
+
...(input.includeRuntimeHealth === false ? {} : { runtimeHealth: await this.getHealth() }),
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
async exportSessionPackage(input) {
|
|
513
|
+
const thread = await this.getThread(input.sessionId);
|
|
514
|
+
const runIds = Array.from(new Set((thread?.runs ?? []).map((item) => item.runId)));
|
|
515
|
+
const runs = await Promise.all(runIds.map((requestId) => this.exportRunPackage({
|
|
516
|
+
sessionId: input.sessionId,
|
|
517
|
+
requestId,
|
|
518
|
+
includeArtifacts: input.includeArtifacts,
|
|
519
|
+
includeArtifactContents: input.includeArtifactContents,
|
|
520
|
+
includeRuntimeHealth: false,
|
|
521
|
+
})));
|
|
522
|
+
return {
|
|
523
|
+
session: thread ? toSessionRecord(thread) : null,
|
|
524
|
+
requests: runs.map((item) => item.request).filter((item) => Boolean(item)),
|
|
525
|
+
approvals: await this.listApprovals({ threadId: input.sessionId }),
|
|
526
|
+
transcript: await this.persistence.listThreadMessages(input.sessionId, 500),
|
|
527
|
+
runs,
|
|
528
|
+
...(input.includeRuntimeHealth === false ? {} : { runtimeHealth: await this.getHealth() }),
|
|
529
|
+
};
|
|
530
|
+
}
|
|
487
531
|
async exportEvaluationBundle(input) {
|
|
488
532
|
const thread = await this.getThread(input.sessionId);
|
|
489
533
|
const run = await this.getRun(input.requestId);
|