opencrowd 0.13.0 → 0.13.2

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.
Files changed (2) hide show
  1. package/bundle/opencrowd.js +44 -15
  2. package/package.json +1 -1
@@ -57184,7 +57184,7 @@ var init_discovery = __esm({
57184
57184
  "use strict";
57185
57185
  init_dist3();
57186
57186
  init_offers();
57187
- RANKED_NOTE = "Ranked by CrowdCode across Base, Solana and Tempo (AgentCash, Coinbase's x402 catalog, MPP catalog and CrowdCode reviews): quality first, then effective price on best_network (including about $0.03 to move USDC between your own networks when that network's balance is short), then your balance there. Prefer the highest-ranked service that fits the task, whatever its network. transfer_needed means your balance on best_network is short: move USDC between your own networks first if you have a tool for that; otherwise say which network needs funds. New/unreviewed services are allowed. Inspect the chosen endpoint before paying.";
57187
+ RANKED_NOTE = "Ranked by CrowdCode across Base, Solana and Tempo (AgentCash, Coinbase's x402 catalog, MPP catalog and CrowdCode reviews): quality first, then effective price on best_network (including about $0.03 to move USDC between your own networks when that network's balance is short), then your balance there. Prefer the highest-ranked service that fits the task, whatever its network. Each result's `networks` are the networks it can be paid on; between results that fit the task equally well, one you can pay from a balance you already hold beats one that needs a transfer first. transfer_needed means your balance on best_network is short: move USDC between your own networks first if you have a tool for that; otherwise say which network needs funds. New/unreviewed services are allowed. Inspect the chosen endpoint before paying.";
57188
57188
  BaseServiceDiscovery = class {
57189
57189
  searchApi;
57190
57190
  options;
@@ -57277,6 +57277,7 @@ var init_discovery = __esm({
57277
57277
  const schema = inspection.data;
57278
57278
  if (!inspection.ok || !schema?.payable)
57279
57279
  return void 0;
57280
+ const networks = Array.isArray(schema.offers) ? [...new Set(schema.offers.filter((offer) => offer.payable).map((offer) => String(offer.network)))] : [];
57280
57281
  const service = {
57281
57282
  endpoint,
57282
57283
  method,
@@ -57284,6 +57285,7 @@ var init_discovery = __esm({
57284
57285
  price_usd: schema.price_usd,
57285
57286
  payment_provider: schema.rail === "mppx" ? "mppx" : "x402",
57286
57287
  network: schema.network ?? BASE_NETWORK,
57288
+ ...networks.length ? { networks } : {},
57287
57289
  payable: true
57288
57290
  };
57289
57291
  return c.ranking ? { ...service, ...ranked(c.ranking, schema) } : service;
@@ -58602,7 +58604,7 @@ var init_gateway = __esm({
58602
58604
  },
58603
58605
  {
58604
58606
  name: "find_paid_service",
58605
- description: "Discover paid capability across Base, Solana and Tempo. `query` searches every catalog (AgentCash, Coinbase's x402 catalog, MPP) and returns services you can pay, ranked best first by CrowdCode: quality, then effective price on your best network (including a transfer between your own networks when its balance is short), then your balance there. `origin` lists a known origin's endpoints.",
58607
+ description: "Discover paid capability across Base, Solana and Tempo. `query` searches every catalog (AgentCash, Coinbase's x402 catalog, MPP) and returns services you can pay, ranked best first by CrowdCode: quality, then effective price on your best network (including a transfer between your own networks when its balance is short), then your balance there. Every result lists `networks`, the networks it can be paid on: when a call fails for funds, come back here and prefer an equivalent service on a network you already hold USDC on over moving funds. `origin` lists a known origin's endpoints.",
58606
58608
  parameters: {
58607
58609
  type: "object",
58608
58610
  properties: {
@@ -58659,7 +58661,7 @@ var init_gateway = __esm({
58659
58661
  },
58660
58662
  {
58661
58663
  name: "bridge_usdc",
58662
- description: "Explicitly bridge USDC between this wallet's own networks (base, tempo, solana) through AgentCash. A financial action, not a purchase; subject to bridge fees.",
58664
+ description: "Explicitly bridge USDC between this wallet's own networks (base, tempo, solana) through AgentCash. A financial action, not a purchase; subject to bridge fees, which are a flat ~$0.02-0.03 whatever the size: aim for about $1 so one fee funds many calls, and when the wallet holds less, keep the fee under about a fifth of what moves.",
58663
58665
  parameters: {
58664
58666
  type: "object",
58665
58667
  properties: {
@@ -81247,6 +81249,21 @@ function hostedDynamicTools(economy) {
81247
81249
  const tools = economyTools(economy);
81248
81250
  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) };
81249
81251
  }
81252
+ function planFundingMove(target, priceUsd, available) {
81253
+ const cents = (usd3) => Math.floor(usd3 * 100) / 100;
81254
+ const needed = Math.ceil((priceUsd + MOVE_FEE_ALLOWANCE_USD) * 100) / 100;
81255
+ const source = available.filter((n) => n.network !== target).sort((a, b) => b.usd - a.usd)[0];
81256
+ if (!source)
81257
+ return void 0;
81258
+ const reserve = source.network === "base" ? BASE_WORKING_RESERVE_USD : 0;
81259
+ const spare = cents(Math.max(0, source.usd - reserve));
81260
+ const ceiling = Math.min(Math.max(needed, spare), cents(source.usd));
81261
+ const amount = Math.min(Math.max(PREFERRED_MOVE_USD, needed), ceiling);
81262
+ if (amount < needed)
81263
+ return void 0;
81264
+ const feeShare = MOVE_FEE_ESTIMATE_USD / amount;
81265
+ return { from: source.network, amount, feeShare, worthwhile: feeShare <= MAX_MOVE_FEE_SHARE };
81266
+ }
81250
81267
  function parseListedService(raw) {
81251
81268
  const row = objectValue5(raw);
81252
81269
  if (!row) {
@@ -81309,7 +81326,7 @@ function numberValue6(value) {
81309
81326
  }
81310
81327
  return void 0;
81311
81328
  }
81312
- var DEFAULT_CROWDCODE_BASE, LIST_CACHE_MS, FIND_TIMEOUT_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;
81329
+ var DEFAULT_CROWDCODE_BASE, LIST_CACHE_MS, FIND_TIMEOUT_MS, PAY_TIMEOUT_MS, RECONCILE_DELAY_MS, NOT_SENT_CODES, FREE_FETCH_TIMEOUT_MS, USDC_ATOMIC_PER_USD, TRANSFER_WAIT_MS, TRANSFER_POLL_MS, PREFERRED_MOVE_USD, MOVE_FEE_ALLOWANCE_USD, MOVE_FEE_ESTIMATE_USD, MAX_MOVE_FEE_SHARE, BASE_WORKING_RESERVE_USD, RAIL_NETWORK2, ServiceDirectory, HostedAgentCashAdapter, usd, isPending, HostedCrowdCodeAdapter, HOSTED_BRIDGE_TOOL;
81313
81330
  var init_hosted_economy = __esm({
81314
81331
  "../../packages/agent-runtime/dist/hosted-economy.js"() {
81315
81332
  "use strict";
@@ -81330,7 +81347,11 @@ var init_hosted_economy = __esm({
81330
81347
  USDC_ATOMIC_PER_USD = 1e6;
81331
81348
  TRANSFER_WAIT_MS = 15e4;
81332
81349
  TRANSFER_POLL_MS = 3e3;
81333
- MIN_PRACTICAL_MOVE_USD = 1;
81350
+ PREFERRED_MOVE_USD = 1;
81351
+ MOVE_FEE_ALLOWANCE_USD = 0.05;
81352
+ MOVE_FEE_ESTIMATE_USD = 0.03;
81353
+ MAX_MOVE_FEE_SHARE = 0.2;
81354
+ BASE_WORKING_RESERVE_USD = 0.25;
81334
81355
  RAIL_NETWORK2 = { "x402-base": "base", "x402-solana": "solana", mppx: "tempo" };
81335
81356
  ServiceDirectory = class {
81336
81357
  fetcher;
@@ -81560,8 +81581,11 @@ var init_hosted_economy = __esm({
81560
81581
  }
81561
81582
  }
81562
81583
  /**
81563
- * After funding_required: where the agent's money is, and the move that
81564
- * would make this purchase payable when another network holds enough.
81584
+ * After funding_required: where the agent's money is, and the two ways
81585
+ * forward, cheaper first. An equivalent service on a network the agent
81586
+ * already funds costs nothing extra; a move costs a bridge fee. A funded
81587
+ * wallet must never be told to go and ask the owner for money, and a move
81588
+ * that would spend most of itself on the fee must never be made quietly.
81565
81589
  */
81566
81590
  async fundingHint(request2) {
81567
81591
  const wallet = await this.getBalance().catch(() => void 0);
@@ -81572,11 +81596,15 @@ var init_hosted_economy = __esm({
81572
81596
  const total = available.reduce((sum, n) => sum + n.usd, 0);
81573
81597
  const line = ` Your available USDC: ${available.map((n) => `${n.network} ${n.usd.toFixed(2)}`).join(", ")} (total ${total.toFixed(2)}).`;
81574
81598
  const target = RAIL_NETWORK2[request2.rail];
81575
- const amount = Math.max(MIN_PRACTICAL_MOVE_USD, Math.ceil((request2.maxAmountUsd + 0.05) * 100) / 100);
81576
- const source = available.filter((n) => n.network !== target).sort((a, b) => b.usd - a.usd)[0];
81577
- if (!target || !source || source.usd < amount + 0.05)
81578
- return `${line} No single network holds enough to move; ask the owner to add funds.`;
81579
- 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.`;
81599
+ const funded = available.filter((n) => n.network !== target && n.usd >= request2.maxAmountUsd).map((n) => n.network);
81600
+ const elsewhere = funded.length ? ` First look for an equivalent service you can already pay: find_paid_service lists every result's networks, and one on ${funded.join(" or ")} costs you no transfer fee.` : "";
81601
+ const move = target ? planFundingMove(target, request2.maxAmountUsd, available) : void 0;
81602
+ if (!target || !move)
81603
+ return `${line}${elsewhere} No network of yours can cover a move to ${target ?? "a network this service accepts"} either, so if no equivalent service fits, tell the owner plainly that this service is sold only on ${target ?? "networks you do not hold"} and ask them to add USDC there.`;
81604
+ const cost = `about $${MOVE_FEE_ESTIMATE_USD.toFixed(2)}`, size5 = `$${move.amount.toFixed(2)}`;
81605
+ if (!move.worthwhile)
81606
+ return `${line}${elsewhere} Moving funds is the other way, but the most ${move.from} can spare is ${size5}, and a fee of ${cost} is ${Math.round(move.feeShare * 100)}% of that \u2014 too much to spend without asking. If no equivalent service fits, say exactly that to the owner: this service is sold only on ${target}, moving ${size5} there would cost ${cost} in fees, and ask whether to do it.`;
81607
+ return `${line}${elsewhere} Otherwise move the funds yourself and retry \u2014 a move this size is within the policy and is not something to ask the owner about, any more than paying for the call is: bridge_usdc {"from":"${move.from}","to":"${target}","amount_usd":${move.amount}} (fee ${cost}, counted as spending; the spending guard pauses it for approval by itself if the owner's mode requires that), then retry this call.`;
81580
81608
  }
81581
81609
  /**
81582
81610
  * Moves this agent's own USDC between its networks through the supervisor:
@@ -81729,7 +81757,7 @@ var init_hosted_economy = __esm({
81729
81757
  };
81730
81758
  HOSTED_BRIDGE_TOOL = {
81731
81759
  name: "bridge_usdc",
81732
- 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.",
81760
+ 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 no equivalent service is sold on a network you already fund. 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, so aim for about $1 and one fee funds many calls; when the wallet holds less, move what the call needs plus the fee, as long as the fee stays under about a fifth of what moves (roughly $0.15 and up). A move within that rule needs no permission from the owner: the spending guard applies their approval mode to the fee by itself. Below the rule, quote_only first and ask, rather than spending most of the move on its fee. Pass transfer_id alone to check a pending move.",
81733
81761
  parameters: {
81734
81762
  type: "object",
81735
81763
  properties: {
@@ -82481,9 +82509,10 @@ async function runAgentTaskDetailed(session, task, options = {}) {
82481
82509
  if (options.hosted)
82482
82510
  systemPromptParts.push("Files the owner sends you: an attached file is saved in this session under uploads/ before its message reaches you, and the message names each one with its path, size and type. Read a text file with read_file at uploads/<name>, and any file with run_shell at artifacts/uploads/<name> from the session directory. Those files are already the owner's and already in their file list: work from them, and never copy or re-save one under artifacts/ to hand it back. Write your own outputs elsewhere under artifacts/; uploads/ is the owner's directory and nothing you write there is delivered. If a file the message names is missing, say so and ask the owner to send it again rather than guessing at its contents.", "Files you produce: only the artifacts/ directory of this session reaches the owner. save_file writes there; anything you write elsewhere is scratch they never see. The owner sees each file at its path without that prefix, so artifacts/generated/report.pdf is generated/report.pdf to them. Name a produced file in your final message by exactly that path as plain text and nothing else \u2014 the owner's interface turns it into a working download and preview link. Never invent a download URL, a sandbox: link, a /mnt/data path, or any other path the owner cannot open, and never claim a file exists before you have verified it.");
82483
82511
  if (options.dynamicTools) {
82484
- 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. A platform judge, not you, writes the public score and text of a paid review from the platform's record of the call; your rating and notes are evidence it reads, so report accurately and never try to talk it into a rating.", `Choosing a service: find_paid_service with a short capability query (for example "web search" or "object storage", not the task's subject) searches every catalog (AgentCash, Coinbase's x402 catalog, the MPP catalog and CrowdCode's reviews) across Base, Solana and Tempo and returns services you can pay, ranked best first by CrowdCode: quality (score and verified reviews), then effective price on the service's best network, including about $0.03 to move USDC between your own networks when that network's balance is short, then your balance there. Prefer the highest-ranked service that fits the task, whatever its network; a better or cheaper service on Solana or Tempo beats a Base default. When the chosen service is marked transfer_needed, move USDC between your own networks first if you have a tool for that; otherwise tell the user which network needs funds. When the ranking is unavailable, compare candidates yourself with inspect_paid_service (reputation, price and network) against your per-network balances.`, ...options.hosted ? [
82512
+ 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. A platform judge, not you, writes the public score and text of a paid review from the platform's record of the call; your rating and notes are evidence it reads, so report accurately and never try to talk it into a rating.", `Choosing a service: find_paid_service with a short capability query (for example "web search" or "object storage", not the task's subject) searches every catalog (AgentCash, Coinbase's x402 catalog, the MPP catalog and CrowdCode's reviews) across Base, Solana and Tempo and returns services you can pay, ranked best first by CrowdCode: quality (score and verified reviews), then effective price on the service's best network, including about $0.03 to move USDC between your own networks when that network's balance is short, then your balance there. Prefer the highest-ranked service that fits the task, whatever its network; a better or cheaper service on Solana or Tempo beats a Base default. Each result also lists \`networks\`, the networks it can be paid on; between services that fit the task equally well, one you can pay from a balance you already hold beats one that needs a transfer first, because a move costs about $0.03. When the chosen service is marked transfer_needed, move USDC between your own networks first if you have a tool for that; otherwise tell the user which network needs funds. When the ranking is unavailable, compare candidates yourself with inspect_paid_service (reputation, price and network) against your per-network balances.`, ...options.hosted ? [
82485
82513
  "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.",
82486
- "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."
82514
+ "funding_required means your USDC is on the wrong network, not that you are out of money, and a wallet with money in it finishes the job. First go back to find_paid_service and look for an equivalent service sold on a network you already hold USDC on \u2014 every result lists its `networks`, and paying from an existing balance costs no transfer fee. If none fits, move funds with bridge_usdc and retry the same call: aim for about $1 so one fee funds many later calls, and when the wallet holds less than that, move what the call needs plus the fee, as long as the fee stays under about a fifth of what moves (roughly $0.15 and up at a $0.03 fee). A move inside that rule is ordinary work, not a decision for the owner: make it and retry, exactly as you would pay for the call itself. The spending guard applies the owner's approval mode to the fee by itself and pauses the run if it has to, so you never need permission before calling bridge_usdc. Stopping to ask whether you may spend three cents moving the owner's own money to the network a seller wants is the dead end this rule exists to prevent. Only below that threshold is a move not worth making on your own: quote_only it, then ask. 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.",
82515
+ "When money is what blocks a task, say exactly that and nothing else: which network the service is sold on, what you hold where, and the single thing you need \u2014 permission for a move you have quoted, or USDC added on that network. Never dress a funding problem up as the service being unsuitable or unavailable, never imply your wallet is empty when it is not, and never offer a recorded request_service as though it were the answer the owner asked for."
82487
82516
  ] : [], 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 (input, output, problem, price_per_call), 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 ?? []);
82488
82517
  } else {
82489
82518
  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.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencrowd",
3
- "version": "0.13.0",
3
+ "version": "0.13.2",
4
4
  "description": "A CLI agent with its own wallet — discovers x402 services, pays in USDC, and completes tasks under a local budget",
5
5
  "type": "module",
6
6
  "license": "MIT",