@ixo/asks-mcp 2.0.0-dev.1 → 2.0.0-dev.3
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/asks-mcp.mjs +566 -223
- package/package.json +1 -1
package/dist/asks-mcp.mjs
CHANGED
|
@@ -7508,7 +7508,7 @@ function reviewSlugOf(facts) {
|
|
|
7508
7508
|
function askPage(site, collectionId, facts) {
|
|
7509
7509
|
const base6 = site.replace(/\/+$/, "");
|
|
7510
7510
|
const review = reviewSlugOf(facts);
|
|
7511
|
-
if (review) return `${base6}/pro
|
|
7511
|
+
if (review) return `${base6}/me/pro-asks/${collectionId}`;
|
|
7512
7512
|
const slug = facts.slug ?? (facts.campaign ? slugOfTag(facts.campaign) : null);
|
|
7513
7513
|
return slug ? `${base6}/opencall/${slug}` : `${base6}/t/${collectionId}`;
|
|
7514
7514
|
}
|
|
@@ -7518,7 +7518,10 @@ function answerPage(site, collectionId, claimId, facts) {
|
|
|
7518
7518
|
return review ? `${base6}/pro/reviews/${collectionId}/report/${encodeURIComponent(claimId)}` : `${base6}/r/${collectionId}/trace/${encodeURIComponent(claimId)}`;
|
|
7519
7519
|
}
|
|
7520
7520
|
function inviteLink(site, token, review) {
|
|
7521
|
-
return review ? `${site.replace(/\/+$/, "")}/
|
|
7521
|
+
return review ? `${site.replace(/\/+$/, "")}/i/${token}` : `${site.replace(/\/+$/, "")}/opencall/i/${token}`;
|
|
7522
|
+
}
|
|
7523
|
+
function sitePath(path) {
|
|
7524
|
+
return path.replace(/^\/pro\/reviews\/([^/?#]+)\/with\//, "/me/pro-asks/$1/with/").replace(/^\/pro\/reviews\/([^/?#]+)$/, "/me/pro-asks/$1").replace(/^\/pro\/work(?=\/|$)/, "/me/work").replace(/^\/pro\/i\//, "/i/").replace(/^\/pro\/pros(?=\/|$)/, "/pros");
|
|
7522
7525
|
}
|
|
7523
7526
|
var isReviewTitle, proPage, roomPage;
|
|
7524
7527
|
var init_world = __esm({
|
|
@@ -7526,8 +7529,8 @@ var init_world = __esm({
|
|
|
7526
7529
|
"use strict";
|
|
7527
7530
|
init_callTag();
|
|
7528
7531
|
isReviewTitle = (title) => /^Expert review:/.test(title ?? "");
|
|
7529
|
-
proPage = (site, handle2) => `${site.replace(/\/+$/, "")}/
|
|
7530
|
-
roomPage = (site, collectionId, pro) => `${site.replace(/\/+$/, "")}/pro
|
|
7532
|
+
proPage = (site, handle2) => `${site.replace(/\/+$/, "")}/pros/${handle2}`;
|
|
7533
|
+
roomPage = (site, collectionId, pro) => `${site.replace(/\/+$/, "")}/me/pro-asks/${collectionId}/with/${encodeURIComponent(pro.replace(/^@/, ""))}`;
|
|
7531
7534
|
}
|
|
7532
7535
|
});
|
|
7533
7536
|
|
|
@@ -8093,18 +8096,18 @@ function formAnswersOf(envelope) {
|
|
|
8093
8096
|
for (const key of keys) {
|
|
8094
8097
|
const value = doc[key];
|
|
8095
8098
|
const isFiles = Array.isArray(value) && value.every((one) => one && typeof one === "object" && typeof one.name === "string");
|
|
8096
|
-
const
|
|
8097
|
-
if (
|
|
8098
|
-
let found = deliverable.indexOf(`: ${
|
|
8099
|
-
while (found !== -1 && !(found + 2 +
|
|
8099
|
+
const said4 = isFiles ? value.map((one) => one.name).join(", ") : typeof value === "boolean" ? value ? "yes" : "no" : typeof value === "string" || typeof value === "number" ? String(value) : null;
|
|
8100
|
+
if (said4 === null) return null;
|
|
8101
|
+
let found = deliverable.indexOf(`: ${said4}`, at);
|
|
8102
|
+
while (found !== -1 && !(found + 2 + said4.length === deliverable.length || deliverable[found + 2 + said4.length] === "\n")) found = deliverable.indexOf(`: ${said4}`, found + 1);
|
|
8100
8103
|
if (found === -1) return null;
|
|
8101
8104
|
const label = deliverable.slice(at, found).trim();
|
|
8102
8105
|
if (!label || label.includes("\n")) return null;
|
|
8103
|
-
at = found + 2 +
|
|
8106
|
+
at = found + 2 + said4.length + 1;
|
|
8104
8107
|
if (isFiles) {
|
|
8105
8108
|
const files = value.filter((one) => isStoredFile(one.content)).map((one) => ({ name: one.name.replace(/\s+/g, " ").trim().slice(0, 80) || "file", mediaType: typeof one.type === "string" ? one.type.slice(0, 80) : "application/octet-stream", url: one.content }));
|
|
8106
8109
|
out.push({ label, files });
|
|
8107
|
-
} else out.push({ label, value:
|
|
8110
|
+
} else out.push({ label, value: said4 });
|
|
8108
8111
|
}
|
|
8109
8112
|
return at >= deliverable.length ? out : null;
|
|
8110
8113
|
}
|
|
@@ -8429,24 +8432,24 @@ function blockOf(raw) {
|
|
|
8429
8432
|
return null;
|
|
8430
8433
|
}
|
|
8431
8434
|
function callOf(raw) {
|
|
8432
|
-
const
|
|
8433
|
-
if (!
|
|
8435
|
+
const call3 = raw;
|
|
8436
|
+
if (!call3 || typeof call3 !== "object") return null;
|
|
8434
8437
|
const L4 = CALL_LIMITS;
|
|
8435
|
-
if (typeof
|
|
8436
|
-
if (!CALL_LEGS.includes(
|
|
8437
|
-
if (!line(
|
|
8438
|
-
if (!Array.isArray(
|
|
8439
|
-
const money2 =
|
|
8438
|
+
if (typeof call3.slug !== "string" || !CALL_SLUG.test(call3.slug)) return null;
|
|
8439
|
+
if (!CALL_LEGS.includes(call3.leg)) return null;
|
|
8440
|
+
if (!line(call3.title, L4.title) || !line(call3.lede, L4.lede) || !line(call3.poster, L4.poster)) return null;
|
|
8441
|
+
if (!Array.isArray(call3.points) || call3.points.length === 0 || call3.points.length > L4.lines || !call3.points.every((one) => finite(one) && one >= 0 && one <= 100)) return null;
|
|
8442
|
+
const money2 = call3.money;
|
|
8440
8443
|
if (!money2 || typeof money2 !== "object") return null;
|
|
8441
8444
|
if (!amount(money2.prize) || !whole(money2.runnersN, 0, 5) || !amount(money2.runnersEach) || !amount(money2.entryEach) || !whole(money2.entryUpTo, 1, 1e4)) return null;
|
|
8442
|
-
const share =
|
|
8445
|
+
const share = call3.share;
|
|
8443
8446
|
if (share !== void 0 && (!share || typeof share !== "object" || !nonNegative(share.network) || !nonNegative(share.node) || share.network + share.node >= 100)) return null;
|
|
8444
|
-
const named =
|
|
8447
|
+
const named = call3.sponsor;
|
|
8445
8448
|
const sponsor = named && typeof named === "object" && typeof named.slug === "string" && CALL_SLUG.test(named.slug) && line(named.name, L4.sponsorName) && typeof named.node === "string" && ENTITY_DID.test(named.node) ? named : void 0;
|
|
8446
|
-
if (!date5(
|
|
8449
|
+
if (!date5(call3.closes) || !date5(call3.drop) || !date5(call3.pick)) return null;
|
|
8447
8450
|
let legs;
|
|
8448
|
-
if (
|
|
8449
|
-
const raw2 =
|
|
8451
|
+
if (call3.legs !== void 0) {
|
|
8452
|
+
const raw2 = call3.legs;
|
|
8450
8453
|
if (!raw2 || typeof raw2 !== "object") return null;
|
|
8451
8454
|
legs = {};
|
|
8452
8455
|
for (const name8 of CALL_LEGS) {
|
|
@@ -8456,42 +8459,42 @@ function callOf(raw) {
|
|
|
8456
8459
|
legs[name8] = id;
|
|
8457
8460
|
}
|
|
8458
8461
|
}
|
|
8459
|
-
if (!Array.isArray(
|
|
8460
|
-
const blocks =
|
|
8462
|
+
if (!Array.isArray(call3.blocks) || call3.blocks.length > L4.blocks) return null;
|
|
8463
|
+
const blocks = call3.blocks.map(blockOf);
|
|
8461
8464
|
if (blocks.some((block2) => block2 === null)) return null;
|
|
8462
8465
|
let review = null;
|
|
8463
|
-
if (
|
|
8464
|
-
if (
|
|
8465
|
-
const subject =
|
|
8466
|
+
if (call3.kind !== void 0) {
|
|
8467
|
+
if (call3.kind !== "review" || call3.mode !== "hire") return null;
|
|
8468
|
+
const subject = call3.subject;
|
|
8466
8469
|
if (subject !== void 0) {
|
|
8467
8470
|
if (!subject || typeof subject !== "object" || !line(subject.name, L4.subjectName)) return null;
|
|
8468
8471
|
if (subject.version !== void 0 && !line(subject.version, L4.version)) return null;
|
|
8469
8472
|
if (subject.where !== void 0 && !line(subject.where, L4.where)) return null;
|
|
8470
8473
|
}
|
|
8471
|
-
if (
|
|
8474
|
+
if (call3.scenarios !== void 0 && (!Array.isArray(call3.scenarios) || call3.scenarios.length === 0 || call3.scenarios.length > L4.scenarios || !call3.scenarios.every((one) => line(one, L4.scenario)))) return null;
|
|
8472
8475
|
review = {
|
|
8473
8476
|
kind: "review",
|
|
8474
8477
|
...subject ? { subject: { name: subject.name, ...subject.version !== void 0 ? { version: subject.version } : {}, ...subject.where !== void 0 ? { where: subject.where } : {} } } : {},
|
|
8475
|
-
...
|
|
8478
|
+
...call3.scenarios !== void 0 ? { scenarios: [...call3.scenarios] } : {}
|
|
8476
8479
|
};
|
|
8477
8480
|
}
|
|
8478
8481
|
return {
|
|
8479
8482
|
call: {
|
|
8480
|
-
slug:
|
|
8481
|
-
leg:
|
|
8483
|
+
slug: call3.slug,
|
|
8484
|
+
leg: call3.leg,
|
|
8482
8485
|
/* The one literal: anything else is a competition, as every call before it was. */
|
|
8483
|
-
...
|
|
8486
|
+
...call3.mode === "hire" ? { mode: "hire" } : {},
|
|
8484
8487
|
...review ?? {},
|
|
8485
|
-
title:
|
|
8486
|
-
lede:
|
|
8487
|
-
poster:
|
|
8488
|
-
points: [...
|
|
8488
|
+
title: call3.title,
|
|
8489
|
+
lede: call3.lede,
|
|
8490
|
+
poster: call3.poster,
|
|
8491
|
+
points: [...call3.points],
|
|
8489
8492
|
money: { prize: money2.prize, runnersN: money2.runnersN, runnersEach: money2.runnersEach, entryEach: money2.entryEach, entryUpTo: money2.entryUpTo },
|
|
8490
8493
|
...share ? { share: { network: share.network, node: share.node } } : {},
|
|
8491
8494
|
...sponsor ? { sponsor: { slug: sponsor.slug, name: sponsor.name, node: sponsor.node } } : {},
|
|
8492
|
-
closes:
|
|
8493
|
-
drop:
|
|
8494
|
-
pick:
|
|
8495
|
+
closes: call3.closes,
|
|
8496
|
+
drop: call3.drop,
|
|
8497
|
+
pick: call3.pick,
|
|
8495
8498
|
...legs ? { legs } : {},
|
|
8496
8499
|
blocks
|
|
8497
8500
|
}
|
|
@@ -9080,7 +9083,7 @@ function toEngineRubric(terms, binding, options = {}) {
|
|
|
9080
9083
|
const screens = [];
|
|
9081
9084
|
if (PHOTOGRAPH.has(normalized.deliverable.type)) {
|
|
9082
9085
|
const photos = pair && !normalized.site ? [PHOTO, BEFORE_PHOTO] : [PHOTO];
|
|
9083
|
-
const
|
|
9086
|
+
const said4 = (photo) => photos.length === 1 ? "The photograph" : photo === BEFORE_PHOTO ? "The before photograph" : "The after photograph";
|
|
9084
9087
|
const screened2 = (sourced) => {
|
|
9085
9088
|
pending.push(sourced);
|
|
9086
9089
|
screens.push({ ...sourced.gate, when: extRef(sourced.name) });
|
|
@@ -9090,7 +9093,7 @@ function toEngineRubric(terms, binding, options = {}) {
|
|
|
9090
9093
|
screened2({
|
|
9091
9094
|
name: PHOTO_CHECKS.notMarkedGenerated,
|
|
9092
9095
|
send: { photo },
|
|
9093
|
-
gate: { "@type": "Gate", code: codeFor(extra, "not-generated"), reason: `${
|
|
9096
|
+
gate: { "@type": "Gate", code: codeFor(extra, "not-generated"), reason: `${said4(photo)} says of itself that an AI generator made it`, onFail: "reject", class: "invalid_evidence" }
|
|
9094
9097
|
});
|
|
9095
9098
|
}
|
|
9096
9099
|
const judged = normalized.criteria.filter((criterion) => criterion.kind === "judge").length;
|
|
@@ -9117,7 +9120,7 @@ function toEngineRubric(terms, binding, options = {}) {
|
|
|
9117
9120
|
gate: {
|
|
9118
9121
|
"@type": "Gate",
|
|
9119
9122
|
code: codeFor(extra, "not-elsewhere"),
|
|
9120
|
-
reason: `${
|
|
9123
|
+
reason: `${said4(photo)}'s own GPS puts it far from the place reported. Take the photograph at the place you are reporting`,
|
|
9121
9124
|
onFail: "reject",
|
|
9122
9125
|
class: "invalid_evidence"
|
|
9123
9126
|
}
|
|
@@ -9812,6 +9815,13 @@ var init_gateMet = __esm({
|
|
|
9812
9815
|
});
|
|
9813
9816
|
|
|
9814
9817
|
// ../../packages/openhands-sdk/src/data/engineUrl.ts
|
|
9818
|
+
var engineUrl_exports = {};
|
|
9819
|
+
__export(engineUrl_exports, {
|
|
9820
|
+
engineConfigured: () => engineConfigured,
|
|
9821
|
+
engineIssuerKeysUrl: () => engineIssuerKeysUrl,
|
|
9822
|
+
engineReceiptUrl: () => engineReceiptUrl,
|
|
9823
|
+
engineUrl: () => engineUrl
|
|
9824
|
+
});
|
|
9815
9825
|
var engineUrl, engineConfigured, engineReceiptUrl, engineIssuerKeysUrl;
|
|
9816
9826
|
var init_engineUrl = __esm({
|
|
9817
9827
|
"../../packages/openhands-sdk/src/data/engineUrl.ts"() {
|
|
@@ -10087,8 +10097,8 @@ var init_engine = __esm({
|
|
|
10087
10097
|
num = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
10088
10098
|
obj2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
10089
10099
|
withPerson = (gate, verdict, reasonCodes) => {
|
|
10090
|
-
const
|
|
10091
|
-
return
|
|
10100
|
+
const said4 = personGate(gate.code, verdict, reasonCodes);
|
|
10101
|
+
return said4 ? { ...gate, ...said4, joined: true } : gate;
|
|
10092
10102
|
};
|
|
10093
10103
|
codesOf = (raw) => Array.isArray(raw) ? raw.filter((one) => typeof one === "string") : [];
|
|
10094
10104
|
engineStatusOf = (decision) => decision.outcome ?? (decision.verdict === "approve" || decision.verdict === "partial" ? 1 : decision.verdict === "reject" ? 2 : 5);
|
|
@@ -28345,18 +28355,18 @@ function waysIn(org, oracle, sourceId) {
|
|
|
28345
28355
|
`In Claude Code: eval-oracle api review-billing enable --source ${sourceId ?? "<source id>"} --kit ${oracle.url.replace(/\/$/, "")} --cap <dollars> (it previews first; add --yes to sign).`
|
|
28346
28356
|
];
|
|
28347
28357
|
}
|
|
28348
|
-
async function sourceCall(oracleUrl2, audience, mint,
|
|
28358
|
+
async function sourceCall(oracleUrl2, audience, mint, call3, options = {}) {
|
|
28349
28359
|
try {
|
|
28350
|
-
const response = await (options.fetch ?? fetch)(`${base3(oracleUrl2)}${
|
|
28351
|
-
method:
|
|
28360
|
+
const response = await (options.fetch ?? fetch)(`${base3(oracleUrl2)}${call3.path}`, {
|
|
28361
|
+
method: call3.method ?? "GET",
|
|
28352
28362
|
headers: {
|
|
28353
28363
|
accept: "application/json",
|
|
28354
|
-
authorization: `Bearer ${await mint(audience,
|
|
28364
|
+
authorization: `Bearer ${await mint(audience, call3.can, call3.sourceId)}`,
|
|
28355
28365
|
"x-auth-type": "ucan",
|
|
28356
|
-
...
|
|
28357
|
-
...
|
|
28366
|
+
...call3.sourceId ? { "x-source-id": call3.sourceId } : {},
|
|
28367
|
+
...call3.body !== void 0 ? { "content-type": "application/json" } : {}
|
|
28358
28368
|
},
|
|
28359
|
-
...
|
|
28369
|
+
...call3.body !== void 0 ? { body: JSON.stringify(call3.body) } : {},
|
|
28360
28370
|
signal: AbortSignal.timeout(TIMEOUT2)
|
|
28361
28371
|
});
|
|
28362
28372
|
const body = await response.json().catch(() => null);
|
|
@@ -28554,8 +28564,8 @@ function parseChecks(raw) {
|
|
|
28554
28564
|
return raw.flatMap((one) => {
|
|
28555
28565
|
const c = one;
|
|
28556
28566
|
if (!c || typeof c.name !== "string" || c.status !== "ok" && c.status !== "error") return [];
|
|
28557
|
-
const
|
|
28558
|
-
return [{ name: c.name, status: c.status, value: c.value ?? null, reason:
|
|
28567
|
+
const said4 = typeof c.reason === "string" ? c.reason.trim() : "";
|
|
28568
|
+
return [{ name: c.name, status: c.status, value: c.value ?? null, reason: said4 ? said4.length > REASON_MAX ? `${said4.slice(0, REASON_MAX).trimEnd()}\u2026` : said4 : null }];
|
|
28559
28569
|
});
|
|
28560
28570
|
}
|
|
28561
28571
|
function parseReviewerNote(raw) {
|
|
@@ -29605,8 +29615,8 @@ function fileAnswers(files, urlOf = ipfsDocUrl) {
|
|
|
29605
29615
|
};
|
|
29606
29616
|
}
|
|
29607
29617
|
function extensionOf(type) {
|
|
29608
|
-
const
|
|
29609
|
-
switch (
|
|
29618
|
+
const bare2 = (type ?? "").toLowerCase().split(";")[0]?.trim() ?? "";
|
|
29619
|
+
switch (bare2) {
|
|
29610
29620
|
case "image/jpeg":
|
|
29611
29621
|
return ".jpg";
|
|
29612
29622
|
case "image/png":
|
|
@@ -29696,14 +29706,14 @@ function rulesOf(rubric, manifest) {
|
|
|
29696
29706
|
const work = manifest && typeof manifest === "object" ? manifest : {};
|
|
29697
29707
|
const ai = listOf(rub.aiChecks).length ? listOf(rub.aiChecks) : listOf(work.ai && typeof work.ai === "object" ? Object.values(work.ai) : []);
|
|
29698
29708
|
const tasks = listOf(rub.review?.tasks).length ? listOf(rub.review?.tasks) : listOf(work.review?.taskDetails);
|
|
29699
|
-
const
|
|
29709
|
+
const said4 = (kind) => (raw) => {
|
|
29700
29710
|
const text4 = clampText(raw, 300);
|
|
29701
29711
|
return text4 ? [{ text: text4, kind }] : [];
|
|
29702
29712
|
};
|
|
29703
29713
|
return [
|
|
29704
|
-
...listOf(rub.gates).flatMap((gate) =>
|
|
29705
|
-
...ai.flatMap((check2) => (Array.isArray(check2.instructions) ? check2.instructions : []).flatMap(
|
|
29706
|
-
...tasks.flatMap((task) =>
|
|
29714
|
+
...listOf(rub.gates).flatMap((gate) => said4("measure")(gate.reason)),
|
|
29715
|
+
...ai.flatMap((check2) => (Array.isArray(check2.instructions) ? check2.instructions : []).flatMap(said4("judge"))),
|
|
29716
|
+
...tasks.flatMap((task) => said4("attest")(task.prompt))
|
|
29707
29717
|
].slice(0, RULES_MAX);
|
|
29708
29718
|
}
|
|
29709
29719
|
async function readProven(resource2, fetchImpl) {
|
|
@@ -30053,7 +30063,7 @@ function checkEnvelope(input) {
|
|
|
30053
30063
|
if (problems.length) throw new Error(problems.join(" "));
|
|
30054
30064
|
const answered = input.fields.filter((field2) => !isEmpty2(input.values[field2.name]));
|
|
30055
30065
|
const answers = Object.fromEntries(answered.map((field2) => [field2.name, answerOf(field2, input.values[field2.name])]));
|
|
30056
|
-
const
|
|
30066
|
+
const said4 = (field2) => {
|
|
30057
30067
|
const value = input.values[field2.name];
|
|
30058
30068
|
if (field2.type === "file") return filesOf(value).map((file3) => file3.name).join(", ");
|
|
30059
30069
|
if (field2.type === "boolean") return value ? "yes" : "no";
|
|
@@ -30067,7 +30077,7 @@ function checkEnvelope(input) {
|
|
|
30067
30077
|
...input.delegate ? { delegate: input.delegate } : {},
|
|
30068
30078
|
...input.alias ? { alias: input.alias } : {},
|
|
30069
30079
|
...input.via ? { via: input.via } : {},
|
|
30070
|
-
deliverable: answered.map((field2) => `${field2.label}: ${
|
|
30080
|
+
deliverable: answered.map((field2) => `${field2.label}: ${said4(field2)}`).join("\n"),
|
|
30071
30081
|
/* Last: a form question that shares an envelope field's name keeps the person's answer, which is what the checker reads. */
|
|
30072
30082
|
...answers
|
|
30073
30083
|
};
|
|
@@ -250658,10 +250668,10 @@ var require_get_proto = __commonJS({
|
|
|
250658
250668
|
var require_hasown = __commonJS({
|
|
250659
250669
|
"../../node_modules/.pnpm/hasown@2.0.4/node_modules/hasown/index.js"(exports, module) {
|
|
250660
250670
|
"use strict";
|
|
250661
|
-
var
|
|
250671
|
+
var call3 = Function.prototype.call;
|
|
250662
250672
|
var $hasOwn = Object.prototype.hasOwnProperty;
|
|
250663
250673
|
var bind2 = require_function_bind();
|
|
250664
|
-
module.exports = bind2.call(
|
|
250674
|
+
module.exports = bind2.call(call3, $hasOwn);
|
|
250665
250675
|
}
|
|
250666
250676
|
});
|
|
250667
250677
|
|
|
@@ -260049,8 +260059,8 @@ async function uploadToLane(bytes3, contentType3, args) {
|
|
|
260049
260059
|
signal: args.signal ?? AbortSignal.timeout(6e4)
|
|
260050
260060
|
});
|
|
260051
260061
|
if (!response.ok) {
|
|
260052
|
-
const
|
|
260053
|
-
throw new LaneRefused(response.status, `the private store refused the file (${response.status}${
|
|
260062
|
+
const said4 = await response.text().catch(() => "");
|
|
260063
|
+
throw new LaneRefused(response.status, `the private store refused the file (${response.status}${said4 ? `: ${said4.slice(0, 160)}` : ""})`);
|
|
260054
260064
|
}
|
|
260055
260065
|
const meta4 = await response.json();
|
|
260056
260066
|
if (typeof meta4.cid !== "string" || !meta4.cid) throw new LaneRefused(502, "the private store gave no address for the file");
|
|
@@ -260327,8 +260337,8 @@ async function allowOperatorAmounts(collectionId, owner, options) {
|
|
|
260327
260337
|
signal: AbortSignal.timeout(1e4)
|
|
260328
260338
|
});
|
|
260329
260339
|
if (response.ok) return { ok: true };
|
|
260330
|
-
const
|
|
260331
|
-
const message = typeof
|
|
260340
|
+
const said4 = await response.json().catch(() => null) ?? null;
|
|
260341
|
+
const message = typeof said4?.error === "string" ? said4.error : said4?.error?.message ?? said4?.message ?? "";
|
|
260332
260342
|
why = `the oracle answered ${response.status}${message ? ` (${String(message).slice(0, 160)})` : ""}`;
|
|
260333
260343
|
if (response.status === 401 || response.status === 403 || response.status === 400) break;
|
|
260334
260344
|
} catch (error54) {
|
|
@@ -260757,9 +260767,9 @@ function dominantWaste(wastes) {
|
|
|
260757
260767
|
}
|
|
260758
260768
|
function wastesOf(assessment) {
|
|
260759
260769
|
if (!assessment) return [];
|
|
260760
|
-
const
|
|
260770
|
+
const said4 = Array.isArray(assessment.wastes) && assessment.wastes.length > 0 ? assessment.wastes : [assessment.waste];
|
|
260761
260771
|
const kept = [];
|
|
260762
|
-
for (const key of ORDERED_WASTE) if (
|
|
260772
|
+
for (const key of ORDERED_WASTE) if (said4.includes(key) && !kept.includes(key)) kept.push(key);
|
|
260763
260773
|
return kept;
|
|
260764
260774
|
}
|
|
260765
260775
|
function listSays(wastes) {
|
|
@@ -261565,8 +261575,8 @@ function broadcastTimeoutId(error54) {
|
|
|
261565
261575
|
const txId = error54.txId;
|
|
261566
261576
|
if (typeof txId !== "string" || !txId) return null;
|
|
261567
261577
|
const named = error54.name === "TimeoutError";
|
|
261568
|
-
const
|
|
261569
|
-
return named ||
|
|
261578
|
+
const said4 = /was submitted but was not yet found on the chain/i.test(String(error54.message ?? ""));
|
|
261579
|
+
return named || said4 ? txId : null;
|
|
261570
261580
|
}
|
|
261571
261581
|
function refusedAtCheckTx(error54) {
|
|
261572
261582
|
if (!error54 || typeof error54 !== "object") return false;
|
|
@@ -263205,7 +263215,7 @@ function ledeOf(trace) {
|
|
|
263205
263215
|
}
|
|
263206
263216
|
function gatheredDetail(checks) {
|
|
263207
263217
|
const ext = checks.filter((check2) => check2.kind === "ext");
|
|
263208
|
-
const named = [...new Set(ext.map((check2) => words3(check2.name)).filter((
|
|
263218
|
+
const named = [...new Set(ext.map((check2) => words3(check2.name)).filter((said4) => Boolean(said4)))];
|
|
263209
263219
|
const unknown3 = ext.filter((check2) => !words3(check2.name)).length;
|
|
263210
263220
|
const measured = unknown3 ? [...named, unknown3 === 1 ? "one other thing" : `${unknown3} other things`] : named;
|
|
263211
263221
|
const duplicates = checks.some((check2) => check2.kind === "unique");
|
|
@@ -263241,8 +263251,8 @@ function rulesSummary(rules, verdict) {
|
|
|
263241
263251
|
const unreached = total - met - failed;
|
|
263242
263252
|
if (!total) return verdict === "approve" ? "Approved against rules fixed before the work began." : "Decided against rules fixed before the work began.";
|
|
263243
263253
|
if (!failed && !unreached) return `${met} of ${total} ${total === 1 ? "rule" : "rules"} met, against rules fixed before the work began.`;
|
|
263244
|
-
const
|
|
263245
|
-
return `Of ${total} rules, ${list6(
|
|
263254
|
+
const said4 = [`${met} met`, `${failed} not met`, ...unreached ? [`${unreached} not reached`] : []];
|
|
263255
|
+
return `Of ${total} rules, ${list6(said4)}.`;
|
|
263246
263256
|
}
|
|
263247
263257
|
function signedDetail(step) {
|
|
263248
263258
|
const host = issuerHost(step.issuer);
|
|
@@ -263314,8 +263324,8 @@ function sentence3(step) {
|
|
|
263314
263324
|
return `${face ? `${face.text} released` : "released"} to ${step.to}. ${paidDetail(step)}${fee}`;
|
|
263315
263325
|
}
|
|
263316
263326
|
case "recorded": {
|
|
263317
|
-
const
|
|
263318
|
-
return `${
|
|
263327
|
+
const said4 = recordedLine(step.status);
|
|
263328
|
+
return `${said4.line}. ${said4.detail}`;
|
|
263319
263329
|
}
|
|
263320
263330
|
}
|
|
263321
263331
|
}
|
|
@@ -263362,23 +263372,23 @@ function lineSentence(line2) {
|
|
|
263362
263372
|
if (sentence4.length > 300) throw new Error(`a judged line is ${sentence4.length} characters with its failure; the jury reads 300 at most`);
|
|
263363
263373
|
return sentence4;
|
|
263364
263374
|
}
|
|
263365
|
-
function legCall(
|
|
263366
|
-
const read9 = callOf({ ...
|
|
263375
|
+
function legCall(call3, leg) {
|
|
263376
|
+
const read9 = callOf({ ...call3, leg });
|
|
263367
263377
|
if (!read9) throw new Error("the call does not read back: a field is missing, too long, or not an https address");
|
|
263368
263378
|
return read9.call;
|
|
263369
263379
|
}
|
|
263370
263380
|
function taskFor(title, leg, kind) {
|
|
263371
263381
|
const named = title.replace(/\s+/g, " ").trim();
|
|
263372
|
-
const
|
|
263373
|
-
return
|
|
263382
|
+
const said4 = leg === "entries" ? `${kind === "review" ? "Expert review" : "Open call"}: ${named}` : leg === "prize" ? `The pick of the open call: ${named}` : `A runner-up of the open call: ${named}`;
|
|
263383
|
+
return said4.length <= 140 ? said4 : `${said4.slice(0, 139)}\u2026`;
|
|
263374
263384
|
}
|
|
263375
263385
|
function callEntriesTerms(input) {
|
|
263376
263386
|
if (input.lines.length !== CALL_LIMITS.lines) throw new Error(`a call is judged on exactly ${CALL_LIMITS.lines} lines`);
|
|
263377
263387
|
if (input.judge.kind !== "oracle" || !input.judge.address) throw new Error("the entries are judged by the oracle, and it has to be named");
|
|
263378
|
-
const
|
|
263379
|
-
if (
|
|
263380
|
-
if (
|
|
263381
|
-
if (
|
|
263388
|
+
const call3 = legCall(input.call, "entries");
|
|
263389
|
+
if (call3.points.length !== CALL_LIMITS.lines) throw new Error("one score per judged line");
|
|
263390
|
+
if (call3.kind === "review" && !input.report) throw new Error("a review call's entries are reports: say report (the extra sections, or none)");
|
|
263391
|
+
if (call3.kind !== "review" && input.report) throw new Error("only a review call is answered as a report");
|
|
263382
263392
|
if (input.approver !== void 0 && !/^ixo1[a-z0-9]{38,64}$/.test(input.approver)) throw new Error("approver is an ixo1 address");
|
|
263383
263393
|
const criteria = [
|
|
263384
263394
|
{ id: "present", kind: "measure", gate: { id: "non-empty" } },
|
|
@@ -263387,11 +263397,11 @@ function callEntriesTerms(input) {
|
|
|
263387
263397
|
];
|
|
263388
263398
|
const terms = {
|
|
263389
263399
|
v: 2,
|
|
263390
|
-
task: taskFor(
|
|
263400
|
+
task: taskFor(call3.title, "entries", call3.kind),
|
|
263391
263401
|
deliverable: { type: "text", prompt: input.report ? REVIEW_DELIVERABLE_PROMPT : "One page, in your own words, covering all five requirements" },
|
|
263392
|
-
campaign: callTag(
|
|
263402
|
+
campaign: callTag(call3.slug),
|
|
263393
263403
|
...input.access ? { access: input.access } : {},
|
|
263394
|
-
call:
|
|
263404
|
+
call: call3,
|
|
263395
263405
|
criteria,
|
|
263396
263406
|
judge: input.judge,
|
|
263397
263407
|
...input.approver ? { approver: input.approver } : {}
|
|
@@ -263399,17 +263409,17 @@ function callEntriesTerms(input) {
|
|
|
263399
263409
|
return input.report ? withReport(terms, input.report, input.approver ? { v: 2 } : void 0) : terms;
|
|
263400
263410
|
}
|
|
263401
263411
|
function callPickTerms(input) {
|
|
263402
|
-
const
|
|
263403
|
-
if (
|
|
263412
|
+
const call3 = legCall(input.call, input.leg);
|
|
263413
|
+
if (call3.mode === "hire") throw new Error("a hiring call has no pick: the entries are the whole call");
|
|
263404
263414
|
const which = input.leg === "prize" ? "the pick" : "a runner-up";
|
|
263405
263415
|
return {
|
|
263406
263416
|
v: 2,
|
|
263407
|
-
task: taskFor(
|
|
263417
|
+
task: taskFor(call3.title, input.leg),
|
|
263408
263418
|
deliverable: { type: "text", prompt: "Quote the number of your entry, nothing else" },
|
|
263409
|
-
campaign: callTag(
|
|
263419
|
+
campaign: callTag(call3.slug),
|
|
263410
263420
|
...input.access ? { access: input.access } : {},
|
|
263411
|
-
call:
|
|
263412
|
-
criteria: [{ id: "picked", kind: "attest", text: `The poster chose this entry as ${which} of call ${
|
|
263421
|
+
call: call3,
|
|
263422
|
+
criteria: [{ id: "picked", kind: "attest", text: `The poster chose this entry as ${which} of call ${call3.slug}` }],
|
|
263413
263423
|
judge: { kind: "poster" }
|
|
263414
263424
|
};
|
|
263415
263425
|
}
|
|
@@ -263421,8 +263431,8 @@ function callDates(openDays, now3 = Date.now(), mode) {
|
|
|
263421
263431
|
}
|
|
263422
263432
|
return { closes: new Date(closes).toISOString(), drop: new Date(closes + DAY_MS2).toISOString(), pick: new Date(closes + 4 * DAY_MS2).toISOString() };
|
|
263423
263433
|
}
|
|
263424
|
-
function legDays(
|
|
263425
|
-
const until = leg === "entries" ? Date.parse(
|
|
263434
|
+
function legDays(call3, leg, now3 = Date.now()) {
|
|
263435
|
+
const until = leg === "entries" ? Date.parse(call3.closes) : Date.parse(call3.pick) + 7 * DAY_MS2;
|
|
263426
263436
|
return Math.max(1, Math.ceil((until - now3) / DAY_MS2));
|
|
263427
263437
|
}
|
|
263428
263438
|
var ENTRY_MIN_CHARS, REVIEW_LINES, REVIEW_DELIVERABLE_PROMPT, DAY_MS2, legsOf, pickQuota;
|
|
@@ -263442,7 +263452,7 @@ var init_call = __esm({
|
|
|
263442
263452
|
];
|
|
263443
263453
|
REVIEW_DELIVERABLE_PROMPT = "A review report: what you tested, your steps per scenario, each finding with its evidence, how to reproduce it and its severity, what to change, and the limitations";
|
|
263444
263454
|
DAY_MS2 = 24 * 3600 * 1e3;
|
|
263445
|
-
legsOf = (
|
|
263455
|
+
legsOf = (call3) => call3.mode === "hire" ? ["entries"] : ["prize", ...call3.money.runnersN > 0 ? ["runnersUp"] : [], "entries"];
|
|
263446
263456
|
pickQuota = (winners) => winners + 2;
|
|
263447
263457
|
}
|
|
263448
263458
|
});
|
|
@@ -263711,12 +263721,12 @@ __export(callRead_exports, {
|
|
|
263711
263721
|
sharedPay: () => sharedPay,
|
|
263712
263722
|
stageWords: () => stageWords
|
|
263713
263723
|
});
|
|
263714
|
-
function stageWords(
|
|
263715
|
-
if (now3 < Date.parse(
|
|
263716
|
-
if (
|
|
263717
|
-
if (now3 < Date.parse(
|
|
263718
|
-
if (now3 < Date.parse(
|
|
263719
|
-
return `closed; the pick was due ${day(
|
|
263724
|
+
function stageWords(call3, now3 = Date.now()) {
|
|
263725
|
+
if (now3 < Date.parse(call3.closes)) return `open until ${day(call3.closes)}`;
|
|
263726
|
+
if (call3.mode === "hire") return `closed ${day(call3.closes)}; every entry that passed is paid as it is judged`;
|
|
263727
|
+
if (now3 < Date.parse(call3.drop)) return `closed ${day(call3.closes)}; the shortlist shows ${day(call3.drop)}`;
|
|
263728
|
+
if (now3 < Date.parse(call3.pick)) return `closed; the shortlist is out; the pick by ${day(call3.pick)}`;
|
|
263729
|
+
return `closed; the pick was due ${day(call3.pick)}`;
|
|
263720
263730
|
}
|
|
263721
263731
|
function sharedPay(quote, share) {
|
|
263722
263732
|
const leg = grossFor(Math.round(quote * 1e6), share);
|
|
@@ -263749,35 +263759,36 @@ ${block2.prompt}`;
|
|
|
263749
263759
|
}
|
|
263750
263760
|
function callReadout(terms, ctx) {
|
|
263751
263761
|
const amount3 = (value, symbol2) => dollarsOfValue(value, symbol2, ctx.network ?? "mainnet");
|
|
263752
|
-
const
|
|
263753
|
-
const m =
|
|
263754
|
-
const hire =
|
|
263762
|
+
const call3 = terms.call;
|
|
263763
|
+
const m = call3.money;
|
|
263764
|
+
const hire = call3.mode === "hire";
|
|
263755
263765
|
const lines2 = terms.criteria.filter((one) => one.kind === "judge").map((one) => one.text);
|
|
263756
263766
|
const n = countWords(lines2.length || 5);
|
|
263757
|
-
const entriesId =
|
|
263767
|
+
const entriesId = call3.leg === "entries" ? ctx.id : call3.legs?.entries;
|
|
263758
263768
|
const money2 = hire ? [`every entry that passes all ${n} lines is paid ${amount3(m.entryEach, ctx.symbol)}, up to ${m.entryUpTo} ${m.entryUpTo === 1 ? "entry" : "entries"}; there is no pick`] : [
|
|
263759
263769
|
`the pick gets ${amount3(m.prize, ctx.symbol)}`,
|
|
263760
263770
|
m.runnersN > 0 ? `${m.runnersN} runner${m.runnersN === 1 ? "-up gets" : "s-up get"} ${amount3(m.runnersEach, ctx.symbol)} each` : "",
|
|
263761
263771
|
`every entry that passes all ${n} lines is paid ${amount3(m.entryEach, ctx.symbol)}, up to ${m.entryUpTo}`
|
|
263762
263772
|
].filter(Boolean);
|
|
263763
263773
|
const who = terms.access === "invite" ? "By invitation: only the people the poster put on the list can enter. If you were sent a link, pass it as submit_work's `invite`; if your address or page was named, nothing more is needed." : terms.access === "apply" ? "By application: apply_to_call first, with a short note; when the poster says yes, submit_work is admitted." : "Open to anyone.";
|
|
263764
|
-
const review =
|
|
263765
|
-
const shared =
|
|
263766
|
-
const shareLine2 = shared &&
|
|
263767
|
-
const proMoney = review &&
|
|
263774
|
+
const review = call3.kind === "review";
|
|
263775
|
+
const shared = call3.share ? sharedPay(m.entryEach, call3.share) : null;
|
|
263776
|
+
const shareLine2 = shared && call3.share ? `each ${review ? "pro" : hire ? "hired person" : "entry paid"} receives ${amount3(shared.receives, ctx.symbol)} (the leg is ${amount3(shared.leg, ctx.symbol)}; the network keeps ${amount3(shared.keeps, ctx.symbol)}: ${shareWords(call3.share, "as posted")})${hire ? "" : "; the pick's and the runners-up's legs carry the same share on top of theirs"}` : "";
|
|
263777
|
+
const proMoney = review && call3.share && hire ? `Money: ${feeLine({ split: call3.share, net: m.entryEach, symbol: ctx.symbol, network: ctx.network ?? "mainnet" })} Up to ${m.entryUpTo} ${m.entryUpTo === 1 ? "report is" : "reports are"} paid, each one that passes all ${n} lines; there is no pick. Held on the ask's own account before anyone enters.` : null;
|
|
263768
263778
|
const out = [
|
|
263769
|
-
`${review ? "Pro ask" : hire ? "Hiring call" : "Open call"} "${
|
|
263770
|
-
|
|
263771
|
-
|
|
263772
|
-
|
|
263773
|
-
|
|
263774
|
-
...review &&
|
|
263779
|
+
`${review ? "Pro ask" : hire ? "Hiring call" : "Open call"} "${call3.slug}" \xB7 posted by ${call3.poster} \xB7 ${stageWords(call3, ctx.now)}`,
|
|
263780
|
+
/* A pro ask's page is its poster's alone (2026-10-29); an invited pro reads the same ask as their job, under Work. */
|
|
263781
|
+
...review && ctx.site ? [`Its pages: the poster's ${ctx.site.replace(/\/+$/, "")}/me/pro-asks/${ctx.id}; an invited pro's job ${ctx.site.replace(/\/+$/, "")}/me/work/${ctx.id}`] : [],
|
|
263782
|
+
call3.title,
|
|
263783
|
+
call3.lede,
|
|
263784
|
+
...review && call3.subject ? [`Reviewing: ${call3.subject.name}${call3.subject.version ? ` ${call3.subject.version}` : ""}${call3.subject.where ? ` \xB7 ${call3.subject.where}` : ""}. Access details, if any, are in your invitation.`] : [],
|
|
263785
|
+
...review && call3.scenarios?.length ? ["Scenarios, each one a step in your report:", ...call3.scenarios.map((one, index) => ` S${index + 1}. ${one}`)] : [],
|
|
263775
263786
|
proMoney ?? `Money: ${[...money2, shareLine2].filter(Boolean).join("; ")}. Locked in ${hire ? "the ask's own account" : "each leg's own account"} before anyone enters.`,
|
|
263776
263787
|
who,
|
|
263777
|
-
|
|
263788
|
+
call3.leg === "entries" ? review ? `Enter: a review report with screenshots, as submit_work's report and files, collectionId "${ctx.id}"${terms.approver ? `; the AI checks it against the requirements, then ${terms.approver} gives final approval to release payment` : "; the AI checks it against the requirements and a passing report is paid"}. One report per account.` : `Enter: one page of text, in your own words: submit_work collectionId "${ctx.id}". One entry per account.` : `The pick's leg: only the entry the poster picked may claim here, with one line naming it. ${entriesId ? `The entries are ask ${entriesId}.` : "The entries are the call's own ask."}`,
|
|
263778
263789
|
hire ? `Judged: ${n} requirements that every entry must meet. Pass all ${n} and the entry is paid on approval; nobody is picked.` : `Judged: ${n} requirements that every entry must meet. Pass all ${n} and the entry is paid; how clearly it meets each requirement ranks the entries for the pick.`,
|
|
263779
263790
|
"",
|
|
263780
|
-
...
|
|
263791
|
+
...call3.blocks.map(blockText).flatMap((text4) => [text4, ""]),
|
|
263781
263792
|
`The ${n} requirements:`,
|
|
263782
263793
|
...lines2.length ? lines2.map((text4, index) => `${index + 1}. ${text4}`) : ["(on the entries ask)"]
|
|
263783
263794
|
];
|
|
@@ -264274,7 +264285,7 @@ async function postNextLegNow(slug, ctx) {
|
|
|
264274
264285
|
tag: tagOf(draft),
|
|
264275
264286
|
...draft.fields.cover?.url ? { cover: draft.fields.cover.url } : {},
|
|
264276
264287
|
/* A review's page is in its world (world.ts); every other call's on Open Call. */
|
|
264277
|
-
url: draft.fields.kind === "review" ? `${ctx.site.replace(/\/+$/, "")}/pro
|
|
264288
|
+
url: draft.fields.kind === "review" ? `${ctx.site.replace(/\/+$/, "")}/me/pro-asks/${slug}` : `${ctx.site.replace(/\/+$/, "")}/opencall/${slug}`,
|
|
264278
264289
|
...dates?.closes ? { endsAt: new Date(new Date(dates.pick ?? dates.closes).getTime() + 30 * 24 * 3600 * 1e3) } : {}
|
|
264279
264290
|
},
|
|
264280
264291
|
{ onMinted: remember2 }
|
|
@@ -264362,10 +264373,10 @@ function callServerEnv(site, env) {
|
|
|
264362
264373
|
OPENHANDS_MAX_PER_DAY_USD: env.OPENHANDS_MAX_PER_DAY_USD?.trim() || "100"
|
|
264363
264374
|
};
|
|
264364
264375
|
}
|
|
264365
|
-
function confirms(
|
|
264366
|
-
const named = /USDC|PAY|IXO/i.exec(
|
|
264376
|
+
function confirms(said4, totalBase, symbol2) {
|
|
264377
|
+
const named = /USDC|PAY|IXO/i.exec(said4)?.[0]?.toUpperCase();
|
|
264367
264378
|
if (symbol2 && named && named !== symbol2.toUpperCase()) return false;
|
|
264368
|
-
const figure =
|
|
264379
|
+
const figure = said4.replace(/[$,\s]|USDC|PAY|IXO/gi, "");
|
|
264369
264380
|
return /^\d+(\.\d+)?$/.test(figure) && Math.round(Number(figure) * MICRO5) === totalBase;
|
|
264370
264381
|
}
|
|
264371
264382
|
var MICRO5, callsDir, fileOf, askInvitesFile, freshDraft, L3, ENTRIES_MAX, INVITES_MAX, INVITE_NOTE_MAX, ADDRESS2, HANDLE_ITEM, isInviteItem, PRO_ASK_INVITE_ONLY, manyLines, overCap, callTwoCoins, SETTLE_MS, chainCheck, InFlightError, PostRefused, feeUnpaid, said2, indexLookupWith, indexLookup, posting, isAskPending, isTxFailed, tagOf, TESTNET_CALL_DEFAULTS, payWords;
|
|
@@ -264545,6 +264556,14 @@ function readLinkedinMessage(message, expected, now3 = Date.now(), maxAgeMs = ST
|
|
|
264545
264556
|
if (parts.length !== 5 || parts[0] !== "linkedin" || parts[1] !== expected.act || parts[2] !== expected.signer || parts[4] !== expected.digest) return "mismatch";
|
|
264546
264557
|
return fresh(parts[3], now3, maxAgeMs);
|
|
264547
264558
|
}
|
|
264559
|
+
async function cashoutWords(act, signer2, body, now3 = Date.now()) {
|
|
264560
|
+
return cashoutMessage(act, signer2, now3, await digestOf(linkedinBody(body)));
|
|
264561
|
+
}
|
|
264562
|
+
function readCashoutMessage(message, expected, now3 = Date.now(), maxAgeMs = STAFF_PROOF_MAX_AGE_MS) {
|
|
264563
|
+
const parts = message.split(":");
|
|
264564
|
+
if (parts.length !== 5 || parts[0] !== "cashout" || parts[1] !== expected.act || parts[2] !== expected.signer || parts[4] !== expected.digest) return "mismatch";
|
|
264565
|
+
return fresh(parts[3], now3, maxAgeMs);
|
|
264566
|
+
}
|
|
264548
264567
|
async function roomWords(act, signer2, body, now3 = Date.now()) {
|
|
264549
264568
|
return roomMessage(act, signer2, now3, await digestOf(roomBody(body)));
|
|
264550
264569
|
}
|
|
@@ -264641,8 +264660,8 @@ function readHandsRemoveMessage(message, expected) {
|
|
|
264641
264660
|
if (parts.length !== 3 || parts[0] !== "hands-remove" || parts[1] !== expected.address) return "mismatch";
|
|
264642
264661
|
return Number(parts[2]) === expected.prefAt ? "ok" : "mismatch";
|
|
264643
264662
|
}
|
|
264644
|
-
function fresh(
|
|
264645
|
-
const at = Number(
|
|
264663
|
+
function fresh(said4, now3, maxAgeMs) {
|
|
264664
|
+
const at = Number(said4);
|
|
264646
264665
|
if (!Number.isFinite(at)) return "mismatch";
|
|
264647
264666
|
return Math.abs(now3 - at) <= maxAgeMs ? "ok" : "stale";
|
|
264648
264667
|
}
|
|
@@ -264662,7 +264681,7 @@ async function digestOf(value) {
|
|
|
264662
264681
|
const bytes3 = new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(canonicalJson2(value))));
|
|
264663
264682
|
return Array.from(bytes3, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
264664
264683
|
}
|
|
264665
|
-
var PROOF_MAX_AGE_MS2, INVITE_OPS, INVITE_WRITES, inviteOpBody, inviteOpMessage, applyMessage, invitedMessage, answersMessage, READ_PROOF_MAX_AGE_MS, FUTURE_SKEW_MS, LEGACY_WORDS_UNTIL, callsMessage, noticesMessage, tellMessage, NOTICE_KINDS, handsMessage, vettingMineMessage, vettingQueueMessage, STAFF_PROOF_MAX_AGE_MS, vetRequestBody, vetRequestMessage, vetBody, vetMessage, handsRemoveMessage, handsMineMessage, LINKEDIN_ACTS, linkedinBody, linkedinMessage, ROOM_ACTS, roomBody, roomMessage, ROOM_SEND_MAX_AGE_MS, SPONSOR_ACTS, sponsorBody, sponsorMessage, HANDS_SHARE_ACTS, handsShareMessage;
|
|
264684
|
+
var PROOF_MAX_AGE_MS2, INVITE_OPS, INVITE_WRITES, inviteOpBody, inviteOpMessage, applyMessage, invitedMessage, answersMessage, READ_PROOF_MAX_AGE_MS, FUTURE_SKEW_MS, LEGACY_WORDS_UNTIL, callsMessage, noticesMessage, tellMessage, NOTICE_KINDS, handsMessage, vettingMineMessage, vettingQueueMessage, STAFF_PROOF_MAX_AGE_MS, vetRequestBody, vetRequestMessage, vetBody, vetMessage, handsRemoveMessage, handsMineMessage, LINKEDIN_ACTS, linkedinBody, linkedinMessage, CASHOUT_ACTS, cashoutMessage, ROOM_ACTS, roomBody, roomMessage, ROOM_SEND_MAX_AGE_MS, SPONSOR_ACTS, sponsorBody, sponsorMessage, HANDS_SHARE_ACTS, handsShareMessage;
|
|
264666
264685
|
var init_inviteMessages = __esm({
|
|
264667
264686
|
"../../packages/openhands-sdk/src/chain/inviteMessages.ts"() {
|
|
264668
264687
|
"use strict";
|
|
@@ -264697,6 +264716,8 @@ var init_inviteMessages = __esm({
|
|
|
264697
264716
|
return rest;
|
|
264698
264717
|
};
|
|
264699
264718
|
linkedinMessage = (act, signer2, now3 = Date.now(), digest2 = "") => `linkedin:${act}:${signer2}:${now3}:${digest2}`;
|
|
264719
|
+
CASHOUT_ACTS = ["quote", "draft", "status"];
|
|
264720
|
+
cashoutMessage = (act, signer2, now3 = Date.now(), digest2 = "") => `cashout:${act}:${signer2}:${now3}:${digest2}`;
|
|
264700
264721
|
ROOM_ACTS = ["mine", "read", "send", "bring", "export"];
|
|
264701
264722
|
roomBody = (body) => {
|
|
264702
264723
|
const { address: _address, proof: _proof, ...rest } = body;
|
|
@@ -264743,6 +264764,7 @@ var init_inviteAnswer = __esm({
|
|
|
264743
264764
|
var inviteProof_exports = {};
|
|
264744
264765
|
__export(inviteProof_exports, {
|
|
264745
264766
|
AVAILABILITY: () => AVAILABILITY,
|
|
264767
|
+
CASHOUT_ACTS: () => CASHOUT_ACTS,
|
|
264746
264768
|
DOES: () => DOES,
|
|
264747
264769
|
FUTURE_SKEW_MS: () => FUTURE_SKEW_MS,
|
|
264748
264770
|
HANDLE: () => HANDLE,
|
|
@@ -264770,6 +264792,8 @@ __export(inviteProof_exports, {
|
|
|
264770
264792
|
applyMessage: () => applyMessage,
|
|
264771
264793
|
callsMessage: () => callsMessage,
|
|
264772
264794
|
canonicalJson: () => canonicalJson2,
|
|
264795
|
+
cashoutMessage: () => cashoutMessage,
|
|
264796
|
+
cashoutWords: () => cashoutWords,
|
|
264773
264797
|
digestOf: () => digestOf,
|
|
264774
264798
|
fresh: () => fresh,
|
|
264775
264799
|
handsMessage: () => handsMessage,
|
|
@@ -264789,6 +264813,7 @@ __export(inviteProof_exports, {
|
|
|
264789
264813
|
readAnswersMessage: () => readAnswersMessage,
|
|
264790
264814
|
readApplyMessage: () => readApplyMessage,
|
|
264791
264815
|
readCallsMessage: () => readCallsMessage,
|
|
264816
|
+
readCashoutMessage: () => readCashoutMessage,
|
|
264792
264817
|
readHandBlock: () => readHandBlock,
|
|
264793
264818
|
readHandProfile: () => readHandProfile,
|
|
264794
264819
|
readHandsMessage: () => readHandsMessage,
|
|
@@ -265112,6 +265137,7 @@ __export(invites_exports, {
|
|
|
265112
265137
|
inviteItemsOf: () => inviteItemsOf,
|
|
265113
265138
|
linkedinStatus: () => linkedinStatus,
|
|
265114
265139
|
markNoticesRead: () => markNoticesRead,
|
|
265140
|
+
myCalls: () => myCalls,
|
|
265115
265141
|
myInvitations: () => myInvitations,
|
|
265116
265142
|
noticeWords: () => noticeWords,
|
|
265117
265143
|
pageWords: () => pageWords,
|
|
@@ -265254,6 +265280,23 @@ async function myInvitations(site, signer2, fetchImpl) {
|
|
|
265254
265280
|
}
|
|
265255
265281
|
return { invited };
|
|
265256
265282
|
}
|
|
265283
|
+
async function myCalls(site, signer2, fetchImpl) {
|
|
265284
|
+
const calls = [];
|
|
265285
|
+
const person = signer2.principal && signer2.principal !== signer2.address ? signer2.principal : null;
|
|
265286
|
+
for (const onBehalfOf of [null, ...person ? [person] : []]) {
|
|
265287
|
+
const message = callsMessage(signer2.address);
|
|
265288
|
+
const answer = await post(site, "/api/invites/calls", { address: signer2.address, ...onBehalfOf ? { onBehalfOf } : {}, closed: true, proof: { kind: "adr36", message, ...await signWords(signer2.mnemonic, message) } }, fetchImpl);
|
|
265289
|
+
const missed = (why) => ({ calls, missed: `the pro asks of ${onBehalfOf}, the account you act for, could not be read just now (${why})` });
|
|
265290
|
+
if (!answer.ok) {
|
|
265291
|
+
if (!onBehalfOf) return { refused: refusalOf(answer) };
|
|
265292
|
+
return missed(refusalOf(answer));
|
|
265293
|
+
}
|
|
265294
|
+
const rows2 = answer.body.calls ?? [];
|
|
265295
|
+
if (onBehalfOf && rows2.some((one) => one.owner && one.owner !== onBehalfOf)) return missed("the site does not read them for an agent yet");
|
|
265296
|
+
for (const one of rows2) if (!calls.some((seen2) => seen2.collectionId === one.collectionId)) calls.push(one);
|
|
265297
|
+
}
|
|
265298
|
+
return { calls };
|
|
265299
|
+
}
|
|
265257
265300
|
async function readNotices(site, signer2, options = {}, fetchImpl) {
|
|
265258
265301
|
const message = noticesMessage(signer2.address);
|
|
265259
265302
|
const answer = await post(site, "/api/invites/notices", { address: signer2.address, ...signer2.principal ? { onBehalfOf: signer2.principal } : {}, ...options, proof: { kind: "adr36", message, ...await signWords(signer2.mnemonic, message) } }, fetchImpl);
|
|
@@ -265270,7 +265313,7 @@ function noticeWords(notices, site) {
|
|
|
265270
265313
|
return notices.map((one) => {
|
|
265271
265314
|
const room = one.kind === "message" ? /\/with\/([^/?#]+)$/.exec(one.href)?.[1] : void 0;
|
|
265272
265315
|
const next = one.kind === "message" ? `read_messages collectionId "${one.collectionId}"${room ? ` with "${decodeURIComponent(room)}"` : ""}` : one.kind === "application" ? `decide_application "${one.collectionId}"` : one.kind === "link-opened" || one.kind === "invite-accepted" ? `call_invites "${one.collectionId}"` : one.kind === "invite-declined" ? `invite_to_call "${one.collectionId}" (someone else)` : one.kind === "invited" && isReviewTitle(one.title) ? `accept_invitation "${one.collectionId}" or decline_invitation` : one.kind === "declined" ? "" : `read_ask "${one.collectionId}"`;
|
|
265273
|
-
const href = isReviewTitle(one.title) ? one.href.replace(/^\/opencall\/(?!i\/)([a-z][a-z0-9-]{2,39})$/, "/pro
|
|
265316
|
+
const href = sitePath(isReviewTitle(one.title) ? one.href.replace(/^\/opencall\/(?!i\/)([a-z][a-z0-9-]{2,39})$/, one.kind === "invited" ? `/me/work/${one.collectionId}` : "/me/pro-asks/$1") : one.href);
|
|
265274
265317
|
return ` \xB7 ${one.headline}: ${one.line}${/["”.]$/.test(one.line) ? "" : "."} ${base6}${href}${next ? ` \xB7 ${next}` : ""}`;
|
|
265275
265318
|
});
|
|
265276
265319
|
}
|
|
@@ -266191,13 +266234,13 @@ function shortTitle(task, max = TITLE_MAX) {
|
|
|
266191
266234
|
return `${(space > max / 2 ? cut.slice(0, space) : cut).replace(/[\s,;:.-]+$/, "")}\u2026`;
|
|
266192
266235
|
}
|
|
266193
266236
|
function askHead(name8, task) {
|
|
266194
|
-
const
|
|
266237
|
+
const said4 = placeJoined((task ?? "").trim());
|
|
266195
266238
|
const named = (name8 ?? "").trim();
|
|
266196
|
-
if (!
|
|
266239
|
+
if (!said4 || said4 === named) return { title: null, task: null };
|
|
266197
266240
|
const stem = named.replace(/…$/, "").trimEnd();
|
|
266198
|
-
const cut = (named.endsWith("\u2026") || named.length >= 140) &&
|
|
266199
|
-
const heading = cut ? shortTitle(
|
|
266200
|
-
const rest = /[.?!]$/.test(heading) &&
|
|
266241
|
+
const cut = (named.endsWith("\u2026") || named.length >= 140) && said4.startsWith(stem);
|
|
266242
|
+
const heading = cut ? shortTitle(said4) : named;
|
|
266243
|
+
const rest = /[.?!]$/.test(heading) && said4.startsWith(heading) ? said4.slice(heading.length).trim() : said4;
|
|
266201
266244
|
return { title: cut ? heading : null, task: rest || null };
|
|
266202
266245
|
}
|
|
266203
266246
|
var TITLE_MAX, placeJoined;
|
|
@@ -266432,10 +266475,10 @@ function clean5(raw) {
|
|
|
266432
266475
|
return text4.length <= MAX_LENGTH ? text4 : `${text4.slice(0, MAX_LENGTH - 1).trimEnd()}\u2026`;
|
|
266433
266476
|
}
|
|
266434
266477
|
async function placeName(point, zoom, reach = {}) {
|
|
266435
|
-
const
|
|
266478
|
+
const call3 = reach.fetch ?? globalThis.fetch;
|
|
266436
266479
|
const url4 = `${ENDPOINT}?lat=${encodeURIComponent(point.lat)}&lon=${encodeURIComponent(point.lon)}&format=jsonv2&zoom=${encodeURIComponent(zoom)}`;
|
|
266437
266480
|
try {
|
|
266438
|
-
const response = await
|
|
266481
|
+
const response = await call3(url4, {
|
|
266439
266482
|
headers: { "user-agent": USER_AGENT, accept: "application/json" },
|
|
266440
266483
|
signal: AbortSignal.timeout(TIMEOUT_MS6)
|
|
266441
266484
|
});
|
|
@@ -266832,6 +266875,129 @@ var init_takeBack = __esm({
|
|
|
266832
266875
|
}
|
|
266833
266876
|
});
|
|
266834
266877
|
|
|
266878
|
+
// src/cashout.ts
|
|
266879
|
+
var cashout_exports = {};
|
|
266880
|
+
__export(cashout_exports, {
|
|
266881
|
+
cashOut: () => cashOut,
|
|
266882
|
+
cashOutStatus: () => cashOutStatus
|
|
266883
|
+
});
|
|
266884
|
+
async function call2(deps, path, body) {
|
|
266885
|
+
try {
|
|
266886
|
+
const response = await deps.fetch(`${deps.site.replace(/\/+$/, "")}${path}`, {
|
|
266887
|
+
method: body === void 0 ? "GET" : "POST",
|
|
266888
|
+
headers: { accept: "application/json", ...body === void 0 ? {} : { "content-type": "application/json" } },
|
|
266889
|
+
...body === void 0 ? {} : { body: JSON.stringify(body) },
|
|
266890
|
+
signal: AbortSignal.timeout(2e4)
|
|
266891
|
+
});
|
|
266892
|
+
return { status: response.status, body: await response.json().catch(() => ({})) ?? {} };
|
|
266893
|
+
} catch {
|
|
266894
|
+
return { status: 0, body: { error: "asks.world did not answer. Try again shortly." } };
|
|
266895
|
+
}
|
|
266896
|
+
}
|
|
266897
|
+
async function signedCall(deps, act, fields) {
|
|
266898
|
+
const full = { ...fields, ...deps.signer.principal ? { onBehalfOf: deps.signer.principal } : {} };
|
|
266899
|
+
const message = await cashoutWords(act, deps.signer.address, full);
|
|
266900
|
+
return call2(deps, `/api/cashout/${act}`, { address: deps.signer.address, ...full, proof: { kind: "adr36", message, ...await signWords(deps.signer.mnemonic, message) } });
|
|
266901
|
+
}
|
|
266902
|
+
async function cashOut(deps, input) {
|
|
266903
|
+
const person = deps.signer.principal ?? deps.signer.address;
|
|
266904
|
+
const [ready, payBase] = await Promise.all([signedCall(deps, "status", {}), deps.payBase(person)]);
|
|
266905
|
+
if (ready.status !== 200) return said3(ready);
|
|
266906
|
+
const kyc = ready.body.kyc;
|
|
266907
|
+
if (!ready.body.linkedin) return "Cash-out needs your LinkedIn connected first. Next: connect_linkedin (about a minute), then cash_out again.";
|
|
266908
|
+
const available = payBase / 1e6;
|
|
266909
|
+
if (available <= 0) return "You have no PAY to cash out yet.";
|
|
266910
|
+
const kycLine = kyc?.status === "verified" ? "" : kyc?.status === "expired" ? `Your identity check has expired. Renew it first: ${deps.site.replace(/\/+$/, "")}/me/identity` : `Cash-out needs an identity check. If you haven't done it yet, do it first: ${deps.site.replace(/\/+$/, "")}/me/identity`;
|
|
266911
|
+
if (kyc?.status === "expired") return kycLine;
|
|
266912
|
+
const country = input.country?.trim().toUpperCase();
|
|
266913
|
+
if (!country || !/^[A-Z]{2}$/.test(country)) return [`You have $${available.toFixed(2)} in PAY to cash out.`, kycLine, 'Which country are you in? (Ask the person; then call cash_out with country, like "NG" or "DE".)'].filter(Boolean).join("\n");
|
|
266914
|
+
const info = await call2(deps, `/api/cashout/info?country=${country}`);
|
|
266915
|
+
if (info.status !== 200) return said3(info);
|
|
266916
|
+
const methods = info.body.methods ?? [];
|
|
266917
|
+
const fee = info.body.fee;
|
|
266918
|
+
if (!methods.length) return `There's no way to cash out in ${country} yet.`;
|
|
266919
|
+
const chosen2 = methods.find((one) => one.method === input.method);
|
|
266920
|
+
if (!chosen2)
|
|
266921
|
+
return [
|
|
266922
|
+
`You have $${available.toFixed(2)} in PAY. Ways to get paid in ${country}:`,
|
|
266923
|
+
...methods.map((one) => `- ${WAYS[one.method] ?? one.method} (method "${one.method}"): $${one.minUsd} to $${one.maxUsd}`),
|
|
266924
|
+
`Fee: ${fee?.bps ? `${fee.bps / 100}%` : "none"}${fee?.minUsd && Number(fee.minUsd) > 0 ? `, at least $${fee.minUsd}` : ""}.`,
|
|
266925
|
+
kycLine,
|
|
266926
|
+
"(Ask which way and how much; then call cash_out with method and amount_usd.)"
|
|
266927
|
+
].filter(Boolean).join("\n");
|
|
266928
|
+
const amount3 = input.amount_usd?.trim().replace(/^\$/, "");
|
|
266929
|
+
if (!amount3 || !/^\d+(\.\d{1,2})?$/.test(amount3)) return `How much do you want to cash out? You have $${available.toFixed(2)}; this way takes $${chosen2.minUsd} to $${chosen2.maxUsd}. (Then call cash_out with amount_usd, like "25".)`;
|
|
266930
|
+
if (Number(amount3) > available) return `You have $${available.toFixed(2)} in PAY, less than $${amount3}. Pick a smaller amount.`;
|
|
266931
|
+
if (Number(amount3) < Number(chosen2.minUsd)) return `The smallest you can cash out this way is $${chosen2.minUsd}.`;
|
|
266932
|
+
if (Number(amount3) > Number(chosen2.maxUsd)) return `The largest you can cash out this way is $${chosen2.maxUsd}.`;
|
|
266933
|
+
const to = input.to?.trim();
|
|
266934
|
+
if (chosen2.fields.includes("address") && !(to && BASE_ADDRESS.test(to))) return "Which Base address should receive the USDC? (An 0x\u2026 address on Base; then call cash_out with to.)";
|
|
266935
|
+
const quote = await signedCall(deps, "quote", { method: chosen2.method, country, amountUsd: amount3 });
|
|
266936
|
+
if (quote.status !== 201) return said3(quote);
|
|
266937
|
+
const q = quote.body;
|
|
266938
|
+
const receive = `You'll receive $${q.receive?.amount ?? q.amountUsd}${q.receive?.currency && q.receive.currency !== "USD" ? ` in ${q.receive.currency}` : ""} (fee $${q.feeUsd ?? "0.00"}).`;
|
|
266939
|
+
const named = chosen2.fields.includes("accountHolder") ? NAME_LINE : "";
|
|
266940
|
+
if (!input.confirm) return [`Cash out $${q.amountUsd} by ${WAYS[chosen2.method] ?? chosen2.method}${to ? ` to ${to}` : ""}.`, receive, named, kycLine, "Nothing is sent yet. To go ahead, call cash_out again with the same answers and confirm: true."].filter(Boolean).join("\n");
|
|
266941
|
+
const link5 = new URL(`${deps.site.replace(/\/+$/, "")}/me/cash-out`);
|
|
266942
|
+
link5.searchParams.set("quote", String(q.quoteId));
|
|
266943
|
+
link5.searchParams.set("method", chosen2.method);
|
|
266944
|
+
link5.searchParams.set("amount", amount3);
|
|
266945
|
+
link5.searchParams.set("country", country);
|
|
266946
|
+
if (to) link5.searchParams.set("to", to);
|
|
266947
|
+
return [receive, named, `Open this and confirm with one tap: ${link5.toString()}`, "Your money leaves only when you confirm there. I signed nothing. (Later, cash_out_status with the id that page shows says where it stands.)"].filter(Boolean).join("\n");
|
|
266948
|
+
}
|
|
266949
|
+
async function cashOutStatus(deps, id) {
|
|
266950
|
+
const answer = await signedCall(deps, "status", { id });
|
|
266951
|
+
if (answer.status === 404) return `No cash-out "${id}" for you on this network.`;
|
|
266952
|
+
if (answer.status !== 200) return said3(answer);
|
|
266953
|
+
const v = answer.body;
|
|
266954
|
+
const lapsed = id.startsWith("cd_") && (v.state === "open" || v.state === "signing") && Date.parse(v.expiresAt ?? "") <= Date.now();
|
|
266955
|
+
const money2 = v.receive?.amount ? `$${v.receive.amount}${v.receive.currency && v.receive.currency !== "USD" ? ` ${v.receive.currency}` : ""}` : v.quote?.amountUsd ? `$${v.quote.amountUsd}` : "your cash-out";
|
|
266956
|
+
switch (lapsed ? "expired" : v.state) {
|
|
266957
|
+
case "open":
|
|
266958
|
+
case "signing":
|
|
266959
|
+
return `Not confirmed yet: open the confirm link and tap confirm (${money2}).`;
|
|
266960
|
+
case "sent":
|
|
266961
|
+
return "Confirmed. The payout is starting.";
|
|
266962
|
+
case "expired":
|
|
266963
|
+
case "failed":
|
|
266964
|
+
return "This cash-out expired before it was confirmed. Nothing was taken. Start a new one with cash_out.";
|
|
266965
|
+
case "converting":
|
|
266966
|
+
case "taking":
|
|
266967
|
+
case "paying":
|
|
266968
|
+
return `On its way: ${money2}.`;
|
|
266969
|
+
case "paid":
|
|
266970
|
+
return `Paid: ${money2}.`;
|
|
266971
|
+
case "needs_attention":
|
|
266972
|
+
return `Your payout didn't go through: ${v.reason ?? "the payout failed"}. Check your details or pick another way: ${v.fixUrl ?? ""}
|
|
266973
|
+
${NAME_LINE}`;
|
|
266974
|
+
case "not_converted":
|
|
266975
|
+
case "cancelled":
|
|
266976
|
+
return "This cash-out didn't go through, and nothing was taken.";
|
|
266977
|
+
case "refunded":
|
|
266978
|
+
return "Your PAY was sent back to you.";
|
|
266979
|
+
default:
|
|
266980
|
+
return `State: ${v.state ?? "unknown"}.`;
|
|
266981
|
+
}
|
|
266982
|
+
}
|
|
266983
|
+
var WAYS, BASE_ADDRESS, NAME_LINE, said3;
|
|
266984
|
+
var init_cashout = __esm({
|
|
266985
|
+
"src/cashout.ts"() {
|
|
266986
|
+
"use strict";
|
|
266987
|
+
init_accountProof();
|
|
266988
|
+
init_inviteProof();
|
|
266989
|
+
WAYS = {
|
|
266990
|
+
usdc_base: "USDC on Base (any country)",
|
|
266991
|
+
stripe_bank: "Bank account, through Stripe",
|
|
266992
|
+
yellowcard_bank: "Bank account, through Yellow Card",
|
|
266993
|
+
yellowcard_momo: "Mobile money, through Yellow Card"
|
|
266994
|
+
};
|
|
266995
|
+
BASE_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
266996
|
+
NAME_LINE = "The payout account name must match the name on your ID.";
|
|
266997
|
+
said3 = (answer) => answer.status === 503 && answer.body.code === "not-open" ? "Cash-out isn't open on this network yet." : String(answer.body.error ?? `Cash-out refused this (${answer.status}).`);
|
|
266998
|
+
}
|
|
266999
|
+
});
|
|
267000
|
+
|
|
266835
267001
|
// src/pairing.ts
|
|
266836
267002
|
var pairing_exports = {};
|
|
266837
267003
|
__export(pairing_exports, {
|
|
@@ -266876,7 +267042,7 @@ var init_pairing = __esm({
|
|
|
266876
267042
|
CODE = /^[a-f0-9]{16}$/;
|
|
266877
267043
|
memoFor = (code10) => `openhands-connect:${code10}`;
|
|
266878
267044
|
connectLinkWithCode = (site, agent, code10) => `${site}/connect?agent=${encodeURIComponent(agent)}&code=${code10}`;
|
|
266879
|
-
pairingSite = (site,
|
|
267045
|
+
pairingSite = (site, _pairing) => site;
|
|
266880
267046
|
}
|
|
266881
267047
|
});
|
|
266882
267048
|
|
|
@@ -266951,6 +267117,8 @@ function roomRows(counts) {
|
|
|
266951
267117
|
switch (room.key) {
|
|
266952
267118
|
case "page":
|
|
266953
267119
|
return { ...room, figure: null, after: null, ...counts.page === "listed" ? { chip: "Listed" } : counts.page === "private" ? { chip: "Private" } : counts.page === "verify" ? { verify: true } : {} };
|
|
267120
|
+
case "proAsks":
|
|
267121
|
+
return { ...room, ...counted(counts.proAsks ?? null, null) };
|
|
266954
267122
|
case "work":
|
|
266955
267123
|
return { ...room, ...counted(counts.work, "waiting") };
|
|
266956
267124
|
case "messages":
|
|
@@ -266972,6 +267140,7 @@ var init_meRooms = __esm({
|
|
|
266972
267140
|
"use strict";
|
|
266973
267141
|
ROOMS = [
|
|
266974
267142
|
{ key: "page", word: "Your page", href: "/me/page" },
|
|
267143
|
+
{ key: "proAsks", word: "Pro asks", href: "/me/pro-asks" },
|
|
266975
267144
|
{ key: "work", word: "Work", href: "/me/work" },
|
|
266976
267145
|
{ key: "messages", word: "Messages", href: "/me/messages" },
|
|
266977
267146
|
{ key: "inbox", word: "Inbox", href: "/me/check" },
|
|
@@ -266984,6 +267153,53 @@ var init_meRooms = __esm({
|
|
|
266984
267153
|
}
|
|
266985
267154
|
});
|
|
266986
267155
|
|
|
267156
|
+
// src/proAsks.ts
|
|
267157
|
+
var proAsks_exports = {};
|
|
267158
|
+
__export(proAsks_exports, {
|
|
267159
|
+
approvePreview: () => approvePreview,
|
|
267160
|
+
handOver: () => handOver,
|
|
267161
|
+
proAskLines: () => proAskLines,
|
|
267162
|
+
proAsksOf: () => proAsksOf,
|
|
267163
|
+
reportPage: () => reportPage,
|
|
267164
|
+
shortDate: () => shortDate
|
|
267165
|
+
});
|
|
267166
|
+
function proAskLines(site, calls, options = {}) {
|
|
267167
|
+
const now3 = options.now ?? Date.now();
|
|
267168
|
+
const base6 = site.replace(/\/+$/, "");
|
|
267169
|
+
return proAsksOf(calls).flatMap((one) => {
|
|
267170
|
+
const open = isOpen2(one, now3);
|
|
267171
|
+
const parts = [open ? "Open" : "Closed", `${one.count} of ${one.quota} reports`];
|
|
267172
|
+
const closes = open ? shortDate(one.end_date) : "";
|
|
267173
|
+
if (closes) parts.push(`closes ${closes}`);
|
|
267174
|
+
const held = options.held?.get(one.collectionId);
|
|
267175
|
+
if (held) parts.push(`holds ${held}`);
|
|
267176
|
+
const toApprove = options.waiting?.filter((item) => item.collectionId === one.collectionId).length ?? 0;
|
|
267177
|
+
if (toApprove) parts.push(`${toApprove} ${toApprove === 1 ? "report" : "reports"} to approve`);
|
|
267178
|
+
return [`#${one.collectionId} ${bare(one.title)} \xB7 ${parts.join(" \xB7 ")}`, ` ${base6}/me/pro-asks/${one.collectionId}`];
|
|
267179
|
+
});
|
|
267180
|
+
}
|
|
267181
|
+
function approvePreview(site, input) {
|
|
267182
|
+
const page = reportPage(site, input.collectionId, input.claimId);
|
|
267183
|
+
const what = `Approving report ${input.claimId} on pro ask #${input.collectionId} pays ${input.pro}${input.pays ? ` ${input.pays}` : ""} from what the ask holds. Approval is final.`;
|
|
267184
|
+
return input.canSign ? [what, `The report: ${page}`, "", "To approve, call approve_report again with confirm: true."].join("\n") : [what, handOver(site, input), "Nothing was sent."].join("\n");
|
|
267185
|
+
}
|
|
267186
|
+
var bare, shortDate, isOpen2, proAsksOf, reportPage, handOver;
|
|
267187
|
+
var init_proAsks = __esm({
|
|
267188
|
+
"src/proAsks.ts"() {
|
|
267189
|
+
"use strict";
|
|
267190
|
+
init_world();
|
|
267191
|
+
bare = (title) => (title ?? "").replace(/^Expert review:\s*/, "") || "A pro ask";
|
|
267192
|
+
shortDate = (iso) => {
|
|
267193
|
+
const at = iso ? new Date(iso) : null;
|
|
267194
|
+
return at && !Number.isNaN(at.getTime()) ? at.toLocaleDateString("en-GB", { day: "numeric", month: "short", timeZone: "UTC" }) : "";
|
|
267195
|
+
};
|
|
267196
|
+
isOpen2 = (one, now3) => one.state === 0 && (!one.end_date || Date.parse(one.end_date) > now3);
|
|
267197
|
+
proAsksOf = (calls) => calls.filter((one) => isReviewTitle(one.title)).sort((a, b) => Number(b.collectionId) - Number(a.collectionId));
|
|
267198
|
+
reportPage = (site, collectionId, claimId) => `${site.replace(/\/+$/, "")}/pro/reviews/${collectionId}/report/${encodeURIComponent(claimId)}`;
|
|
267199
|
+
handOver = (site, input) => `Only ${input.approver} can give this OK, signed in as themselves: the Approve button on the report's page, ${reportPage(site, input.collectionId, input.claimId)}#decide. This key acts for them but cannot sign their OK at the verifier.`;
|
|
267200
|
+
}
|
|
267201
|
+
});
|
|
267202
|
+
|
|
266987
267203
|
// src/verdictSource.ts
|
|
266988
267204
|
var verdictSource_exports = {};
|
|
266989
267205
|
__export(verdictSource_exports, {
|
|
@@ -292144,7 +292360,7 @@ import { randomBytes as randomBytes7 } from "node:crypto";
|
|
|
292144
292360
|
// package.json
|
|
292145
292361
|
var package_default = {
|
|
292146
292362
|
name: "@ixo/asks-mcp",
|
|
292147
|
-
version: "2.0.0-dev.
|
|
292363
|
+
version: "2.0.0-dev.3",
|
|
292148
292364
|
description: "The Openhands Network MCP server: read the board, answer asks, post work and get paid on the ixo chain, with a key of its own on your machine.",
|
|
292149
292365
|
license: "Apache-2.0",
|
|
292150
292366
|
repository: {
|
|
@@ -292366,6 +292582,20 @@ var TOOLS = {
|
|
|
292366
292582
|
/* A second sweep finds nothing to send: the first one emptied the key. */
|
|
292367
292583
|
annotations: { ...acts, idempotentHint: true }
|
|
292368
292584
|
},
|
|
292585
|
+
cash_out: {
|
|
292586
|
+
title: "Cash out your PAY",
|
|
292587
|
+
description: `Turn the PAY the person earned into money: USDC on Base, or a bank account where offered. One step per call: it reads their PAY, their LinkedIn and identity check, then asks the country, the way to get paid, the amount and (for USDC) the Base address, and shows the quote in plain words ("You'll receive $X (fee $0)"). With confirm: true it gives ONE link: the person opens it and confirms with one tap; that page checks their identity and they sign there. Limits and fees come from IXO's cash-out service, never from here. No LinkedIn: say connect_linkedin first. Signs no money and holds no key of theirs.`,
|
|
292588
|
+
spends: false,
|
|
292589
|
+
hosted: false,
|
|
292590
|
+
annotations: acts
|
|
292591
|
+
},
|
|
292592
|
+
cash_out_status: {
|
|
292593
|
+
title: "Where a cash-out stands",
|
|
292594
|
+
description: "Given a cash-out's id (cd_\u2026 or wd_\u2026, from the confirm page), says where it stands in plain words: waiting for the tap, on its way, paid, or that it didn't go through and where to fix it. Spends nothing.",
|
|
292595
|
+
spends: false,
|
|
292596
|
+
hosted: false,
|
|
292597
|
+
annotations: reads
|
|
292598
|
+
},
|
|
292369
292599
|
my_status: {
|
|
292370
292600
|
title: "This participant's standing",
|
|
292371
292601
|
description: "Address, the account area as seven lines (Your page, Work waiting, Messages unread, Inbox, Money, Agents, Settings, as asks.world/me draws them), what is available and what is on your asks, answers sent, and rewards still owed.",
|
|
@@ -292476,6 +292706,20 @@ var TOOLS = {
|
|
|
292476
292706
|
hosted: false,
|
|
292477
292707
|
annotations: { ...reads, readOnlyHint: true }
|
|
292478
292708
|
},
|
|
292709
|
+
my_pro_asks: {
|
|
292710
|
+
title: "List the pro asks the person posted",
|
|
292711
|
+
description: `The pro asks this key posted, and those of the person it acts for, newest first, one line each as the site's Pro asks room says them: Open or Closed, how many reports of how many, when it closes, what it holds, and what waits for them ("1 report to approve"), with its page, which only they can open. The next step on each is a tool: invite_to_call, collect_answer (reads its reports), approve_report, close_ask. Spends nothing.`,
|
|
292712
|
+
spends: false,
|
|
292713
|
+
hosted: false,
|
|
292714
|
+
annotations: { ...reads, readOnlyHint: true }
|
|
292715
|
+
},
|
|
292716
|
+
approve_report: {
|
|
292717
|
+
title: "Approve a report on a pro ask (spends money)",
|
|
292718
|
+
description: "Give the final OK on one report a pro sent to a pro ask: the verifier records it and the pro is paid from what the ask holds. Approval is final. Call without confirm first: it says the report, who sent it, what approving pays and whose OK it is; then again with confirm: true, which approves when this key is the one the ask names to give the OK. When the OK is the person's own (a pro ask posted for them), it hands them the report's Approve button on the site instead, and sends nothing.",
|
|
292719
|
+
spends: true,
|
|
292720
|
+
hosted: false,
|
|
292721
|
+
annotations: acts
|
|
292722
|
+
},
|
|
292479
292723
|
accept_invitation: {
|
|
292480
292724
|
title: "Accept an invitation to a pro ask",
|
|
292481
292725
|
description: "Accept an invitation to a pro ask: a link or the ask's number. As the account you act for when connected, else as this key. The builder hears you accepted, and your room with them opens with their note first; a link becomes yours, so nobody else can use it. Someone who is not a verified pro is refused, and the link stays open. Previews; `confirm: true` accepts, once the person says yes. Spends nothing.",
|
|
@@ -292949,17 +293193,17 @@ function measureOf(reason) {
|
|
|
292949
293193
|
function reasonText(reason) {
|
|
292950
293194
|
const rest = reason.detail.startsWith(`${reason.label}: `) ? reason.detail.slice(reason.label.length + 2) : reason.detail;
|
|
292951
293195
|
const measure = measureOf(reason);
|
|
292952
|
-
const
|
|
292953
|
-
const sayMeasured = reason.value !== void 0 &&
|
|
292954
|
-
return [sayMeasured ? "" : measure,
|
|
293196
|
+
const said4 = rest === reason.label || rest === RESULT_WORD[reason.result] || rest === "Did not pass" ? "" : rest;
|
|
293197
|
+
const sayMeasured = reason.value !== void 0 && said4.startsWith(num2(reason.value, reason.unit));
|
|
293198
|
+
return [sayMeasured ? "" : measure, said4].filter(Boolean).join(". ");
|
|
292955
293199
|
}
|
|
292956
293200
|
var evidenceLine = (why) => why.evidenceGrade ? `Time/place: ${why.evidenceGrade}` : null;
|
|
292957
293201
|
function whyLines(why, indent3 = "") {
|
|
292958
293202
|
if (!why) return [`${indent3}${WHY_UNREADABLE}.`];
|
|
292959
293203
|
const lines2 = [`${indent3}${why.summary}`];
|
|
292960
293204
|
for (const reason of why.reasons) {
|
|
292961
|
-
const
|
|
292962
|
-
lines2.push(`${indent3} ${RESULT_WORD[reason.result]}: ${reason.label}${
|
|
293205
|
+
const said4 = reasonText(reason);
|
|
293206
|
+
lines2.push(`${indent3} ${RESULT_WORD[reason.result]}: ${reason.label}${said4 ? ` \u2014 ${said4}` : ""}`);
|
|
292963
293207
|
}
|
|
292964
293208
|
const evidence = evidenceLine(why);
|
|
292965
293209
|
if (evidence) lines2.push(`${indent3}${evidence}`);
|
|
@@ -293098,8 +293342,8 @@ function whyFromReceipt(receipt, rubric) {
|
|
|
293098
293342
|
const push = (r) => {
|
|
293099
293343
|
const clean6 = { ...r, label: scrub(r.label, 200), detail: scrub(r.detail) };
|
|
293100
293344
|
const key = `${clean6.result}|${clean6.label}`;
|
|
293101
|
-
const
|
|
293102
|
-
if (seen2.has(`${key}|${clean6.detail}`) ||
|
|
293345
|
+
const bare2 = clean6.detail === "Passed" || clean6.detail === "Did not pass";
|
|
293346
|
+
if (seen2.has(`${key}|${clean6.detail}`) || bare2 && seen2.has(key)) return;
|
|
293103
293347
|
seen2.add(key).add(`${key}|${clean6.detail}`);
|
|
293104
293348
|
reasons.push(clean6);
|
|
293105
293349
|
};
|
|
@@ -294368,10 +294612,10 @@ To go ahead, call again with confirm: "${token}".`;
|
|
|
294368
294612
|
return chargeDay(args.bucket, args.total);
|
|
294369
294613
|
}
|
|
294370
294614
|
const withNotes = (guard, notes) => {
|
|
294371
|
-
const
|
|
294372
|
-
return guard.startsWith("Refused") ||
|
|
294615
|
+
const said4 = notes.filter((note) => Boolean(note));
|
|
294616
|
+
return guard.startsWith("Refused") || said4.length === 0 ? guard : `${guard}
|
|
294373
294617
|
|
|
294374
|
-
${
|
|
294618
|
+
${said4.join("\n")}`;
|
|
294375
294619
|
};
|
|
294376
294620
|
const principal2 = async () => actingFor2(await address2());
|
|
294377
294621
|
const unchosen = async () => {
|
|
@@ -294540,18 +294784,18 @@ Each is its own ask and pays on its own. Read one with read_ask before deciding.
|
|
|
294540
294784
|
calls.set(tag, { slug, entries: entries2, shared });
|
|
294541
294785
|
})
|
|
294542
294786
|
);
|
|
294543
|
-
const callLine = (row,
|
|
294787
|
+
const callLine = (row, call3) => {
|
|
294544
294788
|
const summary = row.campaignSummary;
|
|
294545
|
-
const review = isReviewTitle(
|
|
294546
|
-
const title =
|
|
294789
|
+
const review = isReviewTitle(call3.entries?.title);
|
|
294790
|
+
const title = call3.entries?.title.replace(/^(Open call|Expert review): /, "") ?? null;
|
|
294547
294791
|
if (title) taint2(title);
|
|
294548
294792
|
const facts = row.callSummary;
|
|
294549
|
-
const shares =
|
|
294550
|
-
const entryPays = shares && facts?.entryEach !== void 0 &&
|
|
294793
|
+
const shares = call3.shared;
|
|
294794
|
+
const entryPays = shares && facts?.entryEach !== void 0 && call3.entries?.pays ? `${faceOf2({ value: facts.entryEach, symbol: call3.entries.pays.symbol }, SANDBOX)?.text} (the network's share is on top of it)` : call3.entries?.pays ? `${faceOf2(call3.entries.pays, SANDBOX)?.text}${shares ? ", less the network's share" : ""}` : void 0;
|
|
294551
294795
|
return [
|
|
294552
|
-
`${review ? "Expert review" : "Open call"} "${
|
|
294796
|
+
`${review ? "Expert review" : "Open call"} "${call3.slug}" \xB7 ${summary.open} of ${summary.places} legs open${entryPays ? ` \xB7 every ${review ? "report" : "entry"} that meets the bar is paid ${entryPays}` : ""} \xB7 needs-a-human`,
|
|
294553
294797
|
title ? asData("ask-title", title) : "",
|
|
294554
|
-
`${review ? "A specialist's report on the review's scenarios, assessed against its requirements. A report that meets them is paid, after the builder's final approval when they give one." : "A written entry assessed against five requirements. Entries that meet all five are paid. For competitions, the poster also chooses a prize winner."} ${
|
|
294798
|
+
`${review ? "A specialist's report on the review's scenarios, assessed against its requirements. A report that meets them is paid, after the builder's final approval when they give one." : "A written entry assessed against five requirements. Entries that meet all five are paid. For competitions, the poster also chooses a prize winner."} ${call3.entries ? `Read it with read_ask "${call3.entries.id}"; the page is` : "Read its legs on the page:"} ${review ? `${EXPERT_SITE}/me/pro-asks/${call3.entries?.id ?? call3.slug}` : `${SITE}/opencall/${call3.slug}`}`
|
|
294555
294799
|
].filter(Boolean).join("\n");
|
|
294556
294800
|
};
|
|
294557
294801
|
const lines2 = board.rows.filter(within2).map((row) => {
|
|
@@ -294569,8 +294813,8 @@ Each is its own ask and pays on its own. Read one with read_ask before deciding.
|
|
|
294569
294813
|
}
|
|
294570
294814
|
if ((row.card === "campaign" || row.card === "call") && row.campaignSummary) {
|
|
294571
294815
|
const summary = row.campaignSummary;
|
|
294572
|
-
const
|
|
294573
|
-
if (
|
|
294816
|
+
const call3 = calls.get(summary.tag);
|
|
294817
|
+
if (call3) return callLine(row, call3);
|
|
294574
294818
|
const low = summary.low ? faceOf2(summary.low, SANDBOX)?.text : void 0;
|
|
294575
294819
|
const high = summary.high ? faceOf2(summary.high, SANDBOX)?.text : void 0;
|
|
294576
294820
|
const range = summary.pool || !low ? "paid from pools" : high && high !== low ? `${low} to ${high} a place` : `${low} a place`;
|
|
@@ -294821,13 +295065,13 @@ You cannot complete it, and trying would spend the gate's network fee to be reje
|
|
|
294821
295065
|
});
|
|
294822
295066
|
if (!granted.ok) {
|
|
294823
295067
|
const body = await granted.text();
|
|
294824
|
-
let
|
|
295068
|
+
let said4 = body.slice(0, 200);
|
|
294825
295069
|
try {
|
|
294826
295070
|
const parsed = JSON.parse(body);
|
|
294827
|
-
if (typeof parsed.error === "string" && parsed.error)
|
|
295071
|
+
if (typeof parsed.error === "string" && parsed.error) said4 = parsed.error.replace(/\.?$/, ".");
|
|
294828
295072
|
} catch {
|
|
294829
295073
|
}
|
|
294830
|
-
return `The gate refused: ${
|
|
295074
|
+
return `The gate refused: ${said4}`;
|
|
294831
295075
|
}
|
|
294832
295076
|
return null;
|
|
294833
295077
|
};
|
|
@@ -294872,9 +295116,9 @@ You cannot complete it, and trying would spend the gate's network fee to be reje
|
|
|
294872
295116
|
...lane ? { private: true, fit: lane.fit, upload: lane.store.upload, fetchBack: lane.store.fetchBack, publish: lane.store.publish } : {}
|
|
294873
295117
|
};
|
|
294874
295118
|
const who = { submitter, ...acting ? { delegate: actor.address } : {}, ...alias ? { alias } : {} };
|
|
294875
|
-
const
|
|
294876
|
-
if (
|
|
294877
|
-
return text4(withAccepted(expertAsk &&
|
|
295119
|
+
const said4 = report ? await sendReport({ collectionId, report, paths: files ?? [], requirement, ...uses_memory ? { usesMemory: true } : {}, ...who }, world) : await sendFields({ fields: expertAsk.check.fields, values: fields, collectionId, ...who }, world);
|
|
295120
|
+
if (said4.startsWith("Answered")) nudge("scan", collectionId, expertAsk?.checker ?? (await Promise.resolve().then(() => (init_call2(), call_exports2))).nudgeAtFor(NETWORK2, judgeAddress));
|
|
295121
|
+
return text4(withAccepted(expertAsk && said4.startsWith("Answered") ? said4.replace(/^(Answered #\d+ as \S+)\./, `$1, for ${expertAsk.checker.name} to check.`) : said4));
|
|
294878
295122
|
}
|
|
294879
295123
|
const refusedToPrepare = await prepare2();
|
|
294880
295124
|
if (refusedToPrepare) return text4(withAccepted(refusedToPrepare));
|
|
@@ -295278,18 +295522,18 @@ ${SITE}/t/${earlier.id}`);
|
|
|
295278
295522
|
const callPerCheck = async (checker = CHECKER) => (await Promise.resolve().then(() => (init_reviewBilling(), reviewBilling_exports))).deploymentBillsPerCheck(checker).catch(() => false);
|
|
295279
295523
|
const callChecker2 = async (review) => (await Promise.resolve().then(() => (init_call2(), call_exports2))).callChecker(NETWORK2, review, CHECKER);
|
|
295280
295524
|
const callSplit = async () => (await Promise.resolve().then(() => (init_query43(), query_exports43))).feeSplitOrNull();
|
|
295281
|
-
async function sharedPays(leg, posted,
|
|
295525
|
+
async function sharedPays(leg, posted, bare2 = false) {
|
|
295282
295526
|
if (leg?.is_oracle_payment !== true || !leg.amount?.[0]) return null;
|
|
295283
295527
|
const { coinDisplay: coinDisplay2, faceOf: faceOf2 } = await Promise.resolve().then(() => (init_format(), format_exports));
|
|
295284
295528
|
const { netOf: netOf2 } = await Promise.resolve().then(() => (init_share(), share_exports));
|
|
295285
295529
|
const { shareWords: shareWords2 } = await Promise.resolve().then(() => (init_callRead(), callRead_exports));
|
|
295286
295530
|
const { denom, amount: amount3 } = leg.amount[0];
|
|
295287
|
-
const
|
|
295531
|
+
const said4 = (base6) => faceOf2(coinDisplay2([{ denom, amount: String(base6) }]), SANDBOX)?.text ?? "see the record";
|
|
295288
295532
|
const split3 = posted ?? await callSplit();
|
|
295289
|
-
if (!split3) return `${
|
|
295533
|
+
if (!split3) return `${said4(Number(amount3))} less the network's share (the fee split could not be read just now)`;
|
|
295290
295534
|
const receives = netOf2(Number(amount3), split3);
|
|
295291
|
-
if (
|
|
295292
|
-
return `${
|
|
295535
|
+
if (bare2) return said4(receives);
|
|
295536
|
+
return `${said4(receives)} (the leg is ${said4(Number(amount3))}; the network keeps ${said4(Number(amount3) - receives)}: ${shareWords2(split3, posted ? "as posted" : "today")})`;
|
|
295293
295537
|
}
|
|
295294
295538
|
const callLocks = (rewardBase, feeBase, symbol2 = ASK_SYMBOL) => `${pays(rewardBase, symbol2)}${feeBase > 0 ? ` and ${feeWords(feeBase)} for reviews` : ""}`;
|
|
295295
295539
|
function escrowTotal(pay, spots, legBase, symbol2 = ASK_SYMBOL, sameCoin = true, feeSymbol = FEE_SYMBOL) {
|
|
@@ -295897,11 +296141,42 @@ Left on this key: ${skipped.length === 1 ? "a coin" : `${skipped.length} coins`}
|
|
|
295897
296141
|
],
|
|
295898
296142
|
"earnings home"
|
|
295899
296143
|
);
|
|
295900
|
-
const
|
|
295901
|
-
return text4(`Sent ${
|
|
296144
|
+
const said4 = coinsSaid(moving);
|
|
296145
|
+
return text4(`Sent ${said4} to ${home}.
|
|
295902
296146
|
tx ${result.transactionHash}${leftWords}`);
|
|
295903
296147
|
}
|
|
295904
296148
|
);
|
|
296149
|
+
const cashoutDeps = async () => {
|
|
296150
|
+
const acting = await principal2();
|
|
296151
|
+
const key = await loadKey2();
|
|
296152
|
+
return { site: SITE, signer: { address: await address2(), mnemonic: key.mnemonic, principal: acting?.principal ?? null }, fetch: fetch2 };
|
|
296153
|
+
};
|
|
296154
|
+
if (offered("cash_out")) server2.registerTool(
|
|
296155
|
+
"cash_out",
|
|
296156
|
+
{
|
|
296157
|
+
...meta3("cash_out"),
|
|
296158
|
+
inputSchema: {
|
|
296159
|
+
country: external_exports.string().max(2).optional().describe("Where the person lives: two letters, like NG or DE."),
|
|
296160
|
+
method: external_exports.string().max(40).optional().describe("The way to get paid, as cash_out listed it (like usdc_base)."),
|
|
296161
|
+
amount_usd: external_exports.string().max(12).optional().describe('How much, in dollars, like "25" or "25.50".'),
|
|
296162
|
+
to: external_exports.string().max(64).optional().describe("USDC on Base only: the 0x\u2026 address that receives it."),
|
|
296163
|
+
confirm: external_exports.boolean().optional().describe("true, after the person said yes to the quote: gives the one link to confirm.")
|
|
296164
|
+
}
|
|
296165
|
+
},
|
|
296166
|
+
async (args) => {
|
|
296167
|
+
const { cashOut: cashOut2 } = await Promise.resolve().then(() => (init_cashout(), cashout_exports));
|
|
296168
|
+
const participant = await Promise.resolve().then(() => (init_src5(), src_exports4));
|
|
296169
|
+
return text4(await cashOut2({ ...await cashoutDeps(), payBase: async (who) => Number((await participant.balancesOf(who)).upay ?? 0) }, args));
|
|
296170
|
+
}
|
|
296171
|
+
);
|
|
296172
|
+
if (offered("cash_out_status")) server2.registerTool(
|
|
296173
|
+
"cash_out_status",
|
|
296174
|
+
{ ...meta3("cash_out_status"), inputSchema: { id: external_exports.string().regex(/^(cd|wd)_[a-z2-7]{24}$/).describe("The cash-out's id, cd_\u2026 or wd_\u2026.") } },
|
|
296175
|
+
async ({ id }) => {
|
|
296176
|
+
const { cashOutStatus: cashOutStatus2 } = await Promise.resolve().then(() => (init_cashout(), cashout_exports));
|
|
296177
|
+
return text4(await cashOutStatus2(await cashoutDeps(), id));
|
|
296178
|
+
}
|
|
296179
|
+
);
|
|
295905
296180
|
if (offered("set_payout_settings")) {
|
|
295906
296181
|
server2.registerTool("set_payout_settings", { ...meta3("set_payout_settings"), inputSchema: settingsInput }, async (args) => {
|
|
295907
296182
|
const { readOrgPayouts: readOrgPayouts2, facilitatorHealth: facilitatorHealth2, oracleResolves: oracleResolves2 } = await Promise.resolve().then(() => (init_orgPayouts(), orgPayouts_exports));
|
|
@@ -296174,10 +296449,11 @@ ${pending.link}`);
|
|
|
296174
296449
|
})();
|
|
296175
296450
|
const rooms = await (async () => {
|
|
296176
296451
|
try {
|
|
296177
|
-
const [{ roomLines: roomLines2 }, invitesModule, roomsModule] = await Promise.all([Promise.resolve().then(() => (init_meRooms(), meRooms_exports)), Promise.resolve().then(() => (init_invites(), invites_exports)), Promise.resolve().then(() => (init_rooms(), rooms_exports))]);
|
|
296452
|
+
const [{ roomLines: roomLines2 }, invitesModule, roomsModule, { proAsksOf: proAsksOf2 }] = await Promise.all([Promise.resolve().then(() => (init_meRooms(), meRooms_exports)), Promise.resolve().then(() => (init_invites(), invites_exports)), Promise.resolve().then(() => (init_rooms(), rooms_exports)), Promise.resolve().then(() => (init_proAsks(), proAsks_exports))]);
|
|
296178
296453
|
const signer3 = await inviteSigner(await principal2());
|
|
296179
|
-
const [page, invited, mineRooms, waiting, agents] = await Promise.all([
|
|
296454
|
+
const [page, calls, invited, mineRooms, waiting, agents] = await Promise.all([
|
|
296180
296455
|
invitesModule.readMyPage(SITE, signer3).catch(() => void 0),
|
|
296456
|
+
invitesModule.myCalls(SITE, signer3).catch(() => null),
|
|
296181
296457
|
invitesModule.myInvitations(SITE, signer3).catch(() => null),
|
|
296182
296458
|
roomsModule.myRooms(SITE, signer3).catch(() => null),
|
|
296183
296459
|
fetch2(`${SITE}/api/waiting?address=${encodeURIComponent(signer3.address)}`, { signal: AbortSignal.timeout(2e4) }).then((r) => r.ok ? r.json() : null).catch(() => null),
|
|
@@ -296188,6 +296464,7 @@ ${pending.link}`);
|
|
|
296188
296464
|
"You, as the account area says it:",
|
|
296189
296465
|
...roomLines2({
|
|
296190
296466
|
page: page === void 0 ? null : page === null ? "none" : !verified ? "verify" : page.profile.listed === false ? "private" : "listed",
|
|
296467
|
+
proAsks: calls && "calls" in calls ? proAsksOf2(calls.calls).length : null,
|
|
296191
296468
|
work: invited && "invited" in invited ? invited.invited.filter((one) => one.answer === "sent").length : null,
|
|
296192
296469
|
unread: mineRooms && "rooms" in mineRooms ? mineRooms.rooms.reduce((sum2, one) => sum2 + one.unread, 0) : null,
|
|
296193
296470
|
inbox: Array.isArray(waiting?.waiting) ? waiting.waiting.length : null,
|
|
@@ -296259,7 +296536,7 @@ ${pending.link}`);
|
|
|
296259
296536
|
const { needsChain: needsChain2, verdictFacts: verdictFacts2 } = await Promise.resolve().then(() => (init_verdictSource(), verdictSource_exports));
|
|
296260
296537
|
const onChain = needsChain2(ours.evaluationByClaimId) ? await (await Promise.resolve().then(() => (init_claimVerdict(), claimVerdict_exports))).claimVerdictOnChain(ours.claimId) : null;
|
|
296261
296538
|
const facts = verdictFacts2(ours.evaluationByClaimId, onChain);
|
|
296262
|
-
const
|
|
296539
|
+
const said4 = verdictSays2(facts.status);
|
|
296263
296540
|
const paid = faceOf2(coinDisplay2(facts.amount ?? void 0), SANDBOX);
|
|
296264
296541
|
const arrived = paid && facts.amount?.length ? await sharedPays({ amount: facts.amount, is_oracle_payment: receipt.payments?.["approval"]?.is_oracle_payment }, null) : null;
|
|
296265
296542
|
const proofRaw = facts.verificationProof;
|
|
@@ -296276,7 +296553,7 @@ ${pending.link}`);
|
|
|
296276
296553
|
return checkFailed2(await readHeldClaim2(ask.oracle.url, key, ours.claimId));
|
|
296277
296554
|
} : void 0;
|
|
296278
296555
|
const why = await whyBlock(ours.claimId, proofRaw, ours.agentAddress === mine ? mint : void 0, failed ? { failed } : {});
|
|
296279
|
-
return text4([`#${collectionId}: ${
|
|
296556
|
+
return text4([`#${collectionId}: ${said4}.${paid ? ` Paid ${arrived ?? paid.text}.` : ""}`, `answer ${ours.claimId}`, `${SITE}/r/${collectionId}/trace/${encodeURIComponent(ours.claimId)}`, ...why, ...steps, ...tail].join("\n"));
|
|
296280
296557
|
}
|
|
296281
296558
|
if (local) {
|
|
296282
296559
|
server2.registerTool(
|
|
@@ -296468,27 +296745,27 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
296468
296745
|
}
|
|
296469
296746
|
},
|
|
296470
296747
|
async ({ slug: named, clear, ...input }) => {
|
|
296471
|
-
const
|
|
296748
|
+
const call3 = await Promise.resolve().then(() => (init_call2(), call_exports2));
|
|
296472
296749
|
const { CALL_SLUG: CALL_SLUG2 } = await Promise.resolve().then(() => (init_terms(), terms_exports));
|
|
296473
|
-
if (
|
|
296474
|
-
const slug = named?.trim() ||
|
|
296750
|
+
if (call3.typedText(input).some((one) => isTainted(one))) return text4(TAINT_REFUSAL);
|
|
296751
|
+
const slug = named?.trim() || call3.nextSlug();
|
|
296475
296752
|
if (!CALL_SLUG2.test(slug)) return text4(`"${slug}" cannot name a call: lowercase letters, digits and dashes, starting with a letter, 3 to 40 long. Nothing was saved.`);
|
|
296476
|
-
const existing =
|
|
296753
|
+
const existing = call3.readDraft(slug);
|
|
296477
296754
|
const posted = existing ? Object.values(existing.posted).some(Boolean) || Boolean(existing.inFlight) : false;
|
|
296478
296755
|
const changing = clear || Object.values(input).some((value) => value !== void 0);
|
|
296479
296756
|
if (posted && changing) return text4(`Call "${slug}" is already posted: its terms were frozen with the money. Start a new call with another slug.`);
|
|
296480
|
-
const start = clear || !existing ?
|
|
296481
|
-
const merged =
|
|
296482
|
-
const coin =
|
|
296757
|
+
const start = clear || !existing ? call3.freshDraft(slug) : existing;
|
|
296758
|
+
const merged = call3.mergeDraft(start, input);
|
|
296759
|
+
const coin = call3.callCoin(merged.draft, NETWORK2, ASK_DENOM);
|
|
296483
296760
|
if (typeof coin !== "string") return text4(`Refused: ${coin.refused}. Nothing was saved.`);
|
|
296484
296761
|
const refused2 = merged.refused;
|
|
296485
296762
|
const draft = coin !== ASK_DENOM ? { ...merged.draft, coin } : merged.draft;
|
|
296486
|
-
|
|
296763
|
+
call3.writeDraft(draft);
|
|
296487
296764
|
const coinSymbol = symbolOf(coin);
|
|
296488
296765
|
const acting = await principal2();
|
|
296489
296766
|
const held = await heldBy(acting, coin);
|
|
296490
296767
|
const holds = held === null ? null : pays(held.reward, coinSymbol);
|
|
296491
|
-
const missing2 =
|
|
296768
|
+
const missing2 = call3.missingOf(draft.fields, { symbol: coinSymbol, holds });
|
|
296492
296769
|
const out = [`Draft "${slug}" saved${posted ? " (posted)" : ""}.`];
|
|
296493
296770
|
if (refused2.length) out.push("", "Not taken:", ...refused2.map((one) => ` - ${one}`));
|
|
296494
296771
|
if (missing2.length) {
|
|
@@ -296497,7 +296774,7 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
296497
296774
|
"Still needed, in this order. Ask the person, a group at a time, in their words; never write the brief for them:",
|
|
296498
296775
|
...missing2.flatMap((one, index) => [` ${index + 1}. ${one.field}: ${one.question}`, ` e.g. ${one.example}`])
|
|
296499
296776
|
);
|
|
296500
|
-
const optional5 =
|
|
296777
|
+
const optional5 = call3.optionalOf(draft.fields, originOf(NETWORK2));
|
|
296501
296778
|
if (optional5.length) out.push("", "Optional, not given yet:", ...optional5.map((one) => ` - ${one}`));
|
|
296502
296779
|
return text4(out.join("\n"));
|
|
296503
296780
|
}
|
|
@@ -296507,20 +296784,20 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
296507
296784
|
const checker = await callChecker2(draft.fields.kind === "review");
|
|
296508
296785
|
if (checker.fee && checker.fee.denom !== coin) return text4(`Refused: ${checker.name} is paid in another coin than this call pays in, and a review pays in its verifier's coin. Start a new review.`);
|
|
296509
296786
|
const perCheck = checker.fee ? false : await callPerCheck(checker.address);
|
|
296510
|
-
const priced =
|
|
296787
|
+
const priced = call3.callShare(draft.fields, call3.callShares(draft.fields) ? await callSplit() : null);
|
|
296511
296788
|
if ("unread" in priced) {
|
|
296512
296789
|
out.push("", "Not priced yet: this call is a hire by invitation or application, which carries the network's share, and the fee split could not be read just now. The draft is saved; call draft_call again in a minute.");
|
|
296513
296790
|
return text4(out.join("\n"));
|
|
296514
296791
|
}
|
|
296515
296792
|
const proAsk = draft.fields.kind === "review";
|
|
296516
|
-
const plan =
|
|
296793
|
+
const plan = call3.callPlan(draft, { poster: shortPoster, checkerLegBase: (terms) => checker.fee ? checker.fee.base : perCheck ? 0 : checkerLegBase2(FEE_DENOM, terms, CHECK_REWARD), oracle: checker.address || "the verifier", share: priced.share, feeInReward: Boolean(checker.fee) || coin === FEE_DENOM });
|
|
296517
296794
|
const feeTotal = plan.legs.reduce((sum2, one) => sum2 + one.feeBase, 0);
|
|
296518
296795
|
const finalOk = draft.fields.kind === "review" ? acting?.principal ?? null : null;
|
|
296519
|
-
const preview =
|
|
296520
|
-
const twoCoins = acting && feeTotal > 0 ? `Can't post as ${acting.principal}: ${
|
|
296796
|
+
const preview = call3.legTerms(draft, "entries", { poster: shortPoster, dates: plan.dates, oracle: { kind: "oracle", address: checker.address || "the verifier" }, approver: finalOk, share: plan.share });
|
|
296797
|
+
const twoCoins = acting && feeTotal > 0 ? `Can't post as ${acting.principal}: ${call3.callTwoCoins}.` : null;
|
|
296521
296798
|
const { capCoinRefusal: capCoinRefusal2, capIn: capIn2 } = await Promise.resolve().then(() => (init_hq(), hq_exports));
|
|
296522
296799
|
const otherCoin = capCoinRefusal2(acting, coin, checker.fee ? `${SITE}/connect` : void 0);
|
|
296523
|
-
const capped4 =
|
|
296800
|
+
const capped4 = call3.capWords(plan.legs, CAP_BASE, coinSymbol, NETWORK2);
|
|
296524
296801
|
const keyOnly = !acting && feeTotal > 0;
|
|
296525
296802
|
const blocked = capped4.length > 0 || Boolean(otherCoin) || Boolean(twoCoins) && draft.fields.kind !== "review";
|
|
296526
296803
|
const m = draft.fields.money;
|
|
@@ -296540,15 +296817,15 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
296540
296817
|
!hire && m.prize < m.entryEach ? `The prize (${face(m.prize, coinSymbol)}) is less than one entry earns (${face(m.entryEach, coinSymbol)}).` : "",
|
|
296541
296818
|
draft.fields.access === "invite" && !draft.fields.invite?.length ? proAsk ? "Nobody invited yet: find_pro suggests verified pros; add them with invite now, or invite_to_call after it posts." : 'By invitation, and nobody invited yet: add invite (addresses, @handles, "link") now, or invite_to_call after it posts.' : "",
|
|
296542
296819
|
draft.fields.access === "apply" ? "By application: people apply on the call's page or with apply_to_call; you say yes with decide_application before they can enter." : "",
|
|
296543
|
-
...
|
|
296820
|
+
...call3.balanceWarnings(held, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
|
|
296544
296821
|
acting?.cap && !otherCoin && Number(capIn2(acting, coin)?.remainingBase ?? 0) < plan.totalBase ? `Their cap has ${pays(Number(capIn2(acting, coin)?.remainingBase ?? 0), coinSymbol)} left; the call locks ${pays(plan.totalBase, coinSymbol)}. They raise it at ${SITE}/connect.` : "",
|
|
296545
|
-
keyOnly ? `Not connected, and a connection would not carry this call: ${
|
|
296822
|
+
keyOnly ? `Not connected, and a connection would not carry this call: ${call3.callTwoCoins}. With plain_key: true it posts as this key itself, ${await address2()}, from its own money.` : !acting ? `Not connected: post_call refuses until the person connects this key (connect_account gives them the link). For a rehearsal, plain_key: true posts as this key itself, ${await address2()}, from its own money.` : ""
|
|
296546
296823
|
].filter(Boolean);
|
|
296547
296824
|
out.push(
|
|
296548
296825
|
"",
|
|
296549
296826
|
blocked ? "Drafted, but post_call would refuse it as it stands (the warnings say why). This is the call as an entrant's AI will read it:" : "Ready. This is the call as an entrant's AI will read it:",
|
|
296550
296827
|
"",
|
|
296551
|
-
|
|
296828
|
+
call3.callReadout(preview, { id: "(the entries ask, once posted)", symbol: coinSymbol, network: NETWORK2 }),
|
|
296552
296829
|
"",
|
|
296553
296830
|
"What each leg locks:",
|
|
296554
296831
|
...legRows,
|
|
@@ -296562,7 +296839,7 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
296562
296839
|
`Who may enter: ${draft.fields.access === "invite" ? `by invitation only${draft.fields.invite?.length ? `. ${draft.fields.invite.length} people will be invited when the Ask is posted${draft.fields.inviteNote ? ", each with your private note" : ""}` : ""}` : draft.fields.access === "apply" ? "by application, listed on the board" : "anyone, listed on the board"}.`,
|
|
296563
296840
|
...draft.fields.kind === "review" ? [
|
|
296564
296841
|
`A pro ask: every entry is a review report with screenshots (submit_work's report and files), checked by ${checker.name ?? "the AI"} on the lines${acting ? `, then ${acting.principal} gives final approval before anyone is paid` : `; posted from this key itself, ${checker.name ?? "the AI"} decides alone and passing reports are paid as they are judged`}.`,
|
|
296565
|
-
draft.posted.entries ? `Its page: ${EXPERT_SITE}/pro
|
|
296842
|
+
draft.posted.entries ? `Its page: ${EXPERT_SITE}/me/pro-asks/${draft.posted.entries.id}` : "Its page is named by the pro ask's number, given once it posts."
|
|
296566
296843
|
] : [],
|
|
296567
296844
|
...warnings2.length ? ["", "Warnings:", ...warnings2.map((one) => ` - ${one}`)] : [],
|
|
296568
296845
|
"",
|
|
@@ -296585,17 +296862,17 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
296585
296862
|
},
|
|
296586
296863
|
async ({ slug, confirm, plain_key, pay_by }) => {
|
|
296587
296864
|
const card = pay_by === "card";
|
|
296588
|
-
const
|
|
296589
|
-
const found =
|
|
296865
|
+
const call3 = await Promise.resolve().then(() => (init_call2(), call_exports2));
|
|
296866
|
+
const found = call3.readDraft(slug);
|
|
296590
296867
|
if (!found) return text4(`No draft called "${slug}". Start one with draft_call.`);
|
|
296591
296868
|
const review = found.fields.kind === "review";
|
|
296592
296869
|
const checker = await callChecker2(review);
|
|
296593
|
-
const linkOf = (posted2) => review ? `${EXPERT_SITE}/pro
|
|
296594
|
-
const settled = found.inFlight ? await
|
|
296870
|
+
const linkOf = (posted2) => review ? `${EXPERT_SITE}/me/pro-asks/${posted2.entries?.id ?? slug}` : `${SITE}/opencall/${slug}`;
|
|
296871
|
+
const settled = found.inFlight ? await call3.settleInFlight(slug, call3.indexLookup) : null;
|
|
296595
296872
|
if (settled?.state === "pending") return text4(settled.words);
|
|
296596
296873
|
if (settled?.state === "landed") {
|
|
296597
296874
|
nudge("hire", settled.id, checker.at);
|
|
296598
|
-
const after2 =
|
|
296875
|
+
const after2 = call3.nextLeg(settled.draft);
|
|
296599
296876
|
return text4(
|
|
296600
296877
|
[
|
|
296601
296878
|
`The earlier post landed: ${LEG_WORDS[settled.leg]} is #${settled.id}. It is recorded, and nothing was posted twice.`,
|
|
@@ -296604,14 +296881,14 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
296604
296881
|
);
|
|
296605
296882
|
}
|
|
296606
296883
|
const draft = settled?.draft ?? found;
|
|
296607
|
-
const coin =
|
|
296884
|
+
const coin = call3.callCoin(draft, NETWORK2, ASK_DENOM);
|
|
296608
296885
|
if (typeof coin !== "string") return text4(`Refused: ${coin.refused}. Nothing was posted.`);
|
|
296609
296886
|
const coinSymbol = symbolOf(coin);
|
|
296610
|
-
const next =
|
|
296887
|
+
const next = call3.nextLeg(draft);
|
|
296611
296888
|
const ids = ["prize", "runnersUp", "entries"].flatMap((leg2) => draft.posted[leg2] ? [`${LEG_WORDS[leg2]} #${draft.posted[leg2].id}`] : []);
|
|
296612
296889
|
if (!next) return text4(`Everything is posted: ${ids.join(", ")}.
|
|
296613
296890
|
The call: ${linkOf(draft.posted)}`);
|
|
296614
|
-
if (!
|
|
296891
|
+
if (!call3.isReady(draft.fields)) return text4(`"${slug}" is not ready: ${call3.missingOf(draft.fields, { symbol: coinSymbol, holds: null }).map((one) => one.field).join(", ")} still missing. Finish it with draft_call.`);
|
|
296615
296892
|
const cannot = await unjudged();
|
|
296616
296893
|
if (cannot) return text4(cannot);
|
|
296617
296894
|
if (!checker.address) return text4("No verifier is configured on this deployment, so nothing could judge the entries. Refusing rather than posting a call nobody can settle.");
|
|
@@ -296626,15 +296903,15 @@ Then call post_call again. Nothing was posted.`);
|
|
|
296626
296903
|
const poster = acting?.principal ?? await address2();
|
|
296627
296904
|
if (checker.fee && checker.fee.denom !== coin) return text4(`Refused: ${checker.name} is paid in another coin than this call pays in, and a review pays in its verifier's coin. Start a new review. Nothing was posted.`);
|
|
296628
296905
|
const perCheck = checker.fee ? false : await callPerCheck(checker.address);
|
|
296629
|
-
const split3 =
|
|
296630
|
-
const priced =
|
|
296631
|
-
if ("unread" in priced) return text4(
|
|
296632
|
-
const plan =
|
|
296906
|
+
const split3 = call3.callShares(draft.fields) ? await callSplit() : null;
|
|
296907
|
+
const priced = call3.callShare(draft.fields, split3);
|
|
296908
|
+
if ("unread" in priced) return text4(call3.SHARE_UNREAD);
|
|
296909
|
+
const plan = call3.callPlan(draft, { poster: `${poster.slice(0, 10)}\u2026${poster.slice(-4)}`, checkerLegBase: (terms) => checker.fee ? checker.fee.base : perCheck ? 0 : checkerLegBase2(FEE_DENOM, terms, CHECK_REWARD), oracle: checker.address, share: priced.share, feeInReward: Boolean(checker.fee) || coin === FEE_DENOM });
|
|
296633
296910
|
const feeTotal = plan.legs.reduce((sum2, one) => sum2 + one.feeBase, 0);
|
|
296634
296911
|
const total = pays(plan.totalBase, coinSymbol);
|
|
296635
296912
|
const { feeLine: feeLine2 } = await Promise.resolve().then(() => (init_feeLine(), feeLine_exports));
|
|
296636
296913
|
const moneySentence = review && plan.share ? feeLine2({ split: plan.share, net: draft.fields.money.entryEach, symbol: coinSymbol, network: NETWORK2 }) : null;
|
|
296637
|
-
if (acting && feeTotal > 0) return text4(`Refused: ${
|
|
296914
|
+
if (acting && feeTotal > 0) return text4(`Refused: ${call3.callTwoCoins}.${review ? ` ${PLAIN_REVIEW}` : ""} Nothing was posted.`);
|
|
296638
296915
|
const approver = review && acting ? acting.principal : null;
|
|
296639
296916
|
if (approver) {
|
|
296640
296917
|
const notReady = await approverRefusal(approver, async (who) => (await Promise.resolve().then(() => (init_personReview(), personReview_exports))).approverReady(who, { self: true }));
|
|
@@ -296668,21 +296945,21 @@ Then call post_call again. Nothing was posted.`);
|
|
|
296668
296945
|
actingNote(acting) ?? (review ? "Posting from your own account (this key), not the person's account; the AI decides each report alone, with no final OK from the person." : `Posting as this key, ${poster}.`),
|
|
296669
296946
|
...pick2 ? [pick2] : [],
|
|
296670
296947
|
`Spent today (call): ${spentWords("call", coinSymbol)}. Every tool together: ${spentAllWords()}.`,
|
|
296671
|
-
...
|
|
296672
|
-
...
|
|
296948
|
+
...call3.capWords(plan.legs.filter((one) => !draft.posted[one.leg]), CAP_BASE, coinSymbol, NETWORK2),
|
|
296949
|
+
...call3.balanceWarnings(held2, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
|
|
296673
296950
|
"",
|
|
296674
296951
|
`To go ahead, call again with confirm: "${total}".`
|
|
296675
296952
|
].join("\n")
|
|
296676
296953
|
);
|
|
296677
296954
|
}
|
|
296678
|
-
if (!
|
|
296679
|
-
if (
|
|
296955
|
+
if (!call3.confirms(confirm, plan.totalBase, coinSymbol)) return text4(`Refused: confirm said "${confirm}" but the call locks ${total}. Preview it again.`);
|
|
296956
|
+
if (call3.overCap(leg, CAP_BASE)) return text4(`Refused: this leg locks ${pays(leg.escrowBase, coinSymbol)}, over your own ${face(MAX_PER_ASK, coinSymbol)} per-ask cap (OPENHANDS_MAX_PER_ASK_USD, which you set: raise or remove it where you set it). Paying by card (pay_by "card") is not capped.`);
|
|
296680
296957
|
if (ids.length === 0) {
|
|
296681
|
-
const taken = await fetch2(`${SITE}/api/board?campaign=${encodeURIComponent(
|
|
296958
|
+
const taken = await fetch2(`${SITE}/api/board?campaign=${encodeURIComponent(call3.tagOf(draft))}&size=5`, { signal: AbortSignal.timeout(15e3) }).then((response) => response.ok ? response.json() : null).catch(() => null);
|
|
296682
296959
|
if (taken?.rows?.length) return text4(`Refused: "${slug}" already names a call with open Asks on this board. Draft it under another slug with draft_call. Nothing was posted.`);
|
|
296683
296960
|
}
|
|
296684
296961
|
const { balancesOfStrict: balancesOfStrict2 } = await Promise.resolve().then(() => (init_balance(), balance_exports));
|
|
296685
|
-
const refusedBefore = await
|
|
296962
|
+
const refusedBefore = await call3.preCheck(leg, {
|
|
296686
296963
|
acting,
|
|
296687
296964
|
poster,
|
|
296688
296965
|
askDenom: coin,
|
|
@@ -296699,7 +296976,7 @@ Then call post_call again. Nothing was posted.`);
|
|
|
296699
296976
|
const key = await loadKey2();
|
|
296700
296977
|
let posted;
|
|
296701
296978
|
try {
|
|
296702
|
-
posted = await
|
|
296979
|
+
posted = await call3.postNextLeg(slug, {
|
|
296703
296980
|
site: SITE,
|
|
296704
296981
|
askDenom: coin,
|
|
296705
296982
|
checker: checker.address,
|
|
@@ -296715,10 +296992,10 @@ Then call post_call again. Nothing was posted.`);
|
|
|
296715
296992
|
feeSplit: split3
|
|
296716
296993
|
});
|
|
296717
296994
|
} catch (error54) {
|
|
296718
|
-
if (error54 instanceof
|
|
296995
|
+
if (error54 instanceof call3.InFlightError || error54 instanceof call3.PostRefused) return text4(error54.message);
|
|
296719
296996
|
if (isUnanchored(error54)) return text4(unanchoredWords(error54));
|
|
296720
296997
|
if (error54 instanceof Error && error54.name === "TxFailed") {
|
|
296721
|
-
if (
|
|
296998
|
+
if (call3.feeUnpaid(error54, coin)) return text4(`Nothing moved: this agent's key could not pay the network fee for ${LEG_WORDS[next]}. Call post_call again in a minute; it arranges the fee before it signs anything. If it is refused again, tell the person the network fee could not be arranged just now.`);
|
|
296722
296999
|
return text4(`The network refused ${LEG_WORDS[next]}: ${error54.message}. Nothing moved. Fix that (often what the account holds, or its cap) and call post_call again.`);
|
|
296723
297000
|
}
|
|
296724
297001
|
return text4(
|
|
@@ -296728,7 +297005,7 @@ Then call post_call again. Nothing was posted.`);
|
|
|
296728
297005
|
if ("done" in posted) return text4(`Everything is posted.
|
|
296729
297006
|
The call: ${linkOf(posted.draft.posted)}`);
|
|
296730
297007
|
const done = order2.filter((one) => posted.draft.posted[one]).length;
|
|
296731
|
-
const after =
|
|
297008
|
+
const after = call3.nextLeg(posted.draft);
|
|
296732
297009
|
const hire = posted.draft.fields.mode === "hire";
|
|
296733
297010
|
const held = posted.screen?.verdict === "hold" ? heldWords(posted.screen.reason) : null;
|
|
296734
297011
|
const invited = !after && posted.draft.fields.access && posted.draft.fields.access !== "public" ? await writeDraftInvites(posted.draft, posted.id, acting) : null;
|
|
@@ -296951,7 +297228,7 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every rep
|
|
|
296951
297228
|
const answer = await invitesModule.myInvitations(SITE, signer3);
|
|
296952
297229
|
if ("refused" in answer) return text4(`Refused: ${answer.refused}`);
|
|
296953
297230
|
const missed = answer.missed ? `Not shown: ${answer.missed}.` : "";
|
|
296954
|
-
if (answer.invited.length === 0) return text4([`Nothing yet: no poster has put this key${signer3.principal && signer3.principal !== signer3.address ? ", or the person it acts for," : ""} on a list. A person's own invitations are also on the site, signed in: ${EXPERT_SITE}/
|
|
297231
|
+
if (answer.invited.length === 0) return text4([`Nothing yet: no poster has put this key${signer3.principal && signer3.principal !== signer3.address ? ", or the person it acts for," : ""} on a list. A person's own invitations are also on the site, signed in: ${EXPERT_SITE}/me/work for pro asks, ${SITE}/opencall for other calls.`, missed].filter(Boolean).join("\n"));
|
|
296955
297232
|
const rooms = await roomsModule.myRooms(SITE, signer3).catch(() => ({ refused: "unreachable" }));
|
|
296956
297233
|
const roomOf = "refused" in rooms ? null : new Map(rooms.rooms.filter((one) => one.role === "pro").map((one) => [one.collectionId, one]));
|
|
296957
297234
|
const me = roomsModule.actorOf(signer3);
|
|
@@ -296959,7 +297236,7 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every rep
|
|
|
296959
297236
|
[
|
|
296960
297237
|
"Invited to:",
|
|
296961
297238
|
...answer.invited.flatMap((one) => [
|
|
296962
|
-
` #${one.collectionId}${one.title ? ` \xB7 ${one.title}` : ""}${one.answer ? ` \xB7 ${invitesModule.answerLine(one)}` : ""}${one.campaign?.startsWith("call-") ? ` \xB7 ${isReviewTitle(one.title) ? `${EXPERT_SITE}/
|
|
297239
|
+
` #${one.collectionId}${one.title ? ` \xB7 ${one.title}` : ""}${one.answer ? ` \xB7 ${invitesModule.answerLine(one)}` : ""}${one.campaign?.startsWith("call-") ? ` \xB7 ${isReviewTitle(one.title) ? `${EXPERT_SITE}/me/work/${one.collectionId}` : askPage(SITE, one.collectionId, { campaign: one.campaign, title: one.title })}` : ""} \xB7 ${one.answer === "sent" ? `accept_invitation "${one.collectionId}" or decline_invitation` : `read_ask "${one.collectionId}"`}`,
|
|
296963
297240
|
...one.note ? [` The poster's note to you: ${asData("invitation-note", one.note)}`] : [],
|
|
296964
297241
|
...roomOf ? [roomsModule.invitationRoomLine(one, roomOf.get(one.collectionId) ?? null, { site: SITE, me })].filter((line2) => Boolean(line2)) : []
|
|
296965
297242
|
]),
|
|
@@ -296973,12 +297250,78 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every rep
|
|
|
296973
297250
|
const peeked = await invitesModule.peekInvitation(SITE, which.token).catch(() => null);
|
|
296974
297251
|
return peeked ? `pro ask #${peeked.collectionId}${peeked.title ? ` (${peeked.title.replace(/^Expert review:\s*/, "")})` : ""}` : "the pro ask this link names";
|
|
296975
297252
|
};
|
|
297253
|
+
if (offered("my_pro_asks")) server2.registerTool("my_pro_asks", { ...meta3("my_pro_asks"), inputSchema: {} }, async () => {
|
|
297254
|
+
const [invitesModule, proAsksModule] = await Promise.all([Promise.resolve().then(() => (init_invites(), invites_exports)), Promise.resolve().then(() => (init_proAsks(), proAsks_exports))]);
|
|
297255
|
+
const signer3 = await inviteSigner(await principal2());
|
|
297256
|
+
const answer = await invitesModule.myCalls(SITE, signer3);
|
|
297257
|
+
if ("refused" in answer) return text4(`Refused: ${answer.refused}`);
|
|
297258
|
+
const missed = answer.missed ? `Not shown: ${answer.missed}.` : "";
|
|
297259
|
+
const asks = proAsksModule.proAsksOf(answer.calls);
|
|
297260
|
+
if (asks.length === 0) return text4([`No pro asks yet${signer3.principal && signer3.principal !== signer3.address ? " from this key or the person it acts for" : ""}. draft_call with kind "review" sets one up.`, missed].filter(Boolean).join("\n"));
|
|
297261
|
+
const owners = [...new Set(asks.map((one) => one.owner ?? signer3.address))];
|
|
297262
|
+
const [held, waiting] = await Promise.all([
|
|
297263
|
+
(async () => {
|
|
297264
|
+
const { asksHolding: asksHolding2 } = await Promise.resolve().then(() => (init_onAsks(), onAsks_exports));
|
|
297265
|
+
const { graphqlUrl: graphqlUrl4, restUrl: restUrl2 } = await Promise.resolve().then(() => (init_env(), env_exports));
|
|
297266
|
+
const lists = await Promise.all(owners.map((who) => asksHolding2(who, { graphqlUrl: graphqlUrl4(), restUrl: restUrl2() })));
|
|
297267
|
+
return new Map(lists.flat().map((one) => [one.collectionId, pays(one.held, "upay")]));
|
|
297268
|
+
})().catch(() => null),
|
|
297269
|
+
Promise.all(owners.map((who) => fetch2(`${SITE}/api/waiting?address=${encodeURIComponent(who)}`, { signal: AbortSignal.timeout(2e4) }).then((r) => r.ok ? r.json() : null))).then((answers) => answers.flatMap((one) => one?.waiting ?? [])).catch(() => null)
|
|
297270
|
+
]);
|
|
297271
|
+
return text4([`Pro asks (${asks.length}):`, ...proAsksModule.proAskLines(EXPERT_SITE, asks, { held, waiting }), missed].filter(Boolean).join("\n"));
|
|
297272
|
+
});
|
|
297273
|
+
if (offered("approve_report")) server2.registerTool(
|
|
297274
|
+
"approve_report",
|
|
297275
|
+
{
|
|
297276
|
+
...meta3("approve_report"),
|
|
297277
|
+
inputSchema: {
|
|
297278
|
+
collectionId: external_exports.string().regex(/^\d+$/).describe("The pro ask's number (my_pro_asks shows it)."),
|
|
297279
|
+
claimId: external_exports.string().min(1).max(128).describe("The report's id: the claim my_pro_asks or the ask's page names."),
|
|
297280
|
+
confirm: external_exports.boolean().optional().describe("Leave out to see what approving pays and whose OK it is. true approves.")
|
|
297281
|
+
}
|
|
297282
|
+
},
|
|
297283
|
+
async ({ collectionId, claimId, confirm }) => {
|
|
297284
|
+
const proAsksModule = await Promise.resolve().then(() => (init_proAsks(), proAsks_exports));
|
|
297285
|
+
const mine = await address2();
|
|
297286
|
+
const acting = await principal2();
|
|
297287
|
+
const who = acting?.principal ?? mine;
|
|
297288
|
+
const queue = await fetch2(`${SITE}/api/waiting?address=${encodeURIComponent(who)}`, { signal: AbortSignal.timeout(2e4) }).then((r) => r.ok ? r.json() : null).catch(() => null);
|
|
297289
|
+
if (!queue || queue.unavailable) return text4("Refused: the reports waiting for an OK could not be read just now. Nothing was sent; try again in a minute.");
|
|
297290
|
+
const item = (queue.waiting ?? []).find((one) => one.collectionId === collectionId && one.claimId === claimId);
|
|
297291
|
+
if (!item) return text4(`Nothing to approve: report ${claimId} on pro ask #${collectionId} is not waiting for ${who === mine ? "this key's" : `${who}'s`} OK. It may be approved already, still being checked, or another account's to approve. The report: ${proAsksModule.reportPage(EXPERT_SITE, collectionId, claimId)}`);
|
|
297292
|
+
const approver = item.approver ?? who;
|
|
297293
|
+
const canSign = approver === mine;
|
|
297294
|
+
const paid = item.pays ? face(item.pays.value, item.pays.symbol) : null;
|
|
297295
|
+
const facts = { collectionId, claimId, pro: item.agentAddress, pays: paid, approver, canSign };
|
|
297296
|
+
if (!confirm || !canSign) return text4(proAsksModule.approvePreview(EXPERT_SITE, facts));
|
|
297297
|
+
const ask = await readJson3(`${SITE}/api/oracle/${encodeURIComponent(collectionId)}`).catch(() => null);
|
|
297298
|
+
if (!ask?.oracle?.url) return text4("Refused: the verifier for this pro ask could not be reached. Nothing was sent; try again in a minute.");
|
|
297299
|
+
const review = await Promise.resolve().then(() => (init_personReview(), personReview_exports));
|
|
297300
|
+
const key = { address: mine, mnemonic: (await loadKey2()).mnemonic };
|
|
297301
|
+
const held = await review.readHeldClaim(ask.oracle.url, key, claimId);
|
|
297302
|
+
if (!held?.decision || held.decision.status !== "pending_review") return text4(`Nothing to approve: the verifier has no decision waiting on report ${claimId}${held?.decision?.status ? ` (it is ${held.decision.status.replace(/_/g, " ")})` : ""}. Nothing was sent.`);
|
|
297303
|
+
const protocol = item.protocol ?? ask.protocol ?? null;
|
|
297304
|
+
const { engineUrl: engineUrl2 } = await Promise.resolve().then(() => (init_engineUrl(), engineUrl_exports));
|
|
297305
|
+
const questions = protocol && engineUrl2() ? await review.reviewQuestions(engineUrl2(), protocol, held.decision.pendingTasks).catch(() => null) : null;
|
|
297306
|
+
if (questions?.some((one) => one.answer.type !== "boolean")) return text4(`Not approved: this report has a question that is not a yes or no, so its OK is given on the report's page: ${proAsksModule.reportPage(EXPERT_SITE, collectionId, claimId)}#decide. Nothing was sent.`);
|
|
297307
|
+
const answers = Object.fromEntries(held.decision.pendingTasks.map((task) => [task, true]));
|
|
297308
|
+
const receipt = await askReceipt(collectionId);
|
|
297309
|
+
if (receipt?.owner === mine) {
|
|
297310
|
+
const ends = ask.endsAt ? Math.floor(Date.parse(ask.endsAt) / 1e3) : null;
|
|
297311
|
+
await review.ensureReviewing({ owner: key, oracleUrl: ask.oracle.url, collectionId, reviewer: mine, endsAt: Number.isFinite(ends) ? ends : null }).catch(() => null);
|
|
297312
|
+
}
|
|
297313
|
+
const sent = await review.sendReview({ reviewer: key, oracleUrl: ask.oracle.url, collectionId, claimId, answers });
|
|
297314
|
+
if (!sent.ok) return text4(`Not approved: ${sent.why}${sent.detail ? ` (${sent.detail})` : ""}. Nothing was paid.`);
|
|
297315
|
+
return text4(`Approved report ${claimId} on pro ask #${collectionId}. The verifier records the OK and pays ${item.agentAddress}${paid ? ` ${paid}` : ""} on the ledger in a minute or two.
|
|
297316
|
+
The report: ${proAsksModule.reportPage(EXPERT_SITE, collectionId, claimId)}`);
|
|
297317
|
+
}
|
|
297318
|
+
);
|
|
296976
297319
|
if (offered("accept_invitation")) server2.registerTool(
|
|
296977
297320
|
"accept_invitation",
|
|
296978
297321
|
{
|
|
296979
297322
|
...meta3("accept_invitation"),
|
|
296980
297323
|
inputSchema: {
|
|
296981
|
-
invitation: external_exports.string().min(1).max(512).describe("The invitation: its link (\u2026/
|
|
297324
|
+
invitation: external_exports.string().min(1).max(512).describe("The invitation: its link (\u2026/i/\u2026), or the pro ask's number (my_invitations shows it)."),
|
|
296982
297325
|
confirm: external_exports.boolean().optional().describe("false (the default) previews; true accepts, once the person has said yes.")
|
|
296983
297326
|
}
|
|
296984
297327
|
},
|
|
@@ -297002,7 +297345,7 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every rep
|
|
|
297002
297345
|
return text4(
|
|
297003
297346
|
[
|
|
297004
297347
|
done.state === "already" ? `Already accepted #${id}.` : `Accepted #${id}${acting ? ` as ${acting.principal}` : ""}. The builder knows.`,
|
|
297005
|
-
`Your job page: ${EXPERT_SITE}/
|
|
297348
|
+
`Your job page: ${EXPERT_SITE}/me/work/${id}`,
|
|
297006
297349
|
`Next: read_ask "${id}" for the brief, read_messages collectionId "${id}" for the builder's note, then submit_work when the person says so.`
|
|
297007
297350
|
].join("\n")
|
|
297008
297351
|
);
|
|
@@ -297013,7 +297356,7 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every rep
|
|
|
297013
297356
|
{
|
|
297014
297357
|
...meta3("decline_invitation"),
|
|
297015
297358
|
inputSchema: {
|
|
297016
|
-
invitation: external_exports.string().min(1).max(512).describe("The invitation: its link (\u2026/
|
|
297359
|
+
invitation: external_exports.string().min(1).max(512).describe("The invitation: its link (\u2026/i/\u2026), or the pro ask's number (my_invitations shows it)."),
|
|
297017
297360
|
note: external_exports.string().max(200).optional().describe("A line for the builder, in the person's words: only they read it. Optional."),
|
|
297018
297361
|
confirm: external_exports.boolean().optional().describe("false (the default) previews; true declines, once the person has said yes.")
|
|
297019
297362
|
}
|
|
@@ -297105,7 +297448,7 @@ The room's page: ${roomPage(SITE, collectionId, page?.profile.handle ?? sent.pro
|
|
|
297105
297448
|
const pageInput = external_exports.object({
|
|
297106
297449
|
verificationServices: external_exports.array(verificationServiceSchema).max(6).optional(),
|
|
297107
297450
|
verificationCredentials: external_exports.array(credentialReferenceSchema).max(12).optional(),
|
|
297108
|
-
handle: external_exports.string().max(30).describe("Lowercase letters, digits and dashes, 3 to 30, starting with a letter. The page's address: /
|
|
297451
|
+
handle: external_exports.string().max(30).describe("Lowercase letters, digits and dashes, 3 to 30, starting with a letter. The page's address: /pros/<handle>."),
|
|
297109
297452
|
name: external_exports.string().max(80),
|
|
297110
297453
|
headline: external_exports.string().max(160).optional().describe("One line: what they do, in their words."),
|
|
297111
297454
|
about: external_exports.string().max(2e3).optional().describe("The summary, a few sentences in their words."),
|
|
@@ -297209,12 +297552,12 @@ No private link was made: ${link5.refused}.`;
|
|
|
297209
297552
|
const page = await invitesModule.readMyPage(SITE, await inviteSigner(acting));
|
|
297210
297553
|
if (!page) return text4("No pro page yet. Next: connect_linkedin (about a minute).");
|
|
297211
297554
|
return text4(`${invitesModule.pageWords(page, SITE)}
|
|
297212
|
-
${page.profile.listed === false ? `Your page is private. Preview it at ${EXPERT_SITE}/
|
|
297555
|
+
${page.profile.listed === false ? `Your page is private. Preview it at ${EXPERT_SITE}/me/page/preview (only you can see it), or ask me for your private link.
|
|
297213
297556
|
` : ""}${page.shared ? 'Private link: there is one (it is shown only when made; set_my_page with share_link: "replace" gives a new one and switches the old one off).' : 'Private link: none (set_my_page with share_link: "create" makes one).'}
|
|
297214
297557
|
|
|
297215
297558
|
${page.linkedin?.credentialUrl || page.linkedin?.credential ? `${credentialWords(page.linkedin, page.profile.listed !== false)}
|
|
297216
297559
|
|
|
297217
|
-
` : ""}Edit the profile at ${EXPERT_SITE}/
|
|
297560
|
+
` : ""}Edit the profile at ${EXPERT_SITE}/me/page/edit.${page.linkedin ? "" : " Next: connect_linkedin verifies it, so you can be invited to pro asks."}`);
|
|
297218
297561
|
});
|
|
297219
297562
|
if (offered("find_pro")) server2.registerTool(
|
|
297220
297563
|
"find_pro",
|
|
@@ -297244,7 +297587,7 @@ ${page.linkedin?.credentialUrl || page.linkedin?.credential ? `${credentialWords
|
|
|
297244
297587
|
return text4(pros.prosWords(found, { site: SITE, q, available }));
|
|
297245
297588
|
}
|
|
297246
297589
|
);
|
|
297247
|
-
const credentialWords = (linkedin, listed) => linkedin?.credentialUrl && listed ? `You also have a LinkedIn credential: it shows you logged in to this LinkedIn account, and any app can check it. Its public link: ${linkedin.credentialUrl}. Download it at ${EXPERT_SITE}/
|
|
297590
|
+
const credentialWords = (linkedin, listed) => linkedin?.credentialUrl && listed ? `You also have a LinkedIn credential: it shows you logged in to this LinkedIn account, and any app can check it. Its public link: ${linkedin.credentialUrl}. Download it at ${EXPERT_SITE}/me/page/edit.` : `You also have a LinkedIn credential: it shows you logged in to this LinkedIn account, and any app can check it. ${listed && !linkedin?.credential && !linkedin?.credentialUrl ? "It appears on your page once the page is published." : "Only you can see it while your page is private; it goes public when the page does."} Download it at ${EXPERT_SITE}/me/page/edit.`;
|
|
297248
297591
|
if (offered("connect_linkedin")) server2.registerTool(
|
|
297249
297592
|
"connect_linkedin",
|
|
297250
297593
|
{
|
|
@@ -297293,7 +297636,7 @@ ${asData("linkedin", JSON.stringify(prefill, null, 2))}`
|
|
|
297293
297636
|
const owner = acting?.principal ?? await address2();
|
|
297294
297637
|
const page = await invitesModule.readMyPage(SITE, await inviteSigner(acting));
|
|
297295
297638
|
if (!page) return text4(`${owner} has no page. Nothing to remove.`);
|
|
297296
|
-
const where2 = `${SITE.replace(/\/+$/, "")}/
|
|
297639
|
+
const where2 = `${SITE.replace(/\/+$/, "")}/pros/${page.profile.handle}`;
|
|
297297
297640
|
if (!confirm)
|
|
297298
297641
|
return text4(
|
|
297299
297642
|
[
|