@lucid-agents/pi-xgate 0.1.5 → 0.1.7
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 +103 -7
- package/dist/codec.d.ts +40 -0
- package/dist/codec.js +553 -0
- package/dist/extension.d.ts +16 -0
- package/dist/extension.js +132 -0
- package/dist/generated/openai-model-capabilities.json +847 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/provider.d.ts +24 -0
- package/dist/provider.js +243 -0
- package/dist/taskmarket.d.ts +131 -0
- package/dist/taskmarket.js +275 -0
- package/dist/transport.d.ts +72 -0
- package/dist/transport.js +21 -0
- package/package.json +21 -9
- package/src/codec.ts +117 -26
- package/src/extension.ts +60 -12
- package/src/index.ts +45 -0
- package/src/provider.ts +68 -26
- package/src/taskmarket.ts +484 -0
- package/src/transport.ts +94 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createXgateProvider, invocationId, type Broker, type XgateProviderOptions, type XgatePurchaseFailure, } from "./provider.ts";
|
|
2
|
+
export { XgatePurchaseError, type XgateChannelBalance, type XgatePayment, type XgatePurchaseResult, type XgateResponseHead, type XgateTransport, } from "./transport.ts";
|
|
3
|
+
export { createXgateExtension, type XgateExtensionOptions, } from "./extension.ts";
|
|
4
|
+
export { XgateError } from "@lucid-agents/xgate-client/types";
|
|
5
|
+
export type { Invocation, PurchaseResult, Route, Settlement, } from "@lucid-agents/xgate-client/types";
|
|
6
|
+
export { createTaskMarketTransport, type TaskMarketChargeStatus, type TaskMarketFundingBalance, type TaskMarketInvocationState, type TaskMarketInvocationStatus, type TaskMarketPayCallOptions, type TaskMarketPayErrorCode, type TaskMarketPayer, type TaskMarketPayerLimits, type TaskMarketPayRequest, type TaskMarketPayResponse, type TaskMarketPayResult, type TaskMarketPaymentSummary, type TaskMarketPaymentTerms, type TaskMarketTransportOptions, } from "./taskmarket.ts";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Supported entry point. Hosts build the provider around their own transport; the default
|
|
2
|
+
// Pi extension (`./extension`) keeps the standalone wallet broker.
|
|
3
|
+
export { createXgateProvider, invocationId, } from "./provider.js";
|
|
4
|
+
export { XgatePurchaseError, } from "./transport.js";
|
|
5
|
+
export { createXgateExtension, } from "./extension.js";
|
|
6
|
+
export { XgateError } from "@lucid-agents/xgate-client/types";
|
|
7
|
+
export { createTaskMarketTransport, } from "./taskmarket.js";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Provider } from "@earendil-works/pi-ai";
|
|
2
|
+
import { type PiContext } from "./codec.ts";
|
|
3
|
+
import { type XgatePayment, type XgatePurchaseResult, type XgateTransport } from "./transport.ts";
|
|
4
|
+
/** @deprecated Use `XgateTransport`. */
|
|
5
|
+
export type Broker = XgateTransport;
|
|
6
|
+
export interface XgateProviderOptions {
|
|
7
|
+
/** Invocation identity scope when Pi supplies no `sessionId`. Defaults to `"standalone"`. */
|
|
8
|
+
sessionId?: () => string;
|
|
9
|
+
/** Display-only notification of a verified paid result; it cannot change the outcome. */
|
|
10
|
+
onPaid?: (result: XgatePurchaseResult) => void;
|
|
11
|
+
/** Terminal notification of a purchase that ended without a verified result. */
|
|
12
|
+
onPurchaseFailed?: (failure: XgatePurchaseFailure) => void;
|
|
13
|
+
}
|
|
14
|
+
export interface XgatePurchaseFailure {
|
|
15
|
+
/** The original invocation ID; reconcile it, never retry under a new one. */
|
|
16
|
+
invocationId: string;
|
|
17
|
+
code: string;
|
|
18
|
+
/** False only when the transport proved no unresolved payment. */
|
|
19
|
+
pending: boolean;
|
|
20
|
+
payment?: XgatePayment;
|
|
21
|
+
}
|
|
22
|
+
/** Stable across automatic retries and payload hooks; a changed paid payload cannot claim a new intent. */
|
|
23
|
+
export declare function invocationId(model: string, context: PiContext, session: string): string;
|
|
24
|
+
export declare function createXgateProvider(transport: XgateTransport, { sessionId: identity, onPaid, onPurchaseFailed, }?: XgateProviderOptions): Promise<Provider>;
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { createAssistantMessageEventStream, } from "@earendil-works/pi-ai";
|
|
3
|
+
import { XgateError } from "@lucid-agents/xgate-client/types";
|
|
4
|
+
import { catalogEntries, encode, decode } from "./codec.js";
|
|
5
|
+
import { XgatePurchaseError, } from "./transport.js";
|
|
6
|
+
const hash = (value) => createHash("sha256").update(value).digest("hex");
|
|
7
|
+
const zero = () => ({
|
|
8
|
+
input: 0,
|
|
9
|
+
output: 0,
|
|
10
|
+
cacheRead: 0,
|
|
11
|
+
cacheWrite: 0,
|
|
12
|
+
totalTokens: 0,
|
|
13
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
14
|
+
});
|
|
15
|
+
/** Stable across automatic retries and payload hooks; a changed paid payload cannot claim a new intent. */
|
|
16
|
+
export function invocationId(model, context, session) {
|
|
17
|
+
// Pi 0.85 carries the prompt and tools beside the messages; Pi 1.1 carries them inside.
|
|
18
|
+
const legacy = "systemPrompt" in context || "tools" in context
|
|
19
|
+
? { systemPrompt: context.systemPrompt, tools: context.tools }
|
|
20
|
+
: {};
|
|
21
|
+
return hash(JSON.stringify({
|
|
22
|
+
session,
|
|
23
|
+
model,
|
|
24
|
+
messages: context.messages.filter((m) => m.role !== "assistant" ||
|
|
25
|
+
!["error", "aborted"].includes(m.stopReason)),
|
|
26
|
+
...legacy,
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
export async function createXgateProvider(transport, { sessionId: identity = () => "standalone", onPaid, onPurchaseFailed, } = {}) {
|
|
30
|
+
let entries = catalogEntries(await transport.models());
|
|
31
|
+
const stream = (model, context, options = {}) => {
|
|
32
|
+
const events = createAssistantMessageEventStream();
|
|
33
|
+
const timeout = options.timeoutMs ?? 180000;
|
|
34
|
+
if (!Number.isSafeInteger(timeout) || timeout <= 0 || timeout > 180000)
|
|
35
|
+
options = { ...options, timeoutMs: 180000 };
|
|
36
|
+
const deadline = AbortSignal.timeout(Math.min(options.timeoutMs ?? 180000, 180000));
|
|
37
|
+
options = {
|
|
38
|
+
...options,
|
|
39
|
+
signal: options.signal
|
|
40
|
+
? AbortSignal.any([options.signal, deadline])
|
|
41
|
+
: deadline,
|
|
42
|
+
};
|
|
43
|
+
const message = {
|
|
44
|
+
role: "assistant",
|
|
45
|
+
provider: "xgate",
|
|
46
|
+
api: model.api,
|
|
47
|
+
model: model.id,
|
|
48
|
+
content: [],
|
|
49
|
+
usage: zero(),
|
|
50
|
+
stopReason: "pending",
|
|
51
|
+
timestamp: Date.now(),
|
|
52
|
+
};
|
|
53
|
+
let attempted, paid;
|
|
54
|
+
void (async () => {
|
|
55
|
+
try {
|
|
56
|
+
options.signal?.throwIfAborted();
|
|
57
|
+
const current = catalogEntries(await transport.models(options.signal)), entry = current.find((e) => e.model.id === model.id && e.model.api === model.api);
|
|
58
|
+
if (!entry)
|
|
59
|
+
throw new XgateError("model_not_qualified");
|
|
60
|
+
const original = encode(entry, context, {
|
|
61
|
+
...options,
|
|
62
|
+
// Respect a lower Pi model override without exceeding live catalog limits.
|
|
63
|
+
maxTokens: options.maxTokens ??
|
|
64
|
+
Math.min(4096, model.maxTokens, entry.model.maxTokens),
|
|
65
|
+
}), replacement = await options.onPayload?.(structuredClone(original), model), payload = replacement === undefined ? original : replacement;
|
|
66
|
+
const limit = entry.route.endsWith("/messages")
|
|
67
|
+
? "max_tokens"
|
|
68
|
+
: "max_output_tokens";
|
|
69
|
+
if (!payload ||
|
|
70
|
+
payload.model !== model.id ||
|
|
71
|
+
payload.stream !== false ||
|
|
72
|
+
payload[limit] !== original[limit] ||
|
|
73
|
+
JSON.stringify(payload.tools) !== JSON.stringify(original.tools) ||
|
|
74
|
+
(!entry.route.endsWith("/messages") && payload.store !== false))
|
|
75
|
+
throw new XgateError("payload_hook_changed_scope");
|
|
76
|
+
const body = JSON.stringify(payload);
|
|
77
|
+
if (Buffer.byteLength(body) > 8 * 1024 * 1024)
|
|
78
|
+
throw new XgateError("request_bound");
|
|
79
|
+
const id = invocationId(model.id, context, options.sessionId ?? identity());
|
|
80
|
+
let observed = false;
|
|
81
|
+
attempted = id;
|
|
82
|
+
const result = await transport.purchase({ id, route: entry.route, body }, options.signal, async (response) => {
|
|
83
|
+
observed = true;
|
|
84
|
+
await options.onResponse?.(response, model);
|
|
85
|
+
});
|
|
86
|
+
paid = result;
|
|
87
|
+
// In-process injected transports have no HTTP body; retain the observation hook there too.
|
|
88
|
+
if (!observed)
|
|
89
|
+
await options.onResponse?.({
|
|
90
|
+
status: 200,
|
|
91
|
+
headers: {
|
|
92
|
+
"content-type": "application/json",
|
|
93
|
+
"cache-control": "no-store",
|
|
94
|
+
},
|
|
95
|
+
}, model);
|
|
96
|
+
const value = decode(entry, result.body);
|
|
97
|
+
message.usage = value.usage;
|
|
98
|
+
message.responseId = value.responseId;
|
|
99
|
+
options.signal?.throwIfAborted();
|
|
100
|
+
events.push({ type: "start", partial: message });
|
|
101
|
+
for (const block of value.content) {
|
|
102
|
+
const contentIndex = message.content.length;
|
|
103
|
+
if (block.type === "text") {
|
|
104
|
+
message.content.push({ ...block, text: "" });
|
|
105
|
+
events.push({ type: "text_start", contentIndex, partial: message });
|
|
106
|
+
message.content[contentIndex].text = block.text;
|
|
107
|
+
events.push({
|
|
108
|
+
type: "text_delta",
|
|
109
|
+
contentIndex,
|
|
110
|
+
delta: block.text,
|
|
111
|
+
partial: message,
|
|
112
|
+
});
|
|
113
|
+
events.push({
|
|
114
|
+
type: "text_end",
|
|
115
|
+
contentIndex,
|
|
116
|
+
content: block.text,
|
|
117
|
+
partial: message,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
else if (block.type === "thinking") {
|
|
121
|
+
message.content.push({
|
|
122
|
+
...block,
|
|
123
|
+
thinking: block.redacted ? block.thinking : "",
|
|
124
|
+
});
|
|
125
|
+
events.push({
|
|
126
|
+
type: "thinking_start",
|
|
127
|
+
contentIndex,
|
|
128
|
+
partial: message,
|
|
129
|
+
});
|
|
130
|
+
if (!block.redacted) {
|
|
131
|
+
message.content[contentIndex].thinking =
|
|
132
|
+
block.thinking;
|
|
133
|
+
events.push({
|
|
134
|
+
type: "thinking_delta",
|
|
135
|
+
contentIndex,
|
|
136
|
+
delta: block.thinking,
|
|
137
|
+
partial: message,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
events.push({
|
|
141
|
+
type: "thinking_end",
|
|
142
|
+
contentIndex,
|
|
143
|
+
content: block.thinking,
|
|
144
|
+
partial: message,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
message.content.push({ ...block, arguments: {} });
|
|
149
|
+
events.push({
|
|
150
|
+
type: "toolcall_start",
|
|
151
|
+
contentIndex,
|
|
152
|
+
partial: message,
|
|
153
|
+
});
|
|
154
|
+
message.content[contentIndex].arguments =
|
|
155
|
+
block.arguments;
|
|
156
|
+
events.push({
|
|
157
|
+
type: "toolcall_delta",
|
|
158
|
+
contentIndex,
|
|
159
|
+
delta: JSON.stringify(block.arguments),
|
|
160
|
+
partial: message,
|
|
161
|
+
});
|
|
162
|
+
events.push({
|
|
163
|
+
type: "toolcall_end",
|
|
164
|
+
contentIndex,
|
|
165
|
+
toolCall: block,
|
|
166
|
+
partial: message,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
message.stopReason = value.stopReason;
|
|
171
|
+
try {
|
|
172
|
+
onPaid?.(result);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
/* UI diagnostics cannot reverse verified completion. */
|
|
176
|
+
}
|
|
177
|
+
events.push({ type: "done", reason: value.stopReason, message });
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
const aborted = options.signal?.aborted === true;
|
|
181
|
+
message.stopReason = aborted ? "aborted" : "error";
|
|
182
|
+
message.errorMessage = aborted
|
|
183
|
+
? "Xgate operation stopped. Inspect /xgate status; payment may require reconciliation."
|
|
184
|
+
: error instanceof XgateError
|
|
185
|
+
? error.message
|
|
186
|
+
: "Xgate operation stopped. Inspect /xgate status before requesting another purchase.";
|
|
187
|
+
if (attempted !== undefined) {
|
|
188
|
+
// After a verified result the charge is known even if Pi discards the content.
|
|
189
|
+
const payment = paid?.payment ??
|
|
190
|
+
(error instanceof XgatePurchaseError ? error.payment : undefined);
|
|
191
|
+
const failure = {
|
|
192
|
+
invocationId: attempted,
|
|
193
|
+
code: error instanceof XgateError ? error.code : "purchase_failed",
|
|
194
|
+
pending: paid === undefined &&
|
|
195
|
+
!(error instanceof XgatePurchaseError && !error.pending),
|
|
196
|
+
...(payment ? { payment } : {}),
|
|
197
|
+
};
|
|
198
|
+
// The original ID is the only reconciliation key. "Billing" also keeps Pi's transient
|
|
199
|
+
// error classifier from retrying a message whose hex ID happens to contain "500".
|
|
200
|
+
message.errorMessage += ` Billing invocation: ${attempted}.`;
|
|
201
|
+
try {
|
|
202
|
+
onPurchaseFailed?.(failure);
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
/* Diagnostics cannot change the terminal outcome. */
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
events.push({
|
|
209
|
+
type: "error",
|
|
210
|
+
reason: message.stopReason,
|
|
211
|
+
error: message,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
finally {
|
|
215
|
+
events.end();
|
|
216
|
+
}
|
|
217
|
+
})();
|
|
218
|
+
return events;
|
|
219
|
+
};
|
|
220
|
+
return {
|
|
221
|
+
id: "xgate",
|
|
222
|
+
name: "xgate",
|
|
223
|
+
auth: {
|
|
224
|
+
apiKey: {
|
|
225
|
+
name: "Policy constrained xgate wallet",
|
|
226
|
+
resolve: async () => ({ auth: {}, source: "xgate wallet broker" }),
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
getModels: () => entries.map((e) => e.model),
|
|
230
|
+
refreshModels: async (context) => {
|
|
231
|
+
if (!context.allowNetwork)
|
|
232
|
+
return;
|
|
233
|
+
const updated = catalogEntries(await transport.models(context.signal));
|
|
234
|
+
await context.publish({
|
|
235
|
+
update: () => {
|
|
236
|
+
entries = updated;
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
},
|
|
240
|
+
stream: (model, context, options) => stream(model, context, options),
|
|
241
|
+
streamSimple: stream,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { type XgateTransport } from "./transport.ts";
|
|
2
|
+
type Open<T extends string> = T | (string & {});
|
|
3
|
+
export type TaskMarketChargeStatus = Open<"none" | "reserved" | "pending" | "settled" | "amount_unknown" | "released" | "manually_resolved">;
|
|
4
|
+
export type TaskMarketInvocationState = Open<"in_progress" | "interrupted" | "completed" | "failed">;
|
|
5
|
+
export type TaskMarketPayErrorCode = Open<"invalid_request" | "request_body_too_large" | "response_body_too_large" | "challenge_invalid" | "invocation_conflict" | "invocation_duplicate" | "invocation_not_found" | "destination_rejected" | "policy_denied" | "payment_declined" | "no_supported_rail" | "signer_unavailable" | "journal_unavailable" | "aborted" | "outcome_uncertain" | "paid_retry_prohibited" | "request_failed" | "allocation_not_found" | "allocation_conflict" | "allocation_closed" | "allocation_exhausted" | "allocation_mismatch" | "funding_exhausted" | "allocation_required" | "reservation_not_found">;
|
|
6
|
+
export interface TaskMarketPayerLimits {
|
|
7
|
+
maxRequestBodyBytes: number;
|
|
8
|
+
maxResponseBodyBytes: number;
|
|
9
|
+
maxChallengeBodyBytes: number;
|
|
10
|
+
}
|
|
11
|
+
export interface TaskMarketPayRequest {
|
|
12
|
+
apiVersion: 1;
|
|
13
|
+
invocationId: string;
|
|
14
|
+
url: string;
|
|
15
|
+
method: "GET" | "POST";
|
|
16
|
+
headers?: Record<string, string>;
|
|
17
|
+
body?: Uint8Array;
|
|
18
|
+
policyRuleId?: string;
|
|
19
|
+
nonInteractive?: boolean;
|
|
20
|
+
limits?: Partial<TaskMarketPayerLimits>;
|
|
21
|
+
allocationId?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface TaskMarketPaymentTerms {
|
|
24
|
+
origin: string;
|
|
25
|
+
pathname: string;
|
|
26
|
+
method: "GET" | "POST";
|
|
27
|
+
rail: {
|
|
28
|
+
id: string;
|
|
29
|
+
kind: string;
|
|
30
|
+
};
|
|
31
|
+
scheme: string;
|
|
32
|
+
network: string;
|
|
33
|
+
asset: string;
|
|
34
|
+
payTo: string;
|
|
35
|
+
authorizedAmount: string;
|
|
36
|
+
policyRuleId?: string;
|
|
37
|
+
windowMaximum?: string;
|
|
38
|
+
unattended: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface TaskMarketPayCallOptions {
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
confirmPayment?: (terms: TaskMarketPaymentTerms) => Promise<boolean>;
|
|
43
|
+
}
|
|
44
|
+
export interface TaskMarketPaymentSummary {
|
|
45
|
+
paymentId: string;
|
|
46
|
+
rail: {
|
|
47
|
+
id: string;
|
|
48
|
+
kind: string;
|
|
49
|
+
};
|
|
50
|
+
network: string;
|
|
51
|
+
scheme: string;
|
|
52
|
+
asset: string;
|
|
53
|
+
payTo: string;
|
|
54
|
+
payer: string;
|
|
55
|
+
authorizedAmount: string;
|
|
56
|
+
settledAmount?: string;
|
|
57
|
+
transaction?: string;
|
|
58
|
+
commitment?: string;
|
|
59
|
+
charge: TaskMarketChargeStatus;
|
|
60
|
+
}
|
|
61
|
+
export interface TaskMarketPayResponse {
|
|
62
|
+
status: number;
|
|
63
|
+
headers: Record<string, string>;
|
|
64
|
+
contentType: string;
|
|
65
|
+
bytes: number;
|
|
66
|
+
sha256: string;
|
|
67
|
+
body: Uint8Array;
|
|
68
|
+
}
|
|
69
|
+
export interface TaskMarketPayResult {
|
|
70
|
+
apiVersion: number;
|
|
71
|
+
invocationId: string;
|
|
72
|
+
requestFingerprint: string;
|
|
73
|
+
payment?: TaskMarketPaymentSummary;
|
|
74
|
+
response: TaskMarketPayResponse;
|
|
75
|
+
}
|
|
76
|
+
export interface TaskMarketInvocationStatus {
|
|
77
|
+
apiVersion: number;
|
|
78
|
+
invocationId: string;
|
|
79
|
+
requestFingerprint: string;
|
|
80
|
+
state: TaskMarketInvocationState;
|
|
81
|
+
charge: TaskMarketChargeStatus;
|
|
82
|
+
uncertain: boolean;
|
|
83
|
+
errorCode?: TaskMarketPayErrorCode;
|
|
84
|
+
createdAt: string;
|
|
85
|
+
updatedAt: string;
|
|
86
|
+
payment?: TaskMarketPaymentSummary;
|
|
87
|
+
}
|
|
88
|
+
/** Structural `X402Payer` v1. */
|
|
89
|
+
export interface TaskMarketPayer {
|
|
90
|
+
readonly apiVersion: 1;
|
|
91
|
+
request(input: TaskMarketPayRequest, options?: TaskMarketPayCallOptions): Promise<TaskMarketPayResult>;
|
|
92
|
+
status(invocationId: string): Promise<TaskMarketInvocationStatus>;
|
|
93
|
+
reconcile(invocationId: string): Promise<TaskMarketInvocationStatus>;
|
|
94
|
+
}
|
|
95
|
+
/** Structural `X402FundingBalance`: one session-rail deposit. */
|
|
96
|
+
export interface TaskMarketFundingBalance {
|
|
97
|
+
railId: string;
|
|
98
|
+
sessionKey: string;
|
|
99
|
+
network: string;
|
|
100
|
+
asset: string;
|
|
101
|
+
depositing: string;
|
|
102
|
+
locked: string;
|
|
103
|
+
refunded: string;
|
|
104
|
+
charged: string;
|
|
105
|
+
pending: string;
|
|
106
|
+
refundable: string;
|
|
107
|
+
}
|
|
108
|
+
export interface TaskMarketTransportOptions {
|
|
109
|
+
payer: TaskMarketPayer;
|
|
110
|
+
/** Router origin, e.g. `https://api.xgate.run`. */
|
|
111
|
+
origin: string;
|
|
112
|
+
/** Allocation that bounds this agent's inference; forwarded on every request. */
|
|
113
|
+
allocationId?: string;
|
|
114
|
+
policyRuleId?: string;
|
|
115
|
+
/** Authorize only through unattended policy rules. */
|
|
116
|
+
nonInteractive?: boolean;
|
|
117
|
+
/** Attended confirmation, forwarded to the payer. */
|
|
118
|
+
confirmPayment?: (terms: TaskMarketPaymentTerms) => Promise<boolean>;
|
|
119
|
+
/** Restrict the offered models; the router catalog still qualifies them. */
|
|
120
|
+
models?: readonly string[];
|
|
121
|
+
/** Session-rail balances for display, e.g. TaskMarket's `X402Allocations.balances`. */
|
|
122
|
+
balances?: () => Promise<readonly TaskMarketFundingBalance[]>;
|
|
123
|
+
/** Unpaid catalog reads. Defaults to the global `fetch`. */
|
|
124
|
+
fetch?: typeof fetch;
|
|
125
|
+
}
|
|
126
|
+
/** Never sends the request again for an ID the payer has seen: `purchase` maps every non-verified outcome to a terminal error. */
|
|
127
|
+
export declare function createTaskMarketTransport(options: TaskMarketTransportOptions): XgateTransport & {
|
|
128
|
+
status(): Promise<unknown>;
|
|
129
|
+
reconcile(invocationId: string): Promise<unknown>;
|
|
130
|
+
};
|
|
131
|
+
export {};
|