@402flow/sdk 0.1.0-alpha.2 → 0.1.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +368 -23
- package/dist/agent-harness.d.ts +163 -0
- package/dist/agent-harness.js +474 -0
- package/dist/agent-harness.js.map +1 -0
- package/dist/challenge-detection.d.ts +17 -5
- package/dist/challenge-detection.js +65 -102
- package/dist/challenge-detection.js.map +1 -1
- package/dist/contracts.d.ts +4604 -326
- package/dist/contracts.js +230 -18
- package/dist/contracts.js.map +1 -1
- package/dist/harness-instructions.d.ts +7 -0
- package/dist/harness-instructions.js +28 -0
- package/dist/harness-instructions.js.map +1 -0
- package/dist/index.d.ts +105 -8
- package/dist/index.js +997 -32
- package/dist/index.js.map +1 -1
- package/dist/version.d.ts +4 -0
- package/dist/version.js +9 -0
- package/dist/version.js.map +1 -0
- package/package.json +11 -8
- package/dist/challenge-types.d.ts +0 -57
- package/dist/challenge-types.js +0 -111
- package/dist/challenge-types.js.map +0 -1
- package/dist/x402-v1.d.ts +0 -4
- package/dist/x402-v1.js +0 -53
- package/dist/x402-v1.js.map +0 -1
- package/dist/x402-v2.d.ts +0 -4
- package/dist/x402-v2.js +0 -52
- package/dist/x402-v2.js.map +0 -1
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentHarness provides a small in-memory orchestration layer on top of
|
|
3
|
+
* AgentPayClient for hosts that prefer preparedId-based handoffs over holding
|
|
4
|
+
* full prepared request objects.
|
|
5
|
+
*
|
|
6
|
+
* The intended host-facing flow is:
|
|
7
|
+
*
|
|
8
|
+
* 1. prepare a candidate request and receive a preparedId plus the preparation summary
|
|
9
|
+
* 2. execute later by preparedId once nextAction is execute
|
|
10
|
+
* 3. read back the stored execution result by preparedId
|
|
11
|
+
*
|
|
12
|
+
* This is useful for tool-driven hosts such as OpenAI tools, MCP servers,
|
|
13
|
+
* Claude tools, LangGraph nodes, or custom orchestrators where passing a small
|
|
14
|
+
* opaque id between turns is easier than preserving the full prepared object.
|
|
15
|
+
*
|
|
16
|
+
* This file implements only a convenience layer. The core SDK contract remains
|
|
17
|
+
* AgentPayClient with preparePaidRequest() and executePreparedRequest().
|
|
18
|
+
*
|
|
19
|
+
* Important behavior:
|
|
20
|
+
* - State is kept only in memory inside this process.
|
|
21
|
+
* - Prepared requests expire after a TTL.
|
|
22
|
+
* - A newer active preparation for the same method + origin + pathname supersedes
|
|
23
|
+
* the older one.
|
|
24
|
+
* - Execution is rejected locally unless the stored preparation is still active,
|
|
25
|
+
* kind === 'ready', and nextAction === 'execute'.
|
|
26
|
+
*/
|
|
27
|
+
import { randomUUID } from 'node:crypto';
|
|
28
|
+
/** Typed error used internally to convert local state failures into stable results. */
|
|
29
|
+
export class AgentHarnessError extends Error {
|
|
30
|
+
code;
|
|
31
|
+
preparedId;
|
|
32
|
+
constructor(code, message, preparedId) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = 'AgentHarnessError';
|
|
35
|
+
this.code = code;
|
|
36
|
+
this.preparedId = preparedId;
|
|
37
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const defaultPreparedTtlMs = 5 * 60 * 1000;
|
|
41
|
+
// Preparations supersede by stable execution target, not by full query/body, so a
|
|
42
|
+
// newer attempt for the same endpoint path invalidates older active ones.
|
|
43
|
+
function createSupersessionKey(binding) {
|
|
44
|
+
const url = new URL(binding.url);
|
|
45
|
+
return `${binding.method}:${url.origin}${url.pathname}`;
|
|
46
|
+
}
|
|
47
|
+
function deepFreeze(value) {
|
|
48
|
+
if (value === null || typeof value !== 'object' || Object.isFrozen(value)) {
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
if (Array.isArray(value)) {
|
|
52
|
+
for (const entry of value) {
|
|
53
|
+
deepFreeze(entry);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
for (const entry of Object.values(value)) {
|
|
58
|
+
deepFreeze(entry);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return Object.freeze(value);
|
|
62
|
+
}
|
|
63
|
+
// All records exposed back to callers are cloned and frozen so host code cannot
|
|
64
|
+
// mutate the harness' in-memory state by retaining object references.
|
|
65
|
+
function cloneValue(value) {
|
|
66
|
+
return structuredClone(value);
|
|
67
|
+
}
|
|
68
|
+
function createFrozenClone(value) {
|
|
69
|
+
return deepFreeze(cloneValue(value));
|
|
70
|
+
}
|
|
71
|
+
function normalizeHeaders(headers) {
|
|
72
|
+
const normalizedHeaders = {};
|
|
73
|
+
if (!headers) {
|
|
74
|
+
return normalizedHeaders;
|
|
75
|
+
}
|
|
76
|
+
const headerMap = new Headers(headers);
|
|
77
|
+
headerMap.forEach((value, key) => {
|
|
78
|
+
normalizedHeaders[key] = value;
|
|
79
|
+
});
|
|
80
|
+
return normalizedHeaders;
|
|
81
|
+
}
|
|
82
|
+
function buildExecutionBinding(prepared) {
|
|
83
|
+
// Capture the exact prepared execution payload once so later execute calls do
|
|
84
|
+
// not depend on the host resending or reconstructing it correctly.
|
|
85
|
+
return createFrozenClone({
|
|
86
|
+
method: prepared.request.method,
|
|
87
|
+
url: prepared.request.url,
|
|
88
|
+
headers: normalizeHeaders(prepared.request.headers),
|
|
89
|
+
...(prepared.request.body !== undefined ? { body: prepared.request.body } : {}),
|
|
90
|
+
...(prepared.request.bodyHash !== undefined
|
|
91
|
+
? { bodyHash: prepared.request.bodyHash }
|
|
92
|
+
: {}),
|
|
93
|
+
...(prepared.kind === 'ready'
|
|
94
|
+
? {
|
|
95
|
+
challenge: {
|
|
96
|
+
protocol: prepared.challenge.protocol,
|
|
97
|
+
headers: normalizeHeaders(prepared.challenge.headers),
|
|
98
|
+
...(prepared.challenge.body !== undefined
|
|
99
|
+
? { body: cloneValue(prepared.challenge.body) }
|
|
100
|
+
: {}),
|
|
101
|
+
},
|
|
102
|
+
}
|
|
103
|
+
: {}),
|
|
104
|
+
merchantOrigin: new URL(prepared.request.url).origin,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
const knownNetworkLabels = {
|
|
108
|
+
'eip155:84532': 'Base Sepolia',
|
|
109
|
+
'base-sepolia': 'Base Sepolia',
|
|
110
|
+
'eip155:8453': 'Base',
|
|
111
|
+
base: 'Base',
|
|
112
|
+
'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'Solana Devnet',
|
|
113
|
+
'solana-devnet': 'Solana Devnet',
|
|
114
|
+
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': 'Solana',
|
|
115
|
+
'solana-mainnet': 'Solana',
|
|
116
|
+
};
|
|
117
|
+
const knownAssetMetadata = {
|
|
118
|
+
'0x036cbd53842c5426634e7929541ec2318f3dcf7e': {
|
|
119
|
+
name: 'USDC',
|
|
120
|
+
precision: 6,
|
|
121
|
+
},
|
|
122
|
+
'0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': {
|
|
123
|
+
name: 'USDC',
|
|
124
|
+
precision: 6,
|
|
125
|
+
},
|
|
126
|
+
'4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU': {
|
|
127
|
+
name: 'USDC',
|
|
128
|
+
precision: 6,
|
|
129
|
+
},
|
|
130
|
+
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v: {
|
|
131
|
+
name: 'USDC',
|
|
132
|
+
precision: 6,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
function normalizeAssetLookupKey(asset) {
|
|
136
|
+
return asset.startsWith('0x') ? asset.toLowerCase() : asset;
|
|
137
|
+
}
|
|
138
|
+
function formatMinorAmount(amountMinor, precision) {
|
|
139
|
+
const normalizedMinor = amountMinor.replace(/^0+(?=\d)/, '') || '0';
|
|
140
|
+
if (precision === 0) {
|
|
141
|
+
return normalizedMinor;
|
|
142
|
+
}
|
|
143
|
+
const paddedMinor = normalizedMinor.padStart(precision + 1, '0');
|
|
144
|
+
const wholePart = paddedMinor.slice(0, -precision) || '0';
|
|
145
|
+
const fractionalPart = paddedMinor.slice(-precision);
|
|
146
|
+
return `${wholePart}.${fractionalPart}`;
|
|
147
|
+
}
|
|
148
|
+
function getChallengeAssetName(challengeDetails) {
|
|
149
|
+
const extra = challengeDetails?.accepts[0]?.extra;
|
|
150
|
+
if (!extra || typeof extra !== 'object') {
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
const name = extra.name;
|
|
154
|
+
return typeof name === 'string' && name.length > 0 ? name : undefined;
|
|
155
|
+
}
|
|
156
|
+
function getChallengePrecision(challengeDetails) {
|
|
157
|
+
const extra = challengeDetails?.accepts[0]?.extra;
|
|
158
|
+
if (!extra || typeof extra !== 'object') {
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
const precision = extra.precision;
|
|
162
|
+
return typeof precision === 'number' && Number.isInteger(precision) ? precision : undefined;
|
|
163
|
+
}
|
|
164
|
+
function getAmountTypeLabel(amountType) {
|
|
165
|
+
if (amountType === 'exact') {
|
|
166
|
+
return 'exact';
|
|
167
|
+
}
|
|
168
|
+
if (amountType === 'max') {
|
|
169
|
+
return 'up to';
|
|
170
|
+
}
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
function buildCostSummary(prepared) {
|
|
174
|
+
if (prepared.kind === 'passthrough') {
|
|
175
|
+
return 'No payment required.';
|
|
176
|
+
}
|
|
177
|
+
const paymentRequirement = prepared.paymentRequirement;
|
|
178
|
+
if (!paymentRequirement) {
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
const knownAsset = paymentRequirement.asset
|
|
182
|
+
? knownAssetMetadata[normalizeAssetLookupKey(paymentRequirement.asset)]
|
|
183
|
+
: undefined;
|
|
184
|
+
const resolvedPrecision = paymentRequirement.precision
|
|
185
|
+
?? getChallengePrecision(prepared.challengeDetails)
|
|
186
|
+
?? knownAsset?.precision;
|
|
187
|
+
const amount = paymentRequirement.amount
|
|
188
|
+
?? (paymentRequirement.amountMinor !== undefined && resolvedPrecision !== undefined
|
|
189
|
+
? formatMinorAmount(paymentRequirement.amountMinor, resolvedPrecision)
|
|
190
|
+
: undefined);
|
|
191
|
+
const assetName = getChallengeAssetName(prepared.challengeDetails)
|
|
192
|
+
?? (paymentRequirement.asset
|
|
193
|
+
? knownAsset?.name
|
|
194
|
+
?? paymentRequirement.asset
|
|
195
|
+
: undefined);
|
|
196
|
+
const networkLabel = paymentRequirement.network
|
|
197
|
+
? knownNetworkLabels[paymentRequirement.network] ?? paymentRequirement.network
|
|
198
|
+
: undefined;
|
|
199
|
+
const amountTypeLabel = getAmountTypeLabel(paymentRequirement.amountType);
|
|
200
|
+
if (!amount || !assetName || !networkLabel || !amountTypeLabel) {
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
return `Costs ${amount} ${assetName} on ${networkLabel} (${amountTypeLabel}).`;
|
|
204
|
+
}
|
|
205
|
+
function summarizePreparedRecord(record) {
|
|
206
|
+
const costSummary = buildCostSummary(record.prepared);
|
|
207
|
+
return cloneValue({
|
|
208
|
+
preparedId: record.preparedId,
|
|
209
|
+
state: 'active',
|
|
210
|
+
kind: record.prepared.kind,
|
|
211
|
+
protocol: record.prepared.protocol,
|
|
212
|
+
...(costSummary ? { costSummary } : {}),
|
|
213
|
+
...(record.prepared.kind === 'ready' && record.prepared.challengeDetails
|
|
214
|
+
? { challengeDetails: record.prepared.challengeDetails }
|
|
215
|
+
: {}),
|
|
216
|
+
...(record.prepared.kind === 'ready' && record.prepared.paymentRequirement
|
|
217
|
+
? { paymentRequirement: record.prepared.paymentRequirement }
|
|
218
|
+
: {}),
|
|
219
|
+
hints: record.prepared.hints,
|
|
220
|
+
...(record.prepared.probe ? { probe: record.prepared.probe } : {}),
|
|
221
|
+
validationIssues: record.prepared.validationIssues,
|
|
222
|
+
nextAction: record.prepared.nextAction,
|
|
223
|
+
expiresAt: record.expiresAt,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
async function summarizeMerchantResponse(response) {
|
|
227
|
+
const headers = {};
|
|
228
|
+
response.headers.forEach((value, key) => {
|
|
229
|
+
headers[key] = value;
|
|
230
|
+
});
|
|
231
|
+
return {
|
|
232
|
+
status: response.status,
|
|
233
|
+
headers,
|
|
234
|
+
body: await response.clone().text(),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
async function summarizeExecutionOutcome(preparedId, outcome) {
|
|
238
|
+
return {
|
|
239
|
+
preparedId,
|
|
240
|
+
harnessDisposition: 'executed',
|
|
241
|
+
sdkOutcomeKind: outcome.kind,
|
|
242
|
+
status: outcome.response.status,
|
|
243
|
+
merchantResponse: await summarizeMerchantResponse(outcome.response),
|
|
244
|
+
...('receiptId' in outcome && outcome.receiptId
|
|
245
|
+
? { receiptId: outcome.receiptId }
|
|
246
|
+
: {}),
|
|
247
|
+
...('paidRequestId' in outcome && outcome.paidRequestId
|
|
248
|
+
? { paidRequestId: outcome.paidRequestId }
|
|
249
|
+
: {}),
|
|
250
|
+
...('paymentAttemptId' in outcome && outcome.paymentAttemptId
|
|
251
|
+
? { paymentAttemptId: outcome.paymentAttemptId }
|
|
252
|
+
: {}),
|
|
253
|
+
...('reason' in outcome && typeof outcome.reason === 'string'
|
|
254
|
+
? { reason: outcome.reason }
|
|
255
|
+
: {}),
|
|
256
|
+
...('policyReviewEventId' in outcome && outcome.policyReviewEventId
|
|
257
|
+
? { policyReviewEventId: outcome.policyReviewEventId }
|
|
258
|
+
: {}),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function isFetchPaidFailureResponse(value) {
|
|
262
|
+
if (typeof value !== 'object' || value === null) {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
const candidate = value;
|
|
266
|
+
return (typeof candidate.kind === 'string' &&
|
|
267
|
+
typeof candidate.protocol === 'string' &&
|
|
268
|
+
candidate.response instanceof Response &&
|
|
269
|
+
typeof candidate.reason === 'string' &&
|
|
270
|
+
typeof candidate.decision === 'object' &&
|
|
271
|
+
candidate.decision !== null);
|
|
272
|
+
}
|
|
273
|
+
function isFetchPaidErrorLike(error) {
|
|
274
|
+
if (!(error instanceof Error) || error.name !== 'FetchPaidError') {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
const candidate = error;
|
|
278
|
+
return isFetchPaidFailureResponse(candidate.details);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Optional in-memory preparedId wrapper over AgentPayClient.
|
|
282
|
+
*/
|
|
283
|
+
export class AgentHarness {
|
|
284
|
+
client;
|
|
285
|
+
preparedTtlMs;
|
|
286
|
+
now;
|
|
287
|
+
createPreparedId;
|
|
288
|
+
preparedRecords = new Map();
|
|
289
|
+
constructor(options) {
|
|
290
|
+
this.client = options.client;
|
|
291
|
+
this.preparedTtlMs = options.preparedTtlMs ?? defaultPreparedTtlMs;
|
|
292
|
+
this.now = options.now ?? (() => new Date());
|
|
293
|
+
this.createPreparedId = options.createPreparedId ?? (() => randomUUID());
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Prepare a candidate request through the core SDK and store the immutable
|
|
297
|
+
* prepared result behind a generated preparedId for later execution.
|
|
298
|
+
*/
|
|
299
|
+
async preparePaidRequest(input) {
|
|
300
|
+
// Prepare against the SDK, then store the exact prepared request behind a
|
|
301
|
+
// deterministic id so later tool calls do not need to resend the full payload.
|
|
302
|
+
const prepared = await this.client.preparePaidRequest(input.url, {
|
|
303
|
+
...(input.method ? { method: input.method } : {}),
|
|
304
|
+
...(input.headers ? { headers: input.headers } : {}),
|
|
305
|
+
...(input.body !== undefined ? { body: input.body } : {}),
|
|
306
|
+
}, {
|
|
307
|
+
...(input.externalMetadata
|
|
308
|
+
? { externalMetadata: input.externalMetadata }
|
|
309
|
+
: {}),
|
|
310
|
+
});
|
|
311
|
+
const createdAt = this.now();
|
|
312
|
+
const preparedId = this.createPreparedId();
|
|
313
|
+
const record = {
|
|
314
|
+
preparedId,
|
|
315
|
+
state: 'active',
|
|
316
|
+
createdAt: createdAt.toISOString(),
|
|
317
|
+
expiresAt: new Date(createdAt.getTime() + this.preparedTtlMs).toISOString(),
|
|
318
|
+
prepared: createFrozenClone(prepared),
|
|
319
|
+
executionBinding: buildExecutionBinding(prepared),
|
|
320
|
+
};
|
|
321
|
+
this.supersedeActiveRecords(record);
|
|
322
|
+
this.preparedRecords.set(preparedId, record);
|
|
323
|
+
return summarizePreparedRecord(record);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Execute a previously stored ready preparation. Local state failures are
|
|
327
|
+
* converted into deterministic rejected results rather than thrown to the host.
|
|
328
|
+
*/
|
|
329
|
+
async executePreparedRequest(input) {
|
|
330
|
+
try {
|
|
331
|
+
// Execution is only allowed for active, ready preparations. All rejected
|
|
332
|
+
// local states are converted into stored deterministic results.
|
|
333
|
+
const record = this.getRecordForExecution(input.preparedId);
|
|
334
|
+
const outcome = await this.runExecution(record, input.executionContext);
|
|
335
|
+
record.state = 'consumed';
|
|
336
|
+
record.executionResult = createFrozenClone(outcome);
|
|
337
|
+
return cloneValue(outcome);
|
|
338
|
+
}
|
|
339
|
+
catch (error) {
|
|
340
|
+
if (!(error instanceof AgentHarnessError)) {
|
|
341
|
+
throw error;
|
|
342
|
+
}
|
|
343
|
+
return this.handleExecutionRejection(input.preparedId, error);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Return the durable stored outcome for a preparedId without re-running any
|
|
348
|
+
* merchant or control-plane call.
|
|
349
|
+
*/
|
|
350
|
+
getExecutionResult(preparedId) {
|
|
351
|
+
// This lookup lets an agent fetch the durable outcome later without re-running
|
|
352
|
+
// execution or depending on host-specific tool memory.
|
|
353
|
+
const record = this.getKnownRecord(preparedId);
|
|
354
|
+
this.refreshRecordState(record);
|
|
355
|
+
return cloneValue({
|
|
356
|
+
preparedId: record.preparedId,
|
|
357
|
+
state: record.state,
|
|
358
|
+
...(record.supersededByPreparedId
|
|
359
|
+
? { supersededByPreparedId: record.supersededByPreparedId }
|
|
360
|
+
: {}),
|
|
361
|
+
...(record.executionResult
|
|
362
|
+
? { executionResult: record.executionResult }
|
|
363
|
+
: {}),
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Return the full stored record for debugging, tests, or host inspection.
|
|
368
|
+
*/
|
|
369
|
+
getPreparedRecord(preparedId) {
|
|
370
|
+
const record = this.getKnownRecord(preparedId);
|
|
371
|
+
this.refreshRecordState(record);
|
|
372
|
+
return cloneValue({
|
|
373
|
+
preparedId: record.preparedId,
|
|
374
|
+
state: record.state,
|
|
375
|
+
createdAt: record.createdAt,
|
|
376
|
+
expiresAt: record.expiresAt,
|
|
377
|
+
...(record.supersededByPreparedId
|
|
378
|
+
? { supersededByPreparedId: record.supersededByPreparedId }
|
|
379
|
+
: {}),
|
|
380
|
+
prepared: record.prepared,
|
|
381
|
+
executionBinding: record.executionBinding,
|
|
382
|
+
...(record.executionResult
|
|
383
|
+
? { executionResult: record.executionResult }
|
|
384
|
+
: {}),
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
async runExecution(record, executionContext) {
|
|
388
|
+
try {
|
|
389
|
+
const response = await this.client.executePreparedRequest(record.prepared, executionContext);
|
|
390
|
+
return summarizeExecutionOutcome(record.preparedId, response);
|
|
391
|
+
}
|
|
392
|
+
catch (error) {
|
|
393
|
+
if (!isFetchPaidErrorLike(error)) {
|
|
394
|
+
throw error;
|
|
395
|
+
}
|
|
396
|
+
return summarizeExecutionOutcome(record.preparedId, error.details);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
// Rejection results are stored so later lookups remain deterministic even when
|
|
400
|
+
// execution never reached the core SDK or merchant.
|
|
401
|
+
handleExecutionRejection(preparedId, error) {
|
|
402
|
+
const rejectedResult = {
|
|
403
|
+
preparedId,
|
|
404
|
+
harnessDisposition: 'rejected',
|
|
405
|
+
rejectionCode: error.code,
|
|
406
|
+
message: error.message,
|
|
407
|
+
};
|
|
408
|
+
const record = preparedId ? this.preparedRecords.get(preparedId) : undefined;
|
|
409
|
+
if (record &&
|
|
410
|
+
error.code !== 'prepared_request_consumed' &&
|
|
411
|
+
!record.executionResult) {
|
|
412
|
+
record.executionResult = createFrozenClone(rejectedResult);
|
|
413
|
+
}
|
|
414
|
+
return rejectedResult;
|
|
415
|
+
}
|
|
416
|
+
getRecordForExecution(preparedId) {
|
|
417
|
+
const record = this.getKnownRecord(preparedId);
|
|
418
|
+
this.refreshRecordState(record);
|
|
419
|
+
if (record.state === 'expired') {
|
|
420
|
+
throw new AgentHarnessError('expired_prepared_id', `Prepared request ${preparedId} has expired.`, preparedId);
|
|
421
|
+
}
|
|
422
|
+
if (record.state === 'superseded') {
|
|
423
|
+
throw new AgentHarnessError('prepared_request_superseded', record.supersededByPreparedId
|
|
424
|
+
? `Prepared request ${preparedId} was superseded by ${record.supersededByPreparedId}.`
|
|
425
|
+
: `Prepared request ${preparedId} was superseded by a newer preparation.`, preparedId);
|
|
426
|
+
}
|
|
427
|
+
if (record.state === 'consumed') {
|
|
428
|
+
throw new AgentHarnessError('prepared_request_consumed', `Prepared request ${preparedId} has already been consumed.`, preparedId);
|
|
429
|
+
}
|
|
430
|
+
if (record.prepared.kind !== 'ready') {
|
|
431
|
+
throw new AgentHarnessError('prepared_request_not_ready', `Prepared request ${preparedId} is not executable because it is ${record.prepared.kind}.`, preparedId);
|
|
432
|
+
}
|
|
433
|
+
if (record.prepared.nextAction !== 'execute') {
|
|
434
|
+
throw new AgentHarnessError('prepared_request_not_executable', `Prepared request ${preparedId} requires ${record.prepared.nextAction} before execution.`, preparedId);
|
|
435
|
+
}
|
|
436
|
+
return record;
|
|
437
|
+
}
|
|
438
|
+
getKnownRecord(preparedId) {
|
|
439
|
+
if (preparedId.trim().length === 0) {
|
|
440
|
+
throw new AgentHarnessError('missing_prepared_id', 'A preparedId is required.');
|
|
441
|
+
}
|
|
442
|
+
const record = this.preparedRecords.get(preparedId);
|
|
443
|
+
if (!record) {
|
|
444
|
+
throw new AgentHarnessError('unknown_prepared_id', `Prepared request ${preparedId} is unknown.`, preparedId);
|
|
445
|
+
}
|
|
446
|
+
return record;
|
|
447
|
+
}
|
|
448
|
+
// Expiry is checked lazily on access so the harness does not need timers or a
|
|
449
|
+
// background cleanup loop.
|
|
450
|
+
refreshRecordState(record) {
|
|
451
|
+
if (record.state !== 'active') {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if (this.now().getTime() >= new Date(record.expiresAt).getTime()) {
|
|
455
|
+
record.state = 'expired';
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
supersedeActiveRecords(nextRecord) {
|
|
459
|
+
// Only one active preparation should survive for the same method + origin +
|
|
460
|
+
// pathname. Older active preparations become stale as soon as a newer one is stored.
|
|
461
|
+
const nextKey = createSupersessionKey(nextRecord.executionBinding);
|
|
462
|
+
for (const record of this.preparedRecords.values()) {
|
|
463
|
+
if (record.state !== 'active') {
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
if (createSupersessionKey(record.executionBinding) !== nextKey) {
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
record.state = 'superseded';
|
|
470
|
+
record.supersededByPreparedId = nextRecord.preparedId;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
//# sourceMappingURL=agent-harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-harness.js","sourceRoot":"","sources":["../src/agent-harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Detects whether an unpaid merchant response is actually a payable challenge and,
|
|
3
|
+
* if so, which paid-request protocol it speaks.
|
|
4
|
+
*/
|
|
5
|
+
import type { PaidRequestProtocol } from './contracts.js';
|
|
6
|
+
/** Minimal challenge shape the rest of the SDK needs in order to proceed. */
|
|
7
|
+
export type DetectedChallenge = {
|
|
8
|
+
protocol: PaidRequestProtocol;
|
|
9
|
+
headers: Record<string, string>;
|
|
10
|
+
body?: unknown;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Inspect a merchant response for x402/l402 challenge evidence in either headers
|
|
14
|
+
* or a JSON body. The SDK prefers header evidence first because that is the most
|
|
15
|
+
* direct live protocol signal.
|
|
16
|
+
*/
|
|
17
|
+
export declare function detectChallengeFromResponse(response: Response): Promise<DetectedChallenge | undefined>;
|