@atrib/agent 0.3.2 → 0.3.3
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.
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* `dev.atrib/attribution` MCP extension v0.1 — client-side helpers (D141 /
|
|
3
|
+
* spec §1.5.4.1; extension spec docs/extensions/dev.atrib-attribution/v0.1.md).
|
|
4
|
+
*
|
|
5
|
+
* Two surfaces, both opt-in and §5.8-shaped:
|
|
6
|
+
*
|
|
7
|
+
* - {@link declareAttributionExtension}: return a NEW outbound `_meta`
|
|
8
|
+
* that declares the extension per-request under the core-reserved
|
|
9
|
+
* `io.modelcontextprotocol/clientCapabilities` key (and optionally
|
|
10
|
+
* carries the prefixed request block: propagation token + explicit
|
|
11
|
+
* context_id). Never mutates the caller's object; idempotent.
|
|
12
|
+
* - {@link parseAttributionReceipt}: read the gated result block from
|
|
13
|
+
* `result._meta`, validate its structure and internal consistency per
|
|
14
|
+
* extension spec §6.2, and return a typed receipt — or `undefined` with
|
|
15
|
+
* an `atrib:`-prefixed warning when the block is absent, malformed, or
|
|
16
|
+
* inconsistent. Receipt invalidity never invalidates the tool result.
|
|
17
|
+
*
|
|
18
|
+
* Clients using these helpers keep writing the legacy carriers
|
|
19
|
+
* (`buildOutboundMeta` already emits `atrib`, `tracestate`, `X-Atrib-Chain`)
|
|
20
|
+
* so non-adopting servers keep chaining: the extension is upside, not a
|
|
21
|
+
* dependency.
|
|
22
|
+
*/
|
|
23
|
+
import { ATTRIBUTION_ACCEPT_VALUES, ATTRIBUTION_EXTENSION_ID, ATTRIBUTION_EXTENSION_VERSION, MCP_CLIENT_CAPABILITIES_META_KEY } from '@atrib/mcp';
|
|
24
|
+
import type { AttributionAcceptValue, AttributionReceipt, AttributionResultBlock } from '@atrib/mcp';
|
|
25
|
+
export { ATTRIBUTION_ACCEPT_VALUES, ATTRIBUTION_EXTENSION_ID, ATTRIBUTION_EXTENSION_VERSION, MCP_CLIENT_CAPABILITIES_META_KEY, };
|
|
26
|
+
export type { AttributionAcceptValue, AttributionReceipt, AttributionResultBlock };
|
|
26
27
|
/** Options for {@link declareAttributionExtension}. */
|
|
27
28
|
export interface DeclareAttributionExtensionOptions {
|
|
28
29
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-attribution.d.ts","sourceRoot":"","sources":["../src/extension-attribution.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"extension-attribution.d.ts","sourceRoot":"","sources":["../src/extension-attribution.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,gCAAgC,EAGjC,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,gCAAgC,GACjC,CAAA;AACD,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,CAAA;AAIlF,uDAAuD;AACvD,MAAM,WAAW,kCAAkC;IACjD;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAA;IAC1C;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,OAAO,GAAE,kCAAuC,GAC/C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAmDzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,OAAO,GAClB,sBAAsB,GAAG,SAAS,CAmBpC"}
|
|
@@ -21,21 +21,8 @@
|
|
|
21
21
|
* so non-adopting servers keep chaining: the extension is upside, not a
|
|
22
22
|
* dependency.
|
|
23
23
|
*/
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
-
// module (the identifier freezes on publication per extension spec §3;
|
|
27
|
-
// breaking changes require a new identifier).
|
|
28
|
-
export const ATTRIBUTION_EXTENSION_ID = 'dev.atrib/attribution';
|
|
29
|
-
export const ATTRIBUTION_EXTENSION_VERSION = '0.1';
|
|
30
|
-
export const MCP_CLIENT_CAPABILITIES_META_KEY = 'io.modelcontextprotocol/clientCapabilities';
|
|
31
|
-
/** Receipt verbosities a client can request (extension spec §4.2 `accept`). */
|
|
32
|
-
export const ATTRIBUTION_ACCEPT_VALUES = ['token', 'record'];
|
|
33
|
-
const LOG_SUBMISSION_STATUSES = new Set([
|
|
34
|
-
'queued',
|
|
35
|
-
'submitted',
|
|
36
|
-
'disabled',
|
|
37
|
-
'failed',
|
|
38
|
-
]);
|
|
24
|
+
import { ATTRIBUTION_ACCEPT_VALUES, ATTRIBUTION_EXTENSION_ID, ATTRIBUTION_EXTENSION_VERSION, MCP_CLIENT_CAPABILITIES_META_KEY, decodeToken, verifyAttributionReceipt, } from '@atrib/mcp';
|
|
25
|
+
export { ATTRIBUTION_ACCEPT_VALUES, ATTRIBUTION_EXTENSION_ID, ATTRIBUTION_EXTENSION_VERSION, MCP_CLIENT_CAPABILITIES_META_KEY, };
|
|
39
26
|
const HEX32 = /^[0-9a-f]{32}$/;
|
|
40
27
|
function isPlainObject(value) {
|
|
41
28
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -103,60 +90,6 @@ export function declareAttributionExtension(meta = {}, options = {}) {
|
|
|
103
90
|
return { ...meta };
|
|
104
91
|
}
|
|
105
92
|
}
|
|
106
|
-
function isStructurallyReceiptBlock(block) {
|
|
107
|
-
if (!isPlainObject(block))
|
|
108
|
-
return false;
|
|
109
|
-
if (typeof block.token !== 'string')
|
|
110
|
-
return false;
|
|
111
|
-
const receipt = block.receipt;
|
|
112
|
-
if (!isPlainObject(receipt))
|
|
113
|
-
return false;
|
|
114
|
-
for (const field of [
|
|
115
|
-
'record_hash',
|
|
116
|
-
'creator_key',
|
|
117
|
-
'context_id',
|
|
118
|
-
'event_type',
|
|
119
|
-
'chain_root',
|
|
120
|
-
'log_submission',
|
|
121
|
-
]) {
|
|
122
|
-
if (typeof receipt[field] !== 'string')
|
|
123
|
-
return false;
|
|
124
|
-
}
|
|
125
|
-
if (block.record !== undefined && !isPlainObject(block.record))
|
|
126
|
-
return false;
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Internal-consistency check per extension spec §6.2: the token,
|
|
131
|
-
* `record_hash`, and `creator_key` must agree with each other and — when
|
|
132
|
-
* the full record body is attached — recompute from the record's canonical
|
|
133
|
-
* bytes. Mirrors `verifyAttributionReceipt` in @atrib/mcp.
|
|
134
|
-
*/
|
|
135
|
-
function receiptIsConsistent(block) {
|
|
136
|
-
const decoded = decodeToken(block.token);
|
|
137
|
-
if (!decoded)
|
|
138
|
-
return false;
|
|
139
|
-
if (block.receipt.record_hash !== `sha256:${hexEncode(decoded.recordHash)}`)
|
|
140
|
-
return false;
|
|
141
|
-
if (block.receipt.creator_key !== base64urlEncode(decoded.creatorKey))
|
|
142
|
-
return false;
|
|
143
|
-
if (!LOG_SUBMISSION_STATUSES.has(block.receipt.log_submission))
|
|
144
|
-
return false;
|
|
145
|
-
if (block.record) {
|
|
146
|
-
if (block.token !== encodeToken(block.record))
|
|
147
|
-
return false;
|
|
148
|
-
const recordHashHex = hexEncode(sha256(canonicalRecord(block.record)));
|
|
149
|
-
if (block.receipt.record_hash !== `sha256:${recordHashHex}`)
|
|
150
|
-
return false;
|
|
151
|
-
if (block.receipt.creator_key !== block.record.creator_key)
|
|
152
|
-
return false;
|
|
153
|
-
if (block.receipt.context_id !== block.record.context_id)
|
|
154
|
-
return false;
|
|
155
|
-
if (block.receipt.chain_root !== block.record.chain_root)
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
return true;
|
|
159
|
-
}
|
|
160
93
|
/**
|
|
161
94
|
* Parse the gated `dev.atrib/attribution` block from a tool result's
|
|
162
95
|
* `_meta` (extension spec §6). Returns the typed, consistency-checked block,
|
|
@@ -181,11 +114,12 @@ export function parseAttributionReceipt(resultMeta) {
|
|
|
181
114
|
if (!(ATTRIBUTION_EXTENSION_ID in resultMeta))
|
|
182
115
|
return undefined;
|
|
183
116
|
const block = resultMeta[ATTRIBUTION_EXTENSION_ID];
|
|
184
|
-
|
|
117
|
+
const verification = verifyAttributionReceipt(block);
|
|
118
|
+
if (!verification.valid && verification.mismatched.includes('malformed')) {
|
|
185
119
|
console.warn('atrib: malformed dev.atrib/attribution receipt block, discarding');
|
|
186
120
|
return undefined;
|
|
187
121
|
}
|
|
188
|
-
if (!
|
|
122
|
+
if (!verification.valid) {
|
|
189
123
|
console.warn('atrib: inconsistent dev.atrib/attribution receipt, discarding');
|
|
190
124
|
return undefined;
|
|
191
125
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-attribution.js","sourceRoot":"","sources":["../src/extension-attribution.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"extension-attribution.js","sourceRoot":"","sources":["../src/extension-attribution.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,gCAAgC,EAChC,WAAW,EACX,wBAAwB,GACzB,MAAM,YAAY,CAAA;AAOnB,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,gCAAgC,GACjC,CAAA;AAGD,MAAM,KAAK,GAAG,gBAAgB,CAAA;AAsB9B,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,2BAA2B,CACzC,OAAgC,EAAE,EAClC,UAA8C,EAAE;IAEhD,MAAM,GAAG,GAA4B,EAAE,GAAG,IAAI,EAAE,CAAA;IAChD,IAAI,CAAC;QACH,uEAAuE;QACvE,6DAA6D;QAC7D,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACvD,yBAA+C,CAAC,QAAQ,CAAC,CAAC,CAAC,CAC7D,CAAA;QACD,MAAM,QAAQ,GAA4B;YACxC,OAAO,EAAE,6BAA6B;YACtC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;SAC7D,CAAA;QAED,MAAM,YAAY,GAAG,GAAG,CAAC,gCAAgC,CAAC,CAAA;QAC1D,MAAM,IAAI,GAA4B,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC5F,MAAM,kBAAkB,GAAG,IAAI,CAAC,UAAU,CAAA;QAC1C,MAAM,UAAU,GAA4B,aAAa,CAAC,kBAAkB,CAAC;YAC3E,CAAC,CAAC,EAAE,GAAG,kBAAkB,EAAE;YAC3B,CAAC,CAAC,EAAE,CAAA;QACN,UAAU,CAAC,wBAAwB,CAAC,GAAG,QAAQ,CAAA;QAC/C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,GAAG,CAAC,gCAAgC,CAAC,GAAG,IAAI,CAAA;QAE5C,oEAAoE;QACpE,mEAAmE;QACnE,MAAM,KAAK,GAA4B,EAAE,CAAA;QACzC,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC7E,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAA;YACnF,CAAC;QACH,CAAC;QACD,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACpC,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3E,KAAK,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAA;YACtC,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAA;YAC5E,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,aAAa,GAAG,GAAG,CAAC,wBAAwB,CAAC,CAAA;YACnD,GAAG,CAAC,wBAAwB,CAAC,GAAG,aAAa,CAAC,aAAa,CAAC;gBAC1D,CAAC,CAAC,EAAE,GAAG,aAAa,EAAE,GAAG,KAAK,EAAE;gBAChC,CAAC,CAAC,KAAK,CAAA;QACX,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,iEAAiE,EAAE,GAAG,CAAC,CAAA;QACpF,OAAO,EAAE,GAAG,IAAI,EAAE,CAAA;IACpB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAAmB;IAEnB,IAAI,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC;YAAE,OAAO,SAAS,CAAA;QAChD,IAAI,CAAC,CAAC,wBAAwB,IAAI,UAAU,CAAC;YAAE,OAAO,SAAS,CAAA;QAC/D,MAAM,KAAK,GAAG,UAAU,CAAC,wBAAwB,CAAC,CAAA;QAClD,MAAM,YAAY,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAA;QACpD,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACzE,OAAO,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAA;YAChF,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAA;YAC7E,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,OAAO,KAA+B,CAAA;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,kEAAkE,EAAE,GAAG,CAAC,CAAA;QACrF,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atrib/agent",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"@noble/ed25519": "^3.1.0",
|
|
37
37
|
"@noble/hashes": "^2.2.0",
|
|
38
38
|
"canonicalize": "^3.0.0",
|
|
39
|
-
"@atrib/mcp": "0.
|
|
40
|
-
"@atrib/verify": "0.8.
|
|
39
|
+
"@atrib/mcp": "0.20.0",
|
|
40
|
+
"@atrib/verify": "0.8.3"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^25.9.3",
|