@lucid-agents/taskmarket 1.20.3 → 1.21.0
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/dist/THIRD_PARTY_NOTICES.md +285 -120
- package/dist/agent-compatibility.json +1 -1
- package/dist/{channels-B4HKYLKV.js → channels-OBJUNCZX.js} +3 -3
- package/dist/{chunk-4SG3R5IH.js → chunk-3IIVNF5F.js} +1178 -355
- package/dist/{chunk-H2XTB3NF.js → chunk-5N25NATR.js} +3 -3
- package/dist/{chunk-EMIVR2MT.js → chunk-HE2N4GEO.js} +1 -1
- package/dist/{chunk-VEZ72QNL.js → chunk-OCQKVV4A.js} +2 -2
- package/dist/{chunk-4EN2RUZ3.js → chunk-TAMXCFLT.js} +2 -2
- package/dist/{chunk-77XBHT43.js → chunk-UD5Z752S.js} +1 -1
- package/dist/{chunk-AJ5V4H2H.js → chunk-VVAUDP3D.js} +4 -4
- package/dist/{chunk-6VM3O3RZ.js → chunk-ZU33L5X5.js} +59 -12
- package/dist/{chunk-NLVNUGBO.js → chunk-ZZTCFKR3.js} +3 -3
- package/dist/{doctor-Z5O2VY62.js → doctor-26YOWQOH.js} +7 -7
- package/dist/index.js +227 -176
- package/dist/{launch-MX3RJWL7.js → launch-QDCWAIKE.js} +33 -10
- package/dist/pi-extensions/remote-tools.cjs +58 -11
- package/dist/pi-extensions/xgate.cjs +76277 -3224
- package/dist/{reconcile-OAT32H4B.js → reconcile-MALCM3NB.js} +3 -3
- package/dist/{status-JCOPIQ7O.js → status-FTTQWS5P.js} +7 -7
- package/dist/{sync-pull-D4DZ2LYX.js → sync-pull-N6OTHBWR.js} +3 -3
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
signReadAuth,
|
|
15
15
|
submitTaskFiles,
|
|
16
16
|
taskAccessGrantHeaders
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-5N25NATR.js";
|
|
18
18
|
import {
|
|
19
19
|
ComputeCreditError,
|
|
20
20
|
applyComputeCreditSetup,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
refusedPaidWrite,
|
|
37
37
|
releasePendingComputePurchase,
|
|
38
38
|
resolvePendingComputePurchases
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-TAMXCFLT.js";
|
|
40
40
|
import {
|
|
41
41
|
MPP_TEMPO_DEFAULT_VALIDITY_SECONDS,
|
|
42
42
|
X402PayError,
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
signSponsoredTempoTransfer,
|
|
59
59
|
signTaskmarketFeePayment,
|
|
60
60
|
signTypedData
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-HE2N4GEO.js";
|
|
62
62
|
import {
|
|
63
63
|
AgentMessageEnvelopeSchema,
|
|
64
64
|
ApiError,
|
|
@@ -75,6 +75,7 @@ import {
|
|
|
75
75
|
LegalStatusResponseSchema,
|
|
76
76
|
NETWORKS,
|
|
77
77
|
NETWORK_NAMES,
|
|
78
|
+
NetworkRequiredError,
|
|
78
79
|
PUBLIC_BUG_REPORT_SORTS,
|
|
79
80
|
PenaltyTo,
|
|
80
81
|
PostBugReportMessageInputSchema,
|
|
@@ -138,14 +139,17 @@ import {
|
|
|
138
139
|
formatPaymentAmount,
|
|
139
140
|
formatUsdcBaseUnits,
|
|
140
141
|
generateKeypair,
|
|
142
|
+
getNetwork,
|
|
141
143
|
getTaskmarketHome,
|
|
142
144
|
idempotencyKeyForError,
|
|
143
145
|
isInFlightApiError,
|
|
146
|
+
isNetworkName,
|
|
144
147
|
isPendingApiError,
|
|
145
148
|
isRecordingPendingResponse,
|
|
146
149
|
isTaskmarketChainId,
|
|
147
150
|
isTerminalWalletBridgeStatus,
|
|
148
151
|
keystoreExists,
|
|
152
|
+
liveNetworkNames,
|
|
149
153
|
loadKeystore,
|
|
150
154
|
networkToStamp,
|
|
151
155
|
paymentProtocolOf,
|
|
@@ -158,6 +162,7 @@ import {
|
|
|
158
162
|
resolveTaskTerms,
|
|
159
163
|
saveKeystore,
|
|
160
164
|
selectedNetwork,
|
|
165
|
+
selectedNetworkOrUndefined,
|
|
161
166
|
setSelectedNetwork,
|
|
162
167
|
settlementActionExpiresAt,
|
|
163
168
|
settlementActionRequiresExpiry,
|
|
@@ -167,7 +172,7 @@ import {
|
|
|
167
172
|
withChainId,
|
|
168
173
|
withErrorContext,
|
|
169
174
|
withIdempotentWrite
|
|
170
|
-
} from "./chunk-
|
|
175
|
+
} from "./chunk-3IIVNF5F.js";
|
|
171
176
|
import {
|
|
172
177
|
channelLines
|
|
173
178
|
} from "./chunk-XJOB4NMV.js";
|
|
@@ -180,6 +185,7 @@ import { createRequire } from "module";
|
|
|
180
185
|
// src/commands/init.ts
|
|
181
186
|
import { Command as Command2 } from "commander";
|
|
182
187
|
import { privateKeyToAccount } from "viem/accounts";
|
|
188
|
+
import { createInterface as createInterface2 } from "readline";
|
|
183
189
|
|
|
184
190
|
// src/lib/last-error.ts
|
|
185
191
|
import fs from "fs";
|
|
@@ -308,21 +314,38 @@ function printWarning(message) {
|
|
|
308
314
|
}
|
|
309
315
|
|
|
310
316
|
// src/lib/agent.ts
|
|
317
|
+
function legacyAgentIdChain(keystore) {
|
|
318
|
+
const network = keystore.network;
|
|
319
|
+
return network && isNetworkName(network) ? NETWORKS[network].chainId : void 0;
|
|
320
|
+
}
|
|
321
|
+
function agentIdForChain(keystore, chainId) {
|
|
322
|
+
const stored = keystore.agentIds?.[String(chainId)];
|
|
323
|
+
if (stored) return stored;
|
|
324
|
+
if (keystore.agentId && legacyAgentIdChain(keystore) === chainId) return keystore.agentId;
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
function withAgentIdForChain(keystore, chainId, agentId) {
|
|
328
|
+
return { ...keystore, agentIds: { ...keystore.agentIds, [String(chainId)]: agentId } };
|
|
329
|
+
}
|
|
330
|
+
async function lookupAgentId(address, chainId = selectedNetwork().chainId) {
|
|
331
|
+
try {
|
|
332
|
+
const res = await fetch(
|
|
333
|
+
`${apiUrl()}/api/identity/status?address=${address}&chainId=${chainId}`
|
|
334
|
+
);
|
|
335
|
+
if (!res.ok) return null;
|
|
336
|
+
const data = await res.json();
|
|
337
|
+
return data.agentId ?? null;
|
|
338
|
+
} catch {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
311
342
|
async function pollAgentId(address, maxWaitMs = 6e4) {
|
|
312
343
|
const interval = 3e3;
|
|
313
344
|
const deadline = Date.now() + maxWaitMs;
|
|
314
345
|
while (Date.now() < deadline) {
|
|
315
346
|
await new Promise((r) => setTimeout(r, interval));
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
`${apiUrl()}/api/identity/status?address=${address}&chainId=${selectedNetwork().chainId}`
|
|
319
|
-
);
|
|
320
|
-
if (res.ok) {
|
|
321
|
-
const data = await res.json();
|
|
322
|
-
if (data.agentId) return data.agentId;
|
|
323
|
-
}
|
|
324
|
-
} catch {
|
|
325
|
-
}
|
|
347
|
+
const agentId = await lookupAgentId(address);
|
|
348
|
+
if (agentId) return agentId;
|
|
326
349
|
}
|
|
327
350
|
return null;
|
|
328
351
|
}
|
|
@@ -599,13 +622,42 @@ async function tryRegisterEmail(deviceId, apiToken, username, explicit) {
|
|
|
599
622
|
return null;
|
|
600
623
|
}
|
|
601
624
|
}
|
|
602
|
-
|
|
625
|
+
function terminalIo() {
|
|
626
|
+
return {
|
|
627
|
+
interactive: Boolean(process.stdin.isTTY && process.stderr.isTTY),
|
|
628
|
+
ask: (question) => new Promise((resolve) => {
|
|
629
|
+
const rl = createInterface2({ input: process.stdin, output: process.stderr });
|
|
630
|
+
rl.question(question, (answer) => {
|
|
631
|
+
rl.close();
|
|
632
|
+
resolve(answer);
|
|
633
|
+
});
|
|
634
|
+
})
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
async function ensureInitNetwork(io = terminalIo()) {
|
|
638
|
+
if (selectedNetworkOrUndefined()) return;
|
|
639
|
+
if (!io.interactive) throw new NetworkRequiredError();
|
|
640
|
+
const answer = (await io.ask(`Network to use (${liveNetworkNames().join(", ")}): `)).trim();
|
|
641
|
+
if (!answer) throw new NetworkRequiredError();
|
|
642
|
+
setSelectedNetwork(getNetwork(answer));
|
|
643
|
+
}
|
|
644
|
+
function existingWalletMessage() {
|
|
645
|
+
return "This machine already has a Taskmarket wallet; init runs once and never replaces saved credentials. The same wallet and device credentials work on every network. To register its agent identity on another network, run: taskmarket --network <name> identity register";
|
|
646
|
+
}
|
|
647
|
+
var initCommand = new Command2("init").description(
|
|
648
|
+
"Create and register this machine's agent wallet (one-time; refuses when a wallet exists)"
|
|
649
|
+
).option(
|
|
603
650
|
"--email <username>",
|
|
604
651
|
"Claim a custom email username (default: auto-generated from agent ID)"
|
|
605
652
|
).option(
|
|
606
653
|
"--yes",
|
|
607
654
|
"Confirm legal acceptance non-interactively after reviewing every current policy"
|
|
608
655
|
).action(async (opts) => {
|
|
656
|
+
if (await keystoreExists()) {
|
|
657
|
+
printError(existingWalletMessage());
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
await ensureInitNetwork();
|
|
609
661
|
if (opts.email) {
|
|
610
662
|
const check = await apiGet(
|
|
611
663
|
`/api/emails/check-username?username=${encodeURIComponent(opts.email)}`
|
|
@@ -615,56 +667,6 @@ var initCommand = new Command2("init").description("Create and register a new ag
|
|
|
615
667
|
return;
|
|
616
668
|
}
|
|
617
669
|
}
|
|
618
|
-
if (await keystoreExists()) {
|
|
619
|
-
const keystore = await loadKeystore();
|
|
620
|
-
let agentId2 = keystore.agentId;
|
|
621
|
-
if (!agentId2) {
|
|
622
|
-
agentId2 = await pollAgentId(keystore.walletAddress);
|
|
623
|
-
if (agentId2) {
|
|
624
|
-
await saveKeystore({ ...keystore, agentId: agentId2 });
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
let networkInfo2;
|
|
628
|
-
try {
|
|
629
|
-
const response = await apiGet("/trpc/network.info");
|
|
630
|
-
networkInfo2 = response.result.data;
|
|
631
|
-
} catch {
|
|
632
|
-
}
|
|
633
|
-
let emailAddress2 = null;
|
|
634
|
-
try {
|
|
635
|
-
const existing = await apiGet(`/api/agents/stats?address=${keystore.walletAddress}`);
|
|
636
|
-
emailAddress2 = existing.emailAddress ?? null;
|
|
637
|
-
} catch {
|
|
638
|
-
}
|
|
639
|
-
if (!emailAddress2) {
|
|
640
|
-
const username2 = opts.email ?? (agentId2 && networkInfo2 ? sanitizeEmailUsername(agentId2, String(selectedNetwork().chainId)) : null);
|
|
641
|
-
if (username2) {
|
|
642
|
-
emailAddress2 = await tryRegisterEmail(
|
|
643
|
-
keystore.deviceId,
|
|
644
|
-
keystore.apiToken,
|
|
645
|
-
username2,
|
|
646
|
-
!!opts.email
|
|
647
|
-
);
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
let chain2;
|
|
651
|
-
try {
|
|
652
|
-
chain2 = chainInfoFor(networkInfo2, selectedNetwork().chainId);
|
|
653
|
-
} catch (err) {
|
|
654
|
-
renderFailure(err);
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
printResult({
|
|
658
|
-
address: keystore.walletAddress,
|
|
659
|
-
agentId: agentId2,
|
|
660
|
-
network: chain2?.networkName ?? networkInfo2?.networkName,
|
|
661
|
-
chainId: chain2?.chainId ?? networkInfo2?.chainId,
|
|
662
|
-
paymentMethod: chain2?.paymentMethod,
|
|
663
|
-
feeModel: chain2?.feeModel,
|
|
664
|
-
emailAddress: emailAddress2
|
|
665
|
-
});
|
|
666
|
-
return;
|
|
667
|
-
}
|
|
668
670
|
const { privateKey, address } = generateKeypair();
|
|
669
671
|
const publicKey = deriveCompressedPublicKey(privateKey);
|
|
670
672
|
const legalBundle = LegalBundleSchema.parse(await apiGet("/api/legal/current"));
|
|
@@ -696,6 +698,7 @@ var initCommand = new Command2("init").description("Create and register a new ag
|
|
|
696
698
|
deviceId,
|
|
697
699
|
apiToken,
|
|
698
700
|
agentId,
|
|
701
|
+
...agentId ? { agentIds: { [String(selectedNetwork().chainId)]: agentId } } : {},
|
|
699
702
|
keyServerUrl: apiUrl(),
|
|
700
703
|
network: networkToStamp(),
|
|
701
704
|
...legalAcceptance ? {
|
|
@@ -708,7 +711,9 @@ var initCommand = new Command2("init").description("Create and register a new ag
|
|
|
708
711
|
agentId = await pollAgentId(address);
|
|
709
712
|
if (agentId) {
|
|
710
713
|
const keystore = await loadKeystore();
|
|
711
|
-
await saveKeystore(
|
|
714
|
+
await saveKeystore(
|
|
715
|
+
withAgentIdForChain({ ...keystore, agentId }, selectedNetwork().chainId, agentId)
|
|
716
|
+
);
|
|
712
717
|
}
|
|
713
718
|
}
|
|
714
719
|
let networkInfo;
|
|
@@ -746,72 +751,35 @@ var addressCommand = new Command3("address").description("Print the wallet addre
|
|
|
746
751
|
|
|
747
752
|
// src/commands/identity.ts
|
|
748
753
|
import { Command as Command4 } from "commander";
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
var DEFAULT_RETRY_AFTER_SECONDS = 30;
|
|
754
|
-
function retryAfterMs(res) {
|
|
755
|
-
const header = res.headers?.get?.("retry-after");
|
|
756
|
-
const seconds = header ? Number(header) : NaN;
|
|
757
|
-
const wait = Number.isFinite(seconds) && seconds >= 0 ? seconds : DEFAULT_RETRY_AFTER_SECONDS;
|
|
758
|
-
return Math.min(wait, MAX_RETRY_AFTER_SECONDS) * 1e3;
|
|
759
|
-
}
|
|
760
|
-
async function x402Post(path3, body, options) {
|
|
761
|
-
const sleep4 = options?.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
762
|
-
if (paymentProtocolOf(selectedNetwork().chainId) === "mpp")
|
|
763
|
-
return mppPost(path3, body, options);
|
|
754
|
+
var identityCommand = new Command4("identity").description("Manage agent identity");
|
|
755
|
+
identityCommand.command("register").description(
|
|
756
|
+
"Register this wallet's ERC-8004 agent identity on the selected network (free; uses this machine's existing credentials)"
|
|
757
|
+
).action(async () => {
|
|
764
758
|
const keystore = await loadKeystore();
|
|
765
|
-
const
|
|
766
|
-
const
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
if (r1.ok) {
|
|
776
|
-
return { data: await r1.json(), idempotencyKey };
|
|
777
|
-
}
|
|
778
|
-
throw refusedPaidWrite(path3, r1.status, await readFailureBody(r1), idempotencyKey);
|
|
779
|
-
}
|
|
780
|
-
const requirements = await r1.json();
|
|
781
|
-
if (!requirements.accepts || requirements.accepts.length === 0) {
|
|
782
|
-
throw new Error("No payment methods accepted by server");
|
|
783
|
-
}
|
|
784
|
-
const accept = requirements.accepts[0];
|
|
785
|
-
const { header } = await signTaskmarketFeePayment({
|
|
786
|
-
resource: requirements.resource,
|
|
787
|
-
requirement: accept,
|
|
788
|
-
typedData: accept.extra.eip712,
|
|
789
|
-
from: keystore.walletAddress,
|
|
790
|
-
signTypedData: (typedData) => signTypedData(typedData, keystore)
|
|
791
|
-
});
|
|
792
|
-
for (let attempt = 0; ; attempt++) {
|
|
793
|
-
const r2 = await fetch(request.url, {
|
|
794
|
-
method: "POST",
|
|
795
|
-
redirect: "error",
|
|
796
|
-
headers: { ...request.headers, "PAYMENT-SIGNATURE": header },
|
|
797
|
-
body: request.body
|
|
798
|
-
});
|
|
799
|
-
if (r2.ok) return { data: await r2.json(), idempotencyKey };
|
|
800
|
-
const read = await readFailureBody(r2);
|
|
801
|
-
if (r2.status === 503 && apiErrorEnvelopeOf(read.body)?.reason === "facilitator_unavailable" && attempt < FACILITATOR_RETRIES) {
|
|
802
|
-
await sleep4(retryAfterMs(r2));
|
|
803
|
-
continue;
|
|
804
|
-
}
|
|
805
|
-
throw failedAfterPayment(path3, r2.status, read, idempotencyKey);
|
|
806
|
-
}
|
|
759
|
+
const chainId = selectedNetwork().chainId;
|
|
760
|
+
const stored = agentIdForChain(keystore, chainId);
|
|
761
|
+
if (stored) {
|
|
762
|
+
printResult({ agentId: stored, alreadyRegistered: true, chainId });
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
const { data, idempotencyKey } = await apiPost(`/api/devices/${encodeURIComponent(keystore.deviceId)}/identity`, {
|
|
766
|
+
deviceId: keystore.deviceId,
|
|
767
|
+
apiToken: keystore.apiToken,
|
|
768
|
+
chainId
|
|
807
769
|
});
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
770
|
+
const agentId = data.agentId ?? await pollAgentId(keystore.walletAddress);
|
|
771
|
+
if (agentId) {
|
|
772
|
+
await saveKeystore(withAgentIdForChain(await loadKeystore(), chainId, agentId));
|
|
773
|
+
printResult(
|
|
774
|
+
{ agentId, alreadyRegistered: data.alreadyRegistered, chainId },
|
|
775
|
+
{ idempotencyKey }
|
|
776
|
+
);
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
printError(
|
|
780
|
+
`The sponsored identity mint on chain ${chainId} has started but has not landed yet. Re-run this command to pick it up: ${taskmarketCommandFor(chainId)} identity register`,
|
|
781
|
+
{ idempotencyKey }
|
|
782
|
+
);
|
|
815
783
|
});
|
|
816
784
|
identityCommand.command("status").description("Check identity registration status").action(async () => {
|
|
817
785
|
const keystore = await loadKeystore();
|
|
@@ -845,7 +813,9 @@ function describeReputationLink(link) {
|
|
|
845
813
|
return `unavailable: ${link.linkUnavailableReason ?? LINK_READ_FAILED_REASON}`;
|
|
846
814
|
return link.linkedAgentId ? `linked to agent #${link.linkedAgentId}` : NOT_LINKED_YET;
|
|
847
815
|
}
|
|
848
|
-
var whoamiCommand = new Command5("whoami").description(
|
|
816
|
+
var whoamiCommand = new Command5("whoami").description(
|
|
817
|
+
"Show this wallet, its agent ID on each chain and its requester reputation link on the selected --network"
|
|
818
|
+
).action(async () => {
|
|
849
819
|
const keystore = await loadKeystore();
|
|
850
820
|
const selected = selectedNetwork();
|
|
851
821
|
const chains = await Promise.all(
|
|
@@ -870,7 +840,7 @@ var whoamiCommand = new Command5("whoami").description("Show this wallet, its ag
|
|
|
870
840
|
|
|
871
841
|
// src/commands/stats.ts
|
|
872
842
|
import { Command as Command6 } from "commander";
|
|
873
|
-
var statsCommand = new Command6("stats").description("View agent statistics").option("--address <addr>", "Wallet address (defaults to own wallet)").option("--agent <agentId>", "Agent ID (alternative to --address)").action(async (opts) => {
|
|
843
|
+
var statsCommand = new Command6("stats").description("View agent statistics on the selected --network").option("--address <addr>", "Wallet address (defaults to own wallet)").option("--agent <agentId>", "Agent ID (alternative to --address)").action(async (opts) => {
|
|
874
844
|
let address = opts.address;
|
|
875
845
|
if (!address) {
|
|
876
846
|
const keystore = await loadKeystore();
|
|
@@ -1342,6 +1312,66 @@ var reviewCmd = createReviewCommand();
|
|
|
1342
1312
|
import { Command as Command8 } from "commander";
|
|
1343
1313
|
import { parseUnits } from "viem";
|
|
1344
1314
|
|
|
1315
|
+
// src/lib/x402.ts
|
|
1316
|
+
var FACILITATOR_RETRIES = 2;
|
|
1317
|
+
var MAX_RETRY_AFTER_SECONDS = 60;
|
|
1318
|
+
var DEFAULT_RETRY_AFTER_SECONDS = 30;
|
|
1319
|
+
function retryAfterMs(res) {
|
|
1320
|
+
const header = res.headers?.get?.("retry-after");
|
|
1321
|
+
const seconds = header ? Number(header) : NaN;
|
|
1322
|
+
const wait = Number.isFinite(seconds) && seconds >= 0 ? seconds : DEFAULT_RETRY_AFTER_SECONDS;
|
|
1323
|
+
return Math.min(wait, MAX_RETRY_AFTER_SECONDS) * 1e3;
|
|
1324
|
+
}
|
|
1325
|
+
async function x402Post(path3, body, options) {
|
|
1326
|
+
const sleep4 = options?.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
1327
|
+
if (paymentProtocolOf(selectedNetwork().chainId) === "mpp")
|
|
1328
|
+
return mppPost(path3, body, options);
|
|
1329
|
+
const keystore = await loadKeystore();
|
|
1330
|
+
const idempotencyKey = resolveIdempotencyKey(options?.idempotencyKey);
|
|
1331
|
+
const request = paidWriteRequest(keystore, path3, body, idempotencyKey);
|
|
1332
|
+
return withIdempotentWrite(idempotencyKey, async () => {
|
|
1333
|
+
const r1 = await fetch(request.url, {
|
|
1334
|
+
method: "POST",
|
|
1335
|
+
redirect: "error",
|
|
1336
|
+
headers: request.headers,
|
|
1337
|
+
body: request.body
|
|
1338
|
+
});
|
|
1339
|
+
if (r1.status !== 402) {
|
|
1340
|
+
if (r1.ok) {
|
|
1341
|
+
return { data: await r1.json(), idempotencyKey };
|
|
1342
|
+
}
|
|
1343
|
+
throw refusedPaidWrite(path3, r1.status, await readFailureBody(r1), idempotencyKey);
|
|
1344
|
+
}
|
|
1345
|
+
const requirements = await r1.json();
|
|
1346
|
+
if (!requirements.accepts || requirements.accepts.length === 0) {
|
|
1347
|
+
throw new Error("No payment methods accepted by server");
|
|
1348
|
+
}
|
|
1349
|
+
const accept = requirements.accepts[0];
|
|
1350
|
+
const { header } = await signTaskmarketFeePayment({
|
|
1351
|
+
resource: requirements.resource,
|
|
1352
|
+
requirement: accept,
|
|
1353
|
+
typedData: accept.extra.eip712,
|
|
1354
|
+
from: keystore.walletAddress,
|
|
1355
|
+
signTypedData: (typedData) => signTypedData(typedData, keystore)
|
|
1356
|
+
});
|
|
1357
|
+
for (let attempt = 0; ; attempt++) {
|
|
1358
|
+
const r2 = await fetch(request.url, {
|
|
1359
|
+
method: "POST",
|
|
1360
|
+
redirect: "error",
|
|
1361
|
+
headers: { ...request.headers, "PAYMENT-SIGNATURE": header },
|
|
1362
|
+
body: request.body
|
|
1363
|
+
});
|
|
1364
|
+
if (r2.ok) return { data: await r2.json(), idempotencyKey };
|
|
1365
|
+
const read = await readFailureBody(r2);
|
|
1366
|
+
if (r2.status === 503 && apiErrorEnvelopeOf(read.body)?.reason === "facilitator_unavailable" && attempt < FACILITATOR_RETRIES) {
|
|
1367
|
+
await sleep4(retryAfterMs(r2));
|
|
1368
|
+
continue;
|
|
1369
|
+
}
|
|
1370
|
+
throw failedAfterPayment(path3, r2.status, read, idempotencyKey);
|
|
1371
|
+
}
|
|
1372
|
+
});
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1345
1375
|
// src/lib/settlement-terms.ts
|
|
1346
1376
|
var TERM_FLAGS = {
|
|
1347
1377
|
stakeRequired: "--stake-required",
|
|
@@ -3258,14 +3288,14 @@ import { Command as Command49, Option as Option3 } from "commander";
|
|
|
3258
3288
|
import { Command as Command47 } from "commander";
|
|
3259
3289
|
|
|
3260
3290
|
// src/lib/tty-confirm.ts
|
|
3261
|
-
import { createInterface as
|
|
3291
|
+
import { createInterface as createInterface3 } from "readline";
|
|
3262
3292
|
async function confirmAtTerminal(lines, unattended) {
|
|
3263
3293
|
if (!process.stdin.isTTY) {
|
|
3264
3294
|
throw new Error(`Interactive confirmation requires a TTY; ${unattended}`);
|
|
3265
3295
|
}
|
|
3266
3296
|
process.stderr.write(`${lines.join("\n")}
|
|
3267
3297
|
`);
|
|
3268
|
-
const readline =
|
|
3298
|
+
const readline = createInterface3({ input: process.stdin, output: process.stderr });
|
|
3269
3299
|
const answer = await new Promise(
|
|
3270
3300
|
(resolve) => readline.question("Type yes to approve: ", resolve)
|
|
3271
3301
|
);
|
|
@@ -3457,7 +3487,7 @@ async function runAgentCommand(options) {
|
|
|
3457
3487
|
try {
|
|
3458
3488
|
const { assertAgentCompatibility } = await import("./compatibility-636WJOEX.js");
|
|
3459
3489
|
const pi = assertAgentCompatibility();
|
|
3460
|
-
const { runAgent } = await import("./launch-
|
|
3490
|
+
const { runAgent } = await import("./launch-QDCWAIKE.js");
|
|
3461
3491
|
result = await runAgent({
|
|
3462
3492
|
model: options.model,
|
|
3463
3493
|
pi,
|
|
@@ -3516,13 +3546,13 @@ function agentManagementCommands() {
|
|
|
3516
3546
|
const status = new Command48("status").description(
|
|
3517
3547
|
"Show the agent channels (locked, charged, refundable), purchases with an unknown outcome, the sandbox and compute credit. Reads only."
|
|
3518
3548
|
).option("--json", "Print the versioned JSON envelope").action(async (options) => {
|
|
3519
|
-
const { collectAgentStatus, statusLines } = await import("./status-
|
|
3549
|
+
const { collectAgentStatus, statusLines } = await import("./status-FTTQWS5P.js");
|
|
3520
3550
|
await run(options, () => collectAgentStatus(), statusLines);
|
|
3521
3551
|
});
|
|
3522
3552
|
const doctor = new Command48("doctor").description(
|
|
3523
3553
|
"Check that the agent can start: Node and the bundled runtime, wallet and policy, channels, API, sandbox broker, host keys, xgate and RPC. Reads only."
|
|
3524
3554
|
).option("--json", "Print the versioned JSON envelope").action(async (options) => {
|
|
3525
|
-
const { runDoctor, doctorLines } = await import("./doctor-
|
|
3555
|
+
const { runDoctor, doctorLines } = await import("./doctor-26YOWQOH.js");
|
|
3526
3556
|
const report = await run(options, () => runDoctor(), doctorLines);
|
|
3527
3557
|
if (report && !report.ok) process.exitCode = 1;
|
|
3528
3558
|
});
|
|
@@ -3533,7 +3563,7 @@ function agentManagementCommands() {
|
|
|
3533
3563
|
"Reconcile the open purchases of this channel, as status lists it; also reaches retired channels"
|
|
3534
3564
|
).option("--json", "Print the versioned JSON envelope").action(
|
|
3535
3565
|
async (invocationId, options) => {
|
|
3536
|
-
const { reconcileChannelPurchases, reconcileInvocation } = await import("./reconcile-
|
|
3566
|
+
const { reconcileChannelPurchases, reconcileInvocation } = await import("./reconcile-MALCM3NB.js");
|
|
3537
3567
|
const choice = { rail: options.rail, channel: options.channel };
|
|
3538
3568
|
if (invocationId !== void 0) {
|
|
3539
3569
|
await run(
|
|
@@ -3591,7 +3621,7 @@ function agentManagementCommands() {
|
|
|
3591
3621
|
`Not a USDC amount: ${options.amount} (digits, at most 6 decimals)`
|
|
3592
3622
|
);
|
|
3593
3623
|
}
|
|
3594
|
-
const { openAgentChannels, requestTopUp, selectRail, withdrawalHatch } = await import("./channels-
|
|
3624
|
+
const { openAgentChannels, requestTopUp, selectRail, withdrawalHatch } = await import("./channels-OBJUNCZX.js");
|
|
3595
3625
|
const { rails } = await openAgentChannels();
|
|
3596
3626
|
const result = await requestTopUp(selectRail(rails, options.rail), amount);
|
|
3597
3627
|
return {
|
|
@@ -3615,8 +3645,8 @@ function agentManagementCommands() {
|
|
|
3615
3645
|
async () => {
|
|
3616
3646
|
await requireExperimental();
|
|
3617
3647
|
const { AGENT_VIEW_VERSION } = await import("./budget-view-J6L7X6EY.js");
|
|
3618
|
-
const { closeChannel, openAgentChannels, selectChannel } = await import("./channels-
|
|
3619
|
-
const { reconcileLeasedPurchase } = await import("./reconcile-
|
|
3648
|
+
const { closeChannel, openAgentChannels, selectChannel } = await import("./channels-OBJUNCZX.js");
|
|
3649
|
+
const { reconcileLeasedPurchase } = await import("./reconcile-MALCM3NB.js");
|
|
3620
3650
|
const opened = await openAgentChannels();
|
|
3621
3651
|
const { rail, retired } = selectChannel(opened, options);
|
|
3622
3652
|
const result = await closeChannel(
|
|
@@ -3687,7 +3717,7 @@ function agentManagementCommands() {
|
|
|
3687
3717
|
options,
|
|
3688
3718
|
async () => {
|
|
3689
3719
|
await requireExperimental();
|
|
3690
|
-
const { runPull } = await import("./sync-pull-
|
|
3720
|
+
const { runPull } = await import("./sync-pull-N6OTHBWR.js");
|
|
3691
3721
|
const { terminalPrompter } = await import("./prompter-LSICEYSQ.js");
|
|
3692
3722
|
return runPull(options, {
|
|
3693
3723
|
interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY) && !options.json,
|
|
@@ -3750,7 +3780,7 @@ for (const command of agentManagementCommands()) {
|
|
|
3750
3780
|
|
|
3751
3781
|
// src/commands/agents.ts
|
|
3752
3782
|
import { Command as Command50 } from "commander";
|
|
3753
|
-
var agentsCommand = new Command50("agents").description("Browse the agent directory").option("--sort <order>", "Sort order: reputation or tasks", "reputation").option("--skill <tag>", "Filter by skill tag").option("--search <query>", "Search by agentId or wallet address").option("--limit <n>", "Maximum results to return", "20").action(async (opts) => {
|
|
3783
|
+
var agentsCommand = new Command50("agents").description("Browse the agent directory on the selected --network").option("--sort <order>", "Sort order: reputation or tasks", "reputation").option("--skill <tag>", "Filter by skill tag").option("--search <query>", "Search by agentId or wallet address").option("--limit <n>", "Maximum results to return", "20").action(async (opts) => {
|
|
3754
3784
|
const params = new URLSearchParams();
|
|
3755
3785
|
if (opts.sort) params.set("sort", opts.sort);
|
|
3756
3786
|
if (opts.skill) params.set("skill", opts.skill);
|
|
@@ -3862,7 +3892,7 @@ var walletBalanceCommand = new Command54("balance").description("Show the wallet
|
|
|
3862
3892
|
|
|
3863
3893
|
// src/commands/wallet/import.ts
|
|
3864
3894
|
import { Command as Command55 } from "commander";
|
|
3865
|
-
import { createInterface as
|
|
3895
|
+
import { createInterface as createInterface4 } from "readline";
|
|
3866
3896
|
import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
|
|
3867
3897
|
function normalizePrivateKey(raw) {
|
|
3868
3898
|
const hex = raw.startsWith("0x") ? raw.slice(2) : raw;
|
|
@@ -3873,7 +3903,7 @@ function normalizePrivateKey(raw) {
|
|
|
3873
3903
|
}
|
|
3874
3904
|
function promptHiddenInput(prompt) {
|
|
3875
3905
|
return new Promise((resolve) => {
|
|
3876
|
-
const rl =
|
|
3906
|
+
const rl = createInterface4({
|
|
3877
3907
|
input: process.stdin,
|
|
3878
3908
|
output: process.stdout,
|
|
3879
3909
|
terminal: true
|
|
@@ -3902,7 +3932,10 @@ var walletImportCommand = new Command55("import").description("Import an existin
|
|
|
3902
3932
|
).action(async (opts) => {
|
|
3903
3933
|
if (await keystoreExists()) {
|
|
3904
3934
|
const keystore = await loadKeystore();
|
|
3905
|
-
printResult({
|
|
3935
|
+
printResult({
|
|
3936
|
+
address: keystore.walletAddress,
|
|
3937
|
+
agentId: agentIdForChain(keystore, selectedNetwork().chainId)
|
|
3938
|
+
});
|
|
3906
3939
|
return;
|
|
3907
3940
|
}
|
|
3908
3941
|
let rawKey;
|
|
@@ -3950,6 +3983,7 @@ var walletImportCommand = new Command55("import").description("Import an existin
|
|
|
3950
3983
|
deviceId,
|
|
3951
3984
|
apiToken,
|
|
3952
3985
|
agentId,
|
|
3986
|
+
...agentId ? { agentIds: { [String(selectedNetwork().chainId)]: agentId } } : {},
|
|
3953
3987
|
keyServerUrl: apiUrl(),
|
|
3954
3988
|
network: networkToStamp(),
|
|
3955
3989
|
...legalAcceptance ? {
|
|
@@ -3962,7 +3996,9 @@ var walletImportCommand = new Command55("import").description("Import an existin
|
|
|
3962
3996
|
agentId = await pollAgentId(address);
|
|
3963
3997
|
if (agentId) {
|
|
3964
3998
|
const keystore = await loadKeystore();
|
|
3965
|
-
await saveKeystore(
|
|
3999
|
+
await saveKeystore(
|
|
4000
|
+
withAgentIdForChain({ ...keystore, agentId }, selectedNetwork().chainId, agentId)
|
|
4001
|
+
);
|
|
3966
4002
|
}
|
|
3967
4003
|
}
|
|
3968
4004
|
if (keySource === "flag") {
|
|
@@ -4282,7 +4318,11 @@ var withdrawDreamsCommand = new Command62("withdraw-dreams").description("Withdr
|
|
|
4282
4318
|
withChainId(`/api/wallet/dreams-balance?address=${workerAddress}`)
|
|
4283
4319
|
);
|
|
4284
4320
|
if (!balance.hookAddress || balance.chainId === void 0) {
|
|
4285
|
-
|
|
4321
|
+
const chainId = selectedNetwork().chainId;
|
|
4322
|
+
const chain = isTaskmarketChainId(chainId) ? taskmarketChain(chainId) : void 0;
|
|
4323
|
+
printError(
|
|
4324
|
+
chain && !chain.features.dreamsRewards ? `${chain.name} has no DREAMS rewards` : "DREAMS rewards are not configured on this server"
|
|
4325
|
+
);
|
|
4286
4326
|
return;
|
|
4287
4327
|
}
|
|
4288
4328
|
if (!isTaskmarketChainId(balance.chainId)) {
|
|
@@ -5796,6 +5836,33 @@ function sleepOrAbort(ms, signal) {
|
|
|
5796
5836
|
});
|
|
5797
5837
|
}
|
|
5798
5838
|
var MAX_SEEN_TASK_IDS = 2e3;
|
|
5839
|
+
function buildDaemonTaskParams(filters, chainId) {
|
|
5840
|
+
const params = new URLSearchParams();
|
|
5841
|
+
params.set("status", "open");
|
|
5842
|
+
params.set("limit", "50");
|
|
5843
|
+
params.set("chainId", String(chainId));
|
|
5844
|
+
if (typeof filters.mode === "string") {
|
|
5845
|
+
params.set("mode", filters.mode);
|
|
5846
|
+
}
|
|
5847
|
+
const tagsValue = filters.tags;
|
|
5848
|
+
if (typeof tagsValue === "string") {
|
|
5849
|
+
params.set("tags", tagsValue);
|
|
5850
|
+
} else if (Array.isArray(tagsValue)) {
|
|
5851
|
+
params.set("tags", tagsValue.join(","));
|
|
5852
|
+
}
|
|
5853
|
+
return params;
|
|
5854
|
+
}
|
|
5855
|
+
function buildDaemonAuctionParams(chainId) {
|
|
5856
|
+
return new URLSearchParams({
|
|
5857
|
+
mode: "auction",
|
|
5858
|
+
status: "open",
|
|
5859
|
+
limit: "50",
|
|
5860
|
+
chainId: String(chainId)
|
|
5861
|
+
});
|
|
5862
|
+
}
|
|
5863
|
+
function daemonInboxPath(address, chainId) {
|
|
5864
|
+
return `/api/agents/inbox?address=${encodeURIComponent(address)}&chainId=${chainId}`;
|
|
5865
|
+
}
|
|
5799
5866
|
var daemonCommand = new Command69("daemon").description("Long-running agent daemon: XMTP stream, heartbeats, and task polling").option("--heartbeat-interval <ms>", "Heartbeat interval in milliseconds", "1800000").option("--inbox-interval <ms>", "Inbox poll interval in milliseconds", "15000").option("--task-interval <ms>", "New task poll interval in milliseconds", "15000").option(
|
|
5800
5867
|
"--auction-poll-interval <ms>",
|
|
5801
5868
|
"Poll interval for clock-based auction tasks (dutch/reverse_dutch) in milliseconds",
|
|
@@ -5900,24 +5967,10 @@ var daemonCommand = new Command69("daemon").description("Long-running agent daem
|
|
|
5900
5967
|
const taskPollLoop = async () => {
|
|
5901
5968
|
const knownStatuses = /* @__PURE__ */ new Map();
|
|
5902
5969
|
const seenTaskIds = /* @__PURE__ */ new Set();
|
|
5903
|
-
const buildTaskParams = () =>
|
|
5904
|
-
const params = new URLSearchParams();
|
|
5905
|
-
params.set("status", "open");
|
|
5906
|
-
params.set("limit", "50");
|
|
5907
|
-
if (typeof taskFilters.mode === "string") {
|
|
5908
|
-
params.set("mode", taskFilters.mode);
|
|
5909
|
-
}
|
|
5910
|
-
const tagsValue = taskFilters.tags;
|
|
5911
|
-
if (typeof tagsValue === "string") {
|
|
5912
|
-
params.set("tags", tagsValue);
|
|
5913
|
-
} else if (Array.isArray(tagsValue)) {
|
|
5914
|
-
params.set("tags", tagsValue.join(","));
|
|
5915
|
-
}
|
|
5916
|
-
return params;
|
|
5917
|
-
};
|
|
5970
|
+
const buildTaskParams = () => buildDaemonTaskParams(taskFilters, selectedNetwork().chainId);
|
|
5918
5971
|
try {
|
|
5919
5972
|
const inbox = await apiGet(
|
|
5920
|
-
|
|
5973
|
+
daemonInboxPath(address, selectedNetwork().chainId)
|
|
5921
5974
|
);
|
|
5922
5975
|
for (const task of [...inbox.asRequester, ...inbox.asWorker]) {
|
|
5923
5976
|
knownStatuses.set(task.id, task.status);
|
|
@@ -5937,7 +5990,7 @@ var daemonCommand = new Command69("daemon").description("Long-running agent daem
|
|
|
5937
5990
|
if (stopped) break;
|
|
5938
5991
|
try {
|
|
5939
5992
|
const inbox = await apiGet(
|
|
5940
|
-
|
|
5993
|
+
daemonInboxPath(address, selectedNetwork().chainId)
|
|
5941
5994
|
);
|
|
5942
5995
|
const allTasks = [...inbox.asRequester, ...inbox.asWorker];
|
|
5943
5996
|
const nextStatuses = /* @__PURE__ */ new Map();
|
|
@@ -5950,7 +6003,9 @@ var daemonCommand = new Command69("daemon").description("Long-running agent daem
|
|
|
5950
6003
|
const role = isRequester ? "requester" : "worker";
|
|
5951
6004
|
let pendingActions = [];
|
|
5952
6005
|
try {
|
|
5953
|
-
const detail = await apiGet(
|
|
6006
|
+
const detail = await apiGet(
|
|
6007
|
+
`/api/tasks/${change.taskId}?chainId=${selectedNetwork().chainId}`
|
|
6008
|
+
);
|
|
5954
6009
|
pendingActions = detail.pendingActions ?? [];
|
|
5955
6010
|
} catch {
|
|
5956
6011
|
}
|
|
@@ -6025,11 +6080,7 @@ var daemonCommand = new Command69("daemon").description("Long-running agent daem
|
|
|
6025
6080
|
let cursor;
|
|
6026
6081
|
let hasMore = true;
|
|
6027
6082
|
while (hasMore) {
|
|
6028
|
-
const params =
|
|
6029
|
-
mode: "auction",
|
|
6030
|
-
status: "open",
|
|
6031
|
-
limit: "50"
|
|
6032
|
-
});
|
|
6083
|
+
const params = buildDaemonAuctionParams(selectedNetwork().chainId);
|
|
6033
6084
|
if (cursor) params.set("cursor", cursor);
|
|
6034
6085
|
const result = await apiGet(`/api/tasks?${params.toString()}`);
|
|
6035
6086
|
for (const task of result.tasks) {
|
|
@@ -6700,7 +6751,7 @@ import { Command as Command93 } from "commander";
|
|
|
6700
6751
|
|
|
6701
6752
|
// src/commands/x402/payments.ts
|
|
6702
6753
|
import { Command as Command90, Option as Option4 } from "commander";
|
|
6703
|
-
import { createInterface as
|
|
6754
|
+
import { createInterface as createInterface5 } from "readline";
|
|
6704
6755
|
var PAYMENT_STATES = [
|
|
6705
6756
|
"reserved",
|
|
6706
6757
|
"approval_pending",
|
|
@@ -6715,7 +6766,7 @@ var PAYMENT_STATES = [
|
|
|
6715
6766
|
];
|
|
6716
6767
|
async function confirmManualResolution() {
|
|
6717
6768
|
if (!process.stdin.isTTY) throw new Error("Manual resolution requires an interactive TTY");
|
|
6718
|
-
const readline =
|
|
6769
|
+
const readline = createInterface5({ input: process.stdin, output: process.stderr });
|
|
6719
6770
|
const answer = await new Promise(
|
|
6720
6771
|
(resolve) => readline.question(
|
|
6721
6772
|
"Manual resolution changes local spending accounting. Type resolve to continue: ",
|
|
@@ -6755,7 +6806,7 @@ x402PaymentsCommand.command("resolve").description("Manually record an externall
|
|
|
6755
6806
|
// src/commands/x402/policy.ts
|
|
6756
6807
|
import { promises as fs4 } from "fs";
|
|
6757
6808
|
import { Command as Command91 } from "commander";
|
|
6758
|
-
import { createInterface as
|
|
6809
|
+
import { createInterface as createInterface6 } from "readline";
|
|
6759
6810
|
async function confirmUnattendedRule(rule) {
|
|
6760
6811
|
if (!process.stdin.isTTY) {
|
|
6761
6812
|
throw new Error("Authorizing an unattended policy rule requires an interactive TTY");
|
|
@@ -6773,7 +6824,7 @@ async function confirmUnattendedRule(rule) {
|
|
|
6773
6824
|
].join("\n")}
|
|
6774
6825
|
`
|
|
6775
6826
|
);
|
|
6776
|
-
const readline =
|
|
6827
|
+
const readline = createInterface6({ input: process.stdin, output: process.stderr });
|
|
6777
6828
|
const answer = await new Promise(
|
|
6778
6829
|
(resolve) => readline.question("Type authorize to grant unattended spending: ", resolve)
|
|
6779
6830
|
);
|
|
@@ -10738,7 +10789,7 @@ setLastErrorCliVersion(version);
|
|
|
10738
10789
|
program.name("taskmarket").description("Taskmarket CLI for AI agents").version(version);
|
|
10739
10790
|
program.option(
|
|
10740
10791
|
"--network <name>",
|
|
10741
|
-
`Network to use: ${NETWORK_NAMES.join(", ")} (
|
|
10792
|
+
`Network to use: ${NETWORK_NAMES.join(", ")} (else TASKMARKET_NETWORK, then the keystore's network; there is no default)`
|
|
10742
10793
|
).hook("preAction", async (thisCommand) => {
|
|
10743
10794
|
const { network } = thisCommand.opts();
|
|
10744
10795
|
setSelectedNetwork(
|