@agenticprimitives/a2a 0.0.0-alpha.16 → 0.0.0-alpha.18
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 +20 -0
- package/dist/agent.d.ts +75 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +97 -10
- package/dist/agent.js.map +1 -1
- package/dist/auth.d.ts +6 -7
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +12 -14
- package/dist/auth.js.map +1 -1
- package/dist/authority-extension.d.ts +58 -0
- package/dist/authority-extension.d.ts.map +1 -0
- package/dist/authority-extension.js +70 -0
- package/dist/authority-extension.js.map +1 -0
- package/dist/card-audience.d.ts +87 -0
- package/dist/card-audience.d.ts.map +1 -0
- package/dist/card-audience.js +135 -0
- package/dist/card-audience.js.map +1 -0
- package/dist/grant.d.ts +4 -2
- package/dist/grant.d.ts.map +1 -1
- package/dist/grant.js +21 -13
- package/dist/grant.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/jsonrpc.d.ts.map +1 -1
- package/dist/jsonrpc.js +22 -0
- package/dist/jsonrpc.js.map +1 -1
- package/dist/runtime.d.ts +10 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +1 -6
- package/dist/runtime.js.map +1 -1
- package/dist/skill-handler.d.ts +13 -0
- package/dist/skill-handler.d.ts.map +1 -1
- package/dist/skill-handler.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// The AP authority extension for the Agent Card (ADR-0059 / spec 341 §2.1).
|
|
2
|
+
//
|
|
3
|
+
// THE PROBLEM IT SOLVES. The Card declares no `securitySchemes` — not a wrong one, none. A peer reading
|
|
4
|
+
// it learns which skills exist and nothing about how to be allowed to call them. Every caller therefore
|
|
5
|
+
// needs out-of-band knowledge, which is the definition of a private RPC surface wearing a protocol's
|
|
6
|
+
// clothes. Declaring the authority model is what makes the difference between a protocol and skill-RPC
|
|
7
|
+
// cosplay, and it is the thing that lets an EXTERNAL agent use the same skills the Home uses — spec
|
|
8
|
+
// 341's actual success test.
|
|
9
|
+
//
|
|
10
|
+
// WHY AN EXTENSION AND NOT A `securityScheme`. Stock A2A's security schemes are OAuth2 / OIDC / API-key
|
|
11
|
+
// / mTLS — all of them bearer-shaped, all of them "the issuer says you may". Declaring one of those
|
|
12
|
+
// would assert something false about this substrate: here the grant is an ERC-4337-SA-bound,
|
|
13
|
+
// signature-verified, on-chain-revocable **delegation**, re-evaluated at the moment of acting, and a
|
|
14
|
+
// bearer token is at most an envelope carrying a reference to it (ADR-0041). Picking the nearest stock
|
|
15
|
+
// scheme to look compliant would invert the exact property that distinguishes this system, so the
|
|
16
|
+
// authority model is declared as a first-class `AgentExtension` instead — the same mechanism this
|
|
17
|
+
// package already ships for x402 pricing.
|
|
18
|
+
//
|
|
19
|
+
// WHAT THIS EXTENSION IS NOT. It is not authority. Advertising it grants nothing, and a caller that
|
|
20
|
+
// activates it is not thereby authorized; it tells a peer WHICH question will be asked of it, never
|
|
21
|
+
// what the answer will be. The decision still happens server-side against the principal SA, at the
|
|
22
|
+
// moment of acting, every time (ADR-0041, ADR-0043).
|
|
23
|
+
/** The extension URI. Versioned in the path: a change to what the authority model REQUIRES is a new
|
|
24
|
+
* URI, not a silent redefinition of this one — a peer must be able to detect the difference. */
|
|
25
|
+
export const AP_AUTHORITY_EXTENSION_URI = 'https://agenticprimitives.org/a2a/authority/v1';
|
|
26
|
+
/** The activation header stock A2A defines for extensions; clients opt in by naming the URI. */
|
|
27
|
+
export const A2A_EXTENSIONS_HEADER = 'X-A2A-Extensions';
|
|
28
|
+
/**
|
|
29
|
+
* Build the Card's authority extension.
|
|
30
|
+
*
|
|
31
|
+
* `bearerIsEnvelopeOnly` and `reEvaluatedPerCall` are literal `true` in the type, not booleans a
|
|
32
|
+
* deployment can set. They are not configuration — a deployment that wanted to say otherwise would be
|
|
33
|
+
* describing a different system, and the type refuses to let it say so on our Card (ADR-0041).
|
|
34
|
+
*/
|
|
35
|
+
export function apAuthorityExtension(params) {
|
|
36
|
+
if (params.methods.length === 0) {
|
|
37
|
+
// An authority extension that accepts nothing is not a lean Card, it is a broken one: it tells a
|
|
38
|
+
// peer to authorize and gives it no way to. Fail loudly at build time (ADR-0013 — empty is an
|
|
39
|
+
// answer, and here it is the wrong one).
|
|
40
|
+
throw new Error('apAuthorityExtension: at least one authority method must be declared');
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
uri: AP_AUTHORITY_EXTENSION_URI,
|
|
44
|
+
required: params.required ?? false,
|
|
45
|
+
description: 'Authorization is an on-chain delegation decision against the principal Smart Agent, verified by ' +
|
|
46
|
+
'signature and re-evaluated at the moment of acting. A bearer token is a transport envelope only ' +
|
|
47
|
+
'and never the grant.',
|
|
48
|
+
params: {
|
|
49
|
+
methods: params.methods,
|
|
50
|
+
chain: params.chain,
|
|
51
|
+
bearerIsEnvelopeOnly: true,
|
|
52
|
+
reEvaluatedPerCall: true,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Whether a client activated the extension, per the stock `X-A2A-Extensions` header.
|
|
57
|
+
*
|
|
58
|
+
* NOTE: activation is a CLIENT HINT and nothing more. It reports which extensions the caller
|
|
59
|
+
* understands; it does not authorize, and a server MUST NOT treat activation as a reason to relax any
|
|
60
|
+
* check. A caller that activates nothing still faces the same authority decision — the extension is
|
|
61
|
+
* documentation of the question, not a way to change the answer. */
|
|
62
|
+
export function activatesApAuthority(header) {
|
|
63
|
+
if (!header)
|
|
64
|
+
return false;
|
|
65
|
+
return header
|
|
66
|
+
.split(',')
|
|
67
|
+
.map((s) => s.trim())
|
|
68
|
+
.includes(AP_AUTHORITY_EXTENSION_URI);
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=authority-extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authority-extension.js","sourceRoot":"","sources":["../src/authority-extension.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,wGAAwG;AACxG,wGAAwG;AACxG,qGAAqG;AACrG,uGAAuG;AACvG,oGAAoG;AACpG,6BAA6B;AAC7B,EAAE;AACF,wGAAwG;AACxG,oGAAoG;AACpG,6FAA6F;AAC7F,qGAAqG;AACrG,uGAAuG;AACvG,kGAAkG;AAClG,kGAAkG;AAClG,0CAA0C;AAC1C,EAAE;AACF,oGAAoG;AACpG,oGAAoG;AACpG,mGAAmG;AACnG,qDAAqD;AAErD;iGACiG;AACjG,MAAM,CAAC,MAAM,0BAA0B,GAAG,gDAAgD,CAAC;AAE3F,gGAAgG;AAChG,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AA0CxD;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAkC;IACrE,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,iGAAiG;QACjG,8FAA8F;QAC9F,yCAAyC;QACzC,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO;QACL,GAAG,EAAE,0BAA0B;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,KAAK;QAClC,WAAW,EACT,kGAAkG;YAClG,kGAAkG;YAClG,sBAAsB;QACxB,MAAM,EAAE;YACN,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,oBAAoB,EAAE,IAAI;YAC1B,kBAAkB,EAAE,IAAI;SACzB;KACF,CAAC;AACJ,CAAC;AAED;;;;;qEAKqE;AACrE,MAAM,UAAU,oBAAoB,CAAC,MAAiC;IACpE,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,OAAO,MAAM;SACV,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,QAAQ,CAAC,0BAA0B,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type VerifiedPeerContextV1 } from '@agenticprimitives/types';
|
|
2
|
+
import type { AgentCardAudience } from './agent.js';
|
|
3
|
+
/** What a requester presents to claim a wider card audience. All fields required to get past `public`. */
|
|
4
|
+
export interface CardAudienceClaim {
|
|
5
|
+
/** Claimed canonical id (CAIP-10) or address. Unverified until the signature checks out. */
|
|
6
|
+
requester?: string;
|
|
7
|
+
/** A nonce issued by THIS host. Single-use. */
|
|
8
|
+
challengeNonce?: string;
|
|
9
|
+
signature?: `0x${string}`;
|
|
10
|
+
issuedAt?: string;
|
|
11
|
+
/** The view being asked for. Never granted on its own — this is a request, not a grant. */
|
|
12
|
+
requestedView?: string;
|
|
13
|
+
}
|
|
14
|
+
/** The body a requester signs. Binds the host and the view so a proof is not portable. */
|
|
15
|
+
export interface CardChallengeBody {
|
|
16
|
+
requester: string;
|
|
17
|
+
challengeNonce: string;
|
|
18
|
+
/** This host's origin — a proof for one agent's card must not work at another's. */
|
|
19
|
+
cardOrigin: string;
|
|
20
|
+
requestedView: 'authenticated' | 'private';
|
|
21
|
+
issuedAt: string;
|
|
22
|
+
}
|
|
23
|
+
/** Injected signature verification — satisfied by a `chain-state` reader wrapper. */
|
|
24
|
+
export type CardSignatureVerifier = (args: {
|
|
25
|
+
requester: string;
|
|
26
|
+
body: CardChallengeBody;
|
|
27
|
+
signature: `0x${string}`;
|
|
28
|
+
}) => Promise<boolean>;
|
|
29
|
+
/** Single-use nonce consumption. Returns false if already spent or unknown to this host. */
|
|
30
|
+
export type CardNonceConsumer = (nonce: string, cardOrigin: string) => Promise<boolean>;
|
|
31
|
+
export interface CardAudienceResolverOptions {
|
|
32
|
+
/** This host's canonical origin. A proof bound to another origin is refused. */
|
|
33
|
+
cardOrigin: string;
|
|
34
|
+
verifySignature: CardSignatureVerifier;
|
|
35
|
+
consumeNonce: CardNonceConsumer;
|
|
36
|
+
now: () => string;
|
|
37
|
+
/** Maximum age of a claim. Default 2 minutes. */
|
|
38
|
+
maxClaimAgeMs?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Decides whether a VERIFIED requester may see the `private` view, and is the only place a private
|
|
41
|
+
* audience can be granted. Omit ⇒ a verified requester reaches `authenticated` and no further.
|
|
42
|
+
*
|
|
43
|
+
* Kept separate from signature verification because they answer different questions: the signature
|
|
44
|
+
* says *who* is asking; this says *what that party is entitled to see*.
|
|
45
|
+
*/
|
|
46
|
+
privateViewPolicy?: (requester: string) => Promise<boolean>;
|
|
47
|
+
/** Local-only diagnostics. Never surfaced to the requester. */
|
|
48
|
+
observe?: (o: {
|
|
49
|
+
granted: AgentCardAudience['audience'];
|
|
50
|
+
reason?: string;
|
|
51
|
+
}) => void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* When the TRANSPORT already authenticated the peer (spec 338 W5-b), a separate card challenge is
|
|
55
|
+
* redundant — the connection itself proved who is asking.
|
|
56
|
+
*
|
|
57
|
+
* Accepted ONLY at `strength: 'agent'` (`isAgentAuthenticatedPeer`). Web PKI authenticates a
|
|
58
|
+
* hostname and SPIFFE a workload; neither is a Smart Agent, and treating either as one is exactly
|
|
59
|
+
* the conflation `VerifiedPeerContextV1` exists to prevent.
|
|
60
|
+
*
|
|
61
|
+
* NOTE this does not imply relay resistance: without a channel binding an active relay could be the
|
|
62
|
+
* party on the connection. Hosts that need that guarantee should require a channel-bound peer at the
|
|
63
|
+
* edge rather than loosening anything here.
|
|
64
|
+
*/
|
|
65
|
+
export interface PeerBackedAudienceInput {
|
|
66
|
+
peerContext?: VerifiedPeerContextV1;
|
|
67
|
+
}
|
|
68
|
+
/** The public audience — the floor, and the answer to every failed claim. */
|
|
69
|
+
export declare const PUBLIC_AUDIENCE: AgentCardAudience;
|
|
70
|
+
/**
|
|
71
|
+
* Build the resolver a card route calls to turn a request into an audience.
|
|
72
|
+
*
|
|
73
|
+
* Never throws. Never returns an audience wider than the claim proved.
|
|
74
|
+
*/
|
|
75
|
+
export declare function createCardAudienceResolver(opts: CardAudienceResolverOptions): (claim: CardAudienceClaim, peer?: PeerBackedAudienceInput) => Promise<AgentCardAudience>;
|
|
76
|
+
/**
|
|
77
|
+
* Read a claim from standard request inputs.
|
|
78
|
+
*
|
|
79
|
+
* The signature and nonce come from HEADERS, never the query string: a query parameter lands in
|
|
80
|
+
* access logs, `Referer` headers, and browser history, and a proof that leaks that way is a replay
|
|
81
|
+
* waiting to happen. `view` stays in the query because it is a request, not a secret.
|
|
82
|
+
*/
|
|
83
|
+
export declare function readCardAudienceClaim(input: {
|
|
84
|
+
query: (k: string) => string | undefined;
|
|
85
|
+
header: (k: string) => string | undefined;
|
|
86
|
+
}): CardAudienceClaim;
|
|
87
|
+
//# sourceMappingURL=card-audience.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-audience.d.ts","sourceRoot":"","sources":["../src/card-audience.ts"],"names":[],"mappings":"AAoBA,OAAO,EAA4B,KAAK,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,0GAA0G;AAC1G,MAAM,WAAW,iBAAiB;IAChC,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,0FAA0F;AAC1F,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,oFAAoF;IACpF,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,eAAe,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qFAAqF;AACrF,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;CAC1B,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvB,4FAA4F;AAC5F,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAExF,MAAM,WAAW,2BAA2B;IAC1C,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,qBAAqB,CAAC;IACvC,YAAY,EAAE,iBAAiB,CAAC;IAChC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE;QAAE,OAAO,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACpF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACrC;AAID,6EAA6E;AAC7E,eAAO,MAAM,eAAe,EAAE,iBAA0C,CAAC;AAMzE;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,2BAA2B,WAEjE,iBAAiB,SACjB,uBAAuB,KAC7B,OAAO,CAAC,iBAAiB,CAAC,CAsF9B;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC3C,GAAG,iBAAiB,CAQpB"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// Card-audience authentication (spec 338 §8, W4-b).
|
|
2
|
+
//
|
|
3
|
+
// THE HOLE THIS CLOSES: hosts were serving the extended card on a QUERY PARAMETER
|
|
4
|
+
// (`?view=authenticated`). Anyone could type it. The extended card is supposed to reveal fine-grained
|
|
5
|
+
// skills to *verified* callers, so a parameter that anyone can set makes the split decorative.
|
|
6
|
+
//
|
|
7
|
+
// A requester now proves control of its Smart Agent by signing a challenge bound to
|
|
8
|
+
// {requester, nonce, cardOrigin, requestedView, issuedAt}. Verification goes through the injected
|
|
9
|
+
// signature port — the same `UniversalSignatureValidator` surface used everywhere else, so EOA,
|
|
10
|
+
// ERC-1271, ERC-6492 and passkey credentials all work unchanged.
|
|
11
|
+
//
|
|
12
|
+
// ─── DEGRADE, DON'T DENY ────────────────────────────────────────────────────────────────────────
|
|
13
|
+
// Every failure resolves to `{ audience: 'public' }` rather than an error. That is deliberate and it
|
|
14
|
+
// IS the fail-closed choice here: the public card is genuinely public, so the safe fallback is
|
|
15
|
+
// LEAST DISCLOSURE, not a 401. It also means a plain unauthenticated `curl` keeps working, which is
|
|
16
|
+
// the whole point of a well-known card.
|
|
17
|
+
//
|
|
18
|
+
// The rule to hold onto: a failed proof must never widen the audience. It can only ever leave it at
|
|
19
|
+
// `public`.
|
|
20
|
+
import { isAgentAuthenticatedPeer } from '@agenticprimitives/types';
|
|
21
|
+
const DEFAULT_MAX_CLAIM_AGE_MS = 2 * 60 * 1000;
|
|
22
|
+
/** The public audience — the floor, and the answer to every failed claim. */
|
|
23
|
+
export const PUBLIC_AUDIENCE = { audience: 'public' };
|
|
24
|
+
function normalizeView(v) {
|
|
25
|
+
return v === 'authenticated' || v === 'private' ? v : null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build the resolver a card route calls to turn a request into an audience.
|
|
29
|
+
*
|
|
30
|
+
* Never throws. Never returns an audience wider than the claim proved.
|
|
31
|
+
*/
|
|
32
|
+
export function createCardAudienceResolver(opts) {
|
|
33
|
+
return async (claim, peer) => {
|
|
34
|
+
const deny = (reason) => {
|
|
35
|
+
opts.observe?.({ granted: 'public', reason });
|
|
36
|
+
return PUBLIC_AUDIENCE;
|
|
37
|
+
};
|
|
38
|
+
const view = normalizeView(claim.requestedView);
|
|
39
|
+
// No wider view requested — nothing to verify, and nothing to grant.
|
|
40
|
+
if (!view)
|
|
41
|
+
return PUBLIC_AUDIENCE;
|
|
42
|
+
// Transport-authenticated peer: the connection already proved who is asking, so skip the card
|
|
43
|
+
// challenge. Anything below `agent` strength falls through to the normal challenge path — it has
|
|
44
|
+
// NOT identified a Smart Agent.
|
|
45
|
+
if (peer?.peerContext && isAgentAuthenticatedPeer(peer.peerContext)) {
|
|
46
|
+
const requester = peer.peerContext.canonicalAgentId;
|
|
47
|
+
if (view === 'private') {
|
|
48
|
+
let permitted = false;
|
|
49
|
+
try {
|
|
50
|
+
permitted = (await opts.privateViewPolicy?.(requester)) ?? false;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
permitted = false;
|
|
54
|
+
}
|
|
55
|
+
opts.observe?.({ granted: permitted ? 'private' : 'authenticated', reason: 'peer-authenticated' });
|
|
56
|
+
return { audience: permitted ? 'private' : 'authenticated', requester };
|
|
57
|
+
}
|
|
58
|
+
opts.observe?.({ granted: 'authenticated', reason: 'peer-authenticated' });
|
|
59
|
+
return { audience: 'authenticated', requester };
|
|
60
|
+
}
|
|
61
|
+
if (!claim.requester || !claim.challengeNonce || !claim.signature || !claim.issuedAt) {
|
|
62
|
+
// THE CLOSED HOLE: a bare `?view=authenticated` with no proof lands here and gets the public card.
|
|
63
|
+
return deny('incomplete-claim');
|
|
64
|
+
}
|
|
65
|
+
const issuedAt = Date.parse(claim.issuedAt);
|
|
66
|
+
const nowMs = Date.parse(opts.now());
|
|
67
|
+
if (Number.isNaN(issuedAt) || Number.isNaN(nowMs))
|
|
68
|
+
return deny('unparseable-timestamp');
|
|
69
|
+
if (Math.abs(nowMs - issuedAt) > (opts.maxClaimAgeMs ?? DEFAULT_MAX_CLAIM_AGE_MS)) {
|
|
70
|
+
return deny('stale-claim');
|
|
71
|
+
}
|
|
72
|
+
// Nonce BEFORE signature: a replayed claim must not make the host repeat an expensive chain read.
|
|
73
|
+
let fresh = false;
|
|
74
|
+
try {
|
|
75
|
+
fresh = await opts.consumeNonce(claim.challengeNonce, opts.cardOrigin);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
fresh = false;
|
|
79
|
+
}
|
|
80
|
+
if (!fresh)
|
|
81
|
+
return deny('nonce-spent-or-unknown');
|
|
82
|
+
const body = {
|
|
83
|
+
requester: claim.requester,
|
|
84
|
+
challengeNonce: claim.challengeNonce,
|
|
85
|
+
cardOrigin: opts.cardOrigin,
|
|
86
|
+
requestedView: view,
|
|
87
|
+
issuedAt: claim.issuedAt,
|
|
88
|
+
};
|
|
89
|
+
let valid = false;
|
|
90
|
+
try {
|
|
91
|
+
valid = await opts.verifySignature({ requester: claim.requester, body, signature: claim.signature });
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// A verifier that threw did not verify (ADR-0013: no fallback to a weaker check).
|
|
95
|
+
valid = false;
|
|
96
|
+
}
|
|
97
|
+
if (!valid)
|
|
98
|
+
return deny('signature-invalid');
|
|
99
|
+
if (view === 'private') {
|
|
100
|
+
let permitted = false;
|
|
101
|
+
try {
|
|
102
|
+
permitted = (await opts.privateViewPolicy?.(claim.requester)) ?? false;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
permitted = false;
|
|
106
|
+
}
|
|
107
|
+
if (!permitted) {
|
|
108
|
+
// Authenticated but not entitled to the private view — grant the level they DID earn.
|
|
109
|
+
opts.observe?.({ granted: 'authenticated', reason: 'private-not-permitted' });
|
|
110
|
+
return { audience: 'authenticated', requester: claim.requester };
|
|
111
|
+
}
|
|
112
|
+
opts.observe?.({ granted: 'private' });
|
|
113
|
+
return { audience: 'private', requester: claim.requester };
|
|
114
|
+
}
|
|
115
|
+
opts.observe?.({ granted: 'authenticated' });
|
|
116
|
+
return { audience: 'authenticated', requester: claim.requester };
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Read a claim from standard request inputs.
|
|
121
|
+
*
|
|
122
|
+
* The signature and nonce come from HEADERS, never the query string: a query parameter lands in
|
|
123
|
+
* access logs, `Referer` headers, and browser history, and a proof that leaks that way is a replay
|
|
124
|
+
* waiting to happen. `view` stays in the query because it is a request, not a secret.
|
|
125
|
+
*/
|
|
126
|
+
export function readCardAudienceClaim(input) {
|
|
127
|
+
return {
|
|
128
|
+
requestedView: input.query('view'),
|
|
129
|
+
requester: input.header('x-ap-requester'),
|
|
130
|
+
challengeNonce: input.header('x-ap-challenge'),
|
|
131
|
+
signature: input.header('x-ap-signature'),
|
|
132
|
+
issuedAt: input.header('x-ap-issued-at'),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=card-audience.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-audience.js","sourceRoot":"","sources":["../src/card-audience.ts"],"names":[],"mappings":"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"}
|
package/dist/grant.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Address, Hex } from 'viem';
|
|
2
2
|
import type { Caveat } from '@agenticprimitives/delegation';
|
|
3
3
|
/** The "any skill" sentinel for `allowedMethods` — a grant carrying this selector authorizes every
|
|
4
4
|
* skill on the recipient agent (use sparingly; a specific selector is the default). */
|
|
5
5
|
export declare const A2A_ANY_SKILL: Hex;
|
|
6
|
-
/** Map a skill name to its 4-byte `allowedMethods` selector
|
|
6
|
+
/** Map a skill name to its 4-byte `allowedMethods` selector, plus the A2A "any skill" sentinel.
|
|
7
|
+
* The mapping itself is `delegation.methodSelector` — the package that owns the encoding owns the
|
|
8
|
+
* name→selector rule, so the two cannot drift. */
|
|
7
9
|
export declare function skillSelector(skill: string): Hex;
|
|
8
10
|
/** The deployed enforcer addresses (from the network deployment) the grant pins against. */
|
|
9
11
|
export interface A2aEnforcers {
|
package/dist/grant.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../src/grant.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../src/grant.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AASzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAE5D;wFACwF;AACxF,eAAO,MAAM,aAAa,EAAE,GAAkB,CAAC;AAE/C;;mDAEmD;AACnD,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,CAiBX"}
|
package/dist/grant.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
|
|
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';
|
|
1
|
+
import { buildCaveat, buildMethodAuthorityCaveats, encodeAllowedMethodsTerms, encodeAllowedTargetsTerms, encodeTimestampTerms, methodSelector, } from '@agenticprimitives/delegation';
|
|
7
2
|
/** The "any skill" sentinel for `allowedMethods` — a grant carrying this selector authorizes every
|
|
8
3
|
* skill on the recipient agent (use sparingly; a specific selector is the default). */
|
|
9
4
|
export const A2A_ANY_SKILL = '0x00000000';
|
|
10
|
-
/** Map a skill name to its 4-byte `allowedMethods` selector
|
|
5
|
+
/** Map a skill name to its 4-byte `allowedMethods` selector, plus the A2A "any skill" sentinel.
|
|
6
|
+
* The mapping itself is `delegation.methodSelector` — the package that owns the encoding owns the
|
|
7
|
+
* name→selector rule, so the two cannot drift. */
|
|
11
8
|
export function skillSelector(skill) {
|
|
12
9
|
if (skill === '*' || skill === A2A_ANY_SKILL)
|
|
13
10
|
return A2A_ANY_SKILL;
|
|
14
|
-
return
|
|
11
|
+
return methodSelector(skill);
|
|
15
12
|
}
|
|
16
13
|
/**
|
|
17
14
|
* Build the caveat set for an A2A grant: a timestamp window, the recipient agent SA as the ONLY allowed
|
|
@@ -20,10 +17,21 @@ export function skillSelector(skill) {
|
|
|
20
17
|
* them, rejecting a grant whose target ≠ this agent or whose method ≠ the requested skill.
|
|
21
18
|
*/
|
|
22
19
|
export function buildA2aGrantCaveats(args) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
// Same encoding as any method authority — but the target here is the agent being CALLED, not the
|
|
21
|
+
// agent being acted for. `A2A_ANY_SKILL` is the one A2A-specific case the shared builder has no
|
|
22
|
+
// notion of, so it is expanded here rather than pushed down into `delegation`.
|
|
23
|
+
if (args.skill === '*' || args.skill === A2A_ANY_SKILL) {
|
|
24
|
+
return [
|
|
25
|
+
buildCaveat(args.enforcers.timestamp, encodeTimestampTerms(args.window.validAfter, args.window.validUntil)),
|
|
26
|
+
buildCaveat(args.enforcers.allowedTargets, encodeAllowedTargetsTerms([args.recipientAgentSA])),
|
|
27
|
+
buildCaveat(args.enforcers.allowedMethods, encodeAllowedMethodsTerms([A2A_ANY_SKILL])),
|
|
28
|
+
];
|
|
29
|
+
}
|
|
30
|
+
return buildMethodAuthorityCaveats({
|
|
31
|
+
target: args.recipientAgentSA,
|
|
32
|
+
method: args.skill,
|
|
33
|
+
enforcers: args.enforcers,
|
|
34
|
+
window: args.window,
|
|
35
|
+
});
|
|
28
36
|
}
|
|
29
37
|
//# sourceMappingURL=grant.js.map
|
package/dist/grant.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grant.js","sourceRoot":"","sources":["../src/grant.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"grant.js","sourceRoot":"","sources":["../src/grant.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,WAAW,EACX,2BAA2B,EAC3B,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,EACpB,cAAc,GACf,MAAM,+BAA+B,CAAC;AAGvC;wFACwF;AACxF,MAAM,CAAC,MAAM,aAAa,GAAQ,YAAY,CAAC;AAE/C;;mDAEmD;AACnD,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,aAAa;QAAE,OAAO,aAAa,CAAC;IACnE,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AASD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAKpC;IACC,iGAAiG;IACjG,gGAAgG;IAChG,+EAA+E;IAC/E,IAAI,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;QACvD,OAAO;YACL,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC3G,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAC9F,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;SACvF,CAAC;IACJ,CAAC;IACD,OAAO,2BAA2B,CAAC;QACjC,MAAM,EAAE,IAAI,CAAC,gBAAgB;QAC7B,MAAM,EAAE,IAAI,CAAC,KAAK;QAClB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,18 +5,22 @@ export type { Task, TaskState, Artifact, A2aArtifact, A2aMessage, VaultRef, Task
|
|
|
5
5
|
export { TERMINAL_STATES, isTerminal } from './types.js';
|
|
6
6
|
export type { TaskStore } from './task-store.js';
|
|
7
7
|
export { createInMemoryTaskStore } from './task-store.js';
|
|
8
|
-
export type { SkillHandler, SkillContext, SkillResult, VaultClient, McpClient, HandoffRequest } from './skill-handler.js';
|
|
8
|
+
export type { SkillHandler, SkillExposure, SkillContext, SkillResult, VaultClient, McpClient, HandoffRequest } from './skill-handler.js';
|
|
9
9
|
export { AuthRequired, HandoffRequested, buildSkillRegistry } from './skill-handler.js';
|
|
10
10
|
export type { SkillPayment, PaymentGate, PaymentGateDecision, PaymentLane, X402PaymentMetadata, X402PaymentStatus } from './payment-gate.js';
|
|
11
|
+
export { apAuthorityExtension, activatesApAuthority, AP_AUTHORITY_EXTENSION_URI, A2A_EXTENSIONS_HEADER, } from './authority-extension.js';
|
|
12
|
+
export type { ApAuthorityExtension, ApAuthorityExtensionParams, ApAuthorityMethod } from './authority-extension.js';
|
|
11
13
|
export { X402_EXTENSION_URI, x402AgentCardExtension, buildPaymentRequiredMetadata, buildPaymentSettledMetadata, gateSkillPayment, } from './payment-gate.js';
|
|
12
14
|
export { newTaskRecord, applyTransition, dispatchTask } from './runtime.js';
|
|
13
15
|
export type { TransitionResult } from './runtime.js';
|
|
14
16
|
export { A2A_ANY_SKILL, skillSelector, buildA2aGrantCaveats } from './grant.js';
|
|
15
17
|
export type { A2aEnforcers } from './grant.js';
|
|
16
|
-
export { authorizeA2aMessage, hashA2aMessage, hashA2aTaskRequest, hashPushConfigParams, decodeTimestampTerms, decodeAllowedTargetsTerms, decodeAllowedMethodsTerms, } from './auth.js';
|
|
18
|
+
export { authorizeA2aMessage, hashA2aMessage, hashA2aTaskRequest, hashPushConfigParams, hashArtifactParams, decodeTimestampTerms, decodeAllowedTargetsTerms, decodeAllowedMethodsTerms, } from './auth.js';
|
|
17
19
|
export type { OnChainChecks, MessageIdReserver, MessageIdReservation, AuthorizeResult } from './auth.js';
|
|
18
20
|
export { createA2aAgent } from './agent.js';
|
|
19
|
-
export
|
|
21
|
+
export { PUBLIC_AUDIENCE, createCardAudienceResolver, readCardAudienceClaim } from './card-audience.js';
|
|
22
|
+
export type { CardAudienceClaim, CardAudienceResolverOptions, CardChallengeBody, CardNonceConsumer, CardSignatureVerifier, PeerBackedAudienceInput, } from './card-audience.js';
|
|
23
|
+
export type { AgentCardAudience, A2aAgent, A2aAgentConfig, A2aBudgetPort, A2aReceiptsConfig, AgentCard, MessageSendParams, ResubmitParams, RpcResult, RpcOk, RpcErr } from './agent.js';
|
|
20
24
|
export { dispatchA2aRpc, handleA2aRpcBody } from './jsonrpc.js';
|
|
21
25
|
export type { JsonRpcRequest, JsonRpcResponse } from './jsonrpc.js';
|
|
22
26
|
export { A2aWireAdapter } from './client.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,15 +8,22 @@ export const SPEC_REF = 'specs/269-async-delegation-authorized-a2a.md';
|
|
|
8
8
|
export { TERMINAL_STATES, isTerminal } from './types.js';
|
|
9
9
|
export { createInMemoryTaskStore } from './task-store.js';
|
|
10
10
|
export { AuthRequired, HandoffRequested, buildSkillRegistry } from './skill-handler.js';
|
|
11
|
+
// ADR-0059 / spec 341 §2.1 — the Card declares HOW to authenticate. Not a stock `securityScheme`:
|
|
12
|
+
// those are bearer-shaped, and here the grant is an SA-bound, signature-verified, on-chain-revocable
|
|
13
|
+
// delegation re-checked at the moment of acting (ADR-0041). Declaring the nearest OAuth-ish scheme to
|
|
14
|
+
// look compliant would assert something false about the substrate.
|
|
15
|
+
export { apAuthorityExtension, activatesApAuthority, AP_AUTHORITY_EXTENSION_URI, A2A_EXTENSIONS_HEADER, } from './authority-extension.js';
|
|
11
16
|
export { X402_EXTENSION_URI, x402AgentCardExtension, buildPaymentRequiredMetadata, buildPaymentSettledMetadata, gateSkillPayment, } from './payment-gate.js';
|
|
12
17
|
// Runtime
|
|
13
18
|
export { newTaskRecord, applyTransition, dispatchTask } from './runtime.js';
|
|
14
19
|
// Scoped-grant caveat builders (W2 / FR-4.2)
|
|
15
20
|
export { A2A_ANY_SKILL, skillSelector, buildA2aGrantCaveats } from './grant.js';
|
|
16
21
|
// Delegation-auth gate (W2 / FR-4)
|
|
17
|
-
export { authorizeA2aMessage, hashA2aMessage, hashA2aTaskRequest, hashPushConfigParams, decodeTimestampTerms, decodeAllowedTargetsTerms, decodeAllowedMethodsTerms, } from './auth.js';
|
|
22
|
+
export { authorizeA2aMessage, hashA2aMessage, hashA2aTaskRequest, hashPushConfigParams, hashArtifactParams, decodeTimestampTerms, decodeAllowedTargetsTerms, decodeAllowedMethodsTerms, } from './auth.js';
|
|
18
23
|
// Embeddable agent + JSON-RPC + client (W3)
|
|
19
24
|
export { createA2aAgent } from './agent.js';
|
|
25
|
+
// Card-audience authentication (spec 338 §8, W4-b) — closes the `?view=authenticated` hole.
|
|
26
|
+
export { PUBLIC_AUDIENCE, createCardAudienceResolver, readCardAudienceClaim } from './card-audience.js';
|
|
20
27
|
export { dispatchA2aRpc, handleA2aRpcBody } from './jsonrpc.js';
|
|
21
28
|
export { A2aWireAdapter } from './client.js';
|
|
22
29
|
// Agent discovery (§8) — name → SA → endpoint + agent-card fetch (injected resolvers, ADR-0021)
|
package/dist/index.js.map
CHANGED
|
@@ -1 +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;
|
|
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;AAKxF,kGAAkG;AAClG,qGAAqG;AACrG,sGAAsG;AACtG,mEAAmE;AACnE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,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,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,WAAW,CAAC;AAGnB,4CAA4C;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,4FAA4F;AAC5F,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAWxG,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"}
|
package/dist/jsonrpc.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
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;AAU7F;;;+EAG+E;AAC/E,wBAAsB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAgBnG;AA6CD,+EAA+E;AAC/E,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAIjG"}
|
package/dist/jsonrpc.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const PARSE_ERROR = -32700;
|
|
2
2
|
const INVALID_REQUEST = -32600;
|
|
3
3
|
const METHOD_NOT_FOUND = -32601;
|
|
4
|
+
const INTERNAL_ERROR = -32603;
|
|
4
5
|
const err = (id, code, message) => ({ jsonrpc: '2.0', id, error: { code, message } });
|
|
5
6
|
const ok = (id, result) => ({ jsonrpc: '2.0', id, result });
|
|
6
7
|
/** Dispatch a single JSON-RPC request to the agent. `message/stream` is rejected here (handled by the
|
|
@@ -9,6 +10,23 @@ const ok = (id, result) => ({ jsonrpc: '2.0', id, result });
|
|
|
9
10
|
* an attacker passing a victim's address but no/own signature is rejected. */
|
|
10
11
|
export async function dispatchA2aRpc(agent, req) {
|
|
11
12
|
const id = req.id ?? null;
|
|
13
|
+
try {
|
|
14
|
+
return await dispatch(agent, req, id);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// A THROW IS NOT A PROTOCOL RESPONSE. Handlers read `params` positionally off untrusted JSON, so a
|
|
18
|
+
// caller omitting a field reaches `undefined.toLowerCase()` and the exception escapes the wire
|
|
19
|
+
// entry — surfacing as a 500 with a stack rather than a JSON-RPC error. That is the same class of
|
|
20
|
+
// bug `demo-a2a`'s `validate.ts` exists to prevent, on a PUBLIC surface (`message/send` takes
|
|
21
|
+
// caller-supplied params), and it was reachable until spec 340's task-DO coverage hit it.
|
|
22
|
+
//
|
|
23
|
+
// The message is deliberately generic: the caller learns the request failed, never why internally.
|
|
24
|
+
// A rejected-but-valid request still gets its own typed code from the handler below; this only
|
|
25
|
+
// catches what nothing else answered.
|
|
26
|
+
return err(id, INTERNAL_ERROR, 'internal error');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function dispatch(agent, req, id) {
|
|
12
30
|
if (req.jsonrpc !== '2.0' || typeof req.method !== 'string') {
|
|
13
31
|
return err(id, INVALID_REQUEST, 'not a JSON-RPC 2.0 request');
|
|
14
32
|
}
|
|
@@ -31,6 +49,10 @@ export async function dispatchA2aRpc(agent, req) {
|
|
|
31
49
|
const r = await agent.tasksGet({ taskId: p.taskId, caller: p.caller, signature: (p.signature ?? '0x'), issuedAt: p.issuedAt });
|
|
32
50
|
return r.ok ? ok(id, r.result) : err(id, r.code, r.message);
|
|
33
51
|
}
|
|
52
|
+
case 'tasks/artifact': {
|
|
53
|
+
const r = await agent.tasksArtifact({ taskId: p.taskId, artifactId: p.artifactId, caller: p.caller, signature: (p.signature ?? '0x'), issuedAt: p.issuedAt });
|
|
54
|
+
return r.ok ? ok(id, r.result) : err(id, r.code, r.message);
|
|
55
|
+
}
|
|
34
56
|
case 'tasks/cancel': {
|
|
35
57
|
const r = await agent.tasksCancel({ taskId: p.taskId, caller: p.caller, signature: (p.signature ?? '0x'), issuedAt: p.issuedAt });
|
|
36
58
|
return r.ok ? ok(id, r.result) : err(id, r.code, r.message);
|
package/dist/jsonrpc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonrpc.js","sourceRoot":"","sources":["../src/jsonrpc.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,GAAG,CAAC,KAAK,CAAC;AAC3B,MAAM,eAAe,GAAG,CAAC,KAAK,CAAC;AAC/B,MAAM,gBAAgB,GAAG,CAAC,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"jsonrpc.js","sourceRoot":"","sources":["../src/jsonrpc.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -41,7 +41,16 @@ export declare function applyTransition(record: TaskRecord, to: TaskState, opts?
|
|
|
41
41
|
* caller (alarm loop) persists the record and fans the events to streams/push. `makeContext` wires the
|
|
42
42
|
* per-task vault / mcp / emitArtifact (W4) — the runtime stays transport-agnostic.
|
|
43
43
|
*/
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Skill lookup. A `Map` satisfies this, which is the point — widening the parameter from `Map` to
|
|
46
|
+
* the one accessor the runtime actually calls lets an integrator serve a FAMILY of methods whose
|
|
47
|
+
* members are not known when the registry is built (an agent hosting a set of archetypes defined in
|
|
48
|
+
* its own library, say) without this file knowing anything about that.
|
|
49
|
+
*/
|
|
50
|
+
export interface SkillLookup {
|
|
51
|
+
get(skill: string): SkillHandler | undefined;
|
|
52
|
+
}
|
|
53
|
+
export declare function dispatchTask(record: TaskRecord, registry: SkillLookup, makeContext: (record: TaskRecord) => Omit<SkillContext, 'requestAuth' | 'requestHandoff' | 'principal' | 'sender' | 'taskId' | 'skill'> & {
|
|
45
54
|
input: unknown;
|
|
46
55
|
delegation: Delegation;
|
|
47
56
|
}, now: number, opts?: {
|
package/dist/runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAKA,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACzG,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAkC,KAAK,YAAY,EAAE,KAAK,YAAY,EAAoB,MAAM,oBAAoB,CAAC;AAC5H,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEvE,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,UAAU,CAAC;IACpB,kBAAkB,EAAE,GAAG,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,GAAG,CAAC;CACpB,GAAG,UAAU,CAuBb;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GAClD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC;+FAC+F;AAC/F,wBAAgB,eAAe,CAC7B,MAAM,EAAE,UAAU,EAClB,EAAE,EAAE,SAAS,EACb,IAAI,GAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAe,GACjD,gBAAgB,CAalB;AAED;;;;;GAKG;AACH,
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAKA,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACzG,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAkC,KAAK,YAAY,EAAE,KAAK,YAAY,EAAoB,MAAM,oBAAoB,CAAC;AAC5H,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEvE,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,UAAU,CAAC;IACpB,kBAAkB,EAAE,GAAG,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,GAAG,CAAC;CACpB,GAAG,UAAU,CAuBb;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GAClD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC;+FAC+F;AAC/F,wBAAgB,eAAe,CAC7B,MAAM,EAAE,UAAU,EAClB,EAAE,EAAE,SAAS,EACb,IAAI,GAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAe,GACjD,gBAAgB,CAalB;AAED;;;;;GAKG;AACH;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;CAC9C;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,WAAW,EACrB,WAAW,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,gBAAgB,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,EACpL,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,aAAa,CAAC;IAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5F,OAAO,CAAC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,SAAS,EAAE,CAAA;CAAE,CAAC,CAkHtD;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
package/dist/runtime.js
CHANGED
|
@@ -50,18 +50,13 @@ export function applyTransition(record, to, opts = { now: 0 }) {
|
|
|
50
50
|
};
|
|
51
51
|
return { ok: true, record: next, event: { kind: 'task.status', taskId: record.task.taskId, state: to, rev } };
|
|
52
52
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Dispatch a `submitted` task: reject if the skill is unknown; otherwise move it to `working`, run the
|
|
55
|
-
* handler, and map the outcome to the next state. Returns the final record + the ordered events. The
|
|
56
|
-
* caller (alarm loop) persists the record and fans the events to streams/push. `makeContext` wires the
|
|
57
|
-
* per-task vault / mcp / emitArtifact (W4) — the runtime stays transport-agnostic.
|
|
58
|
-
*/
|
|
59
53
|
export async function dispatchTask(record, registry, makeContext, now, opts) {
|
|
60
54
|
const events = [];
|
|
61
55
|
if (record.task.state !== 'submitted') {
|
|
62
56
|
return { record, events };
|
|
63
57
|
}
|
|
64
58
|
const handler = registry.get(record.skill);
|
|
59
|
+
console.log('[a2a dispatchTask]', record.skill, handler ? 'handler found' : 'NO HANDLER');
|
|
65
60
|
if (!handler) {
|
|
66
61
|
const rejected = applyTransition(record, 'rejected', { now, error: `unknown skill: ${record.skill}` });
|
|
67
62
|
if (rejected.ok) {
|