@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
@@ -2,7 +2,8 @@ import path from "node:path";
2
2
  import { mkdir, rm } from "node:fs/promises";
3
3
  import { createClient } from "@libsql/client";
4
4
  import { fileExists, readJson, writeJson } from "../utils/fs.js";
5
- import { resolveRuntimeRoot, resolveRuntimeSqlitePath } from "../runtime/support/runtime-layout.js";
5
+ import { resolveRuntimeRoot, resolveRuntimeSqlitePath } from "../runtime/layout/runtime-layout.js";
6
+ import { asBoolean, asNullableString, asRow, asString, buildWhereClause, executeWithBusyRetry, nowIso, parseJson, throwWrappedRuntimeSqliteError, toSqliteUrl, } from "./sqlite-runtime.js";
6
7
  import { SqliteRequestContextStore } from "./sqlite-request-context-store.js";
7
8
  import { SqliteRequestQueueStore } from "./sqlite-request-queue-store.js";
8
9
  const RUNTIME_SQLITE_SCHEMA_VERSION = 7;
@@ -15,78 +16,6 @@ const ACTIVE_REQUEST_STATES = new Set([
15
16
  "resuming",
16
17
  "cancelling",
17
18
  ]);
18
- function asRow(value) {
19
- return value;
20
- }
21
- function asString(value) {
22
- return typeof value === "string" ? value : String(value ?? "");
23
- }
24
- function asNullableString(value) {
25
- return value == null ? null : asString(value);
26
- }
27
- function asBoolean(value) {
28
- return value === true || value === 1 || value === "1";
29
- }
30
- function parseJson(value) {
31
- return JSON.parse(asString(value));
32
- }
33
- function toSqliteUrl(filePath) {
34
- return `file:${filePath}`;
35
- }
36
- const SQLITE_BUSY_RETRY_ATTEMPTS = 30;
37
- const SQLITE_BUSY_RETRY_DELAY_MS = 100;
38
- function nowIso() {
39
- return new Date(Date.now()).toISOString();
40
- }
41
- function runtimeSqliteErrorShouldIncludeSql(baseMessage) {
42
- if (process.env.AGENT_HARNESS_RUNTIME_SQLITE_DEBUG === "1") {
43
- return true;
44
- }
45
- return /SQLITE_CONSTRAINT|FOREIGN KEY|UNIQUE constraint|NOT NULL/i.test(baseMessage);
46
- }
47
- function formatRuntimeSqliteErrorMessage(dbPath, sql, baseMessage) {
48
- let detail = `agent-harness runtime SQLite (${dbPath}): ${baseMessage}`;
49
- if (sql && runtimeSqliteErrorShouldIncludeSql(baseMessage)) {
50
- const sqlPreview = sql.replace(/\s+/g, " ").trim();
51
- const truncated = sqlPreview.length > 220 ? `${sqlPreview.slice(0, 220)}…` : sqlPreview;
52
- detail += ` [sql=${truncated}]`;
53
- }
54
- return detail;
55
- }
56
- function throwWrappedRuntimeSqliteError(dbPath, sql, error) {
57
- const base = error instanceof Error ? error.message : String(error);
58
- const wrapped = new Error(formatRuntimeSqliteErrorMessage(dbPath, sql, base));
59
- wrapped.cause = error;
60
- throw wrapped;
61
- }
62
- function collectErrorMessages(error) {
63
- const messages = [];
64
- let current = error;
65
- while (current instanceof Error) {
66
- messages.push(current.message);
67
- current = current.cause;
68
- }
69
- if (typeof current === "string" && current.length > 0) {
70
- messages.push(current);
71
- }
72
- return messages;
73
- }
74
- function isSqliteBusyError(error) {
75
- return collectErrorMessages(error).some((message) => /SQLITE_BUSY|database is locked/i.test(message));
76
- }
77
- function sleep(ms) {
78
- return new Promise((resolve) => setTimeout(resolve, ms));
79
- }
80
- function buildWhereClause(filters) {
81
- const active = filters.filter(([, value]) => value !== undefined);
82
- if (active.length === 0) {
83
- return { clause: "", args: [] };
84
- }
85
- return {
86
- clause: ` WHERE ${active.map(([sql]) => sql).join(" AND ")}`,
87
- args: active.map(([, value]) => value),
88
- };
89
- }
90
19
  async function selectProtectedSessionIds(dbPath) {
91
20
  if (!(await fileExists(dbPath))) {
92
21
  return [];
@@ -141,37 +70,20 @@ export class SqlitePersistence {
141
70
  }
142
71
  async rawExecute(sql, args) {
143
72
  const client = await this.getClient();
144
- for (let attempt = 0;; attempt += 1) {
145
- try {
146
- if (args) {
147
- await client.execute(sql, args);
148
- return;
149
- }
150
- await client.execute(sql);
73
+ await executeWithBusyRetry(client, this.dbPath, sql, args, async () => {
74
+ if (args) {
75
+ await client.execute(sql, args);
151
76
  return;
152
77
  }
153
- catch (error) {
154
- if (!isSqliteBusyError(error) || attempt >= SQLITE_BUSY_RETRY_ATTEMPTS) {
155
- throwWrappedRuntimeSqliteError(this.dbPath, sql, error);
156
- }
157
- await sleep(Math.min(SQLITE_BUSY_RETRY_DELAY_MS * (attempt + 1), 1_000));
158
- }
159
- }
78
+ await client.execute(sql);
79
+ });
160
80
  }
161
81
  async rawSelectAll(sql, args) {
162
82
  const client = await this.getClient();
163
- for (let attempt = 0;; attempt += 1) {
164
- try {
165
- const result = args ? await client.execute(sql, args) : await client.execute(sql);
166
- return result.rows.map((row) => asRow(row));
167
- }
168
- catch (error) {
169
- if (!isSqliteBusyError(error) || attempt >= SQLITE_BUSY_RETRY_ATTEMPTS) {
170
- throwWrappedRuntimeSqliteError(this.dbPath, sql, error);
171
- }
172
- await sleep(Math.min(SQLITE_BUSY_RETRY_DELAY_MS * (attempt + 1), 1_000));
173
- }
174
- }
83
+ return executeWithBusyRetry(client, this.dbPath, sql, args, async () => {
84
+ const result = args ? await client.execute(sql, args) : await client.execute(sql);
85
+ return result.rows.map((row) => asRow(row));
86
+ });
175
87
  }
176
88
  async ensureInitialized() {
177
89
  if (this.initialized) {
@@ -1,4 +1,4 @@
1
- import type { HarnessEvent, RequestDataEvent, RequestEventSnapshot, RequestExecutionStep, RequestPlanState, RequestResult, RuntimeSurfaceItem, UpstreamRuntimeEvent } from "./contracts/types.js";
1
+ import type { HarnessEvent, RequestDataEvent, RequestEventSnapshot, RequestExecutionStep, RequestPlanState, RequestResult, RuntimeSurfaceItem, UpstreamRuntimeEvent } from "../contracts/types.js";
2
2
  type StreamEventItem = {
3
3
  type: "event";
4
4
  event: HarnessEvent;
@@ -1,4 +1,4 @@
1
- import { extractInterruptPayload, extractReasoningStreamOutput, extractToolResult } from "./runtime/parsing/index.js";
1
+ import { extractInterruptPayload, extractReasoningStreamOutput, extractToolResult } from "../runtime/parsing/stream-event-parsing.js";
2
2
  function asObject(value) {
3
3
  return typeof value === "object" && value !== null ? value : null;
4
4
  }
@@ -0,0 +1,39 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { AgentHarnessRuntime } from "../../runtime/harness.js";
3
+ import type { A2aAgentCard, A2aExtendedAgentCard, A2aHttpServerOptions } from "./http.js";
4
+ export declare const SUPPORTED_A2A_VERSIONS: readonly ["1.0", "0.3"];
5
+ export type A2aServiceParameters = {
6
+ version: string;
7
+ extensions: string[];
8
+ };
9
+ export declare function normalizePath(value: string | undefined, fallback: string): string;
10
+ export declare function writeJson(response: ServerResponse, statusCode: number, payload: unknown): void;
11
+ export declare function writeA2aDiscoveryHeaders(response: ServerResponse): void;
12
+ export declare function writeOptionalAgentCardIntegrityHeaders(response: ServerResponse, options: {
13
+ registryUrls?: string[];
14
+ agentCardSignature?: A2aHttpServerOptions["agentCardSignature"];
15
+ }): void;
16
+ export declare function parseA2aServiceParameters(requestUrl: URL, request: IncomingMessage): A2aServiceParameters | null;
17
+ export declare function acceptsSse(request: IncomingMessage): boolean;
18
+ export declare function buildAgentCard(runtime: AgentHarnessRuntime, options: Required<Pick<A2aHttpServerOptions, "agentName" | "agentDescription">> & {
19
+ rpcUrl: string;
20
+ documentationUrl?: string;
21
+ provider?: {
22
+ organization?: string;
23
+ url?: string;
24
+ };
25
+ defaultAgentId?: string;
26
+ registryUrls?: string[];
27
+ agentCardSignature?: A2aHttpServerOptions["agentCardSignature"];
28
+ }): A2aAgentCard;
29
+ export declare function buildExtendedAgentCard(runtime: AgentHarnessRuntime, options: Required<Pick<A2aHttpServerOptions, "agentName" | "agentDescription">> & {
30
+ rpcUrl: string;
31
+ documentationUrl?: string;
32
+ provider?: {
33
+ organization?: string;
34
+ url?: string;
35
+ };
36
+ defaultAgentId?: string;
37
+ registryUrls?: string[];
38
+ agentCardSignature?: A2aHttpServerOptions["agentCardSignature"];
39
+ }): A2aExtendedAgentCard;
@@ -0,0 +1,178 @@
1
+ import { AGENT_HARNESS_VERSION } from "../../package-version.js";
2
+ export const SUPPORTED_A2A_VERSIONS = ["1.0", "0.3"];
3
+ export 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
+ export 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
+ export function writeA2aDiscoveryHeaders(response) {
13
+ response.setHeader("A2A-Version", "1.0");
14
+ response.setHeader("A2A-Supported-Versions", SUPPORTED_A2A_VERSIONS.join(", "));
15
+ }
16
+ function normalizeNonEmptyStringArray(value) {
17
+ if (!Array.isArray(value)) {
18
+ return undefined;
19
+ }
20
+ const items = value.map((item) => item.trim()).filter((item) => item.length > 0);
21
+ return items.length > 0 ? items : undefined;
22
+ }
23
+ function buildDiscoveryMetadata(options) {
24
+ const registryUrls = normalizeNonEmptyStringArray(options.registryUrls);
25
+ const signature = options.agentCardSignature?.signature?.trim();
26
+ const algorithm = options.agentCardSignature?.algorithm?.trim();
27
+ const keyId = options.agentCardSignature?.keyId?.trim();
28
+ if (!registryUrls && (!signature || !algorithm)) {
29
+ return undefined;
30
+ }
31
+ return {
32
+ ...(registryUrls ? { registryUrls } : {}),
33
+ ...(signature && algorithm
34
+ ? {
35
+ signedAgentCard: {
36
+ algorithm,
37
+ signature,
38
+ ...(keyId ? { keyId } : {}),
39
+ },
40
+ }
41
+ : {}),
42
+ };
43
+ }
44
+ export function writeOptionalAgentCardIntegrityHeaders(response, options) {
45
+ const registryUrls = normalizeNonEmptyStringArray(options.registryUrls);
46
+ if (registryUrls) {
47
+ response.setHeader("X-A2A-Registry-Urls", registryUrls.join(", "));
48
+ }
49
+ const signature = options.agentCardSignature?.signature?.trim();
50
+ const algorithm = options.agentCardSignature?.algorithm?.trim();
51
+ const keyId = options.agentCardSignature?.keyId?.trim();
52
+ if (signature && algorithm) {
53
+ response.setHeader("X-A2A-Agent-Card-Signature", signature);
54
+ response.setHeader("X-A2A-Agent-Card-Alg", algorithm);
55
+ if (keyId) {
56
+ response.setHeader("X-A2A-Agent-Card-Key-Id", keyId);
57
+ }
58
+ }
59
+ }
60
+ function readServiceParameter(requestUrl, request, name) {
61
+ const headerValue = request.headers[name.toLowerCase()];
62
+ if (typeof headerValue === "string") {
63
+ return headerValue;
64
+ }
65
+ if (Array.isArray(headerValue)) {
66
+ return headerValue.join(",");
67
+ }
68
+ return requestUrl.searchParams.get(name) ?? undefined;
69
+ }
70
+ export function parseA2aServiceParameters(requestUrl, request) {
71
+ const requestedVersion = readServiceParameter(requestUrl, request, "A2A-Version")?.trim() ?? "";
72
+ const normalizedVersion = requestedVersion.length === 0 ? "0.3" : requestedVersion;
73
+ if (!SUPPORTED_A2A_VERSIONS.includes(normalizedVersion)) {
74
+ return null;
75
+ }
76
+ const requestedExtensions = readServiceParameter(requestUrl, request, "A2A-Extensions") ?? "";
77
+ return {
78
+ version: normalizedVersion,
79
+ extensions: requestedExtensions
80
+ .split(",")
81
+ .map((entry) => entry.trim())
82
+ .filter((entry) => entry.length > 0),
83
+ };
84
+ }
85
+ export function acceptsSse(request) {
86
+ const accept = request.headers.accept;
87
+ if (accept === undefined) {
88
+ return false;
89
+ }
90
+ const values = Array.isArray(accept) ? accept : [accept];
91
+ return values.some((value) => value.includes("text/event-stream"));
92
+ }
93
+ export function buildAgentCard(runtime, options) {
94
+ const inventory = runtime.describeWorkspaceInventory();
95
+ const discovery = buildDiscoveryMetadata({
96
+ registryUrls: options.registryUrls,
97
+ agentCardSignature: options.agentCardSignature,
98
+ });
99
+ const skills = inventory.agents.map((agent) => ({
100
+ id: agent.id,
101
+ name: agent.id,
102
+ description: agent.description || `Agent ${agent.id}`,
103
+ tags: ["agent-harness", agent.parentAgentId ? "subagent" : "agent"],
104
+ examples: [`Send a task to ${agent.id}.`],
105
+ }));
106
+ return {
107
+ name: options.agentName,
108
+ description: options.agentDescription,
109
+ version: AGENT_HARNESS_VERSION,
110
+ protocolVersion: "1.0",
111
+ url: options.rpcUrl,
112
+ preferredTransport: "JSONRPC",
113
+ supportedInterfaces: [
114
+ {
115
+ url: options.rpcUrl,
116
+ protocolBinding: "JSONRPC",
117
+ protocolVersion: "1.0",
118
+ },
119
+ {
120
+ url: options.rpcUrl,
121
+ protocolBinding: "JSONRPC",
122
+ protocolVersion: "0.3",
123
+ },
124
+ ],
125
+ capabilities: {
126
+ streaming: true,
127
+ pushNotifications: true,
128
+ extendedAgentCard: true,
129
+ },
130
+ defaultInputModes: ["text/plain"],
131
+ defaultOutputModes: ["text/plain"],
132
+ skills,
133
+ ...(discovery
134
+ ? {
135
+ metadata: {
136
+ agentHarness: {
137
+ discovery,
138
+ },
139
+ },
140
+ }
141
+ : {}),
142
+ ...(options.documentationUrl ? { documentationUrl: options.documentationUrl } : {}),
143
+ ...(options.provider ? { provider: options.provider } : {}),
144
+ ...(options.defaultAgentId ? { defaultAgentId: options.defaultAgentId } : {}),
145
+ };
146
+ }
147
+ export function buildExtendedAgentCard(runtime, options) {
148
+ const inventory = runtime.describeWorkspaceInventory();
149
+ const card = buildAgentCard(runtime, options);
150
+ const discovery = buildDiscoveryMetadata({
151
+ registryUrls: options.registryUrls,
152
+ agentCardSignature: options.agentCardSignature,
153
+ });
154
+ return {
155
+ ...card,
156
+ metadata: {
157
+ agentHarness: {
158
+ runtime: {
159
+ product: "agent-harness",
160
+ protocolSurface: "a2a-http",
161
+ ...(options.defaultAgentId ? { defaultAgentId: options.defaultAgentId } : {}),
162
+ },
163
+ protocolSurfaces: ["A2A", "ACP", "AG-UI", "runtime MCP"],
164
+ inventory: {
165
+ agentCount: inventory.agents.length,
166
+ subagentCount: inventory.agents.filter((agent) => Boolean(agent.parentAgentId)).length,
167
+ },
168
+ ...(discovery ? { discovery } : {}),
169
+ agents: inventory.agents.map((agent) => ({
170
+ id: agent.id,
171
+ name: agent.id,
172
+ description: agent.description || `Agent ${agent.id}`,
173
+ kind: agent.parentAgentId ? "subagent" : "agent",
174
+ })),
175
+ },
176
+ },
177
+ };
178
+ }
@@ -0,0 +1,28 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { AgentHarnessRuntime } from "../../runtime/harness.js";
3
+ import { type A2aServiceParameters } from "./http-discovery.js";
4
+ import type { A2aAgentCardBuildOptions, A2aHttpServerOptions, A2aJsonRpcRequest, A2aJsonRpcResponse, PendingA2aPushNotificationConfig, StoredA2aPushNotificationConfig } from "./http.js";
5
+ type PushNotificationRegistry = {
6
+ register: (taskId: string, config: PendingA2aPushNotificationConfig) => StoredA2aPushNotificationConfig;
7
+ list: (taskId: string) => StoredA2aPushNotificationConfig[];
8
+ get: (taskId: string, configId: string) => StoredA2aPushNotificationConfig | undefined;
9
+ delete: (taskId: string, configId: string) => boolean;
10
+ dispatch: (taskId: string) => Promise<void>;
11
+ };
12
+ type HandleA2aJsonRpcRequestInput = {
13
+ runtime: AgentHarnessRuntime;
14
+ request: IncomingMessage;
15
+ response: ServerResponse;
16
+ payload: A2aJsonRpcRequest;
17
+ serviceParameters: A2aServiceParameters;
18
+ serverOptions: A2aHttpServerOptions;
19
+ buildCardOptions: () => A2aAgentCardBuildOptions;
20
+ pushNotifications: PushNotificationRegistry;
21
+ };
22
+ export declare function toError(id: string | number | null, code: number, message: string, data?: unknown): A2aJsonRpcResponse;
23
+ export declare function readRequestBody(request: IncomingMessage): Promise<string>;
24
+ export declare function createPushNotificationRegistry(runtime: AgentHarnessRuntime, createId: () => string): PushNotificationRegistry & {
25
+ unsubscribe: () => void;
26
+ };
27
+ export declare function handleA2aJsonRpcRequest(input: HandleA2aJsonRpcRequestInput): Promise<void>;
28
+ export {};