@lucid-agents/taskmarket 1.17.2 → 1.18.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 +54 -27
- package/dist/agent-compatibility.json +1 -1
- package/dist/{budget-view-XKZC3GY5.js → budget-view-JPZ7HWR2.js} +1 -1
- package/dist/{channels-JF4Q5KG3.js → channels-544VRSKF.js} +4 -3
- package/dist/chunk-2QJMUHDT.js +351 -0
- package/dist/{launch-2U3KFTFD.js → chunk-64HQ7ZF2.js} +4977 -2385
- package/dist/chunk-75LS6XS6.js +10302 -0
- package/dist/{chunk-73RXOYME.js → chunk-EB6OJBF5.js} +5 -0
- package/dist/chunk-ESPAXW2P.js +831 -0
- package/dist/chunk-JJUF3KZY.js +447 -0
- package/dist/chunk-L6ZVRENW.js +868 -0
- package/dist/{chunk-GJQUALXN.js → chunk-MO5KMUTL.js} +106 -29
- package/dist/chunk-S4A6V3J3.js +7518 -0
- package/dist/{chunk-52Q2DCZN.js → chunk-W7CXEYST.js} +23 -23
- package/dist/chunk-ZIC2YCLV.js +65 -0
- package/dist/{doctor-7TWLIJWW.js → doctor-5FUGI42V.js} +13 -10
- package/dist/index.js +2064 -712
- package/dist/launch-C5HUFUU2.js +6364 -0
- package/dist/pi-extensions/remote-tools.cjs +74 -3
- package/dist/pi-extensions/xgate.cjs +1039 -25
- package/dist/{status-5IMULBQQ.js → prompter-LSICEYSQ.js} +3 -12
- package/dist/reconcile-Q7XFHDQQ.js +194 -0
- package/dist/status-SDLSTJIA.js +28 -0
- package/dist/sync-pull-TKM4EDGH.js +409 -0
- package/package.json +1 -1
- package/dist/chunk-FRV3ZHUR.js +0 -16141
- package/dist/chunk-LDCFKFF6.js +0 -154
- package/dist/chunk-XXD7TWLP.js +0 -181
- package/dist/reconcile-XZR2UYSW.js +0 -83
|
@@ -6,21 +6,23 @@ import {
|
|
|
6
6
|
createBaseChannelRpcReader,
|
|
7
7
|
createWalletAccountFromKeystore,
|
|
8
8
|
createX402Allocations,
|
|
9
|
-
getTaskmarketHome,
|
|
10
9
|
getX402JournalPath,
|
|
11
10
|
getX402PolicyPath,
|
|
12
|
-
keystoreExists,
|
|
13
11
|
listX402Payments,
|
|
14
|
-
loadKeystore,
|
|
15
12
|
loadX402Policy,
|
|
16
13
|
rpcUrlForNetwork
|
|
17
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-S4A6V3J3.js";
|
|
18
15
|
import {
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
getTaskmarketHome,
|
|
17
|
+
keystoreExists,
|
|
18
|
+
loadKeystore
|
|
19
|
+
} from "./chunk-75LS6XS6.js";
|
|
21
20
|
import {
|
|
22
21
|
formatUsdc
|
|
23
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-EB6OJBF5.js";
|
|
23
|
+
import {
|
|
24
|
+
AgentLaunchError
|
|
25
|
+
} from "./chunk-YM4S6IE4.js";
|
|
24
26
|
|
|
25
27
|
// src/lib/agent/channels.ts
|
|
26
28
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
@@ -334,7 +336,11 @@ async function createAgentRails(options) {
|
|
|
334
336
|
budgetAmount: rail.limits.total,
|
|
335
337
|
depositAmount: rail.limits.deposit,
|
|
336
338
|
policyRuleId: rail.policyRuleId,
|
|
337
|
-
...options.fetch ? { fetch: options.fetch } : {}
|
|
339
|
+
...options.fetch ? { fetch: options.fetch } : {},
|
|
340
|
+
confirmationWait: {
|
|
341
|
+
...options.confirmationWait,
|
|
342
|
+
...options.onConfirmationWait ? { onWait: (progress) => options.onConfirmationWait(rail, progress) } : {}
|
|
343
|
+
}
|
|
338
344
|
});
|
|
339
345
|
const transport = createTaskMarketTransport({
|
|
340
346
|
payer,
|
|
@@ -438,10 +444,12 @@ function createAgentTransport(rails) {
|
|
|
438
444
|
};
|
|
439
445
|
}
|
|
440
446
|
async function reconcileLeftoverOperations(rails, log = () => void 0) {
|
|
441
|
-
|
|
447
|
+
const usable = [];
|
|
448
|
+
const blocked = [];
|
|
449
|
+
for (const entry of rails) {
|
|
450
|
+
const { rail, payer } = entry;
|
|
442
451
|
let pending = (await payer.channelStatus()).pendingOperation;
|
|
443
|
-
if (
|
|
444
|
-
if (pending.kind === "payment") {
|
|
452
|
+
if (pending?.kind === "payment") {
|
|
445
453
|
log(`Reconciling payment ${pending.id} left on rail ${rail.id}`);
|
|
446
454
|
try {
|
|
447
455
|
await payer.reconcile(pending.id);
|
|
@@ -451,13 +459,22 @@ async function reconcileLeftoverOperations(rails, log = () => void 0) {
|
|
|
451
459
|
);
|
|
452
460
|
}
|
|
453
461
|
pending = (await payer.channelStatus()).pendingOperation;
|
|
454
|
-
if (!pending) continue;
|
|
455
462
|
}
|
|
463
|
+
if (!pending) {
|
|
464
|
+
usable.push(entry);
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
const reason = `The ${rail.id} channel has an unresolved ${pending.kind} operation ${pending.id} from an earlier session; it must be reconciled (taskmarket agent reconcile ${pending.id}) before anything else is bought on that channel.`;
|
|
468
|
+
log(`${reason} Its models are left out of this session.`);
|
|
469
|
+
blocked.push(reason);
|
|
470
|
+
}
|
|
471
|
+
if (usable.length === 0 && blocked.length > 0) {
|
|
456
472
|
throw new AgentLaunchError(
|
|
457
473
|
"channel_operation_pending",
|
|
458
|
-
|
|
474
|
+
`${blocked.join(" ")} Try again later.`
|
|
459
475
|
);
|
|
460
476
|
}
|
|
477
|
+
return usable;
|
|
461
478
|
}
|
|
462
479
|
|
|
463
480
|
// src/lib/agent/policy.ts
|
|
@@ -469,7 +486,7 @@ var XGATE_ROUTES = [
|
|
|
469
486
|
"/providers/anthropic/v1/messages",
|
|
470
487
|
"/providers/openai/v1/responses"
|
|
471
488
|
];
|
|
472
|
-
var WORKSPACE_CONSENT_VERSION = "boat-eu-2026-10";
|
|
489
|
+
var WORKSPACE_CONSENT_VERSION = "boat-eu-2026-10-sync";
|
|
473
490
|
var address = z.string().regex(/^0x[0-9a-fA-F]{40}$/, "expected a 0x-prefixed 20-byte address");
|
|
474
491
|
var atomic2 = z.string().regex(/^(0|[1-9][0-9]{0,30})$/, "expected an integer amount string");
|
|
475
492
|
var positiveAtomic = atomic2.refine((value) => BigInt(value) > 0n, "expected an amount above 0");
|
|
@@ -669,15 +686,31 @@ async function assessAgentPolicy(policy, options) {
|
|
|
669
686
|
}
|
|
670
687
|
return { reasons, usage };
|
|
671
688
|
}
|
|
672
|
-
function
|
|
673
|
-
if (requested
|
|
674
|
-
if (!policy.models.includes(requested)) {
|
|
689
|
+
function requireApprovedModel(policy, requested) {
|
|
690
|
+
if (requested !== void 0 && !policy.models.includes(requested)) {
|
|
675
691
|
throw new AgentLaunchError(
|
|
676
692
|
"model_not_allowed",
|
|
677
693
|
`Model ${requested} is not in the approved spending policy (${policy.models.join(", ")})`
|
|
678
694
|
);
|
|
679
695
|
}
|
|
680
|
-
|
|
696
|
+
}
|
|
697
|
+
function planSessionModels(options) {
|
|
698
|
+
const { approved, offered, requested, previous } = options;
|
|
699
|
+
const unavailable = approved.filter((model) => !offered.includes(model));
|
|
700
|
+
if (offered.length === 0) {
|
|
701
|
+
throw new AgentLaunchError(
|
|
702
|
+
"no_qualified_models",
|
|
703
|
+
`None of the approved models (${approved.join(", ")}) is qualified by xgate on a route the policy pays for`
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
if (requested !== void 0 && !offered.includes(requested)) {
|
|
707
|
+
throw new AgentLaunchError(
|
|
708
|
+
"model_not_offered",
|
|
709
|
+
`Model ${requested} is approved, but xgate does not offer it on a route a usable rail of the policy pays for, so this session cannot buy it. This session offers ${offered.join(", ")}`
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
const start = requested ?? (previous !== void 0 && offered.includes(previous) ? previous : offered[0]);
|
|
713
|
+
return { start, unavailable };
|
|
681
714
|
}
|
|
682
715
|
|
|
683
716
|
// src/lib/agent/retired.ts
|
|
@@ -738,7 +771,9 @@ async function openAgentChannels(options = {}) {
|
|
|
738
771
|
models: options.models ? options.models(policy) : [...policy.models],
|
|
739
772
|
walletAddress: keystore.walletAddress,
|
|
740
773
|
getAccount,
|
|
741
|
-
...options.fetch ? { fetch: options.fetch } : {}
|
|
774
|
+
...options.fetch ? { fetch: options.fetch } : {},
|
|
775
|
+
...options.onConfirmationWait ? { onConfirmationWait: options.onConfirmationWait } : {},
|
|
776
|
+
...options.confirmationWait ? { confirmationWait: options.confirmationWait } : {}
|
|
742
777
|
};
|
|
743
778
|
const rails = await createAgentRails(common);
|
|
744
779
|
const retired = await createAgentRails({
|
|
@@ -863,9 +898,7 @@ async function uncertainPurchases(rails, statuses = /* @__PURE__ */ new Map()) {
|
|
|
863
898
|
for (const record2 of records) {
|
|
864
899
|
if (!record2.invocationId || record2.rail?.id !== BASE_CHANNEL_RAIL_ID) continue;
|
|
865
900
|
if (!UNDECIDED.has(record2.state)) continue;
|
|
866
|
-
const rail = rails.find(
|
|
867
|
-
(r) => record2.origin === r.rail.origin && record2.pathname === r.rail.route
|
|
868
|
-
);
|
|
901
|
+
const rail = rails.find((r) => record2.funding?.sessionKey === r.payer.sessionKey);
|
|
869
902
|
if (!rail) continue;
|
|
870
903
|
const lease = statuses.get(rail.rail.id)?.pendingOperation;
|
|
871
904
|
found.push({
|
|
@@ -955,6 +988,34 @@ function outcomeOf(operation) {
|
|
|
955
988
|
if (operation.state === "failed") return "failed";
|
|
956
989
|
return "pending";
|
|
957
990
|
}
|
|
991
|
+
var REFUND_WAIT_TIMEOUT_MS = 9e4;
|
|
992
|
+
var REFUND_WAIT_INTERVAL_MS = 3e3;
|
|
993
|
+
async function awaitRefund(rail, operation, wait = {}) {
|
|
994
|
+
const timeoutMs = wait.timeoutMs ?? REFUND_WAIT_TIMEOUT_MS;
|
|
995
|
+
const intervalMs = Math.max(1, wait.intervalMs ?? REFUND_WAIT_INTERVAL_MS);
|
|
996
|
+
const sleep = wait.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
997
|
+
let current = operation;
|
|
998
|
+
let waitedMs = 0;
|
|
999
|
+
while ((current.state === "dispatched" || current.state === "unknown") && current.transaction && waitedMs < timeoutMs) {
|
|
1000
|
+
try {
|
|
1001
|
+
wait.onWait?.({
|
|
1002
|
+
transaction: current.transaction,
|
|
1003
|
+
amount: current.amount,
|
|
1004
|
+
waitedMs,
|
|
1005
|
+
timeoutMs
|
|
1006
|
+
});
|
|
1007
|
+
} catch {
|
|
1008
|
+
}
|
|
1009
|
+
const step = Math.min(intervalMs, timeoutMs - waitedMs);
|
|
1010
|
+
await sleep(step);
|
|
1011
|
+
waitedMs += step;
|
|
1012
|
+
try {
|
|
1013
|
+
current = await rail.payer.reconcileOperation(current.operationId);
|
|
1014
|
+
} catch {
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
return current;
|
|
1018
|
+
}
|
|
958
1019
|
async function closeSession(allocationId2) {
|
|
959
1020
|
try {
|
|
960
1021
|
await allocationsReader().close(allocationId2);
|
|
@@ -975,7 +1036,11 @@ function closeLines(channel) {
|
|
|
975
1036
|
}
|
|
976
1037
|
async function closeChannel(rail, confirm, options = {}) {
|
|
977
1038
|
const retired = options.retired ?? false;
|
|
978
|
-
|
|
1039
|
+
let status = await rail.payer.channelStatus();
|
|
1040
|
+
if (status.pendingOperation?.kind === "payment" && options.reconcilePurchase) {
|
|
1041
|
+
await options.reconcilePurchase(status.pendingOperation.id);
|
|
1042
|
+
status = await rail.payer.channelStatus();
|
|
1043
|
+
}
|
|
979
1044
|
const channel = await channelView(rail, status, { retired });
|
|
980
1045
|
const result = async (outcome, operation2, reconciled) => {
|
|
981
1046
|
const after = operation2 ? await channelView(rail, void 0, { retired }) : channel;
|
|
@@ -1002,7 +1067,11 @@ async function closeChannel(rail, confirm, options = {}) {
|
|
|
1002
1067
|
if (status.closed) return result("closed", null, false);
|
|
1003
1068
|
const lease = status.pendingOperation;
|
|
1004
1069
|
if (lease?.kind === "lifecycle") {
|
|
1005
|
-
const operation2 = await
|
|
1070
|
+
const operation2 = await awaitRefund(
|
|
1071
|
+
rail,
|
|
1072
|
+
await rail.payer.reconcileOperation(lease.id),
|
|
1073
|
+
options.wait
|
|
1074
|
+
);
|
|
1006
1075
|
return result(outcomeOf(operation2), operation2, true);
|
|
1007
1076
|
}
|
|
1008
1077
|
if (lease?.kind === "payment") {
|
|
@@ -1026,10 +1095,17 @@ async function closeChannel(rail, confirm, options = {}) {
|
|
|
1026
1095
|
if (!await confirm(closeLines(channel))) {
|
|
1027
1096
|
throw new AgentLaunchError("not_approved", "The channel was not closed");
|
|
1028
1097
|
}
|
|
1029
|
-
const
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1098
|
+
const operationId = `agent-close-${randomUUID2()}`;
|
|
1099
|
+
let operation;
|
|
1100
|
+
try {
|
|
1101
|
+
operation = await rail.payer.refund({ operationId, close: true });
|
|
1102
|
+
} catch (error) {
|
|
1103
|
+
if (error.code !== "outcome_uncertain") throw error;
|
|
1104
|
+
const recorded = await rail.payer.reconcileOperation(operationId).catch(() => void 0);
|
|
1105
|
+
if (!recorded || recorded.state !== "dispatched" && recorded.state !== "unknown") throw error;
|
|
1106
|
+
operation = recorded;
|
|
1107
|
+
}
|
|
1108
|
+
operation = await awaitRefund(rail, operation, options.wait);
|
|
1033
1109
|
return result(outcomeOf(operation), operation, false);
|
|
1034
1110
|
}
|
|
1035
1111
|
|
|
@@ -1047,7 +1123,8 @@ export {
|
|
|
1047
1123
|
loadAgentPolicy,
|
|
1048
1124
|
saveAgentPolicy,
|
|
1049
1125
|
assessAgentPolicy,
|
|
1050
|
-
|
|
1126
|
+
requireApprovedModel,
|
|
1127
|
+
planSessionModels,
|
|
1051
1128
|
settledRetiredRails,
|
|
1052
1129
|
openAgentChannels,
|
|
1053
1130
|
selectChannel,
|