@agenticprimitives/a2a 0.0.0-alpha.1
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/CLAUDE.md +67 -0
- package/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/agent.d.ts +114 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +191 -0
- package/dist/agent.js.map +1 -0
- package/dist/auth.d.ts +55 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +116 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +41 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +43 -0
- package/dist/client.js.map +1 -0
- package/dist/cloudflare/index.d.ts +7 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +39 -0
- package/dist/cloudflare/index.js.map +1 -0
- package/dist/discovery.d.ts +29 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +22 -0
- package/dist/discovery.js.map +1 -0
- package/dist/grant.d.ts +29 -0
- package/dist/grant.d.ts.map +1 -0
- package/dist/grant.js +29 -0
- package/dist/grant.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/jsonrpc.d.ts +25 -0
- package/dist/jsonrpc.d.ts.map +1 -0
- package/dist/jsonrpc.js +52 -0
- package/dist/jsonrpc.js.map +1 -0
- package/dist/push.d.ts +28 -0
- package/dist/push.d.ts.map +1 -0
- package/dist/push.js +39 -0
- package/dist/push.js.map +1 -0
- package/dist/runtime.d.ts +53 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +154 -0
- package/dist/runtime.js.map +1 -0
- package/dist/skill-handler.d.ts +88 -0
- package/dist/skill-handler.d.ts.map +1 -0
- package/dist/skill-handler.js +32 -0
- package/dist/skill-handler.js.map +1 -0
- package/dist/sse.d.ts +9 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +18 -0
- package/dist/sse.js.map +1 -0
- package/dist/task-store.d.ts +16 -0
- package/dist/task-store.d.ts.map +1 -0
- package/dist/task-store.js +34 -0
- package/dist/task-store.js.map +1 -0
- package/dist/types.d.ts +80 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +65 -0
- package/spec.md +4 -0
package/dist/auth.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// The A2A delegation-auth gate (spec 269 FR-4 / SR-1..SR-6). Net-new vs the legacy vault path, which
|
|
2
|
+
// checks only timestamp. Every inbound A2A message is gated here BEFORE any task is created:
|
|
3
|
+
// FR-4.1 delegate===requester, timestamp window, on-chain isRevoked (fail-closed), ERC-1271 delegator.
|
|
4
|
+
// FR-4.2 the grant MUST scope to THIS recipient agent (allowedTargets) + the requested skill
|
|
5
|
+
// (allowedMethods) — what makes a grant non-replayable against a different agent/skill.
|
|
6
|
+
// FR-4.3 single-use message-id (inbound replay guard).
|
|
7
|
+
// FR-4.4 the inbound message is signed by the sender.
|
|
8
|
+
// On-chain reads are INJECTED (the package stays transport-agnostic); the consumer wires viem.
|
|
9
|
+
import { decodeAbiParameters, keccak256, encodeAbiParameters, toBytes } from 'viem';
|
|
10
|
+
import { skillSelector, A2A_ANY_SKILL } from './grant.js';
|
|
11
|
+
/** Decode the deployed enforcers' term formats (must mirror delegation's encoders byte-for-byte). */
|
|
12
|
+
export function decodeTimestampTerms(terms) {
|
|
13
|
+
const [validAfter, validUntil] = decodeAbiParameters([{ type: 'uint256' }, { type: 'uint256' }], terms);
|
|
14
|
+
return { validAfter, validUntil };
|
|
15
|
+
}
|
|
16
|
+
export function decodeAllowedTargetsTerms(terms) {
|
|
17
|
+
const [targets] = decodeAbiParameters([{ type: 'address[]' }], terms);
|
|
18
|
+
return targets;
|
|
19
|
+
}
|
|
20
|
+
export function decodeAllowedMethodsTerms(terms) {
|
|
21
|
+
const [selectors] = decodeAbiParameters([{ type: 'bytes4[]' }], terms);
|
|
22
|
+
return selectors;
|
|
23
|
+
}
|
|
24
|
+
/** Canonical hash the SENDER signs for an inbound message (A2A-INV-01). Binds id + sender + skill + body. */
|
|
25
|
+
export function hashA2aMessage(m) {
|
|
26
|
+
return keccak256(encodeAbiParameters([{ type: 'bytes32' }, { type: 'address' }, { type: 'bytes32' }, { type: 'bytes32' }, { type: 'uint256' }], [m.messageId, m.sender, keccak256(toBytes(m.skill)), m.bodyHash, BigInt(m.createdAt)]));
|
|
27
|
+
}
|
|
28
|
+
const eq = (a, b) => a.toLowerCase() === b.toLowerCase();
|
|
29
|
+
const findCaveat = (caveats, enforcer) => caveats.find((c) => eq(c.enforcer, enforcer));
|
|
30
|
+
/**
|
|
31
|
+
* Authorize an inbound A2A message. Returns the principal (delegation.delegator) the sender acts for, or
|
|
32
|
+
* a rejection reason. Fail-closed throughout; no task is created on `ok: false`. The message-id is
|
|
33
|
+
* reserved LAST so a rejected message never burns a nonce, while a replay of a valid message hits the
|
|
34
|
+
* already-reserved id.
|
|
35
|
+
*/
|
|
36
|
+
export async function authorizeA2aMessage(args) {
|
|
37
|
+
const { delegation: d, message, enforcers, checks } = args;
|
|
38
|
+
// FR-4.1 — the delegate IS the requester.
|
|
39
|
+
if (!eq(d.delegate, args.requester))
|
|
40
|
+
return { ok: false, reason: 'delegate != requester' };
|
|
41
|
+
if (!eq(message.sender, args.requester))
|
|
42
|
+
return { ok: false, reason: 'message sender != requester' };
|
|
43
|
+
// FR-4.1 — timestamp window (off-chain decode; the enforcer would check the same on-chain).
|
|
44
|
+
const tsCav = findCaveat(d.caveats, enforcers.timestamp);
|
|
45
|
+
if (!tsCav)
|
|
46
|
+
return { ok: false, reason: 'missing timestamp caveat' };
|
|
47
|
+
let win;
|
|
48
|
+
try {
|
|
49
|
+
win = decodeTimestampTerms(tsCav.terms);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return { ok: false, reason: 'bad timestamp terms' };
|
|
53
|
+
}
|
|
54
|
+
const nowSec = BigInt(Math.floor(args.now / 1000));
|
|
55
|
+
if (nowSec < win.validAfter || nowSec >= win.validUntil)
|
|
56
|
+
return { ok: false, reason: 'grant outside timestamp window' };
|
|
57
|
+
// FR-4.2 — recipient scoping: allowedTargets MUST include this agent.
|
|
58
|
+
const atCav = findCaveat(d.caveats, enforcers.allowedTargets);
|
|
59
|
+
if (!atCav)
|
|
60
|
+
return { ok: false, reason: 'missing allowedTargets caveat (FR-4.2)' };
|
|
61
|
+
let targets;
|
|
62
|
+
try {
|
|
63
|
+
targets = decodeAllowedTargetsTerms(atCav.terms);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return { ok: false, reason: 'bad allowedTargets terms' };
|
|
67
|
+
}
|
|
68
|
+
if (!targets.some((t) => eq(t, args.thisAgentSA)))
|
|
69
|
+
return { ok: false, reason: 'grant not scoped to this agent (allowedTargets)' };
|
|
70
|
+
// FR-4.2 — skill scoping: allowedMethods MUST include the skill selector (or the any-sentinel).
|
|
71
|
+
const amCav = findCaveat(d.caveats, enforcers.allowedMethods);
|
|
72
|
+
if (!amCav)
|
|
73
|
+
return { ok: false, reason: 'missing allowedMethods caveat (FR-4.2)' };
|
|
74
|
+
let selectors;
|
|
75
|
+
try {
|
|
76
|
+
selectors = decodeAllowedMethodsTerms(amCav.terms);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return { ok: false, reason: 'bad allowedMethods terms' };
|
|
80
|
+
}
|
|
81
|
+
const want = skillSelector(args.skill);
|
|
82
|
+
if (!selectors.some((s) => eq(s, want) || eq(s, A2A_ANY_SKILL))) {
|
|
83
|
+
return { ok: false, reason: 'grant not scoped to this skill (allowedMethods)' };
|
|
84
|
+
}
|
|
85
|
+
// FR-4.1 — on-chain isRevoked, fail-closed (any error denies).
|
|
86
|
+
try {
|
|
87
|
+
if (await checks.isRevoked(d))
|
|
88
|
+
return { ok: false, reason: 'delegation revoked' };
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
return { ok: false, reason: `revocation check unavailable: ${e instanceof Error ? e.message : e}` };
|
|
92
|
+
}
|
|
93
|
+
// FR-4.1 — ERC-1271 delegator signature.
|
|
94
|
+
try {
|
|
95
|
+
if (!(await checks.verifyDelegationSignature(d)))
|
|
96
|
+
return { ok: false, reason: 'delegation signature invalid' };
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
return { ok: false, reason: `delegation signature check failed: ${e instanceof Error ? e.message : e}` };
|
|
100
|
+
}
|
|
101
|
+
// FR-4.4 — inbound message signed by the sender.
|
|
102
|
+
try {
|
|
103
|
+
if (!(await checks.verifyMessageSignature(message, hashA2aMessage(message)))) {
|
|
104
|
+
return { ok: false, reason: 'message signature invalid' };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
return { ok: false, reason: `message signature check failed: ${e instanceof Error ? e.message : e}` };
|
|
109
|
+
}
|
|
110
|
+
// FR-4.3 — single-use message id (reserve last; a replay of a valid message hits the reserved id).
|
|
111
|
+
if (!(await args.store.reserveMessageId(message.messageId, args.replayTtlSec ?? 600))) {
|
|
112
|
+
return { ok: false, reason: 'message id already used (replay)' };
|
|
113
|
+
}
|
|
114
|
+
return { ok: true, principal: d.delegator };
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Address, Hex } from '@agenticprimitives/types';
|
|
2
|
+
import type { Delegation } from '@agenticprimitives/delegation';
|
|
3
|
+
import type { Task, TaskEvent, A2aMessage } from './types.js';
|
|
4
|
+
import type { JsonRpcRequest, JsonRpcResponse } from './jsonrpc.js';
|
|
5
|
+
export interface A2aTransport {
|
|
6
|
+
/** POST a JSON-RPC request to `targetAgent`'s /api/a2a and return the parsed response. */
|
|
7
|
+
rpc(targetAgent: Address, request: JsonRpcRequest): Promise<JsonRpcResponse>;
|
|
8
|
+
/** Open the message/stream SSE for a task; yields events until terminal. Optional until W4. */
|
|
9
|
+
stream?(targetAgent: Address, taskId: Hex): AsyncIterable<TaskEvent>;
|
|
10
|
+
}
|
|
11
|
+
export declare class A2aWireAdapter {
|
|
12
|
+
private readonly transport;
|
|
13
|
+
private seq;
|
|
14
|
+
constructor(transport: A2aTransport);
|
|
15
|
+
private id;
|
|
16
|
+
/** Submit an async task. The `message` must already be signed by `requester` (see `hashA2aMessage`). */
|
|
17
|
+
submitTask(targetAgent: Address, args: {
|
|
18
|
+
message: A2aMessage;
|
|
19
|
+
delegation: Delegation;
|
|
20
|
+
requester: Address;
|
|
21
|
+
input: unknown;
|
|
22
|
+
pushConfig?: {
|
|
23
|
+
url: string;
|
|
24
|
+
token?: string;
|
|
25
|
+
};
|
|
26
|
+
}): Promise<{
|
|
27
|
+
taskId: Hex;
|
|
28
|
+
state: Task['state'];
|
|
29
|
+
}>;
|
|
30
|
+
/** Poll a task's current state + artifact refs. */
|
|
31
|
+
getTask(targetAgent: Address, taskId: Hex, caller: Address): Promise<Task & {
|
|
32
|
+
error?: string;
|
|
33
|
+
}>;
|
|
34
|
+
cancelTask(targetAgent: Address, taskId: Hex, caller: Address): Promise<{
|
|
35
|
+
taskId: Hex;
|
|
36
|
+
state: Task['state'];
|
|
37
|
+
}>;
|
|
38
|
+
/** Subscribe to a task's status/artifact events (SSE). Requires a transport that supports streaming. */
|
|
39
|
+
subscribeTaskUpdates(targetAgent: Address, taskId: Hex): AsyncIterable<TaskEvent>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpE,MAAM,WAAW,YAAY;IAC3B,0FAA0F;IAC1F,GAAG,CAAC,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC7E,+FAA+F;IAC/F,MAAM,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;CACtE;AAOD,qBAAa,cAAc;IAEb,OAAO,CAAC,QAAQ,CAAC,SAAS;IADtC,OAAO,CAAC,GAAG,CAAK;gBACa,SAAS,EAAE,YAAY;IAEpD,OAAO,CAAC,EAAE;IAIV,wGAAwG;IAClG,UAAU,CACd,WAAW,EAAE,OAAO,EACpB,IAAI,EAAE;QAAE,OAAO,EAAE,UAAU,CAAC;QAAC,UAAU,EAAE,UAAU,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GACtI,OAAO,CAAC;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC;IAQjD,mDAAmD;IAC7C,OAAO,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAO/F,UAAU,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC;IAOpH,wGAAwG;IACxG,oBAAoB,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,aAAa,CAAC,SAAS,CAAC;CAIlF"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function unwrap(res) {
|
|
2
|
+
if ('error' in res)
|
|
3
|
+
throw new Error(`a2a rpc error ${res.error.code}: ${res.error.message}`);
|
|
4
|
+
return res.result;
|
|
5
|
+
}
|
|
6
|
+
export class A2aWireAdapter {
|
|
7
|
+
transport;
|
|
8
|
+
seq = 0;
|
|
9
|
+
constructor(transport) {
|
|
10
|
+
this.transport = transport;
|
|
11
|
+
}
|
|
12
|
+
id() {
|
|
13
|
+
return ++this.seq;
|
|
14
|
+
}
|
|
15
|
+
/** Submit an async task. The `message` must already be signed by `requester` (see `hashA2aMessage`). */
|
|
16
|
+
async submitTask(targetAgent, args) {
|
|
17
|
+
const res = await this.transport.rpc(targetAgent, {
|
|
18
|
+
jsonrpc: '2.0', id: this.id(), method: 'message/send',
|
|
19
|
+
params: { delegation: args.delegation, requester: args.requester, message: args.message, input: args.input, pushConfig: args.pushConfig },
|
|
20
|
+
});
|
|
21
|
+
return unwrap(res);
|
|
22
|
+
}
|
|
23
|
+
/** Poll a task's current state + artifact refs. */
|
|
24
|
+
async getTask(targetAgent, taskId, caller) {
|
|
25
|
+
const res = await this.transport.rpc(targetAgent, {
|
|
26
|
+
jsonrpc: '2.0', id: this.id(), method: 'tasks/get', params: { taskId, caller },
|
|
27
|
+
});
|
|
28
|
+
return unwrap(res);
|
|
29
|
+
}
|
|
30
|
+
async cancelTask(targetAgent, taskId, caller) {
|
|
31
|
+
const res = await this.transport.rpc(targetAgent, {
|
|
32
|
+
jsonrpc: '2.0', id: this.id(), method: 'tasks/cancel', params: { taskId, caller },
|
|
33
|
+
});
|
|
34
|
+
return unwrap(res);
|
|
35
|
+
}
|
|
36
|
+
/** Subscribe to a task's status/artifact events (SSE). Requires a transport that supports streaming. */
|
|
37
|
+
subscribeTaskUpdates(targetAgent, taskId) {
|
|
38
|
+
if (!this.transport.stream)
|
|
39
|
+
throw new Error('transport does not support streaming (message/stream)');
|
|
40
|
+
return this.transport.stream(targetAgent, taskId);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAgBA,SAAS,MAAM,CAAI,GAAoB;IACrC,IAAI,OAAO,IAAI,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7F,OAAO,GAAG,CAAC,MAAW,CAAC;AACzB,CAAC;AAED,MAAM,OAAO,cAAc;IAEI;IADrB,GAAG,GAAG,CAAC,CAAC;IAChB,YAA6B,SAAuB;QAAvB,cAAS,GAAT,SAAS,CAAc;IAAG,CAAC;IAEhD,EAAE;QACR,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC;IACpB,CAAC;IAED,wGAAwG;IACxG,KAAK,CAAC,UAAU,CACd,WAAoB,EACpB,IAAuI;QAEvI,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE;YAChD,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,cAAc;YACrD,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE;SAC1I,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,mDAAmD;IACnD,KAAK,CAAC,OAAO,CAAC,WAAoB,EAAE,MAAW,EAAE,MAAe;QAC9D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE;YAChD,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;SAC/E,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,WAAoB,EAAE,MAAW,EAAE,MAAe;QACjE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE;YAChD,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;SAClF,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,wGAAwG;IACxG,oBAAoB,CAAC,WAAoB,EAAE,MAAW;QACpD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACrG,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TaskStore } from '../task-store.js';
|
|
2
|
+
/** A durable, cross-isolate TaskStore over a Durable Object's storage. One DO per agent
|
|
3
|
+
* (shard `idFromName(agentSA.toLowerCase())`). `reserveMessageId` is durable + one-shot (the id key is
|
|
4
|
+
* permanent — a message id is single-use by construction; `ttlSec` is advisory). */
|
|
5
|
+
export declare function createDurableObjectTaskStore(storage: DurableObjectStorage): TaskStore;
|
|
6
|
+
export declare const A2A_CLOUDFLARE_ADAPTER_STATUS: "w3";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cloudflare/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAMlD;;qFAEqF;AACrF,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,CA2BrF;AAED,eAAO,MAAM,6BAA6B,EAAG,IAAa,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const TASK = (id) => `task:${id.toLowerCase()}`;
|
|
2
|
+
const DUE = (id) => `due:${id.toLowerCase()}`;
|
|
3
|
+
const MSG = (id) => `msg:${id.toLowerCase()}`;
|
|
4
|
+
/** A durable, cross-isolate TaskStore over a Durable Object's storage. One DO per agent
|
|
5
|
+
* (shard `idFromName(agentSA.toLowerCase())`). `reserveMessageId` is durable + one-shot (the id key is
|
|
6
|
+
* permanent — a message id is single-use by construction; `ttlSec` is advisory). */
|
|
7
|
+
export function createDurableObjectTaskStore(storage) {
|
|
8
|
+
return {
|
|
9
|
+
async put(record) {
|
|
10
|
+
const id = record.task.taskId.toLowerCase();
|
|
11
|
+
await storage.put(TASK(id), record);
|
|
12
|
+
if (record.task.state === 'submitted' || record.task.state === 'working') {
|
|
13
|
+
await storage.put(DUE(id), 1);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
await storage.delete(DUE(id));
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
async get(taskId) {
|
|
20
|
+
return (await storage.get(TASK(taskId))) ?? null;
|
|
21
|
+
},
|
|
22
|
+
async listDue() {
|
|
23
|
+
const map = await storage.list({ prefix: 'due:' });
|
|
24
|
+
const out = [];
|
|
25
|
+
for (const key of map.keys())
|
|
26
|
+
out.push(key.slice('due:'.length));
|
|
27
|
+
return out;
|
|
28
|
+
},
|
|
29
|
+
async reserveMessageId(messageId) {
|
|
30
|
+
const k = MSG(messageId);
|
|
31
|
+
if ((await storage.get(k)) !== undefined)
|
|
32
|
+
return false;
|
|
33
|
+
await storage.put(k, 1);
|
|
34
|
+
return true;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export const A2A_CLOUDFLARE_ADAPTER_STATUS = 'w3';
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cloudflare/index.ts"],"names":[],"mappings":"AAUA,MAAM,IAAI,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;AACxD,MAAM,GAAG,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;AACtD,MAAM,GAAG,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;AAEtD;;qFAEqF;AACrF,MAAM,UAAU,4BAA4B,CAAC,OAA6B;IACxE,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,MAAkB;YAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC5C,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YACpC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzE,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,MAAW;YACnB,OAAO,CAAC,MAAM,OAAO,CAAC,GAAG,CAAa,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAC/D,CAAC;QACD,KAAK,CAAC,OAAO;YACX,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,MAAM,GAAG,GAAU,EAAE,CAAC;YACtB,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAQ,CAAC,CAAC;YACxE,OAAO,GAAG,CAAC;QACb,CAAC;QACD,KAAK,CAAC,gBAAgB,CAAC,SAAc;YACnC,MAAM,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;YACzB,IAAI,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACvD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAa,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Address } from '@agenticprimitives/types';
|
|
2
|
+
import type { AgentCard } from './agent.js';
|
|
3
|
+
/** Injected name→SA resolver (e.g. agent-naming's `AgentNamingClient.resolveName`). */
|
|
4
|
+
export type ResolveAgentName = (name: string) => Promise<Address | null>;
|
|
5
|
+
/** Injected endpoint builder — maps an agent name to its A2A base URL (the app owns the hostname pattern,
|
|
6
|
+
* e.g. `https://<name>.<tld>`; the package appends the protocol paths). */
|
|
7
|
+
export type AgentEndpointFor = (name: string) => string;
|
|
8
|
+
export interface A2aTarget {
|
|
9
|
+
name: string;
|
|
10
|
+
agentSA: Address;
|
|
11
|
+
/** The agent's A2A JSON-RPC endpoint (`…/api/a2a`). */
|
|
12
|
+
endpoint: string;
|
|
13
|
+
/** The agent-card discovery URL (`…/.well-known/agent-card.json`). */
|
|
14
|
+
agentCardUrl: string;
|
|
15
|
+
}
|
|
16
|
+
/** Minimal fetch seam (browser/worker `fetch`-shaped) so the package pulls no global. */
|
|
17
|
+
export type A2aFetch = (url: string) => Promise<{
|
|
18
|
+
ok: boolean;
|
|
19
|
+
json: () => Promise<unknown>;
|
|
20
|
+
}>;
|
|
21
|
+
/** Resolve a target agent: name → SA (injected resolver) → endpoint (injected builder). Returns `null`
|
|
22
|
+
* when the name has no Smart Account (empty is an answer — ADR-0013). */
|
|
23
|
+
export declare function resolveA2aTarget(name: string, deps: {
|
|
24
|
+
resolveName: ResolveAgentName;
|
|
25
|
+
endpointFor: AgentEndpointFor;
|
|
26
|
+
}): Promise<A2aTarget | null>;
|
|
27
|
+
/** Fetch + parse a target's agent-card (skills + capabilities). `fetchFn` is injected. `null` if absent. */
|
|
28
|
+
export declare function fetchAgentCard(agentCardUrl: string, fetchFn: A2aFetch): Promise<AgentCard | null>;
|
|
29
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,uFAAuF;AACvF,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AAEzE;4EAC4E;AAC5E,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAExD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,yFAAyF;AACzF,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC,CAAC;AAE/F;0EAC0E;AAC1E,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,WAAW,EAAE,gBAAgB,CAAC;IAAC,WAAW,EAAE,gBAAgB,CAAA;CAAE,GACrE,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAU3B;AAED,4GAA4G;AAC5G,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAIvG"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Resolve a target agent: name → SA (injected resolver) → endpoint (injected builder). Returns `null`
|
|
2
|
+
* when the name has no Smart Account (empty is an answer — ADR-0013). */
|
|
3
|
+
export async function resolveA2aTarget(name, deps) {
|
|
4
|
+
const agentSA = await deps.resolveName(name);
|
|
5
|
+
if (!agentSA)
|
|
6
|
+
return null;
|
|
7
|
+
const base = deps.endpointFor(name).replace(/\/+$/, '');
|
|
8
|
+
return {
|
|
9
|
+
name,
|
|
10
|
+
agentSA,
|
|
11
|
+
endpoint: `${base}/api/a2a`,
|
|
12
|
+
agentCardUrl: `${base}/.well-known/agent-card.json`,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** Fetch + parse a target's agent-card (skills + capabilities). `fetchFn` is injected. `null` if absent. */
|
|
16
|
+
export async function fetchAgentCard(agentCardUrl, fetchFn) {
|
|
17
|
+
const r = await fetchFn(agentCardUrl);
|
|
18
|
+
if (!r.ok)
|
|
19
|
+
return null;
|
|
20
|
+
return (await r.json());
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AA0BA;0EAC0E;AAC1E,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,IAAsE;IAEtE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO;QACL,IAAI;QACJ,OAAO;QACP,QAAQ,EAAE,GAAG,IAAI,UAAU;QAC3B,YAAY,EAAE,GAAG,IAAI,8BAA8B;KACpD,CAAC;AACJ,CAAC;AAED,4GAA4G;AAC5G,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,YAAoB,EAAE,OAAiB;IAC1E,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAc,CAAC;AACvC,CAAC"}
|
package/dist/grant.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type Address, type Hex } from 'viem';
|
|
2
|
+
import type { Caveat } from '@agenticprimitives/delegation';
|
|
3
|
+
/** The "any skill" sentinel for `allowedMethods` — a grant carrying this selector authorizes every
|
|
4
|
+
* skill on the recipient agent (use sparingly; a specific selector is the default). */
|
|
5
|
+
export declare const A2A_ANY_SKILL: Hex;
|
|
6
|
+
/** Map a skill name to its 4-byte `allowedMethods` selector: keccak256(utf8(skill))[:4]. */
|
|
7
|
+
export declare function skillSelector(skill: string): Hex;
|
|
8
|
+
/** The deployed enforcer addresses (from the network deployment) the grant pins against. */
|
|
9
|
+
export interface A2aEnforcers {
|
|
10
|
+
allowedTargets: Address;
|
|
11
|
+
allowedMethods: Address;
|
|
12
|
+
timestamp: Address;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Build the caveat set for an A2A grant: a timestamp window, the recipient agent SA as the ONLY allowed
|
|
16
|
+
* target, and the requested skill (or `*` → any) as the ONLY allowed method. The caller attaches these
|
|
17
|
+
* to the `Delegation` it signs. The receiving agent's auth gate (`authorizeA2aMessage`) decodes + enforces
|
|
18
|
+
* them, rejecting a grant whose target ≠ this agent or whose method ≠ the requested skill.
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildA2aGrantCaveats(args: {
|
|
21
|
+
recipientAgentSA: Address;
|
|
22
|
+
skill: string;
|
|
23
|
+
enforcers: A2aEnforcers;
|
|
24
|
+
window: {
|
|
25
|
+
validAfter: number;
|
|
26
|
+
validUntil: number;
|
|
27
|
+
};
|
|
28
|
+
}): Caveat[];
|
|
29
|
+
//# sourceMappingURL=grant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../src/grant.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAOlE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAE5D;wFACwF;AACxF,eAAO,MAAM,aAAa,EAAE,GAAkB,CAAC;AAE/C,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAGhD;AAED,4FAA4F;AAC5F,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,YAAY,CAAC;IACxB,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD,GAAG,MAAM,EAAE,CAMX"}
|
package/dist/grant.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Scoped-grant caveat builders (spec 269 FR-4.2). A caller mints a delegation scoped to EXACTLY one
|
|
2
|
+
// recipient agent + one skill so it can't be replayed against a different agent/skill (the A2A
|
|
3
|
+
// non-replayability model — the agent-endpoint analogue of DEL-001's "possession ≠ authority"). Reuses
|
|
4
|
+
// the deployed AllowedTargets / AllowedMethods / Timestamp enforcers — we invent no new ones.
|
|
5
|
+
import { keccak256, toBytes } from 'viem';
|
|
6
|
+
import { buildCaveat, encodeTimestampTerms, encodeAllowedTargetsTerms, encodeAllowedMethodsTerms, } from '@agenticprimitives/delegation';
|
|
7
|
+
/** The "any skill" sentinel for `allowedMethods` — a grant carrying this selector authorizes every
|
|
8
|
+
* skill on the recipient agent (use sparingly; a specific selector is the default). */
|
|
9
|
+
export const A2A_ANY_SKILL = '0x00000000';
|
|
10
|
+
/** Map a skill name to its 4-byte `allowedMethods` selector: keccak256(utf8(skill))[:4]. */
|
|
11
|
+
export function skillSelector(skill) {
|
|
12
|
+
if (skill === '*' || skill === A2A_ANY_SKILL)
|
|
13
|
+
return A2A_ANY_SKILL;
|
|
14
|
+
return keccak256(toBytes(skill)).slice(0, 10); // 0x + 8 hex = 4 bytes
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Build the caveat set for an A2A grant: a timestamp window, the recipient agent SA as the ONLY allowed
|
|
18
|
+
* target, and the requested skill (or `*` → any) as the ONLY allowed method. The caller attaches these
|
|
19
|
+
* to the `Delegation` it signs. The receiving agent's auth gate (`authorizeA2aMessage`) decodes + enforces
|
|
20
|
+
* them, rejecting a grant whose target ≠ this agent or whose method ≠ the requested skill.
|
|
21
|
+
*/
|
|
22
|
+
export function buildA2aGrantCaveats(args) {
|
|
23
|
+
return [
|
|
24
|
+
buildCaveat(args.enforcers.timestamp, encodeTimestampTerms(args.window.validAfter, args.window.validUntil)),
|
|
25
|
+
buildCaveat(args.enforcers.allowedTargets, encodeAllowedTargetsTerms([args.recipientAgentSA])),
|
|
26
|
+
buildCaveat(args.enforcers.allowedMethods, encodeAllowedMethodsTerms([skillSelector(args.skill)])),
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=grant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant.js","sourceRoot":"","sources":["../src/grant.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,+FAA+F;AAC/F,uGAAuG;AACvG,8FAA8F;AAC9F,OAAO,EAAE,SAAS,EAAE,OAAO,EAA0B,MAAM,MAAM,CAAC;AAClE,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AAGvC;wFACwF;AACxF,MAAM,CAAC,MAAM,aAAa,GAAQ,YAAY,CAAC;AAE/C,4FAA4F;AAC5F,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,aAAa;QAAE,OAAO,aAAa,CAAC;IACnE,OAAO,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAQ,CAAC,CAAC,uBAAuB;AAC/E,CAAC;AASD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAKpC;IACC,OAAO;QACL,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC3G,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC9F,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACnG,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const PACKAGE_NAME = "@agenticprimitives/a2a";
|
|
2
|
+
export declare const PACKAGE_STATUS: "w5-acceptance-and-adoption";
|
|
3
|
+
export declare const SPEC_REF = "specs/269-async-delegation-authorized-a2a.md";
|
|
4
|
+
export type { Task, TaskState, Artifact, A2aArtifact, A2aMessage, VaultRef, TaskRecord, TaskEvent, } from './types.js';
|
|
5
|
+
export { TERMINAL_STATES, isTerminal } from './types.js';
|
|
6
|
+
export type { TaskStore } from './task-store.js';
|
|
7
|
+
export { createInMemoryTaskStore } from './task-store.js';
|
|
8
|
+
export type { SkillHandler, SkillContext, SkillResult, VaultClient, McpClient, HandoffRequest } from './skill-handler.js';
|
|
9
|
+
export { AuthRequired, HandoffRequested, buildSkillRegistry } from './skill-handler.js';
|
|
10
|
+
export { newTaskRecord, applyTransition, dispatchTask } from './runtime.js';
|
|
11
|
+
export type { TransitionResult } from './runtime.js';
|
|
12
|
+
export { A2A_ANY_SKILL, skillSelector, buildA2aGrantCaveats } from './grant.js';
|
|
13
|
+
export type { A2aEnforcers } from './grant.js';
|
|
14
|
+
export { authorizeA2aMessage, hashA2aMessage, decodeTimestampTerms, decodeAllowedTargetsTerms, decodeAllowedMethodsTerms, } from './auth.js';
|
|
15
|
+
export type { OnChainChecks, MessageIdReserver, AuthorizeResult } from './auth.js';
|
|
16
|
+
export { createA2aAgent } from './agent.js';
|
|
17
|
+
export type { A2aAgent, A2aAgentConfig, AgentCard, MessageSendParams, ResubmitParams, RpcResult, RpcOk, RpcErr } from './agent.js';
|
|
18
|
+
export { dispatchA2aRpc, handleA2aRpcBody } from './jsonrpc.js';
|
|
19
|
+
export type { JsonRpcRequest, JsonRpcResponse } from './jsonrpc.js';
|
|
20
|
+
export { A2aWireAdapter } from './client.js';
|
|
21
|
+
export type { A2aTransport } from './client.js';
|
|
22
|
+
export { resolveA2aTarget, fetchAgentCard } from './discovery.js';
|
|
23
|
+
export type { A2aTarget, ResolveAgentName, AgentEndpointFor, A2aFetch } from './discovery.js';
|
|
24
|
+
export { hashPushPayload, deliverPush, verifyPushEnvelope } from './push.js';
|
|
25
|
+
export type { PushPayload, PushEnvelope, TerminalSigner, PushSender } from './push.js';
|
|
26
|
+
export { SSE_HEADERS, formatSseEvent, formatSseComment, isStreamEnd } from './sse.js';
|
|
27
|
+
export type { PushConfig } from './types.js';
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY,2BAA2B,CAAC;AACrD,eAAO,MAAM,cAAc,EAAG,4BAAqC,CAAC;AACpE,eAAO,MAAM,QAAQ,iDAAiD,CAAC;AAGvE,YAAY,EACV,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,WAAW,EACX,UAAU,EACV,QAAQ,EACR,UAAU,EACV,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGzD,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAG1D,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC1H,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxF,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5E,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAChF,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAGnF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACnI,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAClE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG9F,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC7E,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACtF,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @agenticprimitives/a2a — async, delegation-authorized Agent-to-Agent task transport (spec 269).
|
|
2
|
+
// W1 (this wave): the transport-agnostic Task runtime + the TaskStore port + the SkillHandler contract.
|
|
3
|
+
// W2+: delegation-auth gate, scoped-grant caveat builders, JSON-RPC handlers, A2aWireAdapter client, and
|
|
4
|
+
// the Cloudflare TaskStoreDO (the `./cloudflare` subpath). See ADR-0034 for the package/boundary shape.
|
|
5
|
+
export const PACKAGE_NAME = '@agenticprimitives/a2a';
|
|
6
|
+
export const PACKAGE_STATUS = 'w5-acceptance-and-adoption';
|
|
7
|
+
export const SPEC_REF = 'specs/269-async-delegation-authorized-a2a.md';
|
|
8
|
+
export { TERMINAL_STATES, isTerminal } from './types.js';
|
|
9
|
+
export { createInMemoryTaskStore } from './task-store.js';
|
|
10
|
+
export { AuthRequired, HandoffRequested, buildSkillRegistry } from './skill-handler.js';
|
|
11
|
+
// Runtime
|
|
12
|
+
export { newTaskRecord, applyTransition, dispatchTask } from './runtime.js';
|
|
13
|
+
// Scoped-grant caveat builders (W2 / FR-4.2)
|
|
14
|
+
export { A2A_ANY_SKILL, skillSelector, buildA2aGrantCaveats } from './grant.js';
|
|
15
|
+
// Delegation-auth gate (W2 / FR-4)
|
|
16
|
+
export { authorizeA2aMessage, hashA2aMessage, decodeTimestampTerms, decodeAllowedTargetsTerms, decodeAllowedMethodsTerms, } from './auth.js';
|
|
17
|
+
// Embeddable agent + JSON-RPC + client (W3)
|
|
18
|
+
export { createA2aAgent } from './agent.js';
|
|
19
|
+
export { dispatchA2aRpc, handleA2aRpcBody } from './jsonrpc.js';
|
|
20
|
+
export { A2aWireAdapter } from './client.js';
|
|
21
|
+
// Agent discovery (§8) — name → SA → endpoint + agent-card fetch (injected resolvers, ADR-0021)
|
|
22
|
+
export { resolveA2aTarget, fetchAgentCard } from './discovery.js';
|
|
23
|
+
// Delivery — signed push + SSE (W4)
|
|
24
|
+
export { hashPushPayload, deliverPush, verifyPushEnvelope } from './push.js';
|
|
25
|
+
export { SSE_HEADERS, formatSseEvent, formatSseComment, isStreamEnd } from './sse.js';
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,wGAAwG;AACxG,yGAAyG;AACzG,wGAAwG;AAExG,MAAM,CAAC,MAAM,YAAY,GAAG,wBAAwB,CAAC;AACrD,MAAM,CAAC,MAAM,cAAc,GAAG,4BAAqC,CAAC;AACpE,MAAM,CAAC,MAAM,QAAQ,GAAG,8CAA8C,CAAC;AAavE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAI1D,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExF,UAAU;AACV,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5E,6CAA6C;AAC7C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGhF,mCAAmC;AACnC,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,WAAW,CAAC;AAGnB,4CAA4C;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,gGAAgG;AAChG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGlE,oCAAoC;AACpC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE7E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { A2aAgent } from './agent.js';
|
|
2
|
+
export interface JsonRpcRequest {
|
|
3
|
+
jsonrpc?: string;
|
|
4
|
+
id?: string | number | null;
|
|
5
|
+
method?: string;
|
|
6
|
+
params?: unknown;
|
|
7
|
+
}
|
|
8
|
+
export type JsonRpcResponse = {
|
|
9
|
+
jsonrpc: '2.0';
|
|
10
|
+
id: string | number | null;
|
|
11
|
+
result: unknown;
|
|
12
|
+
} | {
|
|
13
|
+
jsonrpc: '2.0';
|
|
14
|
+
id: string | number | null;
|
|
15
|
+
error: {
|
|
16
|
+
code: number;
|
|
17
|
+
message: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
/** Dispatch a single JSON-RPC request to the agent. `message/stream` is rejected here (handled by the
|
|
21
|
+
* SSE transport). The `caller` for tasks/get|cancel is taken from `params.caller`. */
|
|
22
|
+
export declare function dispatchA2aRpc(agent: A2aAgent, req: JsonRpcRequest): Promise<JsonRpcResponse>;
|
|
23
|
+
/** Parse a raw JSON body + dispatch. Used by the HTTP/Cloudflare transport. */
|
|
24
|
+
export declare function handleA2aRpcBody(agent: A2aAgent, rawBody: string): Promise<JsonRpcResponse>;
|
|
25
|
+
//# sourceMappingURL=jsonrpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonrpc.d.ts","sourceRoot":"","sources":["../src/jsonrpc.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAqC,MAAM,YAAY,CAAC;AAE9E,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AACD,MAAM,MAAM,eAAe,GACvB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC/D;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAS7F;uFACuF;AACvF,wBAAsB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAiCnG;AAED,+EAA+E;AAC/E,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAIjG"}
|
package/dist/jsonrpc.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const PARSE_ERROR = -32700;
|
|
2
|
+
const INVALID_REQUEST = -32600;
|
|
3
|
+
const METHOD_NOT_FOUND = -32601;
|
|
4
|
+
const err = (id, code, message) => ({ jsonrpc: '2.0', id, error: { code, message } });
|
|
5
|
+
const ok = (id, result) => ({ jsonrpc: '2.0', id, result });
|
|
6
|
+
/** Dispatch a single JSON-RPC request to the agent. `message/stream` is rejected here (handled by the
|
|
7
|
+
* SSE transport). The `caller` for tasks/get|cancel is taken from `params.caller`. */
|
|
8
|
+
export async function dispatchA2aRpc(agent, req) {
|
|
9
|
+
const id = req.id ?? null;
|
|
10
|
+
if (req.jsonrpc !== '2.0' || typeof req.method !== 'string') {
|
|
11
|
+
return err(id, INVALID_REQUEST, 'not a JSON-RPC 2.0 request');
|
|
12
|
+
}
|
|
13
|
+
const p = (req.params ?? {});
|
|
14
|
+
switch (req.method) {
|
|
15
|
+
case 'message/send': {
|
|
16
|
+
const r = await agent.messageSend(p);
|
|
17
|
+
return r.ok ? ok(id, r.result) : err(id, r.code, r.message);
|
|
18
|
+
}
|
|
19
|
+
case 'tasks/resubmit': {
|
|
20
|
+
const r = await agent.resubmit(p);
|
|
21
|
+
return r.ok ? ok(id, r.result) : err(id, r.code, r.message);
|
|
22
|
+
}
|
|
23
|
+
case 'tasks/get': {
|
|
24
|
+
const r = await agent.tasksGet({ taskId: p.taskId, caller: p.caller });
|
|
25
|
+
return r.ok ? ok(id, r.result) : err(id, r.code, r.message);
|
|
26
|
+
}
|
|
27
|
+
case 'tasks/cancel': {
|
|
28
|
+
const r = await agent.tasksCancel({ taskId: p.taskId, caller: p.caller });
|
|
29
|
+
return r.ok ? ok(id, r.result) : err(id, r.code, r.message);
|
|
30
|
+
}
|
|
31
|
+
case 'tasks/pushNotificationConfig/set': {
|
|
32
|
+
const r = await agent.pushConfigSet({ taskId: p.taskId, caller: p.caller, url: p.url, token: p.token });
|
|
33
|
+
return r.ok ? ok(id, r.result) : err(id, r.code, r.message);
|
|
34
|
+
}
|
|
35
|
+
case 'message/stream':
|
|
36
|
+
return err(id, INVALID_REQUEST, 'message/stream must use the SSE transport, not the JSON-RPC body');
|
|
37
|
+
default:
|
|
38
|
+
return err(id, METHOD_NOT_FOUND, `unknown method: ${req.method}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Parse a raw JSON body + dispatch. Used by the HTTP/Cloudflare transport. */
|
|
42
|
+
export async function handleA2aRpcBody(agent, rawBody) {
|
|
43
|
+
let req;
|
|
44
|
+
try {
|
|
45
|
+
req = JSON.parse(rawBody);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return err(null, PARSE_ERROR, 'invalid JSON');
|
|
49
|
+
}
|
|
50
|
+
return dispatchA2aRpc(agent, req);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=jsonrpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonrpc.js","sourceRoot":"","sources":["../src/jsonrpc.ts"],"names":[],"mappings":"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"}
|
package/dist/push.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Address, type Hex } from 'viem';
|
|
2
|
+
import type { TaskState, TaskRecord } from './types.js';
|
|
3
|
+
export interface PushPayload {
|
|
4
|
+
taskId: Hex;
|
|
5
|
+
state: TaskState;
|
|
6
|
+
artifactIds: Hex[];
|
|
7
|
+
/** Unix seconds — also the idempotency input; receiver dedupes on (taskId, state). */
|
|
8
|
+
ts: number;
|
|
9
|
+
}
|
|
10
|
+
export interface PushEnvelope {
|
|
11
|
+
payload: PushPayload;
|
|
12
|
+
/** Assignee SA signature over `hashPushPayload(payload)` (ERC-1271 / session key). */
|
|
13
|
+
signature: Hex;
|
|
14
|
+
/** The token the sender registered with `tasks/pushNotificationConfig/set`. */
|
|
15
|
+
token?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Canonical digest the assignee signs (binds task, state, artifact set, timestamp). */
|
|
18
|
+
export declare function hashPushPayload(p: PushPayload): Hex;
|
|
19
|
+
/** Sign a terminal digest as the assignee SA (KMS/session signer — never a raw key). */
|
|
20
|
+
export type TerminalSigner = (digest: Hex) => Promise<Hex>;
|
|
21
|
+
/** POST a push envelope to `url`. Throws on transport failure so `deliverPush` can retry. */
|
|
22
|
+
export type PushSender = (url: string, envelope: PushEnvelope) => Promise<void>;
|
|
23
|
+
/** Build + sign + best-effort-POST the terminal push, with bounded retry. Returns whether it was
|
|
24
|
+
* delivered. A no-op (false) when the task has no `pushConfig`. */
|
|
25
|
+
export declare function deliverPush(record: TaskRecord, sign: TerminalSigner, send: PushSender, now: number, retries?: number): Promise<boolean>;
|
|
26
|
+
/** Receiver-side verification: the assignee SA signed this envelope over the recomputed digest. */
|
|
27
|
+
export declare function verifyPushEnvelope(envelope: PushEnvelope, assigneeSA: Address, verify: (account: Address, digest: Hex, signature: Hex) => Promise<boolean>): Promise<boolean>;
|
|
28
|
+
//# sourceMappingURL=push.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2C,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,GAAG,CAAC;IACZ,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,GAAG,EAAE,CAAC;IACnB,sFAAsF;IACtF,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,WAAW,CAAC;IACrB,sFAAsF;IACtF,SAAS,EAAE,GAAG,CAAC;IACf,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,CAAC,EAAE,WAAW,GAAG,GAAG,CAOnD;AAED,wFAAwF;AACxF,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAC3D,6FAA6F;AAC7F,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhF;oEACoE;AACpE,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,EACX,OAAO,SAAI,GACV,OAAO,CAAC,OAAO,CAAC,CAmBlB;AAED,mGAAmG;AACnG,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,GAC1E,OAAO,CAAC,OAAO,CAAC,CAElB"}
|