@botbotgo/agent-harness 0.0.309 → 0.0.310
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 +14 -0
- package/README.zh.md +14 -0
- package/dist/acp.d.ts +1 -116
- package/dist/acp.js +1 -310
- package/dist/api.d.ts +1 -1
- package/dist/api.js +1 -1
- package/dist/cli/chat-interactive.d.ts +24 -0
- package/dist/cli/chat-interactive.js +244 -0
- package/dist/cli/chat-rendering.d.ts +9 -0
- package/dist/cli/chat-rendering.js +102 -0
- package/dist/cli/chat-stream.d.ts +23 -0
- package/dist/cli/chat-stream.js +330 -0
- package/dist/cli/chat-ui.d.ts +20 -0
- package/dist/cli/chat-ui.js +198 -0
- package/dist/cli/chat-workspace.d.ts +15 -0
- package/dist/cli/chat-workspace.js +205 -0
- package/dist/cli/main.d.ts +52 -0
- package/dist/cli/main.js +323 -0
- package/dist/cli/managed-service-commands.d.ts +23 -0
- package/dist/cli/managed-service-commands.js +63 -0
- package/dist/cli/managed-service.d.ts +27 -0
- package/dist/cli/managed-service.js +61 -0
- package/dist/cli/options-init-chat.d.ts +16 -0
- package/dist/cli/options-init-chat.js +108 -0
- package/dist/cli/options-runtime.d.ts +27 -0
- package/dist/cli/options-runtime.js +158 -0
- package/dist/cli/options-serve.d.ts +24 -0
- package/dist/cli/options-serve.js +166 -0
- package/dist/cli/options.d.ts +5 -0
- package/dist/cli/options.js +47 -0
- package/dist/cli/process-guards.d.ts +14 -0
- package/dist/cli/process-guards.js +139 -0
- package/dist/cli/request-tree.d.ts +12 -0
- package/dist/cli/request-tree.js +296 -0
- package/dist/cli/runtime-commands.d.ts +15 -0
- package/dist/cli/runtime-commands.js +247 -0
- package/dist/cli/runtime-output.d.ts +5 -0
- package/dist/cli/runtime-output.js +124 -0
- package/dist/cli/server-commands.d.ts +36 -0
- package/dist/cli/server-commands.js +250 -0
- package/dist/cli/workspace.d.ts +6 -0
- package/dist/cli/workspace.js +71 -0
- package/dist/cli.d.ts +1 -78
- package/dist/cli.js +2 -3024
- package/dist/client/acp.d.ts +1 -50
- package/dist/client/acp.js +1 -219
- package/dist/client/in-process.d.ts +5 -5
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +1 -1
- package/dist/contracts/runtime-evaluation.d.ts +103 -0
- package/dist/contracts/runtime-evaluation.js +1 -0
- package/dist/contracts/runtime-memory.d.ts +162 -0
- package/dist/contracts/runtime-memory.js +1 -0
- package/dist/contracts/runtime-observability.d.ts +248 -0
- package/dist/contracts/runtime-observability.js +1 -0
- package/dist/contracts/runtime-requests.d.ts +342 -0
- package/dist/contracts/runtime-requests.js +1 -0
- package/dist/contracts/runtime-scheduling.d.ts +146 -0
- package/dist/contracts/runtime-scheduling.js +1 -0
- package/dist/contracts/runtime.d.ts +5 -1042
- package/dist/contracts/runtime.js +27 -1
- package/dist/flow/build-flow-graph.js +4 -875
- package/dist/flow/flow-graph-normalization.d.ts +56 -0
- package/dist/flow/flow-graph-normalization.js +214 -0
- package/dist/flow/flow-graph-runtime.d.ts +8 -0
- package/dist/flow/flow-graph-runtime.js +107 -0
- package/dist/flow/flow-graph-upstream.d.ts +18 -0
- package/dist/flow/flow-graph-upstream.js +498 -0
- package/dist/flow/types.d.ts +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/init-project.d.ts +1 -12
- package/dist/init-project.js +1 -651
- package/dist/{procedural → knowledge/procedural}/manager.d.ts +3 -3
- package/dist/{procedural → knowledge/procedural}/manager.js +6 -6
- package/dist/mcp.d.ts +2 -76
- package/dist/mcp.js +2 -428
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/persistence/file-store.js +1 -1
- package/dist/persistence/sqlite-runtime.d.ts +19 -0
- package/dist/persistence/sqlite-runtime.js +86 -0
- package/dist/persistence/sqlite-store.js +11 -99
- package/dist/{request-events.d.ts → projections/request-events.d.ts} +1 -1
- package/dist/{upstream-events.js → projections/upstream-events.js} +1 -1
- package/dist/protocol/a2a/http-discovery.d.ts +39 -0
- package/dist/protocol/a2a/http-discovery.js +178 -0
- package/dist/protocol/a2a/http-rpc.d.ts +28 -0
- package/dist/protocol/a2a/http-rpc.js +623 -0
- package/dist/protocol/a2a/http.d.ts +72 -1
- package/dist/protocol/a2a/http.js +14 -1124
- package/dist/protocol/a2a/task-state.d.ts +29 -0
- package/dist/protocol/a2a/task-state.js +317 -0
- package/dist/protocol/acp/client.js +1 -1
- package/dist/protocol/acp/harness-client.d.ts +50 -0
- package/dist/protocol/acp/harness-client.js +219 -0
- package/dist/protocol/acp/server.d.ts +116 -0
- package/dist/protocol/acp/server.js +310 -0
- package/dist/protocol/ag-ui/http.js +1 -1
- package/dist/protocol/mcp/server.d.ts +76 -0
- package/dist/protocol/mcp/server.js +428 -0
- package/dist/resource/backend/workspace-scoped-backend.d.ts +40 -0
- package/dist/resource/backend/workspace-scoped-backend.js +296 -0
- package/dist/resource/mcp/tool-support.d.ts +35 -0
- package/dist/resource/mcp/tool-support.js +296 -0
- package/dist/resource/mcp-tool-support.d.ts +2 -35
- package/dist/resource/mcp-tool-support.js +2 -296
- package/dist/resource/providers/resource-provider.d.ts +22 -0
- package/dist/resource/providers/resource-provider.js +215 -0
- package/dist/resource/resource-impl.d.ts +3 -33
- package/dist/resource/resource-impl.js +2 -808
- package/dist/resource/resource-types.d.ts +33 -0
- package/dist/resource/resource-types.js +1 -0
- package/dist/resource/tools/function-tool-resolver.d.ts +2 -0
- package/dist/resource/tools/function-tool-resolver.js +306 -0
- package/dist/runtime/adapter/middleware-assembly.js +1 -1
- package/dist/runtime/adapter/model/invocation-request.js +2 -2
- package/dist/runtime/adapter/model/message-assembly.js +1 -1
- package/dist/runtime/agent-runtime-adapter.d.ts +3 -63
- package/dist/runtime/agent-runtime-adapter.js +5 -233
- package/dist/runtime/agent-runtime-assembly.d.ts +67 -0
- package/dist/runtime/agent-runtime-assembly.js +211 -0
- package/dist/runtime/harness/background-runtime.d.ts +1 -1
- package/dist/runtime/harness/events/event-sink.js +1 -1
- package/dist/runtime/harness/events/runtime-event-operations.d.ts +1 -1
- package/dist/runtime/harness/events/streaming.js +1 -1
- package/dist/runtime/harness/public-shapes.d.ts +43 -0
- package/dist/runtime/harness/public-shapes.js +186 -0
- package/dist/runtime/harness/run/inspection.js +2 -2
- package/dist/runtime/harness/run/resources.js +1 -1
- package/dist/runtime/harness/run/surface-semantics.js +1 -1
- package/dist/runtime/harness/system/inventory.d.ts +1 -1
- package/dist/runtime/harness/system/inventory.js +2 -2
- package/dist/runtime/harness/system/policy-engine.js +1 -1
- package/dist/runtime/harness/system/runtime-memory-manager.js +1 -1
- package/dist/runtime/harness/system/skill-requirements.d.ts +1 -1
- package/dist/runtime/harness/system/skill-requirements.js +1 -1
- package/dist/runtime/harness.d.ts +2 -2
- package/dist/runtime/harness.js +7 -191
- package/dist/runtime/maintenance/checkpoint-maintenance.js +1 -1
- package/dist/runtime/maintenance/runtime-record-maintenance.js +1 -1
- package/dist/runtime/parsing/output-content.d.ts +11 -0
- package/dist/runtime/parsing/output-content.js +442 -0
- package/dist/runtime/parsing/output-parsing.d.ts +3 -29
- package/dist/runtime/parsing/output-parsing.js +3 -806
- package/dist/runtime/parsing/output-recovery.d.ts +14 -0
- package/dist/runtime/parsing/output-recovery.js +288 -0
- package/dist/runtime/parsing/output-tool-args.d.ts +4 -0
- package/dist/runtime/parsing/output-tool-args.js +120 -0
- package/dist/runtime/support/runtime-factories.js +1 -1
- package/dist/scaffold/init-project.d.ts +12 -0
- package/dist/scaffold/init-project.js +651 -0
- package/dist/{extensions.d.ts → tooling/extensions.d.ts} +1 -1
- package/dist/{extensions.js → tooling/extensions.js} +3 -3
- package/dist/{tool-modules.d.ts → tooling/module-loader.d.ts} +1 -1
- package/dist/{tool-modules.js → tooling/module-loader.js} +2 -2
- package/dist/workspace/agent-binding-compiler.js +2 -2
- package/dist/workspace/compile.js +2 -2
- package/dist/workspace/object-loader-paths.d.ts +11 -0
- package/dist/workspace/object-loader-paths.js +75 -0
- package/dist/workspace/object-loader-readers.d.ts +21 -0
- package/dist/workspace/object-loader-readers.js +187 -0
- package/dist/workspace/object-loader.d.ts +0 -1
- package/dist/workspace/object-loader.js +6 -260
- package/dist/workspace/resource-compilers.js +1 -1
- package/dist/workspace/support/discovery.js +1 -1
- package/package.json +1 -1
- package/dist/runtime/adapter/index.d.ts +0 -13
- package/dist/runtime/adapter/index.js +0 -13
- package/dist/runtime/harness/index.d.ts +0 -19
- package/dist/runtime/harness/index.js +0 -19
- package/dist/runtime/maintenance/index.d.ts +0 -4
- package/dist/runtime/maintenance/index.js +0 -4
- package/dist/runtime/parsing/index.d.ts +0 -2
- package/dist/runtime/parsing/index.js +0 -2
- package/dist/runtime/support/index.d.ts +0 -4
- package/dist/runtime/support/index.js +0 -4
- package/dist/workspace/support/index.d.ts +0 -2
- package/dist/workspace/support/index.js +0 -2
- /package/dist/{procedural → knowledge/procedural}/config.d.ts +0 -0
- /package/dist/{procedural → knowledge/procedural}/config.js +0 -0
- /package/dist/{procedural → knowledge/procedural}/index.d.ts +0 -0
- /package/dist/{procedural → knowledge/procedural}/index.js +0 -0
- /package/dist/{presentation.d.ts → projections/presentation.d.ts} +0 -0
- /package/dist/{presentation.js → projections/presentation.js} +0 -0
- /package/dist/{request-events.js → projections/request-events.js} +0 -0
- /package/dist/{upstream-events.d.ts → projections/upstream-events.d.ts} +0 -0
- /package/dist/runtime/{support → env}/runtime-env.d.ts +0 -0
- /package/dist/runtime/{support → env}/runtime-env.js +0 -0
- /package/dist/runtime/{support → layout}/runtime-layout.d.ts +0 -0
- /package/dist/runtime/{support → layout}/runtime-layout.js +0 -0
- /package/dist/runtime/{support → prompts}/runtime-prompts.d.ts +0 -0
- /package/dist/runtime/{support → prompts}/runtime-prompts.js +0 -0
- /package/dist/runtime/{support → skills}/skill-metadata.d.ts +0 -0
- /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/
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
|
|
154
|
-
|
|
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
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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 "
|
|
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 "
|
|
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 {};
|