@botbotgo/agent-harness 0.0.309 → 0.0.311

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.
Files changed (195) hide show
  1. package/README.md +14 -0
  2. package/README.zh.md +14 -0
  3. package/dist/acp.d.ts +1 -116
  4. package/dist/acp.js +1 -310
  5. package/dist/api.d.ts +1 -1
  6. package/dist/api.js +1 -1
  7. package/dist/cli/chat-interactive.d.ts +24 -0
  8. package/dist/cli/chat-interactive.js +244 -0
  9. package/dist/cli/chat-rendering.d.ts +9 -0
  10. package/dist/cli/chat-rendering.js +102 -0
  11. package/dist/cli/chat-stream.d.ts +23 -0
  12. package/dist/cli/chat-stream.js +330 -0
  13. package/dist/cli/chat-ui.d.ts +20 -0
  14. package/dist/cli/chat-ui.js +198 -0
  15. package/dist/cli/chat-workspace.d.ts +15 -0
  16. package/dist/cli/chat-workspace.js +205 -0
  17. package/dist/cli/main.d.ts +52 -0
  18. package/dist/cli/main.js +323 -0
  19. package/dist/cli/managed-service-commands.d.ts +23 -0
  20. package/dist/cli/managed-service-commands.js +63 -0
  21. package/dist/cli/managed-service.d.ts +27 -0
  22. package/dist/cli/managed-service.js +61 -0
  23. package/dist/cli/options-init-chat.d.ts +16 -0
  24. package/dist/cli/options-init-chat.js +108 -0
  25. package/dist/cli/options-runtime.d.ts +27 -0
  26. package/dist/cli/options-runtime.js +158 -0
  27. package/dist/cli/options-serve.d.ts +24 -0
  28. package/dist/cli/options-serve.js +166 -0
  29. package/dist/cli/options.d.ts +5 -0
  30. package/dist/cli/options.js +47 -0
  31. package/dist/cli/process-guards.d.ts +14 -0
  32. package/dist/cli/process-guards.js +139 -0
  33. package/dist/cli/request-tree.d.ts +12 -0
  34. package/dist/cli/request-tree.js +296 -0
  35. package/dist/cli/runtime-commands.d.ts +15 -0
  36. package/dist/cli/runtime-commands.js +247 -0
  37. package/dist/cli/runtime-output.d.ts +5 -0
  38. package/dist/cli/runtime-output.js +124 -0
  39. package/dist/cli/server-commands.d.ts +36 -0
  40. package/dist/cli/server-commands.js +250 -0
  41. package/dist/cli/workspace.d.ts +6 -0
  42. package/dist/cli/workspace.js +71 -0
  43. package/dist/cli.d.ts +1 -77
  44. package/dist/cli.js +2 -3023
  45. package/dist/client/acp.d.ts +1 -50
  46. package/dist/client/acp.js +1 -219
  47. package/dist/client/in-process.d.ts +5 -5
  48. package/dist/client/index.d.ts +2 -2
  49. package/dist/client/index.js +1 -1
  50. package/dist/contracts/runtime-evaluation.d.ts +103 -0
  51. package/dist/contracts/runtime-evaluation.js +1 -0
  52. package/dist/contracts/runtime-memory.d.ts +162 -0
  53. package/dist/contracts/runtime-memory.js +1 -0
  54. package/dist/contracts/runtime-observability.d.ts +248 -0
  55. package/dist/contracts/runtime-observability.js +1 -0
  56. package/dist/contracts/runtime-requests.d.ts +342 -0
  57. package/dist/contracts/runtime-requests.js +1 -0
  58. package/dist/contracts/runtime-scheduling.d.ts +146 -0
  59. package/dist/contracts/runtime-scheduling.js +1 -0
  60. package/dist/contracts/runtime.d.ts +5 -1042
  61. package/dist/contracts/runtime.js +27 -1
  62. package/dist/flow/build-flow-graph.js +4 -875
  63. package/dist/flow/flow-graph-normalization.d.ts +56 -0
  64. package/dist/flow/flow-graph-normalization.js +214 -0
  65. package/dist/flow/flow-graph-runtime.d.ts +8 -0
  66. package/dist/flow/flow-graph-runtime.js +107 -0
  67. package/dist/flow/flow-graph-upstream.d.ts +18 -0
  68. package/dist/flow/flow-graph-upstream.js +498 -0
  69. package/dist/flow/types.d.ts +1 -1
  70. package/dist/index.d.ts +3 -3
  71. package/dist/index.js +1 -1
  72. package/dist/init-project.d.ts +1 -12
  73. package/dist/init-project.js +1 -651
  74. package/dist/{procedural → knowledge/procedural}/manager.d.ts +3 -3
  75. package/dist/{procedural → knowledge/procedural}/manager.js +6 -6
  76. package/dist/mcp.d.ts +2 -76
  77. package/dist/mcp.js +2 -428
  78. package/dist/package-version.d.ts +1 -1
  79. package/dist/package-version.js +1 -1
  80. package/dist/persistence/file-store.js +1 -1
  81. package/dist/persistence/sqlite-runtime.d.ts +19 -0
  82. package/dist/persistence/sqlite-runtime.js +86 -0
  83. package/dist/persistence/sqlite-store.js +11 -99
  84. package/dist/{request-events.d.ts → projections/request-events.d.ts} +1 -1
  85. package/dist/{upstream-events.js → projections/upstream-events.js} +1 -1
  86. package/dist/protocol/a2a/http-discovery.d.ts +39 -0
  87. package/dist/protocol/a2a/http-discovery.js +178 -0
  88. package/dist/protocol/a2a/http-rpc.d.ts +28 -0
  89. package/dist/protocol/a2a/http-rpc.js +623 -0
  90. package/dist/protocol/a2a/http.d.ts +72 -1
  91. package/dist/protocol/a2a/http.js +14 -1124
  92. package/dist/protocol/a2a/task-state.d.ts +29 -0
  93. package/dist/protocol/a2a/task-state.js +317 -0
  94. package/dist/protocol/acp/client.js +1 -1
  95. package/dist/protocol/acp/harness-client.d.ts +50 -0
  96. package/dist/protocol/acp/harness-client.js +219 -0
  97. package/dist/protocol/acp/server.d.ts +116 -0
  98. package/dist/protocol/acp/server.js +310 -0
  99. package/dist/protocol/ag-ui/http.js +1 -1
  100. package/dist/protocol/mcp/server.d.ts +76 -0
  101. package/dist/protocol/mcp/server.js +428 -0
  102. package/dist/resource/backend/workspace-scoped-backend.d.ts +40 -0
  103. package/dist/resource/backend/workspace-scoped-backend.js +296 -0
  104. package/dist/resource/mcp/tool-support.d.ts +35 -0
  105. package/dist/resource/mcp/tool-support.js +296 -0
  106. package/dist/resource/mcp-tool-support.d.ts +2 -35
  107. package/dist/resource/mcp-tool-support.js +2 -296
  108. package/dist/resource/providers/resource-provider.d.ts +22 -0
  109. package/dist/resource/providers/resource-provider.js +215 -0
  110. package/dist/resource/resource-impl.d.ts +3 -33
  111. package/dist/resource/resource-impl.js +2 -808
  112. package/dist/resource/resource-types.d.ts +33 -0
  113. package/dist/resource/resource-types.js +1 -0
  114. package/dist/resource/tools/function-tool-resolver.d.ts +2 -0
  115. package/dist/resource/tools/function-tool-resolver.js +306 -0
  116. package/dist/runtime/adapter/middleware-assembly.js +1 -1
  117. package/dist/runtime/adapter/model/invocation-request.js +2 -2
  118. package/dist/runtime/adapter/model/message-assembly.js +1 -1
  119. package/dist/runtime/agent-runtime-adapter.d.ts +3 -63
  120. package/dist/runtime/agent-runtime-adapter.js +7 -235
  121. package/dist/runtime/agent-runtime-assembly.d.ts +67 -0
  122. package/dist/runtime/agent-runtime-assembly.js +211 -0
  123. package/dist/runtime/harness/background-runtime.d.ts +1 -1
  124. package/dist/runtime/harness/events/event-sink.js +1 -1
  125. package/dist/runtime/harness/events/runtime-event-operations.d.ts +1 -1
  126. package/dist/runtime/harness/events/streaming.js +1 -1
  127. package/dist/runtime/harness/public-shapes.d.ts +43 -0
  128. package/dist/runtime/harness/public-shapes.js +186 -0
  129. package/dist/runtime/harness/run/inspection.js +2 -2
  130. package/dist/runtime/harness/run/resources.js +1 -1
  131. package/dist/runtime/harness/run/surface-semantics.js +1 -1
  132. package/dist/runtime/harness/system/inventory.d.ts +1 -1
  133. package/dist/runtime/harness/system/inventory.js +2 -2
  134. package/dist/runtime/harness/system/policy-engine.js +1 -1
  135. package/dist/runtime/harness/system/runtime-memory-manager.js +1 -1
  136. package/dist/runtime/harness/system/skill-requirements.d.ts +1 -1
  137. package/dist/runtime/harness/system/skill-requirements.js +1 -1
  138. package/dist/runtime/harness.d.ts +2 -2
  139. package/dist/runtime/harness.js +7 -191
  140. package/dist/runtime/maintenance/checkpoint-maintenance.js +1 -1
  141. package/dist/runtime/maintenance/runtime-record-maintenance.js +1 -1
  142. package/dist/runtime/parsing/output-content.d.ts +11 -0
  143. package/dist/runtime/parsing/output-content.js +442 -0
  144. package/dist/runtime/parsing/output-parsing.d.ts +3 -29
  145. package/dist/runtime/parsing/output-parsing.js +3 -806
  146. package/dist/runtime/parsing/output-recovery.d.ts +14 -0
  147. package/dist/runtime/parsing/output-recovery.js +288 -0
  148. package/dist/runtime/parsing/output-tool-args.d.ts +4 -0
  149. package/dist/runtime/parsing/output-tool-args.js +120 -0
  150. package/dist/runtime/support/runtime-factories.js +1 -1
  151. package/dist/scaffold/init-project.d.ts +12 -0
  152. package/dist/scaffold/init-project.js +651 -0
  153. package/dist/{extensions.d.ts → tooling/extensions.d.ts} +1 -1
  154. package/dist/{extensions.js → tooling/extensions.js} +3 -3
  155. package/dist/{tool-modules.d.ts → tooling/module-loader.d.ts} +1 -1
  156. package/dist/{tool-modules.js → tooling/module-loader.js} +2 -2
  157. package/dist/workspace/agent-binding-compiler.js +2 -2
  158. package/dist/workspace/compile.js +2 -2
  159. package/dist/workspace/object-loader-paths.d.ts +11 -0
  160. package/dist/workspace/object-loader-paths.js +75 -0
  161. package/dist/workspace/object-loader-readers.d.ts +21 -0
  162. package/dist/workspace/object-loader-readers.js +187 -0
  163. package/dist/workspace/object-loader.d.ts +0 -1
  164. package/dist/workspace/object-loader.js +6 -260
  165. package/dist/workspace/resource-compilers.js +1 -1
  166. package/dist/workspace/support/discovery.js +1 -1
  167. package/package.json +1 -1
  168. package/dist/runtime/adapter/index.d.ts +0 -13
  169. package/dist/runtime/adapter/index.js +0 -13
  170. package/dist/runtime/harness/index.d.ts +0 -19
  171. package/dist/runtime/harness/index.js +0 -19
  172. package/dist/runtime/maintenance/index.d.ts +0 -4
  173. package/dist/runtime/maintenance/index.js +0 -4
  174. package/dist/runtime/parsing/index.d.ts +0 -2
  175. package/dist/runtime/parsing/index.js +0 -2
  176. package/dist/runtime/support/index.d.ts +0 -4
  177. package/dist/runtime/support/index.js +0 -4
  178. package/dist/workspace/support/index.d.ts +0 -2
  179. package/dist/workspace/support/index.js +0 -2
  180. /package/dist/{procedural → knowledge/procedural}/config.d.ts +0 -0
  181. /package/dist/{procedural → knowledge/procedural}/config.js +0 -0
  182. /package/dist/{procedural → knowledge/procedural}/index.d.ts +0 -0
  183. /package/dist/{procedural → knowledge/procedural}/index.js +0 -0
  184. /package/dist/{presentation.d.ts → projections/presentation.d.ts} +0 -0
  185. /package/dist/{presentation.js → projections/presentation.js} +0 -0
  186. /package/dist/{request-events.js → projections/request-events.js} +0 -0
  187. /package/dist/{upstream-events.d.ts → projections/upstream-events.d.ts} +0 -0
  188. /package/dist/runtime/{support → env}/runtime-env.d.ts +0 -0
  189. /package/dist/runtime/{support → env}/runtime-env.js +0 -0
  190. /package/dist/runtime/{support → layout}/runtime-layout.d.ts +0 -0
  191. /package/dist/runtime/{support → layout}/runtime-layout.js +0 -0
  192. /package/dist/runtime/{support → prompts}/runtime-prompts.d.ts +0 -0
  193. /package/dist/runtime/{support → prompts}/runtime-prompts.js +0 -0
  194. /package/dist/runtime/{support → skills}/skill-metadata.d.ts +0 -0
  195. /package/dist/runtime/{support → skills}/skill-metadata.js +0 -0
package/dist/mcp.d.ts CHANGED
@@ -1,76 +1,2 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import type { ApprovalRecord, ArtifactListing, CompiledTool, HarnessEvent, ParsedToolObject, RequestRecord, RequestResult, RequestState, RequestSummary, RuntimeSessionPackage, RuntimeSessionPackageInput, SessionRecord, SessionSummary } from "./contracts/types.js";
3
- export type ToolMcpServerOptions = {
4
- agentId: string;
5
- serverInfo?: {
6
- name?: string;
7
- version?: string;
8
- };
9
- includeToolNames?: string[];
10
- };
11
- export type ToolMcpServerTool = {
12
- compiledTool: CompiledTool;
13
- resolvedTool: unknown;
14
- sourceTool?: ParsedToolObject;
15
- };
16
- export type RuntimeMcpServerOptions = {
17
- serverInfo?: {
18
- name?: string;
19
- version?: string;
20
- };
21
- };
22
- export type RuntimeMcpStreamableHttpServerOptions = RuntimeMcpServerOptions & {
23
- hostname?: string;
24
- port?: number;
25
- path?: string;
26
- };
27
- export type RuntimeMcpStreamableHttpServer = {
28
- hostname: string;
29
- port: number;
30
- path: string;
31
- url: string;
32
- completed: Promise<void>;
33
- close: () => Promise<void>;
34
- };
35
- type RuntimeMcpRuntime = {
36
- listSessions: (filter?: {
37
- agentId?: string;
38
- }) => Promise<SessionSummary[]>;
39
- getSessionRecord: (sessionId: string) => Promise<SessionRecord | null>;
40
- listRequests: (filter?: {
41
- agentId?: string;
42
- sessionId?: string;
43
- state?: RequestState;
44
- }) => Promise<RequestSummary[]>;
45
- getRequest: (requestId: string) => Promise<RequestRecord | null>;
46
- listApprovals: (filter?: {
47
- status?: ApprovalRecord["status"];
48
- sessionId?: string;
49
- requestId?: string;
50
- }) => Promise<ApprovalRecord[]>;
51
- getApproval: (approvalId: string) => Promise<ApprovalRecord | null>;
52
- resume: (options: {
53
- approvalId?: string;
54
- sessionId?: string;
55
- requestId?: string;
56
- decision?: "approve" | "edit" | "reject";
57
- editedInput?: Record<string, unknown>;
58
- }) => Promise<RequestResult>;
59
- listRequestArtifacts: (sessionId: string, requestId: string) => Promise<ArtifactListing>;
60
- readRequestArtifact: (sessionId: string, requestId: string, artifactPath: string) => Promise<unknown>;
61
- listRequestEvents: (sessionId: string, requestId: string) => Promise<HarnessEvent[]>;
62
- exportRequestPackage: (input: {
63
- sessionId: string;
64
- requestId: string;
65
- includeArtifacts?: boolean;
66
- includeArtifactContents?: boolean;
67
- includeRuntimeHealth?: boolean;
68
- }) => Promise<unknown>;
69
- exportSessionPackage: (input: RuntimeSessionPackageInput) => Promise<RuntimeSessionPackage>;
70
- };
71
- export declare function createToolMcpServerFromTools(tools: ToolMcpServerTool[], options: ToolMcpServerOptions): Promise<McpServer>;
72
- export declare function serveToolsOverStdioFromHarness(tools: ToolMcpServerTool[], options: ToolMcpServerOptions): Promise<McpServer>;
73
- export declare function createRuntimeMcpServer(runtime: RuntimeMcpRuntime, options?: RuntimeMcpServerOptions): Promise<McpServer>;
74
- export declare function serveRuntimeMcpOverStdio(runtime: RuntimeMcpRuntime, options?: RuntimeMcpServerOptions): Promise<McpServer>;
75
- export declare function serveRuntimeMcpOverStreamableHttp(runtime: RuntimeMcpRuntime, options?: RuntimeMcpStreamableHttpServerOptions): Promise<RuntimeMcpStreamableHttpServer>;
76
- export {};
1
+ export { AGENT_HARNESS_VERSION } from "./package-version.js";
2
+ export * from "./protocol/mcp/server.js";
package/dist/mcp.js CHANGED
@@ -1,428 +1,2 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { randomUUID } from "node:crypto";
5
- import { createServer } from "node:http";
6
- import { pathToFileURL } from "node:url";
7
- import { z } from "zod";
8
- import { AGENT_HARNESS_VERSION } from "./package-version.js";
9
- import { loadToolModuleDefinition } from "./tool-modules.js";
10
- function asResolvedTool(value) {
11
- return typeof value === "object" && value !== null ? value : null;
12
- }
13
- async function buildRawShapeForTool(sourceTool, resolvedTool) {
14
- if (!sourceTool) {
15
- return undefined;
16
- }
17
- if (sourceTool.type === "function") {
18
- const imported = await import(pathToFileURL(sourceTool.sourcePath).href);
19
- const definition = loadToolModuleDefinition(imported, sourceTool.implementationName ?? sourceTool.id);
20
- return typeof definition.schema.shape === "object" && definition.schema.shape !== null
21
- ? definition.schema.shape
22
- : undefined;
23
- }
24
- const typedResolvedTool = asResolvedTool(resolvedTool);
25
- if (!typedResolvedTool?.inputSchemaPromise) {
26
- return undefined;
27
- }
28
- return jsonSchemaObjectToRawShape(await typedResolvedTool.inputSchemaPromise);
29
- }
30
- async function invokeResolvedTool(resolvedTool, input) {
31
- const typed = asResolvedTool(resolvedTool);
32
- if (!typed) {
33
- throw new Error("Resolved tool is not invokable.");
34
- }
35
- if (typeof typed.invoke === "function") {
36
- return typed.invoke(input);
37
- }
38
- if (typeof typed.call === "function") {
39
- return typed.call(input);
40
- }
41
- if (typeof typed.func === "function") {
42
- return typed.func(input);
43
- }
44
- throw new Error("Resolved tool does not expose invoke, call, or func.");
45
- }
46
- function renderToolOutput(output) {
47
- if (typeof output === "string") {
48
- return output;
49
- }
50
- return JSON.stringify(output, null, 2);
51
- }
52
- function normalizePath(value, fallback) {
53
- const source = typeof value === "string" && value.trim().length > 0 ? value.trim() : fallback;
54
- return source.startsWith("/") ? source : `/${source}`;
55
- }
56
- function writeJson(response, statusCode, payload) {
57
- response.statusCode = statusCode;
58
- response.setHeader("content-type", "application/json; charset=utf-8");
59
- response.end(JSON.stringify(payload));
60
- }
61
- function readRequestBody(request) {
62
- return new Promise((resolve, reject) => {
63
- const chunks = [];
64
- request.on("data", (chunk) => {
65
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
66
- });
67
- request.on("end", () => {
68
- resolve(Buffer.concat(chunks).toString("utf8"));
69
- });
70
- request.on("error", reject);
71
- });
72
- }
73
- function isInitializeRequest(payload) {
74
- return typeof payload === "object"
75
- && payload !== null
76
- && !Array.isArray(payload)
77
- && payload.method === "initialize";
78
- }
79
- function jsonSchemaObjectToRawShape(schema) {
80
- if (!schema || schema.type !== "object") {
81
- return undefined;
82
- }
83
- const properties = typeof schema.properties === "object" && schema.properties
84
- ? schema.properties
85
- : {};
86
- const required = Array.isArray(schema.required)
87
- ? new Set(schema.required.filter((item) => typeof item === "string"))
88
- : new Set();
89
- const shape = {};
90
- for (const [key, propertySchema] of Object.entries(properties)) {
91
- const built = jsonSchemaToZod(propertySchema);
92
- shape[key] = required.has(key) ? built : built.optional();
93
- }
94
- return shape;
95
- }
96
- function jsonSchemaToZod(schema) {
97
- switch (schema?.type) {
98
- case "string":
99
- return z.string();
100
- case "number":
101
- return z.number();
102
- case "integer":
103
- return z.number().int();
104
- case "boolean":
105
- return z.boolean();
106
- case "array":
107
- return z.array(jsonSchemaToZod(typeof schema.items === "object" && schema.items ? schema.items : undefined));
108
- case "object": {
109
- const shape = jsonSchemaObjectToRawShape(schema);
110
- return z.object(shape ?? {}).passthrough();
111
- }
112
- default:
113
- return z.any();
114
- }
115
- }
116
- export async function createToolMcpServerFromTools(tools, options) {
117
- const server = new McpServer({
118
- name: options.serverInfo?.name ?? `agent-harness-${options.agentId}`,
119
- version: options.serverInfo?.version ?? AGENT_HARNESS_VERSION,
120
- });
121
- const allowedNames = options.includeToolNames ? new Set(options.includeToolNames) : null;
122
- for (const { compiledTool, resolvedTool, sourceTool } of tools) {
123
- if (allowedNames && !allowedNames.has(compiledTool.name)) {
124
- continue;
125
- }
126
- const rawShape = await buildRawShapeForTool(sourceTool, resolvedTool);
127
- server.tool(compiledTool.name, compiledTool.description, rawShape ?? {}, async (input) => ({
128
- content: [
129
- {
130
- type: "text",
131
- text: renderToolOutput(await invokeResolvedTool(resolvedTool, input)),
132
- },
133
- ],
134
- }));
135
- }
136
- return server;
137
- }
138
- export async function serveToolsOverStdioFromHarness(tools, options) {
139
- const server = await createToolMcpServerFromTools(tools, options);
140
- await server.connect(new StdioServerTransport());
141
- return server;
142
- }
143
- export async function createRuntimeMcpServer(runtime, options = {}) {
144
- const server = new McpServer({
145
- name: options.serverInfo?.name ?? "agent-harness-runtime",
146
- version: options.serverInfo?.version ?? AGENT_HARNESS_VERSION,
147
- });
148
- server.tool("list_sessions", "List persisted runtime sessions.", {
149
- agentId: z.string().optional(),
150
- }, async (input) => ({
151
- content: [{
152
- type: "text",
153
- text: renderToolOutput(await runtime.listSessions(input.agentId ? { agentId: input.agentId } : undefined)),
154
- }],
155
- }));
156
- server.tool("get_session", "Get one persisted runtime session by id.", {
157
- sessionId: z.string(),
158
- }, async (input) => ({
159
- content: [{
160
- type: "text",
161
- text: renderToolOutput(await runtime.getSessionRecord(input.sessionId)),
162
- }],
163
- }));
164
- server.tool("list_requests", "List persisted runtime requests.", {
165
- agentId: z.string().optional(),
166
- sessionId: z.string().optional(),
167
- state: z.enum(["queued", "running", "waiting_for_approval", "completed", "failed", "cancelled"]).optional(),
168
- }, async (input) => ({
169
- content: [{
170
- type: "text",
171
- text: renderToolOutput(await runtime.listRequests({
172
- ...(input.agentId ? { agentId: input.agentId } : {}),
173
- ...(input.sessionId ? { sessionId: input.sessionId } : {}),
174
- ...(input.state ? { state: input.state } : {}),
175
- })),
176
- }],
177
- }));
178
- server.tool("get_request", "Get one persisted runtime request by id.", {
179
- requestId: z.string(),
180
- }, async (input) => ({
181
- content: [{
182
- type: "text",
183
- text: renderToolOutput(await runtime.getRequest(input.requestId)),
184
- }],
185
- }));
186
- server.tool("list_approvals", "List runtime approvals.", {
187
- status: z.enum(["pending", "approved", "edited", "rejected", "expired"]).optional(),
188
- sessionId: z.string().optional(),
189
- requestId: z.string().optional(),
190
- }, async (input) => ({
191
- content: [{
192
- type: "text",
193
- text: renderToolOutput(await runtime.listApprovals({
194
- ...(input.status ? { status: input.status } : {}),
195
- ...(input.sessionId ? { sessionId: input.sessionId } : {}),
196
- ...(input.requestId ? { requestId: input.requestId } : {}),
197
- })),
198
- }],
199
- }));
200
- server.tool("get_approval", "Get one runtime approval by id.", {
201
- approvalId: z.string(),
202
- }, async (input) => ({
203
- content: [{
204
- type: "text",
205
- text: renderToolOutput(await runtime.getApproval(input.approvalId)),
206
- }],
207
- }));
208
- server.tool("resolve_approval", "Resolve one runtime approval.", {
209
- approvalId: z.string(),
210
- decision: z.enum(["approve", "edit", "reject"]),
211
- sessionId: z.string().optional(),
212
- requestId: z.string().optional(),
213
- editedInput: z.record(z.string(), z.any()).optional(),
214
- }, async (input) => ({
215
- content: [{
216
- type: "text",
217
- text: renderToolOutput(await runtime.resume({
218
- approvalId: input.approvalId,
219
- decision: input.decision,
220
- ...(input.sessionId ? { sessionId: input.sessionId } : {}),
221
- ...(input.requestId ? { requestId: input.requestId } : {}),
222
- ...(input.editedInput ? { editedInput: input.editedInput } : {}),
223
- })),
224
- }],
225
- }));
226
- server.tool("list_artifacts", "List artifacts for one runtime request.", {
227
- sessionId: z.string(),
228
- requestId: z.string(),
229
- }, async (input) => ({
230
- content: [{
231
- type: "text",
232
- text: renderToolOutput(await runtime.listRequestArtifacts(input.sessionId, input.requestId)),
233
- }],
234
- }));
235
- server.tool("read_artifact", "Read one runtime artifact.", {
236
- sessionId: z.string(),
237
- requestId: z.string(),
238
- artifactPath: z.string(),
239
- }, async (input) => ({
240
- content: [{
241
- type: "text",
242
- text: renderToolOutput(await runtime.readRequestArtifact(input.sessionId, input.requestId, input.artifactPath)),
243
- }],
244
- }));
245
- server.tool("list_request_events", "List persisted runtime events for one request.", {
246
- sessionId: z.string(),
247
- requestId: z.string(),
248
- }, async (input) => ({
249
- content: [{
250
- type: "text",
251
- text: renderToolOutput(await runtime.listRequestEvents(input.sessionId, input.requestId)),
252
- }],
253
- }));
254
- server.tool("export_request_package", "Export a stable runtime request package for one request.", {
255
- sessionId: z.string(),
256
- requestId: z.string(),
257
- includeArtifacts: z.boolean().optional(),
258
- includeArtifactContents: z.boolean().optional(),
259
- includeRuntimeHealth: z.boolean().optional(),
260
- }, async (input) => ({
261
- content: [{
262
- type: "text",
263
- text: renderToolOutput(await runtime.exportRequestPackage(input)),
264
- }],
265
- }));
266
- server.tool("export_session_package", "Export a stable runtime session package.", {
267
- sessionId: z.string(),
268
- includeArtifacts: z.boolean().optional(),
269
- includeArtifactContents: z.boolean().optional(),
270
- includeRuntimeHealth: z.boolean().optional(),
271
- }, async (input) => ({
272
- content: [{
273
- type: "text",
274
- text: renderToolOutput(await runtime.exportSessionPackage(input)),
275
- }],
276
- }));
277
- return server;
278
- }
279
- export async function serveRuntimeMcpOverStdio(runtime, options = {}) {
280
- const server = await createRuntimeMcpServer(runtime, options);
281
- await server.connect(new StdioServerTransport());
282
- return server;
283
- }
284
- export async function serveRuntimeMcpOverStreamableHttp(runtime, options = {}) {
285
- const hostname = options.hostname?.trim() || "127.0.0.1";
286
- const port = typeof options.port === "number" && Number.isFinite(options.port) ? options.port : 0;
287
- const mcpPath = normalizePath(options.path, "/mcp");
288
- const sessions = new Map();
289
- const closeSession = async (sessionId) => {
290
- const session = sessions.get(sessionId);
291
- if (!session) {
292
- return;
293
- }
294
- sessions.delete(sessionId);
295
- await Promise.allSettled([
296
- session.transport.close(),
297
- session.server.close(),
298
- ]);
299
- };
300
- const httpServer = createServer(async (request, response) => {
301
- try {
302
- const requestUrl = new URL(request.url ?? "/", `http://${hostname}`);
303
- if (requestUrl.pathname !== mcpPath) {
304
- writeJson(response, 404, {
305
- error: "Not Found",
306
- path: mcpPath,
307
- });
308
- return;
309
- }
310
- const headerValue = request.headers["mcp-session-id"];
311
- const sessionId = Array.isArray(headerValue) ? headerValue[0] : headerValue;
312
- if (request.method === "POST") {
313
- const body = await readRequestBody(request);
314
- let payload;
315
- try {
316
- payload = JSON.parse(body);
317
- }
318
- catch {
319
- writeJson(response, 400, {
320
- jsonrpc: "2.0",
321
- id: null,
322
- error: {
323
- code: -32700,
324
- message: "Invalid JSON payload.",
325
- },
326
- });
327
- return;
328
- }
329
- const existingSession = sessionId ? sessions.get(sessionId) : undefined;
330
- if (existingSession) {
331
- await existingSession.transport.handleRequest(request, response, payload);
332
- return;
333
- }
334
- if (sessionId || !isInitializeRequest(payload)) {
335
- writeJson(response, 400, {
336
- jsonrpc: "2.0",
337
- id: null,
338
- error: {
339
- code: -32000,
340
- message: "Bad Request: No valid MCP session was provided.",
341
- },
342
- });
343
- return;
344
- }
345
- let createdTransport;
346
- const server = await createRuntimeMcpServer(runtime, options);
347
- const transport = new StreamableHTTPServerTransport({
348
- sessionIdGenerator: () => randomUUID(),
349
- onsessioninitialized: (initializedSessionId) => {
350
- sessions.set(initializedSessionId, { transport, server });
351
- },
352
- });
353
- createdTransport = transport;
354
- transport.onclose = () => {
355
- const activeSessionId = createdTransport?.sessionId;
356
- if (activeSessionId) {
357
- const active = sessions.get(activeSessionId);
358
- if (active?.transport === createdTransport) {
359
- sessions.delete(activeSessionId);
360
- }
361
- }
362
- };
363
- await server.connect(transport);
364
- await transport.handleRequest(request, response, payload);
365
- return;
366
- }
367
- if (request.method === "GET" || request.method === "DELETE") {
368
- if (!sessionId || !sessions.has(sessionId)) {
369
- writeJson(response, 400, {
370
- jsonrpc: "2.0",
371
- id: null,
372
- error: {
373
- code: -32000,
374
- message: "Bad Request: No valid MCP session was provided.",
375
- },
376
- });
377
- return;
378
- }
379
- const session = sessions.get(sessionId);
380
- await session.transport.handleRequest(request, response);
381
- if (request.method === "DELETE") {
382
- await closeSession(sessionId);
383
- }
384
- return;
385
- }
386
- response.statusCode = 405;
387
- response.setHeader("allow", "GET, POST, DELETE");
388
- response.end();
389
- }
390
- catch (error) {
391
- writeJson(response, 500, {
392
- error: error instanceof Error ? error.message : "Runtime MCP Streamable HTTP transport failed.",
393
- });
394
- }
395
- });
396
- const completed = new Promise((resolve, reject) => {
397
- httpServer.once("close", resolve);
398
- httpServer.once("error", reject);
399
- });
400
- await new Promise((resolve, reject) => {
401
- httpServer.listen(port, hostname, () => resolve());
402
- httpServer.once("error", reject);
403
- });
404
- const address = httpServer.address();
405
- const resolvedPort = typeof address === "object" && address ? address.port : port;
406
- return {
407
- hostname,
408
- port: resolvedPort,
409
- path: mcpPath,
410
- url: `http://${hostname}:${resolvedPort}${mcpPath}`,
411
- completed,
412
- close: async () => {
413
- const sessionIds = Array.from(sessions.keys());
414
- for (const sessionId of sessionIds) {
415
- await closeSession(sessionId);
416
- }
417
- await new Promise((resolve, reject) => {
418
- httpServer.close((error) => {
419
- if (error) {
420
- reject(error);
421
- return;
422
- }
423
- resolve();
424
- });
425
- });
426
- },
427
- };
428
- }
1
+ export { AGENT_HARNESS_VERSION } from "./package-version.js";
2
+ export * from "./protocol/mcp/server.js";
@@ -1 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.308";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.310";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.308";
1
+ export const AGENT_HARNESS_VERSION = "0.0.310";
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { appendFile, readFile, readdir, rm, writeFile } from "node:fs/promises";
3
3
  import { ensureDir, fileExists, readJson, writeJson } from "../utils/fs.js";
4
- import { resolveRuntimeArtifactsRoot } from "../runtime/support/runtime-layout.js";
4
+ import { resolveRuntimeArtifactsRoot } from "../runtime/layout/runtime-layout.js";
5
5
  function nowIso() {
6
6
  return new Date(Date.now()).toISOString();
7
7
  }
@@ -0,0 +1,19 @@
1
+ import type { Client, InValue } from "@libsql/client";
2
+ export type SqlRow = Record<string, unknown>;
3
+ export declare const SQLITE_BUSY_RETRY_ATTEMPTS = 30;
4
+ export declare const SQLITE_BUSY_RETRY_DELAY_MS = 100;
5
+ export declare function asRow(value: unknown): SqlRow;
6
+ export declare function asString(value: unknown): string;
7
+ export declare function asNullableString(value: unknown): string | null;
8
+ export declare function asBoolean(value: unknown): boolean;
9
+ export declare function parseJson<T>(value: unknown): T;
10
+ export declare function toSqliteUrl(filePath: string): string;
11
+ export declare function nowIso(): string;
12
+ export declare function throwWrappedRuntimeSqliteError(dbPath: string, sql: string | undefined, error: unknown): never;
13
+ export declare function isSqliteBusyError(error: unknown): boolean;
14
+ export declare function sleep(ms: number): Promise<void>;
15
+ export declare function executeWithBusyRetry<T>(client: Client, dbPath: string, sql: string, args: InValue[] | undefined, run: () => Promise<T>): Promise<T>;
16
+ export declare function buildWhereClause(filters: Array<[sql: string, value: InValue | undefined]>): {
17
+ clause: string;
18
+ args: InValue[];
19
+ };
@@ -0,0 +1,86 @@
1
+ export const SQLITE_BUSY_RETRY_ATTEMPTS = 30;
2
+ export const SQLITE_BUSY_RETRY_DELAY_MS = 100;
3
+ export function asRow(value) {
4
+ return value;
5
+ }
6
+ export function asString(value) {
7
+ return typeof value === "string" ? value : String(value ?? "");
8
+ }
9
+ export function asNullableString(value) {
10
+ return value == null ? null : asString(value);
11
+ }
12
+ export function asBoolean(value) {
13
+ return value === true || value === 1 || value === "1";
14
+ }
15
+ export function parseJson(value) {
16
+ return JSON.parse(asString(value));
17
+ }
18
+ export function toSqliteUrl(filePath) {
19
+ return `file:${filePath}`;
20
+ }
21
+ export function nowIso() {
22
+ return new Date(Date.now()).toISOString();
23
+ }
24
+ function runtimeSqliteErrorShouldIncludeSql(baseMessage) {
25
+ if (process.env.AGENT_HARNESS_RUNTIME_SQLITE_DEBUG === "1") {
26
+ return true;
27
+ }
28
+ return /SQLITE_CONSTRAINT|FOREIGN KEY|UNIQUE constraint|NOT NULL/i.test(baseMessage);
29
+ }
30
+ function formatRuntimeSqliteErrorMessage(dbPath, sql, baseMessage) {
31
+ let detail = `agent-harness runtime SQLite (${dbPath}): ${baseMessage}`;
32
+ if (sql && runtimeSqliteErrorShouldIncludeSql(baseMessage)) {
33
+ const sqlPreview = sql.replace(/\s+/g, " ").trim();
34
+ const truncated = sqlPreview.length > 220 ? `${sqlPreview.slice(0, 220)}…` : sqlPreview;
35
+ detail += ` [sql=${truncated}]`;
36
+ }
37
+ return detail;
38
+ }
39
+ export function throwWrappedRuntimeSqliteError(dbPath, sql, error) {
40
+ const base = error instanceof Error ? error.message : String(error);
41
+ const wrapped = new Error(formatRuntimeSqliteErrorMessage(dbPath, sql, base));
42
+ wrapped.cause = error;
43
+ throw wrapped;
44
+ }
45
+ function collectErrorMessages(error) {
46
+ const messages = [];
47
+ let current = error;
48
+ while (current instanceof Error) {
49
+ messages.push(current.message);
50
+ current = current.cause;
51
+ }
52
+ if (typeof current === "string" && current.length > 0) {
53
+ messages.push(current);
54
+ }
55
+ return messages;
56
+ }
57
+ export function isSqliteBusyError(error) {
58
+ return collectErrorMessages(error).some((message) => /SQLITE_BUSY|database is locked/i.test(message));
59
+ }
60
+ export function sleep(ms) {
61
+ return new Promise((resolve) => setTimeout(resolve, ms));
62
+ }
63
+ export async function executeWithBusyRetry(client, dbPath, sql, args, run) {
64
+ void client;
65
+ for (let attempt = 0;; attempt += 1) {
66
+ try {
67
+ return await run();
68
+ }
69
+ catch (error) {
70
+ if (!isSqliteBusyError(error) || attempt >= SQLITE_BUSY_RETRY_ATTEMPTS) {
71
+ throwWrappedRuntimeSqliteError(dbPath, sql, error);
72
+ }
73
+ await sleep(Math.min(SQLITE_BUSY_RETRY_DELAY_MS * (attempt + 1), 1_000));
74
+ }
75
+ }
76
+ }
77
+ export function buildWhereClause(filters) {
78
+ const active = filters.filter(([, value]) => value !== undefined);
79
+ if (active.length === 0) {
80
+ return { clause: "", args: [] };
81
+ }
82
+ return {
83
+ clause: ` WHERE ${active.map(([sql]) => sql).join(" AND ")}`,
84
+ args: active.map(([, value]) => value),
85
+ };
86
+ }