opencrowd 0.8.0 → 0.9.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/bundle/opencrowd.js +201 -19
- package/package.json +1 -1
package/bundle/opencrowd.js
CHANGED
|
@@ -16182,6 +16182,8 @@ var init_financial_state = __esm({
|
|
|
16182
16182
|
current_run: external_exports.object({
|
|
16183
16183
|
inference_spent_usdc: usdc,
|
|
16184
16184
|
service_spent_usdc: usdc,
|
|
16185
|
+
/** Fees of moves between the agent's own networks started by this run (included in total_spent_usdc). */
|
|
16186
|
+
transfer_fees_usdc: usdc.optional(),
|
|
16185
16187
|
total_spent_usdc: usdc,
|
|
16186
16188
|
reserved_usdc: usdc,
|
|
16187
16189
|
budget_limit_usdc: usdc,
|
|
@@ -16995,6 +16997,14 @@ function summarizeToolInput(name, args) {
|
|
|
16995
16997
|
return pick3({ url: text(args.url), method: text(args.method), max_cost_cents: text(args.max_cost_cents) });
|
|
16996
16998
|
case "review_paid_service":
|
|
16997
16999
|
return pick3({ purchase_id: text(args.purchase_id), rating: text(args.rating) });
|
|
17000
|
+
case "bridge_usdc":
|
|
17001
|
+
return pick3({
|
|
17002
|
+
from: text(args.from),
|
|
17003
|
+
to: text(args.to),
|
|
17004
|
+
amount_usd: text(args.amount_usd),
|
|
17005
|
+
quote_only: args.quote_only === true ? "true" : void 0,
|
|
17006
|
+
transfer_id: text(args.transfer_id)
|
|
17007
|
+
});
|
|
16998
17008
|
default:
|
|
16999
17009
|
return void 0;
|
|
17000
17010
|
}
|
|
@@ -57169,6 +57179,8 @@ var init_discovery = __esm({
|
|
|
57169
57179
|
payable: !!offer,
|
|
57170
57180
|
authMode: advisory.authMode,
|
|
57171
57181
|
network: offer?.network_name ? NETWORK_CAIP2[offer.network_name] : void 0,
|
|
57182
|
+
// The payee of the selected offer: receipts on some rails (x402 Solana) omit it, and reviews need it.
|
|
57183
|
+
...offer?.pay_to ? { pay_to: offer.pay_to } : {},
|
|
57172
57184
|
price_usd: offer ? ceiling ?? 0 : read ? 0 : void 0,
|
|
57173
57185
|
...offers.length ? { offers: offers.map((candidate) => ({
|
|
57174
57186
|
network: candidate.network_name ?? candidate.network,
|
|
@@ -58005,7 +58017,7 @@ var init_gateway = __esm({
|
|
|
58005
58017
|
case "read_service":
|
|
58006
58018
|
return this.options.agentcash.read ? await this.options.agentcash.read(String(args.url ?? "")) : { ok: false, error: "Authenticated reads are unavailable" };
|
|
58007
58019
|
case "bridge_usdc":
|
|
58008
|
-
return await this.bridgeUsdc(args);
|
|
58020
|
+
return await this.bridgeUsdc(args, operationId);
|
|
58009
58021
|
default:
|
|
58010
58022
|
return { ok: false, error: `unknown gateway tool: ${name}` };
|
|
58011
58023
|
}
|
|
@@ -58084,11 +58096,13 @@ var init_gateway = __esm({
|
|
|
58084
58096
|
const evidence = await this.serviceEvidence(endpoint);
|
|
58085
58097
|
const rail = railFromSchema(schema.data);
|
|
58086
58098
|
const priceCeilingCents = priceCeilingFromSchema(schema.data);
|
|
58099
|
+
const payTo = schema.data && typeof schema.data === "object" && typeof schema.data.pay_to === "string" ? schema.data.pay_to : void 0;
|
|
58087
58100
|
await this.rememberInspection(inspectionKey(endpoint, method), {
|
|
58088
58101
|
endpoint,
|
|
58089
58102
|
method,
|
|
58090
58103
|
rail,
|
|
58091
58104
|
priceCeilingCents,
|
|
58105
|
+
...payTo ? { payTo } : {},
|
|
58092
58106
|
evidence,
|
|
58093
58107
|
inspectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
58094
58108
|
});
|
|
@@ -58218,7 +58232,9 @@ var init_gateway = __esm({
|
|
|
58218
58232
|
// Confirmed paid successes AND paid failures require reviews; free,
|
|
58219
58233
|
// SIWX, and unknown outcomes create no paid receipt to review.
|
|
58220
58234
|
review_required: paid && supportedRail && await this.crowdcodeEnabled(),
|
|
58221
|
-
|
|
58235
|
+
// x402 Solana receipts carry no payee; CrowdCode needs it to verify a new
|
|
58236
|
+
// service, so use the inspected offer's when the payment settled on that rail.
|
|
58237
|
+
evidence: result.payment && !result.payment.payTo && inspection.payTo && railUsed === inspection.rail ? { ...result.payment, payTo: inspection.payTo } : result.payment,
|
|
58222
58238
|
notes: result.ambiguous ? `${result.ambiguityReason ?? "ambiguous"}: payment state unknown; never auto-retried` : result.error
|
|
58223
58239
|
};
|
|
58224
58240
|
await appendPurchase(session, record3);
|
|
@@ -58378,7 +58394,9 @@ var init_gateway = __esm({
|
|
|
58378
58394
|
await recordReviewSubmitted(this.options.session, purchaseId, rating);
|
|
58379
58395
|
return { ok: true, data: { purchase_id: purchaseId, review: "submitted", rating } };
|
|
58380
58396
|
}
|
|
58381
|
-
async bridgeUsdc(args) {
|
|
58397
|
+
async bridgeUsdc(args, operationId) {
|
|
58398
|
+
if (this.options.hostedSpending)
|
|
58399
|
+
return this.hostedBridge(args, operationId);
|
|
58382
58400
|
if (this.options.approvalMode === "off") {
|
|
58383
58401
|
return { ok: false, error: "financial actions are disabled (approval mode `off`)" };
|
|
58384
58402
|
}
|
|
@@ -58416,6 +58434,37 @@ var init_gateway = __esm({
|
|
|
58416
58434
|
});
|
|
58417
58435
|
return result.ok ? { ok: true, data: result.data } : { ok: false, error: result.error };
|
|
58418
58436
|
}
|
|
58437
|
+
/**
|
|
58438
|
+
* Hosted moves between the agent's own networks. The hosted gateway owns the
|
|
58439
|
+
* quote, the owner's approval policy for the fee and the signing; an
|
|
58440
|
+
* approval pause propagates as a RuntimePause from the adapter.
|
|
58441
|
+
*/
|
|
58442
|
+
async hostedBridge(args, operationId) {
|
|
58443
|
+
const transferId = stringArg(args.transfer_id);
|
|
58444
|
+
if (transferId)
|
|
58445
|
+
return this.options.agentcash.bridge({ from: "", to: "", amountUsd: 0, transferId });
|
|
58446
|
+
const from16 = stringArg(args.from)?.toLowerCase(), to = stringArg(args.to)?.toLowerCase(), amountUsd = numberArg(args.amount_usd);
|
|
58447
|
+
const networks = ["base", "solana", "tempo"];
|
|
58448
|
+
if (!from16 || !to || !networks.includes(from16) || !networks.includes(to) || from16 === to || amountUsd === void 0 || amountUsd <= 0)
|
|
58449
|
+
return { ok: false, error: "bridge_usdc requires two different networks (base, solana, tempo) and a positive amount_usd, or a transfer_id to check" };
|
|
58450
|
+
const quoteOnly = args.quote_only === true;
|
|
58451
|
+
const result = await this.options.agentcash.bridge({ from: from16, to, amountUsd, quoteOnly, operationId });
|
|
58452
|
+
if (!quoteOnly) {
|
|
58453
|
+
const fee = numberArg(result.data?.fee_usd);
|
|
58454
|
+
await appendLedgerEntry(this.options.session.ledgerPath, {
|
|
58455
|
+
session_id: this.options.session.sessionId,
|
|
58456
|
+
type: "service_call",
|
|
58457
|
+
resource_url: `hosted:transfer:${from16}->${to}`,
|
|
58458
|
+
method: "BRIDGE",
|
|
58459
|
+
quoted_cost_cents: fee === void 0 ? 0 : Math.ceil(fee * 100),
|
|
58460
|
+
charged_cost_cents: 0,
|
|
58461
|
+
status: result.ok ? "ok" : "failed",
|
|
58462
|
+
approval_mode: this.options.session.approvalMode,
|
|
58463
|
+
notes: result.ok ? "USDC moved between own networks; the fee counts in the hosted run's spending" : result.error
|
|
58464
|
+
});
|
|
58465
|
+
}
|
|
58466
|
+
return result.ok ? { ok: true, data: result.data } : { ok: false, error: result.error };
|
|
58467
|
+
}
|
|
58419
58468
|
/** Model-visible list of this session's purchases (redacted). */
|
|
58420
58469
|
async listPurchasesRedacted() {
|
|
58421
58470
|
return (await listPurchases(this.options.session)).map(redactPurchase);
|
|
@@ -59216,8 +59265,8 @@ function toolSupportFromList(value) {
|
|
|
59216
59265
|
return value.map(String).includes("tools");
|
|
59217
59266
|
}
|
|
59218
59267
|
function costCentsPer1k(value) {
|
|
59219
|
-
const
|
|
59220
|
-
const parsed = typeof
|
|
59268
|
+
const usd3 = objectValue4(value)?.usd ?? value;
|
|
59269
|
+
const parsed = typeof usd3 === "number" ? usd3 : typeof usd3 === "string" && usd3.trim() !== "" ? Number(usd3) : void 0;
|
|
59221
59270
|
if (parsed === void 0 || !Number.isFinite(parsed) || parsed < 0) {
|
|
59222
59271
|
return void 0;
|
|
59223
59272
|
}
|
|
@@ -81043,13 +81092,34 @@ var init_hosted_provider = __esm({
|
|
|
81043
81092
|
// ../../packages/agent-runtime/dist/hosted-economy.js
|
|
81044
81093
|
import { randomUUID as randomUUID7, createHash as createHash4 } from "node:crypto";
|
|
81045
81094
|
import { join as join20 } from "node:path";
|
|
81095
|
+
function describeTransferError(reply) {
|
|
81096
|
+
return reply.code ? `${reply.error ?? "transfer refused"} (${reply.code})` : reply.error ?? "transfer refused";
|
|
81097
|
+
}
|
|
81098
|
+
function describeTransfer(transfer2) {
|
|
81099
|
+
const state = stringValue5(transfer2.state) ?? "unknown";
|
|
81100
|
+
const data = {
|
|
81101
|
+
transfer_id: stringValue5(transfer2.id),
|
|
81102
|
+
state,
|
|
81103
|
+
from: stringValue5(transfer2.from),
|
|
81104
|
+
to: stringValue5(transfer2.to),
|
|
81105
|
+
amount_usd: usd(transfer2.amount_atomic),
|
|
81106
|
+
fee_usd: usd(transfer2.fee_atomic),
|
|
81107
|
+
received_usd: usd(transfer2.received_atomic),
|
|
81108
|
+
expected_received_usd: usd(transfer2.expected_received_atomic),
|
|
81109
|
+
origin_transaction: stringValue5(transfer2.origin_transaction),
|
|
81110
|
+
destination_transaction: stringValue5(transfer2.destination_transaction),
|
|
81111
|
+
failure: stringValue5(transfer2.failure),
|
|
81112
|
+
note: state === "confirmed" ? "The funds arrived on the destination network and can be spent there now." : isPending(transfer2) ? "Still moving. Check again later with bridge_usdc {transfer_id}; do not start another move meanwhile." : state === "refunded" ? "Relay refunded the move to the origin network." : "The move did not complete."
|
|
81113
|
+
};
|
|
81114
|
+
return state === "failed" ? { ok: false, data, error: `the transfer failed: ${data.failure ?? "no funds moved"}` } : { ok: true, data };
|
|
81115
|
+
}
|
|
81046
81116
|
function createHostedEconomy(options) {
|
|
81047
81117
|
const fetcher = options.fetcher ?? fetch;
|
|
81048
81118
|
const socket = { socketPath: options.socketPath, runId: options.runId, sessionId: options.sessionId };
|
|
81049
81119
|
const directory = new ServiceDirectory(fetcher, (options.crowdcodeBase ?? DEFAULT_CROWDCODE_BASE).replace(/\/+$/, ""));
|
|
81050
81120
|
return new EconomyGateway({
|
|
81051
81121
|
session: options.session,
|
|
81052
|
-
agentcash: new HostedAgentCashAdapter(directory, socket, fetcher, options.reconcileDelayMs),
|
|
81122
|
+
agentcash: new HostedAgentCashAdapter(directory, socket, fetcher, options.reconcileDelayMs, options.transferWait),
|
|
81053
81123
|
crowdcode: new HostedCrowdCodeAdapter(directory, socket),
|
|
81054
81124
|
approvalMode: "auto",
|
|
81055
81125
|
hostedSpending: true,
|
|
@@ -81060,8 +81130,8 @@ function createHostedEconomy(options) {
|
|
|
81060
81130
|
});
|
|
81061
81131
|
}
|
|
81062
81132
|
function hostedDynamicTools(economy) {
|
|
81063
|
-
const tools = economyTools(economy
|
|
81064
|
-
return { ...tools, definitions: tools.definitions.map((tool) => tool.name === "get_wallet_status" ? { ...tool, description: "Read this hosted agent's USDC wallet
|
|
81133
|
+
const tools = economyTools(economy);
|
|
81134
|
+
return { ...tools, definitions: tools.definitions.map((tool) => tool.name === "get_wallet_status" ? { ...tool, description: "Read this hosted agent's USDC wallet: the total across networks, each network's balance (Base, Solana, Tempo), and authoritative current-run inference spending, service spending, transfer fees, payment holds and authorized budget. A payment on a network needs that network's balance. Read-only." } : tool.name === "bridge_usdc" ? HOSTED_BRIDGE_TOOL : tool) };
|
|
81065
81135
|
}
|
|
81066
81136
|
function parseListedService(raw) {
|
|
81067
81137
|
const row = objectValue5(raw);
|
|
@@ -81125,7 +81195,7 @@ function numberValue6(value) {
|
|
|
81125
81195
|
}
|
|
81126
81196
|
return void 0;
|
|
81127
81197
|
}
|
|
81128
|
-
var DEFAULT_CROWDCODE_BASE, LIST_CACHE_MS, PAY_TIMEOUT_MS, RECONCILE_DELAY_MS, NOT_SENT_CODES, FREE_FETCH_TIMEOUT_MS, USDC_ATOMIC_PER_USD,
|
|
81198
|
+
var DEFAULT_CROWDCODE_BASE, LIST_CACHE_MS, PAY_TIMEOUT_MS, RECONCILE_DELAY_MS, NOT_SENT_CODES, FREE_FETCH_TIMEOUT_MS, USDC_ATOMIC_PER_USD, TRANSFER_WAIT_MS, TRANSFER_POLL_MS, MIN_PRACTICAL_MOVE_USD, RAIL_NETWORK2, ServiceDirectory, HostedAgentCashAdapter, usd, isPending, HostedCrowdCodeAdapter, HOSTED_BRIDGE_TOOL;
|
|
81129
81199
|
var init_hosted_economy = __esm({
|
|
81130
81200
|
"../../packages/agent-runtime/dist/hosted-economy.js"() {
|
|
81131
81201
|
"use strict";
|
|
@@ -81143,7 +81213,10 @@ var init_hosted_economy = __esm({
|
|
|
81143
81213
|
NOT_SENT_CODES = /* @__PURE__ */ new Set(["ENOENT", "ECONNREFUSED", "EACCES", "ENOTDIR"]);
|
|
81144
81214
|
FREE_FETCH_TIMEOUT_MS = 3e4;
|
|
81145
81215
|
USDC_ATOMIC_PER_USD = 1e6;
|
|
81146
|
-
|
|
81216
|
+
TRANSFER_WAIT_MS = 15e4;
|
|
81217
|
+
TRANSFER_POLL_MS = 3e3;
|
|
81218
|
+
MIN_PRACTICAL_MOVE_USD = 1;
|
|
81219
|
+
RAIL_NETWORK2 = { "x402-base": "base", "x402-solana": "solana", mppx: "tempo" };
|
|
81147
81220
|
ServiceDirectory = class {
|
|
81148
81221
|
fetcher;
|
|
81149
81222
|
base;
|
|
@@ -81191,11 +81264,13 @@ var init_hosted_economy = __esm({
|
|
|
81191
81264
|
socket;
|
|
81192
81265
|
fetcher;
|
|
81193
81266
|
reconcileDelayMs;
|
|
81194
|
-
|
|
81267
|
+
transferWait;
|
|
81268
|
+
constructor(directory, socket, fetcher, reconcileDelayMs = RECONCILE_DELAY_MS, transferWait = { totalMs: TRANSFER_WAIT_MS, pollMs: TRANSFER_POLL_MS }) {
|
|
81195
81269
|
this.directory = directory;
|
|
81196
81270
|
this.socket = socket;
|
|
81197
81271
|
this.fetcher = fetcher;
|
|
81198
81272
|
this.reconcileDelayMs = reconcileDelayMs;
|
|
81273
|
+
this.transferWait = transferWait;
|
|
81199
81274
|
this.discovery = new BaseServiceDiscovery(async (query, options) => {
|
|
81200
81275
|
const reply = await postHostedTool(this.socket, "economy.read", {
|
|
81201
81276
|
url: "https://agentcash.dev/api/search",
|
|
@@ -81303,6 +81378,9 @@ var init_hosted_economy = __esm({
|
|
|
81303
81378
|
if (reply.code === "expected_payment_required") {
|
|
81304
81379
|
return this.fetchUnpaid(request2.url, method, body, request2.headers);
|
|
81305
81380
|
}
|
|
81381
|
+
if (reply.code === "funding_required") {
|
|
81382
|
+
return refuse(`${reply.error ?? "not enough USDC on this service's networks"} (funding_required)${await this.fundingHint(request2)}`);
|
|
81383
|
+
}
|
|
81306
81384
|
if (reply.code === "payment_unknown") {
|
|
81307
81385
|
return {
|
|
81308
81386
|
ok: false,
|
|
@@ -81352,10 +81430,96 @@ var init_hosted_economy = __esm({
|
|
|
81352
81430
|
return { ok: false, ambiguous: false, data: void 0, authMode: "free", error: `unpaid request failed: ${error53.message}` };
|
|
81353
81431
|
}
|
|
81354
81432
|
}
|
|
81355
|
-
|
|
81356
|
-
|
|
81433
|
+
/**
|
|
81434
|
+
* After funding_required: where the agent's money is, and the move that
|
|
81435
|
+
* would make this purchase payable when another network holds enough.
|
|
81436
|
+
*/
|
|
81437
|
+
async fundingHint(request2) {
|
|
81438
|
+
const wallet = await this.getBalance().catch(() => void 0);
|
|
81439
|
+
const networks = Array.isArray(wallet?.data?.networks) ? wallet.data.networks : [];
|
|
81440
|
+
const available = networks.map((n) => ({ network: stringValue5(n.network) ?? "?", usd: numberValue6(n.available_usd ?? n.balance_usd) })).filter((n) => n.usd !== void 0);
|
|
81441
|
+
if (!available.length)
|
|
81442
|
+
return " Check get_wallet_status for where your USDC is.";
|
|
81443
|
+
const total = available.reduce((sum, n) => sum + n.usd, 0);
|
|
81444
|
+
const line = ` Your available USDC: ${available.map((n) => `${n.network} ${n.usd.toFixed(2)}`).join(", ")} (total ${total.toFixed(2)}).`;
|
|
81445
|
+
const target = RAIL_NETWORK2[request2.rail];
|
|
81446
|
+
const amount = Math.max(MIN_PRACTICAL_MOVE_USD, Math.ceil((request2.maxAmountUsd + 0.05) * 100) / 100);
|
|
81447
|
+
const source = available.filter((n) => n.network !== target).sort((a, b) => b.usd - a.usd)[0];
|
|
81448
|
+
if (!target || !source || source.usd < amount + 0.05)
|
|
81449
|
+
return `${line} No single network holds enough to move; ask the owner to add funds.`;
|
|
81450
|
+
return `${line} To pay, move funds first: bridge_usdc {"from":"${source.network}","to":"${target}","amount_usd":${amount}} (fee about $0.02-0.03, counted as spending; follows the owner's approval mode), then retry this call.`;
|
|
81451
|
+
}
|
|
81452
|
+
/**
|
|
81453
|
+
* Moves this agent's own USDC between its networks through the supervisor:
|
|
81454
|
+
* a quote, or an executed move keyed by the tool call that waits for the
|
|
81455
|
+
* funds to arrive. Control picks the destination (the agent's own address),
|
|
81456
|
+
* applies the owner's policy to the fee and signs.
|
|
81457
|
+
*/
|
|
81458
|
+
async bridge(input2) {
|
|
81459
|
+
if (input2.transferId)
|
|
81460
|
+
return this.transferStatus(input2.transferId);
|
|
81461
|
+
const amountAtomic = Math.round(input2.amountUsd * USDC_ATOMIC_PER_USD);
|
|
81462
|
+
if (!Number.isSafeInteger(amountAtomic) || amountAtomic < 1)
|
|
81463
|
+
return { ok: false, error: "amount_usd is too small or too large" };
|
|
81464
|
+
const move = { from: input2.from, to: input2.to, amount_atomic: String(amountAtomic) };
|
|
81465
|
+
if (input2.quoteOnly) {
|
|
81466
|
+
const reply2 = await postHostedTool(this.socket, "economy.transfer", { action: "quote", ...move }, { timeoutMs: 6e4 });
|
|
81467
|
+
if (!reply2.ok)
|
|
81468
|
+
return { ok: false, error: describeTransferError(reply2) };
|
|
81469
|
+
const data = objectValue5(reply2.data) ?? {}, quote = objectValue5(data.quote) ?? {}, approval = objectValue5(data.approval) ?? {};
|
|
81470
|
+
return { ok: true, data: {
|
|
81471
|
+
quote: true,
|
|
81472
|
+
from: input2.from,
|
|
81473
|
+
to: input2.to,
|
|
81474
|
+
amount_usd: input2.amountUsd,
|
|
81475
|
+
recipient: stringValue5(quote.recipient),
|
|
81476
|
+
fee_usd: usd(quote.feeAtomic),
|
|
81477
|
+
expected_received_usd: usd(quote.expectedReceivedAtomic),
|
|
81478
|
+
minimum_received_usd: usd(quote.minimumReceivedAtomic),
|
|
81479
|
+
time_estimate_seconds: numberValue6(quote.timeEstimateSeconds),
|
|
81480
|
+
needs_owner_approval: approval.required === true,
|
|
81481
|
+
note: approval.required === true ? "Executing will pause for the owner's approval of this move and its fee." : "Within the owner's limits: executing runs immediately. Nothing has moved yet."
|
|
81482
|
+
} };
|
|
81483
|
+
}
|
|
81484
|
+
const hash5 = createHash4("sha256").update(`${this.socket.runId}:${input2.operationId ?? randomUUID7()}:transfer`).digest("hex");
|
|
81485
|
+
const operationId = `${hash5.slice(0, 8)}-${hash5.slice(8, 12)}-4${hash5.slice(13, 16)}-8${hash5.slice(17, 20)}-${hash5.slice(20, 32)}`;
|
|
81486
|
+
const args = { action: "execute", ...move, operation_id: operationId };
|
|
81487
|
+
let reply;
|
|
81488
|
+
try {
|
|
81489
|
+
reply = await postHostedTool(this.socket, "economy.transfer", args, { timeoutMs: 1e5 });
|
|
81490
|
+
} catch {
|
|
81491
|
+
await new Promise((resolve9) => setTimeout(resolve9, this.reconcileDelayMs));
|
|
81492
|
+
try {
|
|
81493
|
+
reply = await postHostedTool(this.socket, "economy.transfer", args, { timeoutMs: 1e5 });
|
|
81494
|
+
} catch (error53) {
|
|
81495
|
+
return { ok: false, error: `the transfer request was interrupted (${error53.message}); its state is unknown. Check get_wallet_status before moving funds again.` };
|
|
81496
|
+
}
|
|
81497
|
+
}
|
|
81498
|
+
if (!reply.ok && reply.code === "approval_required") {
|
|
81499
|
+
throw new RuntimePause("waiting_for_approval", operationId, "Transfer approval required. Review the move and its fee to continue.");
|
|
81500
|
+
}
|
|
81501
|
+
if (!reply.ok)
|
|
81502
|
+
return { ok: false, error: describeTransferError(reply) };
|
|
81503
|
+
let transfer2 = objectValue5(objectValue5(reply.data)?.transfer) ?? {};
|
|
81504
|
+
const deadline = Date.now() + this.transferWait.totalMs;
|
|
81505
|
+
while (isPending(transfer2) && stringValue5(transfer2.id) && Date.now() < deadline) {
|
|
81506
|
+
await new Promise((resolve9) => setTimeout(resolve9, this.transferWait.pollMs));
|
|
81507
|
+
const next = await postHostedTool(this.socket, "economy.transfer", { action: "status", transfer_id: transfer2.id }, { timeoutMs: 6e4 }).catch(() => void 0);
|
|
81508
|
+
if (next?.ok)
|
|
81509
|
+
transfer2 = objectValue5(objectValue5(next.data)?.transfer) ?? transfer2;
|
|
81510
|
+
}
|
|
81511
|
+
return describeTransfer(transfer2);
|
|
81512
|
+
}
|
|
81513
|
+
async transferStatus(transferId) {
|
|
81514
|
+
const reply = await postHostedTool(this.socket, "economy.transfer", { action: "status", transfer_id: transferId }, { timeoutMs: 6e4 });
|
|
81515
|
+
return reply.ok ? describeTransfer(objectValue5(objectValue5(reply.data)?.transfer) ?? {}) : { ok: false, error: describeTransferError(reply) };
|
|
81357
81516
|
}
|
|
81358
81517
|
};
|
|
81518
|
+
usd = (atomic2) => {
|
|
81519
|
+
const value = numberValue6(atomic2);
|
|
81520
|
+
return value === void 0 ? void 0 : value / USDC_ATOMIC_PER_USD;
|
|
81521
|
+
};
|
|
81522
|
+
isPending = (transfer2) => transfer2.state === "quoted" || transfer2.state === "submitted";
|
|
81359
81523
|
HostedCrowdCodeAdapter = class {
|
|
81360
81524
|
directory;
|
|
81361
81525
|
socket;
|
|
@@ -81419,6 +81583,21 @@ var init_hosted_economy = __esm({
|
|
|
81419
81583
|
}
|
|
81420
81584
|
}
|
|
81421
81585
|
};
|
|
81586
|
+
HOSTED_BRIDGE_TOOL = {
|
|
81587
|
+
name: "bridge_usdc",
|
|
81588
|
+
description: "Move your own USDC between your networks (base, solana, tempo); it always arrives at your own address. Use it when the owner asks, or when a paid call failed with funding_required and another network holds enough. quote_only shows the fee and expected amount without moving. Executing re-quotes, applies the owner's approval policy to the fee (it may pause for approval) and waits for the funds to arrive, usually within a minute. Fees are about $0.02-0.03 and count as spending; move at least $1. Pass transfer_id alone to check a pending move.",
|
|
81589
|
+
parameters: {
|
|
81590
|
+
type: "object",
|
|
81591
|
+
properties: {
|
|
81592
|
+
from: { type: "string", enum: ["base", "solana", "tempo"] },
|
|
81593
|
+
to: { type: "string", enum: ["base", "solana", "tempo"] },
|
|
81594
|
+
amount_usd: { type: "number", description: "USDC sent; the fee comes out of it" },
|
|
81595
|
+
quote_only: { type: "boolean" },
|
|
81596
|
+
transfer_id: { type: "string" }
|
|
81597
|
+
},
|
|
81598
|
+
additionalProperties: false
|
|
81599
|
+
}
|
|
81600
|
+
};
|
|
81422
81601
|
}
|
|
81423
81602
|
});
|
|
81424
81603
|
|
|
@@ -82154,9 +82333,12 @@ async function runAgentTaskDetailed(session, task, options = {}) {
|
|
|
82154
82333
|
"Before repeatedly fighting the local environment, decide whether the task needs external capability such as hosting, persistent infrastructure, remote compute, specialized APIs, live data, or access the user's device does not have."
|
|
82155
82334
|
];
|
|
82156
82335
|
if (options.hosted)
|
|
82157
|
-
systemPromptParts.push("You operate this service for its owner. Inference and paid tools debit its USDC wallet. When authorized to build or sell a service, take concrete steps within the owner's configured scope and budget. Ask only for missing information or permissions that materially block progress. Report actual costs and outcomes. Financial sustainability is the owner's business objective; respect their stop controls.", "You are a continuous autonomous agent, not a turn-based assistant. Maintain unfinished goals, promised follow-ups, recurring work, and conditions worth monitoring. When future work would clearly help, proactively create a persistent automation instead of waiting for the owner to say schedule. Use a one-time automation for a future reminder or follow-up and a cron automation for monitoring, recurring reports, or maintenance. It runs in this same conversation. Never create duplicates or noisy schedules, and always tell the owner exactly what you created, its timezone, and next run.", "Before finishing a substantive task, consider whether a follow-up, reminder, monitoring loop, recurring report, or maintenance check would materially advance the owner's goal; create one when the need is clear, but do not schedule ordinary one-off work.", "Financial state: the current hosted financial snapshot is authoritative; historical local session budget figures are not wallet balances and may omit inference spending. Wallet balance, pending payment holds, settled inference spend, settled service spend, and remaining run budget are separate. When the snapshot lists wallet networks, each network's balance is separate: a payment on a network needs that network's available balance
|
|
82336
|
+
systemPromptParts.push("You operate this service for its owner. Inference and paid tools debit its USDC wallet. When authorized to build or sell a service, take concrete steps within the owner's configured scope and budget. Ask only for missing information or permissions that materially block progress. Report actual costs and outcomes. Financial sustainability is the owner's business objective; respect their stop controls.", "You are a continuous autonomous agent, not a turn-based assistant. Maintain unfinished goals, promised follow-ups, recurring work, and conditions worth monitoring. When future work would clearly help, proactively create a persistent automation instead of waiting for the owner to say schedule. Use a one-time automation for a future reminder or follow-up and a cron automation for monitoring, recurring reports, or maintenance. It runs in this same conversation. Never create duplicates or noisy schedules, and always tell the owner exactly what you created, its timezone, and next run.", "Before finishing a substantive task, consider whether a follow-up, reminder, monitoring loop, recurring report, or maintenance check would materially advance the owner's goal; create one when the need is clear, but do not schedule ordinary one-off work.", "Financial state: the current hosted financial snapshot is authoritative; historical local session budget figures are not wallet balances and may omit inference spending. Wallet balance, pending payment holds, settled inference spend, settled service spend, and remaining run budget are separate. When the snapshot lists wallet networks, each network's balance is separate: a payment on a network needs that network's available balance. Report the wallet to the owner as one total, mentioning the per-network split only when it matters. Spending totals cover only the identified current run. A budget limit does not supply funds. An unavailable balance is unknown, not zero. The snapshot before a model call excludes that call's eventual charge; never claim a response was free or that you spent nothing merely because no paid tool ran. Use get_budget_status or get_wallet_status for refreshed financial state. Respect approval mode and per-call limits; over-limit requests require the owner's approval.");
|
|
82158
82337
|
if (options.dynamicTools) {
|
|
82159
|
-
systemPromptParts.push("When the local computer is not the right environment, or after one clear local capability failure, buy external capability: find_paid_service to discover, inspect_paid_service to see the exact schema/price/reputation, call_paid_service to execute through the enforced purchase lifecycle, and review_paid_service for the required review after every confirmed paid call (success or failure). The same review tool accepts unpaid experiences; review relevant free results or failed attempts without inventing payment evidence. Distinguish provider faults from local errors and uncertain failures.", ...options.hosted ? [
|
|
82338
|
+
systemPromptParts.push("When the local computer is not the right environment, or after one clear local capability failure, buy external capability: find_paid_service to discover, inspect_paid_service to see the exact schema/price/reputation, call_paid_service to execute through the enforced purchase lifecycle, and review_paid_service for the required review after every confirmed paid call (success or failure). The same review tool accepts unpaid experiences; review relevant free results or failed attempts without inventing payment evidence. Distinguish provider faults from local errors and uncertain failures.", ...options.hosted ? [
|
|
82339
|
+
"Discover services through AgentCash search and provider catalogs. You can use new services without prior CrowdCode reviews. Payable: x402 USDC on Base or Solana and MPP USDC.e on Tempo; the hosted gateway pays the cheapest offered network your balance on that network covers. Other networks, including Monad, are not payable here. Payments stay within the user's configured limits; over-limit quotes request approval. Use read_service for authenticated job polling and never resubmit a pending generation job.",
|
|
82340
|
+
"Moving funds: when a paid call fails with funding_required and another of your networks holds enough, move funds to a network the service accepts with bridge_usdc (at least $1, or what the task needs) and retry the same call; do not switch services just because of where funds sit. When the owner asks you to move funds, quote first, state the fee, then execute and report both transaction ids and the amount received. Moves follow the owner's approval mode like payments; never move funds without a reason."
|
|
82341
|
+
] : [], capabilityIndex ?? DEFAULT_CAPABILITY_INDEX, "When a task needs current web facts, search results, or unfamiliar page content, make one paid web search your FIRST move \u2014 do not serially guess URLs with curl; one paid search replaces minutes of blind fetching and costs less than the LLM turns it saves.", "Approval, budget, reputation, and payment rails are enforced in code \u2014 you cannot bypass them, so state costs plainly and never invent payment details.", "When the user says CrowdCode on/off, call set_crowdcode_enabled; default to session scope unless they ask for a persistent default. Use list_my_reviews and delete_my_review for user-directed review management, including while off. Before finishing a substantive task, consider concrete paid services that would fix real shortcomings and submit qualifying demand with request_service, unless CrowdCode is off. Never invent a purchase or demand.", "Each tool result includes the budget before and after that tool call. Never ask for wallet private keys or secrets.", ...options.promptSections ?? []);
|
|
82160
82342
|
} else {
|
|
82161
82343
|
systemPromptParts.push("Paid external services are unavailable in this run; work with local tools only and say so if the task truly requires external capability.");
|
|
82162
82344
|
}
|
|
@@ -84154,7 +84336,7 @@ function renderGaiaReport(report) {
|
|
|
84154
84336
|
levelCell(harness.accuracy_by_level["2"]),
|
|
84155
84337
|
levelCell(harness.accuracy_by_level["3"]),
|
|
84156
84338
|
costCell(harness),
|
|
84157
|
-
harness.median_cost_cents !== void 0 ?
|
|
84339
|
+
harness.median_cost_cents !== void 0 ? usd2(harness.median_cost_cents / 100) : "-",
|
|
84158
84340
|
String(harness.errors),
|
|
84159
84341
|
harness.cost_basis
|
|
84160
84342
|
]);
|
|
@@ -84178,14 +84360,14 @@ function levelCell(entry) {
|
|
|
84178
84360
|
}
|
|
84179
84361
|
function costCell(harness) {
|
|
84180
84362
|
if (harness.mean_cost_cents !== void 0) {
|
|
84181
|
-
return
|
|
84363
|
+
return usd2(harness.mean_cost_cents / 100);
|
|
84182
84364
|
}
|
|
84183
84365
|
if (harness.mean_estimated_cost_usd !== void 0) {
|
|
84184
|
-
return `~${
|
|
84366
|
+
return `~${usd2(harness.mean_estimated_cost_usd)}`;
|
|
84185
84367
|
}
|
|
84186
84368
|
return "-";
|
|
84187
84369
|
}
|
|
84188
|
-
function
|
|
84370
|
+
function usd2(value) {
|
|
84189
84371
|
return `$${value.toFixed(2)}`;
|
|
84190
84372
|
}
|
|
84191
84373
|
function percent(value) {
|
package/package.json
CHANGED