opencrowd 0.3.1 → 0.3.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 +116 -29
  2. package/package.json +2 -2
@@ -101,15 +101,11 @@ async function appendLedgerEntry(path3, entry) {
101
101
  }
102
102
  async function readLedger(path3) {
103
103
  const text = await readFile2(path3, "utf8");
104
- const [headerLine, ...lines] = text.trim().split(/\r?\n/);
105
- if (!headerLine) {
104
+ const [headers, ...records] = parseCsv(text);
105
+ if (!headers) {
106
106
  return [];
107
107
  }
108
- const headers = parseCsvLine(headerLine);
109
- return lines.filter(Boolean).map((line) => {
110
- const values = parseCsvLine(line);
111
- return Object.fromEntries(headers.map((header, index2) => [header, values[index2] ?? ""]));
112
- });
108
+ return records.filter((record) => record.length > 1 || (record[0] ?? "") !== "").map((record) => Object.fromEntries(headers.map((header, index2) => [header, record[index2] ?? ""])));
113
109
  }
114
110
  function csvCell(value) {
115
111
  if (/[",\n\r]/.test(value)) {
@@ -117,26 +113,44 @@ function csvCell(value) {
117
113
  }
118
114
  return value;
119
115
  }
120
- function parseCsvLine(line) {
121
- const cells = [];
116
+ function parseCsv(text) {
117
+ const records = [];
118
+ let cells = [];
122
119
  let current = "";
123
120
  let quoted = false;
124
- for (let index2 = 0; index2 < line.length; index2 += 1) {
125
- const char = line[index2];
126
- if (quoted && char === '"' && line[index2 + 1] === '"') {
127
- current += '"';
128
- index2 += 1;
121
+ for (let index2 = 0; index2 < text.length; index2 += 1) {
122
+ const char = text[index2];
123
+ if (quoted) {
124
+ if (char === '"' && text[index2 + 1] === '"') {
125
+ current += '"';
126
+ index2 += 1;
127
+ } else if (char === '"') {
128
+ quoted = false;
129
+ } else {
130
+ current += char;
131
+ }
129
132
  } else if (char === '"') {
130
- quoted = !quoted;
131
- } else if (char === "," && !quoted) {
133
+ quoted = true;
134
+ } else if (char === ",") {
132
135
  cells.push(current);
133
136
  current = "";
137
+ } else if (char === "\n" || char === "\r") {
138
+ if (char === "\r" && text[index2 + 1] === "\n") {
139
+ index2 += 1;
140
+ }
141
+ cells.push(current);
142
+ records.push(cells);
143
+ cells = [];
144
+ current = "";
134
145
  } else {
135
146
  current += char;
136
147
  }
137
148
  }
138
- cells.push(current);
139
- return cells;
149
+ if (current !== "" || cells.length > 0) {
150
+ cells.push(current);
151
+ records.push(cells);
152
+ }
153
+ return records;
140
154
  }
141
155
  var LEDGER_COLUMNS;
142
156
  var init_ledger = __esm({
@@ -1010,7 +1024,7 @@ var init_dist = __esm({
1010
1024
 
1011
1025
  // ../../packages/economy/dist/agentcash.js
1012
1026
  function parsePaidFetchResult(raw, requestedRail) {
1013
- const record = objectValue2(raw) ?? {};
1027
+ const { body, record } = splitFetchPayload(raw);
1014
1028
  const status = numberValue2(record.status ?? record.statusCode);
1015
1029
  const ok3 = typeof record.ok === "boolean" ? record.ok : status !== void 0 ? status < 400 : true;
1016
1030
  const payment = parsePaymentEvidence(record, requestedRail);
@@ -1020,32 +1034,88 @@ function parsePaidFetchResult(raw, requestedRail) {
1020
1034
  ok: ok3,
1021
1035
  ambiguous: false,
1022
1036
  status,
1023
- data: record.data ?? record.body ?? record.response ?? raw,
1037
+ data: body,
1024
1038
  error: ok3 ? void 0 : stringValue2(record.error) ?? (status !== void 0 ? `HTTP ${status}` : "request failed"),
1025
1039
  authMode: payment ? "paid" : usedSiwx ? "siwx" : "free",
1026
1040
  payment
1027
1041
  };
1028
1042
  }
1043
+ function splitFetchPayload(raw) {
1044
+ if (Array.isArray(raw)) {
1045
+ const record2 = {};
1046
+ const bodies = [];
1047
+ for (const block of raw) {
1048
+ const object = objectValue2(block);
1049
+ if (object && looksLikePaymentMetadata(object)) {
1050
+ Object.assign(record2, object);
1051
+ } else {
1052
+ bodies.push(block);
1053
+ }
1054
+ }
1055
+ return { body: bodies.length === 1 ? bodies[0] : bodies, record: record2 };
1056
+ }
1057
+ if (typeof raw === "string") {
1058
+ return splitEmbeddedMetadata(raw) ?? { body: raw, record: {} };
1059
+ }
1060
+ const record = objectValue2(raw) ?? {};
1061
+ return { body: record.data ?? record.body ?? record.response ?? raw, record };
1062
+ }
1063
+ function looksLikePaymentMetadata(record) {
1064
+ if (objectValue2(record.payment ?? record.paymentDetails ?? record.payment_details)) {
1065
+ return true;
1066
+ }
1067
+ const headers = objectValue2(record.headers ?? record.responseHeaders);
1068
+ if (headers && Object.keys(headers).some((key) => /^(x-)?payment-(response|receipt|required)$/i.test(key))) {
1069
+ return true;
1070
+ }
1071
+ return typeof record.protocol === "string" && (record.price !== void 0 || typeof record.network === "string");
1072
+ }
1073
+ function splitEmbeddedMetadata(text) {
1074
+ for (let index2 = text.lastIndexOf("\n{"); index2 >= 0; index2 = text.lastIndexOf("\n{", index2 - 1)) {
1075
+ const candidate = objectValue2(parseMaybeJson(text.slice(index2 + 1)));
1076
+ if (candidate && looksLikePaymentMetadata(candidate)) {
1077
+ const bodyText = text.slice(0, index2).trim();
1078
+ return { body: parseMaybeJson(bodyText), record: candidate };
1079
+ }
1080
+ }
1081
+ return void 0;
1082
+ }
1029
1083
  function parsePaymentEvidence(record, requestedRail) {
1030
1084
  const payment = objectValue2(record.payment ?? record.paymentDetails ?? record.payment_details);
1031
1085
  const headers = objectValue2(record.headers ?? record.responseHeaders) ?? {};
1032
1086
  const proof = stringValue2(payment?.proof ?? payment?.receipt ?? headers["payment-response"] ?? headers["x-payment-response"] ?? headers["payment-receipt"] ?? headers["Payment-Receipt"]);
1033
- const reference = stringValue2(payment?.txHash ?? payment?.tx_hash ?? payment?.transactionHash ?? payment?.reference ?? record.txHash ?? record.tx_hash);
1034
- const paidUsd = numberValue2(payment?.price ?? payment?.amount ?? payment?.paidUsd ?? payment?.amountUsd ?? record.paid ?? record.price);
1087
+ let reference = stringValue2(payment?.txHash ?? payment?.tx_hash ?? payment?.transactionHash ?? payment?.reference ?? record.txHash ?? record.tx_hash);
1088
+ const paidUsd = moneyValue(payment?.price ?? payment?.amount ?? payment?.paidUsd ?? payment?.amountUsd ?? record.paid ?? record.price);
1035
1089
  if (!payment && !proof && !reference && paidUsd === void 0) {
1036
1090
  return void 0;
1037
1091
  }
1038
- const network = stringValue2(payment?.network ?? record.network)?.toLowerCase();
1039
- const protocol = stringValue2(payment?.protocol ?? record.paymentProtocol)?.toLowerCase();
1040
- const rail = network === "tempo" || protocol === "mpp" || protocol === "mppx" ? "mppx" : network === "base" || protocol === "x402" ? "x402-base" : network === void 0 && protocol === void 0 ? requestedRail : "unsupported";
1092
+ const receipt = proof ? objectValue2(parseMaybeJson(decodeBase64(proof) ?? "")) : void 0;
1093
+ reference ??= stringValue2(receipt?.transaction ?? receipt?.transactionHash ?? receipt?.txHash ?? receipt?.reference);
1094
+ const network = stringValue2(payment?.network ?? record.network ?? receipt?.network)?.toLowerCase();
1095
+ const protocol = stringValue2(payment?.protocol ?? record.protocol ?? record.paymentProtocol)?.toLowerCase();
1096
+ const rail = network === "tempo" || protocol === "mpp" || protocol === "mppx" ? "mppx" : network === "base" || network === "eip155:8453" || protocol === "x402" ? "x402-base" : network === void 0 && protocol === void 0 ? requestedRail : "unsupported";
1041
1097
  return {
1042
1098
  paidUsd,
1043
1099
  rail,
1044
1100
  reference,
1045
1101
  proof,
1046
- payTo: stringValue2(payment?.payTo ?? payment?.pay_to ?? payment?.recipient)
1102
+ payTo: stringValue2(payment?.payTo ?? payment?.pay_to ?? payment?.recipient ?? receipt?.payTo ?? receipt?.pay_to ?? receipt?.recipient ?? receipt?.payee)
1047
1103
  };
1048
1104
  }
1105
+ function parseMaybeJson(text) {
1106
+ try {
1107
+ return JSON.parse(text);
1108
+ } catch {
1109
+ return text;
1110
+ }
1111
+ }
1112
+ function decodeBase64(value) {
1113
+ try {
1114
+ return Buffer.from(value, "base64").toString("utf8");
1115
+ } catch {
1116
+ return void 0;
1117
+ }
1118
+ }
1049
1119
  function objectValue2(value) {
1050
1120
  return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
1051
1121
  }
@@ -1061,6 +1131,17 @@ function numberValue2(value) {
1061
1131
  }
1062
1132
  return void 0;
1063
1133
  }
1134
+ function moneyValue(value) {
1135
+ const direct = numberValue2(value);
1136
+ if (direct !== void 0) {
1137
+ return direct;
1138
+ }
1139
+ if (typeof value !== "string") {
1140
+ return void 0;
1141
+ }
1142
+ const cleaned = value.replace(/[$,\s]|usd(c?)/gi, "");
1143
+ return cleaned === "" ? void 0 : numberValue2(cleaned);
1144
+ }
1064
1145
  var McpAgentCashAdapter;
1065
1146
  var init_agentcash2 = __esm({
1066
1147
  "../../packages/economy/dist/agentcash.js"() {
@@ -1852,7 +1933,13 @@ function parseToolContent(content) {
1852
1933
  if (!Array.isArray(content)) {
1853
1934
  return content;
1854
1935
  }
1855
- const text = content.filter((block) => block && typeof block === "object" && block.type === "text").map((block) => String(block.text ?? "")).join("\n");
1936
+ const texts = content.filter((block) => block && typeof block === "object" && block.type === "text").map((block) => String(block.text ?? ""));
1937
+ if (texts.length <= 1) {
1938
+ return parseMaybeJson2(texts[0] ?? "");
1939
+ }
1940
+ return texts.map(parseMaybeJson2);
1941
+ }
1942
+ function parseMaybeJson2(text) {
1856
1943
  try {
1857
1944
  return JSON.parse(text);
1858
1945
  } catch {
@@ -46725,7 +46812,7 @@ async function challengeFromResponse(response) {
46725
46812
  }
46726
46813
  const headerValue = response.headers.get("payment-required") ?? response.headers.get("x-payment-required");
46727
46814
  if (headerValue) {
46728
- const headerChallenge = parseBase64Json(headerValue) ?? parseMaybeJson(headerValue);
46815
+ const headerChallenge = parseBase64Json(headerValue) ?? parseMaybeJson3(headerValue);
46729
46816
  if (headerChallenge) {
46730
46817
  return headerChallenge;
46731
46818
  }
@@ -46810,7 +46897,7 @@ function parseBase64Json(value) {
46810
46897
  return void 0;
46811
46898
  }
46812
46899
  }
46813
- function parseMaybeJson(value) {
46900
+ function parseMaybeJson3(value) {
46814
46901
  try {
46815
46902
  return JSON.parse(value);
46816
46903
  } catch {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "opencrowd",
3
- "version": "0.3.1",
4
- "description": "A CLI agent with its own wallet \u2014 discovers x402 services, pays in USDC, and completes tasks under a local budget",
3
+ "version": "0.3.2",
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",
7
7
  "repository": {