a2a-exposed 0.8.14 → 0.8.16

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.
@@ -0,0 +1,100 @@
1
+ // A2A-Version selects the response shape; the extended card is -32007. Run: npm test
2
+ import { test } from "node:test";
3
+ import assert from "node:assert/strict";
4
+ import worker from "../src/index.ts";
5
+ import { d1 } from "./d1.ts";
6
+
7
+ const BASE = "https://agent.example.com";
8
+
9
+ function setup() {
10
+ const DB = d1(new URL("../migrations/", import.meta.url));
11
+ const env: any = { DB, PUBLIC_URL: BASE, OWNER_TOKEN: "owner-secret", AGENT_NAME: "Test Inbox", PAIRING_APPROVAL: "off" };
12
+ const call = async (method: string, path: string, o: { json?: any; headers?: Record<string, string> } = {}) => {
13
+ const headers: Record<string, string> = { "cf-connecting-ip": "198.51.100.7", ...(o.headers || {}) };
14
+ let body: string | undefined;
15
+ if (o.json !== undefined) { headers["content-type"] = "application/json"; body = JSON.stringify(o.json); }
16
+ const pending: Promise<unknown>[] = [];
17
+ const res = await worker.fetch(new Request(BASE + path, { method, headers, body }) as any, env, { waitUntil: (p: Promise<unknown>) => pending.push(p), passThroughOnException() {} } as any);
18
+ await Promise.allSettled(pending);
19
+ const text = await res.text();
20
+ let data: any = text;
21
+ try { data = JSON.parse(text); } catch { /* text */ }
22
+ return { status: res.status, data, text };
23
+ };
24
+ return { call };
25
+ }
26
+
27
+ test("A2A-Version selects the response shape; an absent header keeps the method name", async () => {
28
+ const s = setup();
29
+ const issued = await s.call("POST", "/owner/peers", { json: { label: "ada" }, headers: { authorization: "Bearer owner-secret" } });
30
+ assert.equal(issued.status, 200, issued.text);
31
+ const token = issued.data.token as string;
32
+ let n = 0;
33
+ const msg = () => ({ message: { role: "user", messageId: `m${++n}`, parts: [{ kind: "text", text: "hi" }] } });
34
+ const rpc = (method: string, params: any, headers: Record<string, string> = {}, path = "/") =>
35
+ s.call("POST", path, { json: { jsonrpc: "2.0", id: 1, method, params }, headers: { authorization: `Bearer ${token}`, ...headers } });
36
+
37
+ const v1 = await rpc("message/send", msg(), { "a2a-version": "1.0" });
38
+ assert.equal(v1.status, 200, v1.text);
39
+ assert.equal(v1.data.result.task.status.state, "TASK_STATE_SUBMITTED");
40
+ assert.equal(v1.data.result.task.kind, undefined);
41
+ assert.equal(v1.data.result.task.history[0].role, "ROLE_USER");
42
+ assert.equal(v1.data.result.task.history[0].parts[0].kind, undefined);
43
+ assert.equal(v1.data.result.task.history[0].parts[0].text, "hi");
44
+
45
+ const v03 = await rpc("SendMessage", msg(), { "a2a-version": "0.3" });
46
+ assert.equal(v03.data.result.kind, "task");
47
+ assert.equal(v03.data.result.status.state, "submitted");
48
+ assert.equal(v03.data.result.task, undefined);
49
+ assert.equal(v03.data.result.history[0].role, "user");
50
+ assert.equal(v03.data.result.history[0].kind, "message");
51
+ assert.equal(v03.data.result.history[0].parts[0].kind, "text");
52
+
53
+ const bare03 = await rpc("message/send", msg());
54
+ assert.equal(bare03.data.result.kind, "task");
55
+ assert.equal(bare03.data.result.status.state, "submitted");
56
+ const bare1 = await rpc("SendMessage", msg());
57
+ assert.equal(bare1.data.result.task.status.state, "TASK_STATE_SUBMITTED");
58
+
59
+ const patch1 = await rpc("message/send", msg(), { "a2a-version": "1.0.1" });
60
+ assert.equal(patch1.data.result.task.status.state, "TASK_STATE_SUBMITTED");
61
+ const patch03 = await rpc("SendMessage", msg(), { "A2A-Version": "0.3.0" });
62
+ assert.equal(patch03.data.result.kind, "task");
63
+ const short1 = await rpc("message/send", msg(), { "a2a-version": "1" });
64
+ assert.equal(short1.data.result.task.status.state, "TASK_STATE_SUBMITTED");
65
+
66
+ const query = await rpc("SendMessage", msg(), {}, "/?A2A-Version=0.3");
67
+ assert.equal(query.data.result.kind, "task");
68
+ assert.equal(query.data.result.status.state, "submitted");
69
+ const headerWins = await rpc("SendMessage", msg(), { "a2a-version": "1.0" }, "/?A2A-Version=0.3");
70
+ assert.equal(headerWins.data.result.task.status.state, "TASK_STATE_SUBMITTED");
71
+
72
+ const created = bare1.data.result.task.id as string;
73
+ const reread = await rpc("GetTask", { id: created }, { "a2a-version": "0.3" });
74
+ assert.equal(reread.data.result.kind, "task");
75
+ assert.equal(reread.data.result.status.state, "submitted");
76
+ assert.equal(reread.data.result.id, created);
77
+
78
+ for (const method of ["SendMessage", "no-such-method"]) {
79
+ const bad = await rpc(method, msg(), { "a2a-version": "2.0" });
80
+ assert.equal(bad.data.error?.code, -32009, method);
81
+ assert.match(bad.data.error.message, /2\.0/);
82
+ }
83
+ const minor = await rpc("SendMessage", msg(), { "a2a-version": "1.2" });
84
+ assert.equal(minor.data.error?.code, -32009);
85
+ const unknown = await rpc("no-such-method", {});
86
+ assert.equal(unknown.data.error?.code, -32601);
87
+ const unknownOk = await rpc("no-such-method", {}, { "a2a-version": "1.0" });
88
+ assert.equal(unknownOk.data.error?.code, -32601);
89
+
90
+ for (const method of ["GetExtendedAgentCard", "agent/getAuthenticatedExtendedCard"]) {
91
+ const missing = await rpc(method, {});
92
+ assert.equal(missing.status, 200);
93
+ assert.equal(missing.data.error?.code, -32007, method);
94
+ assert.equal(missing.data.error?.message, "Extended agent card is not configured");
95
+ const withHeader = await rpc(method, {}, { "a2a-version": "0.3" });
96
+ assert.equal(withHeader.data.error?.code, -32007, method);
97
+ }
98
+ const extFirst = await rpc("GetExtendedAgentCard", {}, { "a2a-version": "2.0" });
99
+ assert.equal(extFirst.data.error?.code, -32009);
100
+ });