@ixo/asks-mcp 1.5.0-dev.0 → 1.5.0-dev.18
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 +646 -141
- package/package.json +1 -1
package/dist/asks-mcp.mjs
CHANGED
|
@@ -4026,12 +4026,12 @@ var require_fast_uri = __commonJS({
|
|
|
4026
4026
|
}
|
|
4027
4027
|
function hasMalformedPercentEncoding(component) {
|
|
4028
4028
|
if (component === void 0) return false;
|
|
4029
|
-
let
|
|
4030
|
-
while (
|
|
4031
|
-
if (
|
|
4029
|
+
let percent2 = component.indexOf("%");
|
|
4030
|
+
while (percent2 !== -1) {
|
|
4031
|
+
if (percent2 + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent2 + 1, percent2 + 3))) {
|
|
4032
4032
|
return true;
|
|
4033
4033
|
}
|
|
4034
|
-
|
|
4034
|
+
percent2 = component.indexOf("%", percent2 + 3);
|
|
4035
4035
|
}
|
|
4036
4036
|
return false;
|
|
4037
4037
|
}
|
|
@@ -7447,12 +7447,21 @@ var init_callTag = __esm({
|
|
|
7447
7447
|
}
|
|
7448
7448
|
});
|
|
7449
7449
|
|
|
7450
|
+
// ../../app/lib/networkName.ts
|
|
7451
|
+
var NETWORK;
|
|
7452
|
+
var init_networkName = __esm({
|
|
7453
|
+
"../../app/lib/networkName.ts"() {
|
|
7454
|
+
"use strict";
|
|
7455
|
+
NETWORK = process.env.NEXT_PUBLIC_CHAIN_NETWORK || "testnet";
|
|
7456
|
+
}
|
|
7457
|
+
});
|
|
7458
|
+
|
|
7450
7459
|
// ../../app/lib/networks.ts
|
|
7451
|
-
var
|
|
7460
|
+
var ORIGIN, originOf, EXPERT, expertOrigin;
|
|
7452
7461
|
var init_networks = __esm({
|
|
7453
7462
|
"../../app/lib/networks.ts"() {
|
|
7454
7463
|
"use strict";
|
|
7455
|
-
|
|
7464
|
+
init_networkName();
|
|
7456
7465
|
ORIGIN = {
|
|
7457
7466
|
mainnet: (process.env.NEXT_PUBLIC_MAINNET_APP_URL || "https://openhands.network").replace(/\/+$/, ""),
|
|
7458
7467
|
testnet: (process.env.NEXT_PUBLIC_TESTNET_APP_URL || "https://test.openhands.network").replace(/\/+$/, "")
|
|
@@ -7472,14 +7481,14 @@ function reviewSlugOf(facts) {
|
|
|
7472
7481
|
function askPage(site, collectionId, facts) {
|
|
7473
7482
|
const base5 = site.replace(/\/+$/, "");
|
|
7474
7483
|
const review = reviewSlugOf(facts);
|
|
7475
|
-
if (review) return `${expertOrigin(base5)}/expert/reviews/${
|
|
7484
|
+
if (review) return `${expertOrigin(base5)}/expert/reviews/${collectionId}`;
|
|
7476
7485
|
const slug = facts.slug ?? (facts.campaign ? slugOfTag(facts.campaign) : null);
|
|
7477
7486
|
return slug ? `${base5}/opencall/${slug}` : `${base5}/t/${collectionId}`;
|
|
7478
7487
|
}
|
|
7479
7488
|
function answerPage(site, collectionId, claimId, facts) {
|
|
7480
7489
|
const base5 = site.replace(/\/+$/, "");
|
|
7481
7490
|
const review = reviewSlugOf(facts);
|
|
7482
|
-
return review ? `${expertOrigin(base5)}/expert/reviews/${
|
|
7491
|
+
return review ? `${expertOrigin(base5)}/expert/reviews/${collectionId}/report/${encodeURIComponent(claimId)}` : `${base5}/r/${collectionId}/trace/${encodeURIComponent(claimId)}`;
|
|
7483
7492
|
}
|
|
7484
7493
|
function inviteLink(site, token, review) {
|
|
7485
7494
|
return review ? `${expertOrigin(site)}/expert/i/${token}` : `${site.replace(/\/+$/, "")}/opencall/i/${token}`;
|
|
@@ -7766,6 +7775,12 @@ function requiredSections(raw) {
|
|
|
7766
7775
|
return [...new Set(names)];
|
|
7767
7776
|
}
|
|
7768
7777
|
function reportCheckText(requirement) {
|
|
7778
|
+
if (requirement.v === 2) {
|
|
7779
|
+
const extra2 = requirement.sections.length ? ` and has the sections ${requirement.sections.map((one) => `"${one}"`).join(", ")}` : "";
|
|
7780
|
+
const line2 = `The answer is a review report (written out, or attached as a PDF) of what this ask asked to be reviewed${extra2}. Fail this only if there is no report, or it plainly reviews something else.`;
|
|
7781
|
+
if (line2.length <= 300) return line2;
|
|
7782
|
+
return "The answer is a review report (written out, or attached as a PDF) of what this ask asked to be reviewed, with the sections the ask names. Fail this only if there is no report, or it plainly reviews something else.";
|
|
7783
|
+
}
|
|
7769
7784
|
const extra = requirement.sections.length ? ` It also has these sections: ${requirement.sections.map((one) => `"${one}"`).join(", ")}.` : "";
|
|
7770
7785
|
return `The answer is a review report, either written out or attached as a PDF. It says what was checked, when, where and what was in scope, and the outcome; lists the steps taken, each with what was expected and what was seen, passed, failed, blocked, not tested or left out; lists the findings, each with its impact and a severity of blocker, major or minor with why, and every major finding says how to reproduce it (a blocker says how, or what is missing to reproduce it); gives recommendations, each with a priority and what would show it is done; and gives the review's limitations.${extra}`;
|
|
7771
7786
|
}
|
|
@@ -7782,6 +7797,7 @@ var init_reportLine = __esm({
|
|
|
7782
7797
|
// ../../packages/openhands-sdk/src/rubric/report.ts
|
|
7783
7798
|
function reportProblems(raw, requirement, fileIds = []) {
|
|
7784
7799
|
const problems = [];
|
|
7800
|
+
const review = requirement?.v === 2;
|
|
7785
7801
|
const report = obj(raw);
|
|
7786
7802
|
if (!report) return ["The report must be an object with summary, steps, findings, recommendations and limitations."];
|
|
7787
7803
|
let size2 = 0;
|
|
@@ -7873,9 +7889,13 @@ function reportProblems(raw, requirement, fileIds = []) {
|
|
|
7873
7889
|
if (finding.severity === "blocker" && finding.how_to_reproduce === void 0 && finding.cannot_reproduce === void 0)
|
|
7874
7890
|
problems.push(`${where2} is a blocker: say how to reproduce it, or under cannot_reproduce what is missing to reproduce it.`);
|
|
7875
7891
|
if (finding.cannot_reproduce !== void 0 && finding.severity !== "blocker") problems.push(`${where2}: only a blocker may say it cannot be reproduced; say how to reproduce it.`);
|
|
7892
|
+
if (review && finding.severity === "minor" && finding.how_to_reproduce === void 0) problems.push(`${where2}: say how to reproduce it.`);
|
|
7893
|
+
if (review && (!Array.isArray(finding.evidence) || finding.evidence.length === 0)) problems.push(`${where2}: attach its evidence (a screenshot, recording or trace) and name the file under evidence.`);
|
|
7876
7894
|
evidence(where2, finding.evidence);
|
|
7877
7895
|
});
|
|
7878
7896
|
}
|
|
7897
|
+
const cited = [report.steps, report.findings].some((entries2) => Array.isArray(entries2) && entries2.some((one) => Array.isArray(obj(one)?.evidence) && obj(one).evidence.length > 0));
|
|
7898
|
+
if (review && !cited) problems.push("Attach your evidence: at least one screenshot, recording or trace, named under a step's or a finding's evidence.");
|
|
7879
7899
|
if (!Array.isArray(report.recommendations)) problems.push("Add recommendations: a list, empty when there are none.");
|
|
7880
7900
|
else if (report.recommendations.length > REPORT_LIMITS.lines) problems.push(`Keep it to ${REPORT_LIMITS.lines} recommendations.`);
|
|
7881
7901
|
else
|
|
@@ -7890,7 +7910,8 @@ function reportProblems(raw, requirement, fileIds = []) {
|
|
|
7890
7910
|
text4(where2, recommendation.done_when, "say what you would see once it is done");
|
|
7891
7911
|
text4(where2, recommendation.advice, "advice is optional text", REPORT_LIMITS.text, false);
|
|
7892
7912
|
});
|
|
7893
|
-
if (
|
|
7913
|
+
if (review && Array.isArray(report.limitations) && report.limitations.length === 0) problems.push("Add limitations: what you could not test, or why the result may not hold.");
|
|
7914
|
+
else if (!Array.isArray(report.limitations)) problems.push("Add limitations: a list of short lines, empty when there are none.");
|
|
7894
7915
|
else if (report.limitations.length > REPORT_LIMITS.lines || report.limitations.some((one) => !isText(one, REPORT_LIMITS.text))) problems.push(`Limitations: at most ${REPORT_LIMITS.lines} lines of text.`);
|
|
7895
7916
|
const sections = report.sections === void 0 ? {} : obj(report.sections);
|
|
7896
7917
|
if (!sections) problems.push("Sections: an object of heading \u2192 text.");
|
|
@@ -8039,6 +8060,38 @@ var init_survey = __esm({
|
|
|
8039
8060
|
}
|
|
8040
8061
|
});
|
|
8041
8062
|
|
|
8063
|
+
// ../../packages/openhands-sdk/src/rubric/share.ts
|
|
8064
|
+
var share_exports = {};
|
|
8065
|
+
__export(share_exports, {
|
|
8066
|
+
grossFor: () => grossFor,
|
|
8067
|
+
isPrivateTerms: () => isPrivateTerms,
|
|
8068
|
+
netOf: () => netOf,
|
|
8069
|
+
sharedCall: () => sharedCall
|
|
8070
|
+
});
|
|
8071
|
+
function isPrivateTerms(terms) {
|
|
8072
|
+
const doc = terms;
|
|
8073
|
+
return doc?.access === "invite" || doc?.access === "apply" || doc?.call?.kind === "review";
|
|
8074
|
+
}
|
|
8075
|
+
var sharedCall, grossFor, netOf;
|
|
8076
|
+
var init_share = __esm({
|
|
8077
|
+
"../../packages/openhands-sdk/src/rubric/share.ts"() {
|
|
8078
|
+
"use strict";
|
|
8079
|
+
sharedCall = (terms) => Boolean(terms?.call) && isPrivateTerms(terms);
|
|
8080
|
+
grossFor = (net, split3) => {
|
|
8081
|
+
const PPM = 1000000n;
|
|
8082
|
+
const rate = BigInt(Math.ceil((split3.network + split3.node) * 1e4));
|
|
8083
|
+
if (rate <= 0n) return net;
|
|
8084
|
+
if (rate >= PPM) throw new Error("the split leaves nothing for the person");
|
|
8085
|
+
const keep = PPM - rate;
|
|
8086
|
+
return Number((BigInt(net) * PPM + keep - 1n) / keep);
|
|
8087
|
+
};
|
|
8088
|
+
netOf = (leg, split3) => {
|
|
8089
|
+
const cut = (percent2) => BigInt(leg) * BigInt(Math.round(percent2 * 1e4)) / 1000000n;
|
|
8090
|
+
return Number(BigInt(leg) - cut(split3.network) - cut(split3.node));
|
|
8091
|
+
};
|
|
8092
|
+
}
|
|
8093
|
+
});
|
|
8094
|
+
|
|
8042
8095
|
// ../../packages/openhands-sdk/src/rubric/terms.ts
|
|
8043
8096
|
var terms_exports = {};
|
|
8044
8097
|
__export(terms_exports, {
|
|
@@ -8062,15 +8115,19 @@ __export(terms_exports, {
|
|
|
8062
8115
|
doneMeansSentence: () => doneMeansSentence,
|
|
8063
8116
|
firstUrl: () => firstUrl,
|
|
8064
8117
|
gatePhrase: () => gatePhrase,
|
|
8118
|
+
grossFor: () => grossFor,
|
|
8065
8119
|
hostOf: () => hostOf,
|
|
8066
8120
|
inferDeliverable: () => inferDeliverable,
|
|
8121
|
+
isPrivateTerms: () => isPrivateTerms,
|
|
8067
8122
|
matchHuman: () => matchHuman,
|
|
8068
8123
|
matchSkill: () => matchSkill,
|
|
8124
|
+
netOf: () => netOf,
|
|
8069
8125
|
normalizeTerms: () => normalizeTerms,
|
|
8070
8126
|
parseTerms: () => parseTerms,
|
|
8071
8127
|
requiredTerms: () => requiredTerms,
|
|
8072
8128
|
requiresPoster: () => requiresPoster,
|
|
8073
8129
|
servableByOracle: () => servableByOracle,
|
|
8130
|
+
sharedCall: () => sharedCall,
|
|
8074
8131
|
withReport: () => withReport
|
|
8075
8132
|
});
|
|
8076
8133
|
function firstUrl(text4) {
|
|
@@ -8227,6 +8284,8 @@ function callOf(raw) {
|
|
|
8227
8284
|
const money = call.money;
|
|
8228
8285
|
if (!money || typeof money !== "object") return null;
|
|
8229
8286
|
if (!amount(money.prize) || !whole(money.runnersN, 0, 5) || !amount(money.runnersEach) || !amount(money.entryEach) || !whole(money.entryUpTo, 1, 1e4)) return null;
|
|
8287
|
+
const share = call.share;
|
|
8288
|
+
if (share !== void 0 && (!share || typeof share !== "object" || !nonNegative(share.network) || !nonNegative(share.node) || share.network + share.node >= 100)) return null;
|
|
8230
8289
|
if (!date5(call.closes) || !date5(call.drop) || !date5(call.pick)) return null;
|
|
8231
8290
|
let legs;
|
|
8232
8291
|
if (call.legs !== void 0) {
|
|
@@ -8271,6 +8330,7 @@ function callOf(raw) {
|
|
|
8271
8330
|
poster: call.poster,
|
|
8272
8331
|
points: [...call.points],
|
|
8273
8332
|
money: { prize: money.prize, runnersN: money.runnersN, runnersEach: money.runnersEach, entryEach: money.entryEach, entryUpTo: money.entryUpTo },
|
|
8333
|
+
...share ? { share: { network: share.network, node: share.node } } : {},
|
|
8274
8334
|
closes: call.closes,
|
|
8275
8335
|
drop: call.drop,
|
|
8276
8336
|
pick: call.pick,
|
|
@@ -8291,10 +8351,10 @@ function deliverableOf(deliverable) {
|
|
|
8291
8351
|
function reportOf(raw) {
|
|
8292
8352
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
8293
8353
|
const sections = requiredSections(raw.sections);
|
|
8294
|
-
return sections ? { report: { sections } } : null;
|
|
8354
|
+
return sections ? { report: { sections, ...raw.v === 2 ? { v: 2 } : {} } } : null;
|
|
8295
8355
|
}
|
|
8296
|
-
function withReport(terms, sections) {
|
|
8297
|
-
const requirement = { sections: requiredSections([...sections]) ?? [] };
|
|
8356
|
+
function withReport(terms, sections, rules) {
|
|
8357
|
+
const requirement = { sections: requiredSections([...sections]) ?? [], ...rules ? { v: rules.v } : {} };
|
|
8298
8358
|
const { via, ...rest } = terms;
|
|
8299
8359
|
const kept = terms.criteria.filter((criterion) => criterion.id !== REPORT_CHECK_ID && !(criterion.kind === "measure" && PAGE_CHECK_GATES.has(criterion.gate?.id ?? "")));
|
|
8300
8360
|
return {
|
|
@@ -8397,6 +8457,7 @@ var init_terms = __esm({
|
|
|
8397
8457
|
"use strict";
|
|
8398
8458
|
init_report();
|
|
8399
8459
|
init_survey();
|
|
8460
|
+
init_share();
|
|
8400
8461
|
PHYSICAL = /\b(photo|photograph|picture|snap|image of|screenshot|screen shot|selfie|video|film|scan|handwritten|sticky note|poster|in person|visit|go to|walk|drive|deliver|pick up|drop off|knock|doorstep|on ?site|meet|queue|shelf|receipt)\b/i;
|
|
8401
8462
|
URL_PATTERN = /\bhttps?:\/\/[^\s"'<>)]+|\b(?:[a-z0-9-]+\.)+(?:com|org|net|io|dev|app|earth|xyz|co|ai|me|so|sh|eu|uk|de)(?:\/[^\s"'<>)]*)?/i;
|
|
8402
8463
|
CHECK_WORDS = /\b(check|verify|confirm|test|load|loads|loading|status|up|down|reachable|online|responds?|working|works|broken|404|uptime|ssl|redirect)\b/i;
|
|
@@ -8606,6 +8667,12 @@ function realPhotoRule(shape) {
|
|
|
8606
8667
|
const refusal = `${shape.pair ? "A photo is" : "This is"} not a direct photograph of the real ${shape.outdoors ? "outdoor place" : "scene"} asked for (a screen, a print, a generated picture${shape.outdoors ? " or an indoor shot" : ""}). Take the photo yourself, there.`;
|
|
8607
8668
|
return { rule, text: `${rule} ${fails}`, refusal };
|
|
8608
8669
|
}
|
|
8670
|
+
function reviewBrief(terms) {
|
|
8671
|
+
const subject = terms.call?.subject;
|
|
8672
|
+
const what = subject ? ` It reviews ${subject.name}${subject.version ? ` version ${subject.version}` : ""}.` : "";
|
|
8673
|
+
const scenarios = terms.call?.scenarios?.length ? ` The scenarios to try: ${terms.call.scenarios.map((one, index) => `${index + 1}. ${one}`).join(" ")}` : "";
|
|
8674
|
+
return `${terms.task.replace(/[.\s]+$/, "")}.${what}${scenarios}`;
|
|
8675
|
+
}
|
|
8609
8676
|
function nativeGate(gate, index) {
|
|
8610
8677
|
switch (gate.id) {
|
|
8611
8678
|
/* `present` is false for null, "" and [] — exactly our "there is a
|
|
@@ -8774,8 +8841,9 @@ function toEngineRubric(terms, binding, options = {}) {
|
|
|
8774
8841
|
const context = { radiusMeters: radius && radius.id === "within-radius" ? radius.meters : null, pinFromAsk: options.pinFromAsk === true };
|
|
8775
8842
|
const pair = normalized.deliverable.type === "photo-pair" || measure("before-after") !== null;
|
|
8776
8843
|
const expectsExtra = normalized.site === true || measure("with-file") !== null || measure("at-registered-point") !== null;
|
|
8844
|
+
const reviewRules = normalized.report?.v === 2 && normalized.call?.kind === "review" && Boolean(normalized.approver);
|
|
8777
8845
|
const judgeSend = {
|
|
8778
|
-
task: literal2(options.task?.trim() || normalized.task),
|
|
8846
|
+
task: literal2(options.task?.trim() || (reviewRules ? reviewBrief(normalized) : normalized.task)),
|
|
8779
8847
|
text: TEXT,
|
|
8780
8848
|
...withPhoto ? { photo: PHOTO } : {},
|
|
8781
8849
|
...pair ? { before: BEFORE_PHOTO, after: AFTER_PHOTO } : {},
|
|
@@ -8784,6 +8852,7 @@ function toEngineRubric(terms, binding, options = {}) {
|
|
|
8784
8852
|
};
|
|
8785
8853
|
const guidance = guidanceFor(normalized.deliverable.type);
|
|
8786
8854
|
const gates = [];
|
|
8855
|
+
const clearFailures = /* @__PURE__ */ new Set();
|
|
8787
8856
|
let review = null;
|
|
8788
8857
|
const personTasks = [];
|
|
8789
8858
|
const shown2 = withPhoto ? [PHOTO, TEXT] : [TEXT];
|
|
@@ -8837,7 +8906,7 @@ function toEngineRubric(terms, binding, options = {}) {
|
|
|
8837
8906
|
expect: "boolean",
|
|
8838
8907
|
onError: ON_ERROR
|
|
8839
8908
|
});
|
|
8840
|
-
|
|
8909
|
+
const gate = {
|
|
8841
8910
|
"@type": "Gate",
|
|
8842
8911
|
code: codeFor(index, "judged"),
|
|
8843
8912
|
reason: criterion.text,
|
|
@@ -8845,7 +8914,9 @@ function toEngineRubric(terms, binding, options = {}) {
|
|
|
8845
8914
|
when: field(`ai.${name8}.valid`, "isTrue"),
|
|
8846
8915
|
onFail: "reject",
|
|
8847
8916
|
class: "refuted"
|
|
8848
|
-
}
|
|
8917
|
+
};
|
|
8918
|
+
gates.push(gate);
|
|
8919
|
+
if (reviewRules && criterion.id === REPORT_CHECK_ID) clearFailures.add(gate);
|
|
8849
8920
|
return;
|
|
8850
8921
|
}
|
|
8851
8922
|
if (!normalized.approver) throw new Error(`criterion ${criterion.id} is attested by the poster; an oracle cannot serve it`);
|
|
@@ -8962,6 +9033,26 @@ function toEngineRubric(terms, binding, options = {}) {
|
|
|
8962
9033
|
onFail: "reject",
|
|
8963
9034
|
class: "insufficient_evidence"
|
|
8964
9035
|
});
|
|
9036
|
+
if (reviewRules) {
|
|
9037
|
+
extra += 1;
|
|
9038
|
+
gates.push({
|
|
9039
|
+
"@type": "Gate",
|
|
9040
|
+
code: codeFor(extra, "report-evidence"),
|
|
9041
|
+
reason: "A review report needs its evidence: attach at least one screenshot, recording or trace and name it under a step's or a finding's evidence",
|
|
9042
|
+
when: { "@type": "Condition", any: [field(TEXT, "matches", escapeRegex2('"evidence":["')), field(PHOTO, "mediaTypeIn", ["application/pdf"])] },
|
|
9043
|
+
onFail: "reject",
|
|
9044
|
+
class: "insufficient_evidence"
|
|
9045
|
+
});
|
|
9046
|
+
extra += 1;
|
|
9047
|
+
gates.push({
|
|
9048
|
+
"@type": "Gate",
|
|
9049
|
+
code: codeFor(extra, "report-limits"),
|
|
9050
|
+
reason: "The report states no limitations: say what could not be tested, or why the result may not hold",
|
|
9051
|
+
when: { "@type": "Condition", any: [field(TEXT, "matches", escapeRegex2(',"limitations":["')), field(PHOTO, "mediaTypeIn", ["application/pdf"])] },
|
|
9052
|
+
onFail: "review",
|
|
9053
|
+
class: "insufficient_evidence"
|
|
9054
|
+
});
|
|
9055
|
+
}
|
|
8965
9056
|
}
|
|
8966
9057
|
if (normalized.approver) {
|
|
8967
9058
|
extra += 1;
|
|
@@ -8989,7 +9080,7 @@ function toEngineRubric(terms, binding, options = {}) {
|
|
|
8989
9080
|
});
|
|
8990
9081
|
if (normalized.approver) {
|
|
8991
9082
|
const readsFacts = (gate) => /"field":"(ext|ai)\./.test(JSON.stringify(gate.when));
|
|
8992
|
-
for (const gate of gates) if (gate.onFail === "reject" && readsFacts(gate)) gate.onFail = "review";
|
|
9083
|
+
for (const gate of gates) if (gate.onFail === "reject" && readsFacts(gate) && !clearFailures.has(gate)) gate.onFail = "review";
|
|
8993
9084
|
for (const source of sources) source.onError = "review";
|
|
8994
9085
|
for (const check2 of aiChecks) check2.onError = "review";
|
|
8995
9086
|
}
|
|
@@ -9536,7 +9627,9 @@ var init_gateMet = __esm({
|
|
|
9536
9627
|
"not-elsewhere": "Taken at the place reported",
|
|
9537
9628
|
"camera-or-live": "The photo carries camera data or a live capture",
|
|
9538
9629
|
person: "A person approved the answer",
|
|
9539
|
-
report: "A review report was sent, as structured text or a PDF"
|
|
9630
|
+
report: "A review report was sent, as structured text or a PDF",
|
|
9631
|
+
"report-evidence": "The report carries its evidence",
|
|
9632
|
+
"report-limits": "The report states its limitations"
|
|
9540
9633
|
};
|
|
9541
9634
|
RULE_IS_REASON = /* @__PURE__ */ new Set(["judged", "real-photo"]);
|
|
9542
9635
|
gateLabel = (code10) => /^OH-\d+-([A-Z0-9-]+)$/.exec(code10)?.[1]?.toLowerCase() ?? null;
|
|
@@ -9565,7 +9658,9 @@ var init_gateMet = __esm({
|
|
|
9565
9658
|
"not-elsewhere": "Taken there",
|
|
9566
9659
|
"camera-or-live": "Camera or live capture",
|
|
9567
9660
|
person: "Approved by a person",
|
|
9568
|
-
report: "Report received"
|
|
9661
|
+
report: "Report received",
|
|
9662
|
+
"report-evidence": "Evidence attached",
|
|
9663
|
+
"report-limits": "Limitations stated"
|
|
9569
9664
|
};
|
|
9570
9665
|
PERSON_WORDS = {
|
|
9571
9666
|
approved: "A person approved the answer",
|
|
@@ -27287,7 +27382,9 @@ function firstStore(candidates, init, timeoutMs, fetchImpl, outer) {
|
|
|
27287
27382
|
}
|
|
27288
27383
|
await response.body?.cancel().catch(() => void 0);
|
|
27289
27384
|
if (!response.ok && (!last || response.status >= 500)) last = { response, url: url4, store: store2 };
|
|
27290
|
-
}).catch(() =>
|
|
27385
|
+
}).catch(() => {
|
|
27386
|
+
if (!done) last = { response: unanswered(), url: url4, store: store2 };
|
|
27387
|
+
}).finally(() => {
|
|
27291
27388
|
if (--pending === 0) settle2(last);
|
|
27292
27389
|
});
|
|
27293
27390
|
});
|
|
@@ -27339,7 +27436,7 @@ async function resolveDocUrl(cid, init = {}) {
|
|
|
27339
27436
|
rememberDocStore(cid, found.store);
|
|
27340
27437
|
return found.url;
|
|
27341
27438
|
}
|
|
27342
|
-
var WHERE_MAX, where, forgetDocStores, ANCHOR_MAX_BYTES, missing;
|
|
27439
|
+
var WHERE_MAX, where, forgetDocStores, ANCHOR_MAX_BYTES, missing, unanswered;
|
|
27343
27440
|
var init_docs = __esm({
|
|
27344
27441
|
"../../packages/openhands-sdk/src/data/docs.ts"() {
|
|
27345
27442
|
"use strict";
|
|
@@ -27352,6 +27449,7 @@ var init_docs = __esm({
|
|
|
27352
27449
|
forgetDocStores = () => void where.clear();
|
|
27353
27450
|
ANCHOR_MAX_BYTES = 2e6;
|
|
27354
27451
|
missing = () => new Response(null, { status: 404, statusText: "not found in any store" });
|
|
27452
|
+
unanswered = () => new Response(null, { status: 504, statusText: "a store did not answer" });
|
|
27355
27453
|
}
|
|
27356
27454
|
});
|
|
27357
27455
|
|
|
@@ -29626,7 +29724,13 @@ var init_checkersRead = __esm({
|
|
|
29626
29724
|
// ../../packages/openhands-sdk/src/data/checkers.ts
|
|
29627
29725
|
var checkers_exports = {};
|
|
29628
29726
|
__export(checkers_exports, {
|
|
29727
|
+
ASKY_CHECKER_ADDRESSES: () => ASKY_CHECKER_ADDRESSES,
|
|
29728
|
+
ASKY_CHECKER_FEES: () => ASKY_CHECKER_FEES,
|
|
29729
|
+
ASKY_CHECKER_NAME: () => ASKY_CHECKER_NAME,
|
|
29730
|
+
ASKY_CHECKER_URLS: () => ASKY_CHECKER_URLS,
|
|
29629
29731
|
ASK_THE_WORLD_CHECKERS: () => ASK_THE_WORLD_CHECKERS,
|
|
29732
|
+
askyChecker: () => askyChecker,
|
|
29733
|
+
askyCheckerUrl: () => askyCheckerUrl,
|
|
29630
29734
|
checkEnvelope: () => checkEnvelope,
|
|
29631
29735
|
checkOfProtocol: () => checkOfProtocol,
|
|
29632
29736
|
checkerByAddress: () => checkerByAddress,
|
|
@@ -29823,11 +29927,17 @@ function checkEnvelope(input) {
|
|
|
29823
29927
|
...answers
|
|
29824
29928
|
};
|
|
29825
29929
|
}
|
|
29826
|
-
var ASK_THE_WORLD_CHECKERS, isOpenhandsChecker, openhandsPath, plain, list4, str5, words2, choiceValue, NOT_ANSWERS, isEmpty2, filesOf, isFile, numberOf;
|
|
29930
|
+
var ASK_THE_WORLD_CHECKERS, ASKY_CHECKER_URLS, ASKY_CHECKER_ADDRESSES, ASKY_CHECKER_FEES, ASKY_CHECKER_NAME, askyCheckerUrl, askyChecker, isOpenhandsChecker, openhandsPath, plain, list4, str5, words2, choiceValue, NOT_ANSWERS, isEmpty2, filesOf, isFile, numberOf;
|
|
29827
29931
|
var init_checkers = __esm({
|
|
29828
29932
|
"../../packages/openhands-sdk/src/data/checkers.ts"() {
|
|
29829
29933
|
"use strict";
|
|
29830
29934
|
ASK_THE_WORLD_CHECKERS = /* @__PURE__ */ new Set(["ixo1qrk9dp4r2u8q5l9cs42yh4dne4pj3wynp4enwq", "ixo12mvzayzrzsvaud86jf9shy6q2nvkea3tygxhsh"]);
|
|
29935
|
+
ASKY_CHECKER_URLS = { devnet: "", testnet: "https://asky-checker.testnet.ixo.earth", mainnet: "" };
|
|
29936
|
+
ASKY_CHECKER_ADDRESSES = { devnet: "", testnet: "ixo149t76xlqg5u5dmpz7sjhlz7y0qktafv4z6qg9u", mainnet: "" };
|
|
29937
|
+
ASKY_CHECKER_FEES = { testnet: { base: 1e6, denom: "upay" } };
|
|
29938
|
+
ASKY_CHECKER_NAME = "Asky Checker";
|
|
29939
|
+
askyCheckerUrl = (network2) => ASKY_CHECKER_URLS[network2] || null;
|
|
29940
|
+
askyChecker = (network2) => ASKY_CHECKER_URLS[network2] && ASKY_CHECKER_ADDRESSES[network2] && ASKY_CHECKER_FEES[network2] ? { url: ASKY_CHECKER_URLS[network2], address: ASKY_CHECKER_ADDRESSES[network2], fee: ASKY_CHECKER_FEES[network2] } : null;
|
|
29831
29941
|
isOpenhandsChecker = (info, own2 = false) => own2 || typeof info?.openhands?.hire === "string";
|
|
29832
29942
|
openhandsPath = (routes, event, collectionId) => (routes?.[event] ?? `/openhands/${event}/:collectionId`).replace(":collectionId", encodeURIComponent(collectionId));
|
|
29833
29943
|
plain = (text4) => text4.trim().toLowerCase();
|
|
@@ -29865,7 +29975,9 @@ __export(format_exports, {
|
|
|
29865
29975
|
learnDenomRoutes: () => learnDenomRoutes,
|
|
29866
29976
|
paysFromPool: () => paysFromPool,
|
|
29867
29977
|
readsAsMoney: () => readsAsMoney,
|
|
29978
|
+
receivedAmount: () => receivedAmount,
|
|
29868
29979
|
resolveDenom: () => resolveDenom,
|
|
29980
|
+
sharedApproval: () => sharedApproval,
|
|
29869
29981
|
shortAddress: () => shortAddress,
|
|
29870
29982
|
shortStr: () => shortStr,
|
|
29871
29983
|
timeAgo: () => timeAgo,
|
|
@@ -29911,6 +30023,14 @@ function approvalAmount(payments) {
|
|
|
29911
30023
|
const display = coinDisplay(payments?.["approval"]?.amount);
|
|
29912
30024
|
return display && display.value > 0 ? display : null;
|
|
29913
30025
|
}
|
|
30026
|
+
function receivedAmount(payments, split3, amount4 = payments?.["approval"]?.amount) {
|
|
30027
|
+
const leg = coinDisplay(amount4);
|
|
30028
|
+
if (!leg || leg.value <= 0) return null;
|
|
30029
|
+
if (!sharedApproval(payments)) return leg;
|
|
30030
|
+
if (!split3) return { ...leg, less: true };
|
|
30031
|
+
const coin = amount4[0];
|
|
30032
|
+
return coinDisplay([{ denom: coin.denom, amount: String(netOf(Number(coin.amount), split3)) }]);
|
|
30033
|
+
}
|
|
29914
30034
|
function evaluationAmount(payments) {
|
|
29915
30035
|
const display = coinDisplay(payments?.["evaluation"]?.amount);
|
|
29916
30036
|
return display && display.value > 0 ? display : null;
|
|
@@ -29943,10 +30063,11 @@ function timeShort(iso) {
|
|
|
29943
30063
|
const date6 = chainTime(iso);
|
|
29944
30064
|
return date6 ? date6.toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" }) : "";
|
|
29945
30065
|
}
|
|
29946
|
-
var shortAddress, PEGGED, isPegged2, ODD, ROUTES, resolveDenom, fractionFor, readsAsMoney, POOL_LEG_BASE, paysFromPool, NAME_MAX3, ESTATE_DEFAULTS, RECORD_SUFFIX, cleanName;
|
|
30066
|
+
var shortAddress, PEGGED, isPegged2, ODD, ROUTES, resolveDenom, fractionFor, readsAsMoney, POOL_LEG_BASE, paysFromPool, sharedApproval, NAME_MAX3, ESTATE_DEFAULTS, RECORD_SUFFIX, cleanName;
|
|
29947
30067
|
var init_format = __esm({
|
|
29948
30068
|
"../../packages/openhands-sdk/src/data/format.ts"() {
|
|
29949
30069
|
"use strict";
|
|
30070
|
+
init_share();
|
|
29950
30071
|
shortAddress = (address2) => shortStr(address2, 12, 6);
|
|
29951
30072
|
PEGGED = /* @__PURE__ */ new Set(["PAY", "USDC", "USDT", "USD"]);
|
|
29952
30073
|
isPegged2 = (symbol2) => PEGGED.has(symbol2);
|
|
@@ -29961,6 +30082,7 @@ var init_format = __esm({
|
|
|
29961
30082
|
readsAsMoney = (amount4) => Boolean(amount4 && amount4.value >= 0.01);
|
|
29962
30083
|
POOL_LEG_BASE = "1";
|
|
29963
30084
|
paysFromPool = (payments) => payments?.["approval"]?.amount?.[0]?.amount === POOL_LEG_BASE;
|
|
30085
|
+
sharedApproval = (payments) => payments?.["approval"]?.is_oracle_payment === true;
|
|
29964
30086
|
NAME_MAX3 = 40;
|
|
29965
30087
|
ESTATE_DEFAULTS = /* @__PURE__ */ new Set([
|
|
29966
30088
|
"wallet send ui user",
|
|
@@ -258263,12 +258385,68 @@ var init_session = __esm({
|
|
|
258263
258385
|
});
|
|
258264
258386
|
|
|
258265
258387
|
// ../../packages/openhands-sdk/src/chain/query.ts
|
|
258388
|
+
var query_exports43 = {};
|
|
258389
|
+
__export(query_exports43, {
|
|
258390
|
+
FeeAllowanceShort: () => FeeAllowanceShort,
|
|
258391
|
+
affords: () => affords,
|
|
258392
|
+
canPay: () => canPay,
|
|
258393
|
+
ensureGas: () => ensureGas,
|
|
258394
|
+
expired: () => expired,
|
|
258395
|
+
feePayerFor: () => feePayerFor,
|
|
258396
|
+
feeSplit: () => feeSplit,
|
|
258397
|
+
feeSplitOrNull: () => feeSplitOrNull,
|
|
258398
|
+
getFeegrantGranter: () => getFeegrantGranter,
|
|
258399
|
+
getQueryClient: () => getQueryClient,
|
|
258400
|
+
getUixoBalance: () => getUixoBalance,
|
|
258401
|
+
legacyPercent: () => legacyPercent,
|
|
258402
|
+
pickFeePayer: () => pickFeePayer,
|
|
258403
|
+
pickGranter: () => pickGranter,
|
|
258404
|
+
txEvents: () => txEvents,
|
|
258405
|
+
valueFromTx: () => valueFromTx,
|
|
258406
|
+
valuesFromEvents: () => valuesFromEvents,
|
|
258407
|
+
valuesFromTx: () => valuesFromTx
|
|
258408
|
+
});
|
|
258266
258409
|
function getQueryClient() {
|
|
258267
258410
|
const url4 = rpcUrl();
|
|
258268
258411
|
let client2 = clients.get(url4);
|
|
258269
|
-
if (!client2)
|
|
258412
|
+
if (!client2) {
|
|
258413
|
+
const value = createQueryClient(url4);
|
|
258414
|
+
clients.set(url4, client2 = value);
|
|
258415
|
+
value.catch(() => {
|
|
258416
|
+
if (clients.get(url4) === value) clients.delete(url4);
|
|
258417
|
+
});
|
|
258418
|
+
}
|
|
258270
258419
|
return client2;
|
|
258271
258420
|
}
|
|
258421
|
+
function legacyPercent(raw) {
|
|
258422
|
+
const value = (raw ?? "").trim();
|
|
258423
|
+
if (!value) return 0;
|
|
258424
|
+
if (/^\d+$/.test(value)) return Number(BigInt(value) * 1000000n / 10n ** 18n) / 1e6;
|
|
258425
|
+
const read9 = Number(value);
|
|
258426
|
+
if (!Number.isFinite(read9)) throw new Error(`not a percentage: ${JSON.stringify(raw)}`);
|
|
258427
|
+
return read9;
|
|
258428
|
+
}
|
|
258429
|
+
async function feeSplit() {
|
|
258430
|
+
const given2 = givenConfig().feeSplit;
|
|
258431
|
+
const chain2 = chainSplit();
|
|
258432
|
+
return given2 ? chain2.catch(() => given2) : chain2;
|
|
258433
|
+
}
|
|
258434
|
+
function chainSplit() {
|
|
258435
|
+
const rpc = rpcUrl();
|
|
258436
|
+
const kept = splitReads.get(rpc);
|
|
258437
|
+
if (kept && Date.now() - kept.at < SPLIT_TTL_MS) return kept.value;
|
|
258438
|
+
const value = (async () => {
|
|
258439
|
+
const client2 = await getQueryClient();
|
|
258440
|
+
const { params } = await client2.ixo.claims.v1beta1.params({});
|
|
258441
|
+
if (!params) throw new Error("the chain answered no claims params");
|
|
258442
|
+
return { network: legacyPercent(params.networkFeePercentage), node: legacyPercent(params.nodeFeePercentage), ixoAccount: params.ixoAccount };
|
|
258443
|
+
})();
|
|
258444
|
+
splitReads.set(rpc, { at: Date.now(), value });
|
|
258445
|
+
value.catch(() => {
|
|
258446
|
+
if (splitReads.get(rpc)?.value === value) splitReads.delete(rpc);
|
|
258447
|
+
});
|
|
258448
|
+
return value;
|
|
258449
|
+
}
|
|
258272
258450
|
async function getUixoBalance(address2) {
|
|
258273
258451
|
const client2 = await getQueryClient();
|
|
258274
258452
|
const { balance } = await client2.cosmos.bank.v1beta1.balance({ address: address2, denom: "uixo" });
|
|
@@ -258369,6 +258547,19 @@ async function txEvents(transactionHash) {
|
|
|
258369
258547
|
if (json2.error) throw new Error(`The chain node could not find transaction ${transactionHash.slice(0, 12)}\u2026: ${json2.error.data ?? json2.error.message ?? "unknown error"}`);
|
|
258370
258548
|
return json2.result?.tx_result?.events ?? [];
|
|
258371
258549
|
}
|
|
258550
|
+
async function valueFromTx(transactionHash, type, key) {
|
|
258551
|
+
for (const event of await txEvents(transactionHash)) {
|
|
258552
|
+
if (event.type !== type) continue;
|
|
258553
|
+
for (const attribute of event.attributes) {
|
|
258554
|
+
const name8 = /^[A-Za-z0-9+/=]+$/.test(attribute.key) && attribute.key !== key ? Buffer.from(attribute.key, "base64").toString("utf8") : attribute.key;
|
|
258555
|
+
if (name8 !== key) continue;
|
|
258556
|
+
const raw = attribute.value ?? "";
|
|
258557
|
+
const decoded = /^[A-Za-z0-9+/=]+$/.test(raw) ? Buffer.from(raw, "base64").toString("utf8") : raw;
|
|
258558
|
+
return (decoded || raw).replace(/^"|"$/g, "");
|
|
258559
|
+
}
|
|
258560
|
+
}
|
|
258561
|
+
return "";
|
|
258562
|
+
}
|
|
258372
258563
|
function valuesFromEvents(events, type, key) {
|
|
258373
258564
|
const out = [];
|
|
258374
258565
|
for (const event of events) {
|
|
@@ -258386,13 +258577,23 @@ function valuesFromEvents(events, type, key) {
|
|
|
258386
258577
|
async function valuesFromTx(transactionHash, type, key) {
|
|
258387
258578
|
return valuesFromEvents(await txEvents(transactionHash), type, key);
|
|
258388
258579
|
}
|
|
258389
|
-
var clients, FeeAllowanceShort;
|
|
258580
|
+
var clients, SPLIT_TTL_MS, splitReads, feeSplitOrNull, FeeAllowanceShort;
|
|
258390
258581
|
var init_query43 = __esm({
|
|
258391
258582
|
"../../packages/openhands-sdk/src/chain/query.ts"() {
|
|
258392
258583
|
"use strict";
|
|
258393
258584
|
init_module23();
|
|
258394
258585
|
init_env();
|
|
258586
|
+
init_given();
|
|
258395
258587
|
clients = /* @__PURE__ */ new Map();
|
|
258588
|
+
SPLIT_TTL_MS = 10 * 6e4;
|
|
258589
|
+
splitReads = /* @__PURE__ */ new Map();
|
|
258590
|
+
feeSplitOrNull = (timeoutMs = 8e3) => Promise.race([
|
|
258591
|
+
feeSplit().catch(() => null),
|
|
258592
|
+
new Promise((resolve2) => {
|
|
258593
|
+
const timer = setTimeout(() => resolve2(givenConfig().feeSplit ?? null), timeoutMs);
|
|
258594
|
+
timer.unref?.();
|
|
258595
|
+
})
|
|
258596
|
+
]);
|
|
258396
258597
|
FeeAllowanceShort = class extends Error {
|
|
258397
258598
|
};
|
|
258398
258599
|
}
|
|
@@ -258952,6 +259153,7 @@ function delegationsAmong(rows2, now3 = Date.now()) {
|
|
|
258952
259153
|
agent,
|
|
258953
259154
|
expiresAt: expiries.length ? expiries.sort()[0] : null,
|
|
258954
259155
|
cap: limit && Number(limit.amount) > 0 ? { denom: limit.denom, remainingBase: limit.amount } : null,
|
|
259156
|
+
caps: (send?.authorization?.spend_limit ?? []).filter((coin) => Number(coin.amount) > 0).map((coin) => ({ denom: coin.denom, remainingBase: coin.amount })),
|
|
258955
259157
|
iidEdits: IID_EDIT_MSGS.every((msg) => typed.has(msg)),
|
|
258956
259158
|
iidDeletes: IID_DELETE_MSGS.every((msg) => typed.has(msg))
|
|
258957
259159
|
});
|
|
@@ -259121,7 +259323,9 @@ __export(connect_exports, {
|
|
|
259121
259323
|
gasRenewWords: () => gasRenewWords,
|
|
259122
259324
|
gasUsedUp: () => gasUsedUp,
|
|
259123
259325
|
keyPins: () => keyPins,
|
|
259124
|
-
markSigned: () => markSigned
|
|
259326
|
+
markSigned: () => markSigned,
|
|
259327
|
+
ownAnswer: () => ownAnswer,
|
|
259328
|
+
receiptWithOurs: () => receiptWithOurs
|
|
259125
259329
|
});
|
|
259126
259330
|
function noteIgnored(agent, pinned, others, log) {
|
|
259127
259331
|
const fresh2 = others.filter((one) => !told.has(`${agent}:${pinned}:${one}`));
|
|
@@ -259202,6 +259406,17 @@ function actingWords(acting, face) {
|
|
|
259202
259406
|
const cap = acting.cap ? `, ${face(Number(acting.cap.remainingBase) / 1e6, symbolOf(acting.cap.denom))} remaining in its spending allowance` : ", no spending allowance remains";
|
|
259203
259407
|
return `Connected to account ${acting.principal}${until}${cap}. This key has permission to post asks and send answers linked to that account. Rewards go to that account.`;
|
|
259204
259408
|
}
|
|
259409
|
+
function ownAnswer(claims, key, filedFor) {
|
|
259410
|
+
return claims.find((claim3) => claim3.agentAddress === key) ?? (filedFor ? claims.find((claim3) => claim3.agentAddress === filedFor) : void 0);
|
|
259411
|
+
}
|
|
259412
|
+
async function receiptWithOurs(read9, key, filedFor, fromIndex) {
|
|
259413
|
+
const first = await read9();
|
|
259414
|
+
const found = first ? ownAnswer(first.claims ?? [], key, filedFor) : void 0;
|
|
259415
|
+
if (!first || found) return { receipt: first, ours: found };
|
|
259416
|
+
const indexed = await fromIndex().catch(() => null);
|
|
259417
|
+
const ours = indexed ? ownAnswer(indexed, key, filedFor) : void 0;
|
|
259418
|
+
return { receipt: ours ? { ...first, claims: [ours, ...first.claims ?? []] } : first, ours };
|
|
259419
|
+
}
|
|
259205
259420
|
function gasUsedUp(found, principalUixo, now3 = Date.now()) {
|
|
259206
259421
|
if (!found) return principalUixo >= GAS_LEND_MIN_UIXO;
|
|
259207
259422
|
const basic = found["@type"]?.endsWith("AllowedMsgAllowance") ? found.allowance ?? {} : found;
|
|
@@ -259244,7 +259459,8 @@ var init_connect = __esm({
|
|
|
259244
259459
|
/* `did:ixo:<address>` is how this chain names an account's DID (`didOf`), and it is what the site served. */
|
|
259245
259460
|
did: `did:ixo:${found.principal}`,
|
|
259246
259461
|
expiresAt: found.expiresAt,
|
|
259247
|
-
cap: found.cap
|
|
259462
|
+
cap: found.cap,
|
|
259463
|
+
caps: found.caps
|
|
259248
259464
|
});
|
|
259249
259465
|
list5 = (principals) => principals.join(", ");
|
|
259250
259466
|
SELF = "self";
|
|
@@ -259406,6 +259622,7 @@ var init_accountProof = __esm({
|
|
|
259406
259622
|
var hq_exports = {};
|
|
259407
259623
|
__export(hq_exports, {
|
|
259408
259624
|
capCoinRefusal: () => capCoinRefusal,
|
|
259625
|
+
capIn: () => capIn,
|
|
259409
259626
|
evaluationBase: () => evaluationBase,
|
|
259410
259627
|
evaluationPrice: () => evaluationPrice,
|
|
259411
259628
|
hqPlan: () => hqPlan,
|
|
@@ -259438,9 +259655,10 @@ function pickCoin(currency, network2, fallback) {
|
|
|
259438
259655
|
const named = currency === "uixo" ? "IXO" : currency === USDC_MAINNET ? "USDC" : currency;
|
|
259439
259656
|
return named?.trim() ? rewardCoin(named, network2) : fallback;
|
|
259440
259657
|
}
|
|
259441
|
-
function capCoinRefusal(acting, coin) {
|
|
259442
|
-
if (!acting?.cap || acting
|
|
259658
|
+
function capCoinRefusal(acting, coin, grantAt) {
|
|
259659
|
+
if (!acting?.cap || capIn(acting, coin)) return null;
|
|
259443
259660
|
const has = symbolOf(acting.cap.denom);
|
|
259661
|
+
if (grantAt) return `${acting.principal}'s allowance for this key is in ${has}, not ${symbolOf(coin)}, so it cannot pay this. They grant a ${symbolOf(coin)} allowance at ${grantAt}`;
|
|
259444
259662
|
return `${acting.principal}'s allowance for this key is in ${has}, not ${symbolOf(coin)}, so it cannot pay this. Pay in ${has} (currency: "${has}") instead`;
|
|
259445
259663
|
}
|
|
259446
259664
|
function hqPlan(args, network2) {
|
|
@@ -259493,7 +259711,7 @@ async function oracleWords(oracle, io) {
|
|
|
259493
259711
|
if (!id) return null;
|
|
259494
259712
|
return named?.name ? `${named.name} (${id})` : id;
|
|
259495
259713
|
}
|
|
259496
|
-
var refuse3, ENTITY2, orgDefaultOracle, offChainPayWords, orgConfirmToken;
|
|
259714
|
+
var refuse3, ENTITY2, orgDefaultOracle, capIn, offChainPayWords, orgConfirmToken;
|
|
259497
259715
|
var init_hq = __esm({
|
|
259498
259716
|
"src/hq.ts"() {
|
|
259499
259717
|
"use strict";
|
|
@@ -259504,6 +259722,7 @@ var init_hq = __esm({
|
|
|
259504
259722
|
refuse3 = (refused2) => ({ refused: refused2 });
|
|
259505
259723
|
ENTITY2 = /^did:ixo:entity:[0-9a-f]{32}$/;
|
|
259506
259724
|
orgDefaultOracle = (allowed, askTheWorld, ordinary) => (ordinary && askTheWorld && allowed.includes(askTheWorld) ? askTheWorld : allowed[0]) ?? null;
|
|
259725
|
+
capIn = (acting, coin) => acting?.caps?.find((one) => one.denom === coin) ?? (acting?.cap?.denom === coin ? acting.cap : null);
|
|
259507
259726
|
offChainPayWords = (payout, orgName) => `${payout.amount} ${payout.currency}`.concat(` per approved answer, off chain via ${orgName ? `${orgName}'s` : "the company's"} payouts (${payout.rails[0] === "stripe" ? "Stripe" : "USDC on Base"})`);
|
|
259508
259727
|
orgConfirmToken = (args) => [args.offChainTotal ?? args.rewards, args.feesSetAside].filter(Boolean).join(" and ");
|
|
259509
259728
|
}
|
|
@@ -259531,10 +259750,6 @@ __export(lane_exports, {
|
|
|
259531
259750
|
signShare: () => signShare,
|
|
259532
259751
|
uploadToLane: () => uploadToLane
|
|
259533
259752
|
});
|
|
259534
|
-
function isPrivateTerms(terms) {
|
|
259535
|
-
const doc = terms;
|
|
259536
|
-
return doc?.access === "invite" || doc?.access === "apply" || doc?.call?.kind === "review";
|
|
259537
|
-
}
|
|
259538
259753
|
async function agentDidKey(mnemonic) {
|
|
259539
259754
|
const { signerFromMnemonic: signerFromMnemonic2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
259540
259755
|
const { signer: signer2 } = await signerFromMnemonic2(mnemonic);
|
|
@@ -259652,6 +259867,7 @@ var init_lane = __esm({
|
|
|
259652
259867
|
"../../packages/openhands-sdk/src/chain/lane.ts"() {
|
|
259653
259868
|
"use strict";
|
|
259654
259869
|
init_docUrls();
|
|
259870
|
+
init_share();
|
|
259655
259871
|
networkVfsDid = () => `did:web:${new URL(laneVfsUrl()).host.replace(/:/g, "%3A")}`;
|
|
259656
259872
|
WRITE_PASS_SECONDS = 3600;
|
|
259657
259873
|
READ_PASS_SECONDS = 86400;
|
|
@@ -260869,6 +261085,7 @@ function prepareAsk(poster, entityDid, adminAccount, terms, now3 = Date.now(), s
|
|
|
260869
261085
|
if (orgFunds && !orgAdmin) throw new Error("an organisation's ask is funded by the organisation: its admin account is needed");
|
|
260870
261086
|
const posterCoins = orgFunds ? [] : coins;
|
|
260871
261087
|
const recorded = offChain ? feeDenom : denom;
|
|
261088
|
+
const shared = sharedCall(terms.rules) && !offChain;
|
|
260872
261089
|
const collection = {
|
|
260873
261090
|
typeUrl: "/ixo.claims.v1beta1.MsgCreateCollection",
|
|
260874
261091
|
value: ixo.claims.v1beta1.MsgCreateCollection.fromPartial({
|
|
@@ -260883,8 +261100,8 @@ function prepareAsk(poster, entityDid, adminAccount, terms, now3 = Date.now(), s
|
|
|
260883
261100
|
payments: {
|
|
260884
261101
|
submission: paymentLeg(adminAccount),
|
|
260885
261102
|
evaluation: paymentLeg(adminAccount, checkReward > 0n ? [{ denom: feeDenom, amount: String(checkReward) }] : void 0),
|
|
260886
|
-
/* Off chain: a leg with no coin. A "0" coin fails (code 18). */
|
|
260887
|
-
approval: paymentLeg(adminAccount, offChain ? void 0 : [{ denom, amount: terms.amountUixo }]),
|
|
261103
|
+
/* Off chain: a leg with no coin. A "0" coin fails (code 18). The chain allows the flag on this leg alone. */
|
|
261104
|
+
approval: paymentLeg(adminAccount, offChain ? void 0 : [{ denom, amount: terms.amountUixo }], shared),
|
|
260888
261105
|
rejection: paymentLeg(adminAccount)
|
|
260889
261106
|
}
|
|
260890
261107
|
})
|
|
@@ -261107,10 +261324,11 @@ var init_ask = __esm({
|
|
|
261107
261324
|
init_env();
|
|
261108
261325
|
init_entityShape();
|
|
261109
261326
|
init_docUrls();
|
|
261327
|
+
init_share();
|
|
261110
261328
|
init_given();
|
|
261111
261329
|
init_envRead();
|
|
261112
261330
|
claimFormRef = (url4, proof) => url4?.trim() && proof?.trim() ? { url: url4.trim(), proof: proof.trim() } : null;
|
|
261113
|
-
paymentLeg = (account, amount4) => ixo.claims.v1beta1.Payment.fromPartial({ account, amount: amount4 ?? [] });
|
|
261331
|
+
paymentLeg = (account, amount4, oraclePayment = false) => ixo.claims.v1beta1.Payment.fromPartial({ account, amount: amount4 ?? [], isOraclePayment: oraclePayment });
|
|
261114
261332
|
ESCROW_MEMO = "Open the ask and escrow the money";
|
|
261115
261333
|
AskPending = class extends Error {
|
|
261116
261334
|
marker;
|
|
@@ -261608,7 +261826,9 @@ function metaGrantMsg2(actor, entityDid, admin, grantee, endDate, authType, maxQ
|
|
|
261608
261826
|
}
|
|
261609
261827
|
function assertAskShape(ask) {
|
|
261610
261828
|
const campaignAsk = typeof ask.terms?.campaign === "string";
|
|
261611
|
-
|
|
261829
|
+
const asky = askyChecker(network());
|
|
261830
|
+
const askyReview = ask.terms?.call?.kind === "review" && asky !== null && asky.fee.denom === "upay" && ask.checker === asky.address;
|
|
261831
|
+
if (!ask.payoutTerms && !campaignAsk && !askyReview && (ask.denom ?? askDenom()) === "upay") throw new Error(PAY_NOT_A_REWARD);
|
|
261612
261832
|
if (ask.payoutTerms) {
|
|
261613
261833
|
if (!ask.org) throw new Error("payout terms need the organisation (org) whose facilitator pays them");
|
|
261614
261834
|
if (ask.amountUixo !== 0) throw new Error("an ask paid off chain carries nothing on chain: amountUixo must be 0, or the worker is paid twice");
|
|
@@ -261782,7 +262002,7 @@ function openAskMessages(actorAddress, owner, ask, at) {
|
|
|
261782
262002
|
const endsAt = at.now + days * 24 * 3600 * 1e3;
|
|
261783
262003
|
const endDate = utils3.proto.toTimestamp(new Date(endsAt));
|
|
261784
262004
|
const judgeUntil = utils3.proto.toTimestamp(new Date(judgeUntilMs(endsAt)));
|
|
261785
|
-
const leg = (amount4) => ixo.claims.v1beta1.Payment.fromPartial({ account: admin, amount: amount4 ?? [] });
|
|
262005
|
+
const leg = (amount4, oraclePayment = false) => ixo.claims.v1beta1.Payment.fromPartial({ account: admin, amount: amount4 ?? [], isOraclePayment: oraclePayment });
|
|
261786
262006
|
const checkReward = ask.checker && ask.checkRewardUixo ? Math.max(0, Math.floor(ask.checkRewardUixo)) : 0;
|
|
261787
262007
|
const approvalLeg = ask.poolCeilingUixo ? 1 : ask.amountUixo;
|
|
261788
262008
|
const offChain = Boolean(ask.payoutTerms);
|
|
@@ -261796,6 +262016,7 @@ function openAskMessages(actorAddress, owner, ask, at) {
|
|
|
261796
262016
|
if (orgFunds && !at.orgAdmin) throw new Error("an organisation's ask is funded by the organisation: its admin account is needed");
|
|
261797
262017
|
const recorded = offChain ? feeDenom : denom;
|
|
261798
262018
|
const escrow = coins.find((coin) => coin.denom === recorded)?.amount ?? "0";
|
|
262019
|
+
const shared = sharedCall(ask.terms) && !offChain && !ask.poolCeilingUixo;
|
|
261799
262020
|
const fee = feeEscrow > 0n && feeDenom !== recorded ? { denom: feeDenom, amount: String(feeEscrow), from: orgFunds ? "org" : "poster" } : null;
|
|
261800
262021
|
const messages = [
|
|
261801
262022
|
{
|
|
@@ -261812,7 +262033,7 @@ function openAskMessages(actorAddress, owner, ask, at) {
|
|
|
261812
262033
|
submission: leg(),
|
|
261813
262034
|
evaluation: leg(checkReward ? [{ denom: feeDenom, amount: String(checkReward) }] : void 0),
|
|
261814
262035
|
/* Off chain: a leg with no coin (NO_PAYMENT). A "0" coin fails (code 18), and so would a MsgSend of 0 (code 10). */
|
|
261815
|
-
approval: leg(offChain ? void 0 : [{ denom, amount: String(approvalLeg) }]),
|
|
262036
|
+
approval: leg(offChain ? void 0 : [{ denom, amount: String(approvalLeg) }], shared),
|
|
261816
262037
|
rejection: leg()
|
|
261817
262038
|
}
|
|
261818
262039
|
})
|
|
@@ -262300,6 +262521,7 @@ var init_chain = __esm({
|
|
|
262300
262521
|
init_delegate();
|
|
262301
262522
|
init_domainIndexer();
|
|
262302
262523
|
init_publish();
|
|
262524
|
+
init_share();
|
|
262303
262525
|
init_proof3();
|
|
262304
262526
|
init_sequenceStore();
|
|
262305
262527
|
init_config3();
|
|
@@ -262310,6 +262532,7 @@ var init_chain = __esm({
|
|
|
262310
262532
|
init_entityShape();
|
|
262311
262533
|
init_docUrls();
|
|
262312
262534
|
init_askImage();
|
|
262535
|
+
init_checkers();
|
|
262313
262536
|
init_store2();
|
|
262314
262537
|
init_pendingTx();
|
|
262315
262538
|
GAS_PRICE2 = import_stargate7.GasPrice.fromString("0.025uixo");
|
|
@@ -262961,7 +263184,7 @@ function callEntriesTerms(input) {
|
|
|
262961
263184
|
judge: input.judge,
|
|
262962
263185
|
...input.approver ? { approver: input.approver } : {}
|
|
262963
263186
|
};
|
|
262964
|
-
return input.report ? withReport(terms, input.report) : terms;
|
|
263187
|
+
return input.report ? withReport(terms, input.report, input.approver ? { v: 2 } : void 0) : terms;
|
|
262965
263188
|
}
|
|
262966
263189
|
function callPickTerms(input) {
|
|
262967
263190
|
const call = legCall(input.call, input.leg);
|
|
@@ -262999,13 +263222,13 @@ var init_call = __esm({
|
|
|
262999
263222
|
init_callTag();
|
|
263000
263223
|
ENTRY_MIN_CHARS = 200;
|
|
263001
263224
|
REVIEW_LINES = [
|
|
263002
|
-
{ text: "
|
|
263003
|
-
{ text: "
|
|
263004
|
-
{ text: "
|
|
263005
|
-
{ text: "
|
|
263006
|
-
{ text: "
|
|
263225
|
+
{ text: "The report covers the scenarios this ask lists, each with what was done and whether it passed, failed, was blocked or was not tested", fail: "a scenario the ask lists is missing from the report altogether" },
|
|
263226
|
+
{ text: "Each finding points at its evidence: a screenshot, recording or trace", fail: "a finding has no evidence at all" },
|
|
263227
|
+
{ text: "Each problem found says how to reproduce it, or for a blocker what is missing to reproduce it", fail: "a problem gives no way to reproduce it" },
|
|
263228
|
+
{ text: "Each problem found has a severity: blocker, major or minor", fail: "a problem has no severity" },
|
|
263229
|
+
{ text: "Each recommendation says what to change", fail: "a recommendation does not say what should change" }
|
|
263007
263230
|
];
|
|
263008
|
-
REVIEW_DELIVERABLE_PROMPT = "A review report:
|
|
263231
|
+
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";
|
|
263009
263232
|
DAY_MS2 = 24 * 3600 * 1e3;
|
|
263010
263233
|
legsOf = (call) => call.mode === "hire" ? ["entries"] : ["prize", ...call.money.runnersN > 0 ? ["runnersUp"] : [], "entries"];
|
|
263011
263234
|
pickQuota = (winners) => winners + 2;
|
|
@@ -263013,6 +263236,15 @@ var init_call = __esm({
|
|
|
263013
263236
|
});
|
|
263014
263237
|
|
|
263015
263238
|
// src/callRead.ts
|
|
263239
|
+
var callRead_exports = {};
|
|
263240
|
+
__export(callRead_exports, {
|
|
263241
|
+
blockText: () => blockText,
|
|
263242
|
+
callReadout: () => callReadout,
|
|
263243
|
+
isPickLeg: () => isPickLeg,
|
|
263244
|
+
shareWords: () => shareWords,
|
|
263245
|
+
sharedPay: () => sharedPay,
|
|
263246
|
+
stageWords: () => stageWords
|
|
263247
|
+
});
|
|
263016
263248
|
function stageWords(call, now3 = Date.now()) {
|
|
263017
263249
|
if (now3 < Date.parse(call.closes)) return `open until ${day(call.closes)}`;
|
|
263018
263250
|
if (call.mode === "hire") return `closed ${day(call.closes)}; every entry that passed is paid as it is judged`;
|
|
@@ -263020,6 +263252,11 @@ function stageWords(call, now3 = Date.now()) {
|
|
|
263020
263252
|
if (now3 < Date.parse(call.pick)) return `closed; the shortlist is out; the pick by ${day(call.pick)}`;
|
|
263021
263253
|
return `closed; the pick was due ${day(call.pick)}`;
|
|
263022
263254
|
}
|
|
263255
|
+
function sharedPay(quote, share) {
|
|
263256
|
+
const leg = grossFor(Math.round(quote * 1e6), share);
|
|
263257
|
+
const receives = netOf(leg, share);
|
|
263258
|
+
return { receives: receives / 1e6, leg: leg / 1e6, keeps: (leg - receives) / 1e6 };
|
|
263259
|
+
}
|
|
263023
263260
|
function blockText(block2) {
|
|
263024
263261
|
switch (block2.kind) {
|
|
263025
263262
|
case "story":
|
|
@@ -263058,14 +263295,16 @@ function callReadout(terms, ctx) {
|
|
|
263058
263295
|
].filter(Boolean);
|
|
263059
263296
|
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.";
|
|
263060
263297
|
const review = call.kind === "review";
|
|
263298
|
+
const shared = call.share ? sharedPay(m.entryEach, call.share) : null;
|
|
263299
|
+
const shareLine2 = shared && call.share ? `each ${review ? "specialist" : 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(call.share, "as posted")})${hire ? "" : "; the pick's and the runners-up's legs carry the same share on top of theirs"}` : "";
|
|
263061
263300
|
const out = [
|
|
263062
263301
|
`${review ? "Expert review" : hire ? "Hiring call" : "Open call"} "${call.slug}" \xB7 posted by ${call.poster} \xB7 ${stageWords(call, ctx.now)}`,
|
|
263063
|
-
...review && ctx.site ? [`Its page: ${expertOrigin(ctx.site)}/expert/reviews/${
|
|
263302
|
+
...review && ctx.site ? [`Its page: ${expertOrigin(ctx.site)}/expert/reviews/${ctx.id}`] : [],
|
|
263064
263303
|
call.title,
|
|
263065
263304
|
call.lede,
|
|
263066
263305
|
...review && call.subject ? [`Reviewing: ${call.subject.name}${call.subject.version ? ` ${call.subject.version}` : ""}${call.subject.where ? ` \xB7 ${call.subject.where}` : ""}. Access details, if any, are in your invitation.`] : [],
|
|
263067
263306
|
...review && call.scenarios?.length ? ["Scenarios, each one a step in your report:", ...call.scenarios.map((one, index) => ` S${index + 1}. ${one}`)] : [],
|
|
263068
|
-
`Money: ${money.join("; ")}. Locked on chain on ${hire ? "the ask's own account" : "each leg's own account"} before anyone enters.`,
|
|
263307
|
+
`Money: ${[...money, shareLine2].filter(Boolean).join("; ")}. Locked on chain on ${hire ? "the ask's own account" : "each leg's own account"} before anyone enters.`,
|
|
263069
263308
|
who,
|
|
263070
263309
|
call.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."}`,
|
|
263071
263310
|
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.`,
|
|
@@ -263076,13 +263315,16 @@ function callReadout(terms, ctx) {
|
|
|
263076
263315
|
];
|
|
263077
263316
|
return out.join("\n");
|
|
263078
263317
|
}
|
|
263079
|
-
var day, amount3, countWords, isPickLeg;
|
|
263318
|
+
var day, amount3, percent, shareWords, countWords, isPickLeg;
|
|
263080
263319
|
var init_callRead = __esm({
|
|
263081
263320
|
"src/callRead.ts"() {
|
|
263082
263321
|
"use strict";
|
|
263322
|
+
init_share();
|
|
263083
263323
|
init_networks();
|
|
263084
263324
|
day = (iso) => new Date(iso).toUTCString().replace(/:\d\d GMT$/, " UTC");
|
|
263085
263325
|
amount3 = (value, symbol2) => `${Number(value.toFixed(6))} ${symbol2}`;
|
|
263326
|
+
percent = (value) => `${Number(value.toFixed(6))} %`;
|
|
263327
|
+
shareWords = (share, when2) => `${percent(share.network + share.node)} ${when2}: ${percent(share.network)} to the network, ${percent(share.node)} to the relayer node`;
|
|
263086
263328
|
countWords = (count2) => ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"][count2] ?? String(count2);
|
|
263087
263329
|
isPickLeg = (terms) => {
|
|
263088
263330
|
const leg = terms?.call?.leg;
|
|
@@ -263099,21 +263341,27 @@ __export(call_exports2, {
|
|
|
263099
263341
|
InFlightError: () => InFlightError,
|
|
263100
263342
|
PostRefused: () => PostRefused,
|
|
263101
263343
|
SETTLE_MS: () => SETTLE_MS,
|
|
263344
|
+
SHARE_UNREAD: () => SHARE_UNREAD,
|
|
263102
263345
|
TESTNET_CALL_DEFAULTS: () => TESTNET_CALL_DEFAULTS,
|
|
263103
263346
|
accessOf: () => accessOf,
|
|
263104
263347
|
askInvitesFile: () => askInvitesFile,
|
|
263105
263348
|
blockText: () => blockText,
|
|
263106
263349
|
blocksOf: () => blocksOf,
|
|
263350
|
+
callChecker: () => callChecker,
|
|
263107
263351
|
callCoin: () => callCoin,
|
|
263108
263352
|
callOfDraft: () => callOfDraft,
|
|
263109
263353
|
callPlan: () => callPlan,
|
|
263110
263354
|
callReadout: () => callReadout,
|
|
263111
263355
|
callServerEnv: () => callServerEnv,
|
|
263356
|
+
callShare: () => callShare,
|
|
263357
|
+
callShares: () => callShares,
|
|
263112
263358
|
callTwoCoins: () => callTwoCoins,
|
|
263113
263359
|
callsDir: () => callsDir,
|
|
263360
|
+
capWords: () => capWords,
|
|
263114
263361
|
chainCheck: () => chainCheck,
|
|
263115
263362
|
confirms: () => confirms,
|
|
263116
263363
|
doorOf: () => doorOf,
|
|
263364
|
+
draftOfEntries: () => draftOfEntries,
|
|
263117
263365
|
freshDraft: () => freshDraft,
|
|
263118
263366
|
indexLookup: () => indexLookup,
|
|
263119
263367
|
indexLookupWith: () => indexLookupWith,
|
|
@@ -263131,7 +263379,9 @@ __export(call_exports2, {
|
|
|
263131
263379
|
missingOf: () => missingOf,
|
|
263132
263380
|
nextLeg: () => nextLeg,
|
|
263133
263381
|
nextSlug: () => nextSlug,
|
|
263382
|
+
nudgeAtFor: () => nudgeAtFor,
|
|
263134
263383
|
optionalOf: () => optionalOf,
|
|
263384
|
+
overCap: () => overCap,
|
|
263135
263385
|
payWords: () => payWords,
|
|
263136
263386
|
postNextLeg: () => postNextLeg,
|
|
263137
263387
|
preCheck: () => preCheck,
|
|
@@ -263166,6 +263416,15 @@ function writeDraft(draft) {
|
|
|
263166
263416
|
writeFileSync3(`${path}.tmp`, JSON.stringify(draft, null, 2), { mode: 384 });
|
|
263167
263417
|
renameSync3(`${path}.tmp`, path);
|
|
263168
263418
|
}
|
|
263419
|
+
function draftOfEntries(collectionId) {
|
|
263420
|
+
if (!existsSync2(callsDir())) return null;
|
|
263421
|
+
for (const name8 of readdirSync(callsDir())) {
|
|
263422
|
+
const slug = /^(.+)\.json$/.exec(name8)?.[1];
|
|
263423
|
+
const draft = slug ? readDraft(slug) : null;
|
|
263424
|
+
if (draft?.posted.entries?.id === collectionId) return draft;
|
|
263425
|
+
}
|
|
263426
|
+
return null;
|
|
263427
|
+
}
|
|
263169
263428
|
function readAskInvites(askId) {
|
|
263170
263429
|
try {
|
|
263171
263430
|
const kept = JSON.parse(readFileSync3(askInvitesFile(askId), "utf8"));
|
|
@@ -263182,8 +263441,7 @@ function keepAskInvites(askId, written) {
|
|
|
263182
263441
|
renameSync3(`${path}.tmp`, path);
|
|
263183
263442
|
}
|
|
263184
263443
|
function nextSlug() {
|
|
263185
|
-
|
|
263186
|
-
return `call-${taken.length ? Math.max(...taken) + 1 : 1}`;
|
|
263444
|
+
return `call-${crypto.randomUUID().replaceAll("-", "")}`;
|
|
263187
263445
|
}
|
|
263188
263446
|
function doorOf(access2, invite) {
|
|
263189
263447
|
const items = (invite ?? []).map((one) => one.trim()).filter(Boolean);
|
|
@@ -263377,6 +263635,10 @@ function mergeDraft(draft, input, now3 = /* @__PURE__ */ new Date()) {
|
|
|
263377
263635
|
}
|
|
263378
263636
|
return { draft: { ...draft, fields, updatedAt: now3.toISOString() }, refused: refused2 };
|
|
263379
263637
|
}
|
|
263638
|
+
function callChecker(network2, review, deployment2) {
|
|
263639
|
+
const asky = review ? askyChecker(network2) : null;
|
|
263640
|
+
return asky ? { address: asky.address, at: { url: asky.url }, name: ASKY_CHECKER_NAME, fee: asky.fee } : { address: deployment2, at: null, name: null, fee: null };
|
|
263641
|
+
}
|
|
263380
263642
|
function missingOf(fields, ctx) {
|
|
263381
263643
|
const out = [];
|
|
263382
263644
|
const review = fields.kind === "review";
|
|
@@ -263461,7 +263723,7 @@ function blocksOf(fields) {
|
|
|
263461
263723
|
else if (fields.kind === "review") blocks.push({ kind: "start", prompt: reviewStart(fields.title) });
|
|
263462
263724
|
return blocks;
|
|
263463
263725
|
}
|
|
263464
|
-
function callOfDraft(draft, poster, dates, legs) {
|
|
263726
|
+
function callOfDraft(draft, poster, dates, legs, share) {
|
|
263465
263727
|
const f = draft.fields;
|
|
263466
263728
|
if (!isReady(f) || !f.money) throw new Error("the draft is not ready to post");
|
|
263467
263729
|
return {
|
|
@@ -263473,20 +263735,30 @@ function callOfDraft(draft, poster, dates, legs) {
|
|
|
263473
263735
|
poster: f.poster ?? poster,
|
|
263474
263736
|
points: linesOf(f).map(() => 100 / L.lines),
|
|
263475
263737
|
money: f.mode === "hire" ? { ...f.money, prize: 0, runnersN: 0, runnersEach: 0 } : f.money,
|
|
263738
|
+
...share ? { share: { network: share.network, node: share.node } } : {},
|
|
263476
263739
|
...dates,
|
|
263477
263740
|
...legs && Object.keys(legs).length ? { legs } : {},
|
|
263478
263741
|
blocks: blocksOf(f)
|
|
263479
263742
|
};
|
|
263480
263743
|
}
|
|
263481
|
-
function legPlan(fields, leg, checkBase) {
|
|
263744
|
+
function legPlan(fields, leg, checkBase, share, feeInReward = false) {
|
|
263482
263745
|
const m = fields.money;
|
|
263746
|
+
const priced = (payBase) => {
|
|
263747
|
+
const legBase = share ? grossFor(payBase, share) : payBase;
|
|
263748
|
+
return { payBase, legBase, shareBase: legBase - payBase };
|
|
263749
|
+
};
|
|
263483
263750
|
if (leg === "entries") {
|
|
263484
|
-
const
|
|
263485
|
-
return { leg,
|
|
263751
|
+
const pay2 = priced(toBase2(m.entryEach));
|
|
263752
|
+
if (feeInReward) return { leg, ...pay2, quota: m.entryUpTo, escrowSpots: m.entryUpTo, checkBase, escrowBase: (pay2.legBase + checkBase) * m.entryUpTo, feeBase: 0 };
|
|
263753
|
+
return { leg, ...pay2, quota: m.entryUpTo, escrowSpots: m.entryUpTo, checkBase, escrowBase: pay2.legBase * m.entryUpTo, feeBase: checkBase * m.entryUpTo };
|
|
263486
263754
|
}
|
|
263487
263755
|
const winners = leg === "prize" ? 1 : m.runnersN;
|
|
263488
|
-
const
|
|
263489
|
-
return { leg,
|
|
263756
|
+
const pay = priced(toBase2(leg === "prize" ? m.prize : m.runnersEach));
|
|
263757
|
+
return { leg, ...pay, quota: pickQuota(winners), escrowSpots: winners, checkBase: 0, escrowBase: pay.legBase * winners, feeBase: 0 };
|
|
263758
|
+
}
|
|
263759
|
+
function callShare(fields, split3) {
|
|
263760
|
+
if (!callShares(fields)) return { share: null };
|
|
263761
|
+
return split3 ? { share: { network: split3.network, node: split3.node } } : { unread: true };
|
|
263490
263762
|
}
|
|
263491
263763
|
function legTerms(draft, leg, ctx) {
|
|
263492
263764
|
const access2 = accessOf(draft.fields);
|
|
@@ -263495,7 +263767,7 @@ function legTerms(draft, leg, ctx) {
|
|
|
263495
263767
|
const review = draft.fields.kind === "review";
|
|
263496
263768
|
return {
|
|
263497
263769
|
...callEntriesTerms({
|
|
263498
|
-
call: callOfDraft(draft, ctx.poster, ctx.dates, legs),
|
|
263770
|
+
call: callOfDraft(draft, ctx.poster, ctx.dates, legs, ctx.share),
|
|
263499
263771
|
lines: linesOf(draft.fields),
|
|
263500
263772
|
judge: ctx.oracle,
|
|
263501
263773
|
access: access2,
|
|
@@ -263505,17 +263777,38 @@ function legTerms(draft, leg, ctx) {
|
|
|
263505
263777
|
via: "mcp"
|
|
263506
263778
|
};
|
|
263507
263779
|
}
|
|
263508
|
-
return { ...callPickTerms({ call: callOfDraft(draft, ctx.poster, ctx.dates), leg, access: access2 }), via: "mcp" };
|
|
263780
|
+
return { ...callPickTerms({ call: callOfDraft(draft, ctx.poster, ctx.dates, void 0, ctx.share), leg, access: access2 }), via: "mcp" };
|
|
263509
263781
|
}
|
|
263510
263782
|
function callPlan(draft, ctx, now3 = Date.now()) {
|
|
263783
|
+
if (callShares(draft.fields) !== Boolean(ctx.share)) throw new Error(ctx.share ? "only a private call carries the network's share" : "a private call is priced with the network's share: read the split first (callShare)");
|
|
263511
263784
|
const dates = draft.dates ?? callDates(draft.fields.openDays, now3, draft.fields.mode === "hire" ? "hire" : void 0);
|
|
263512
|
-
const entries2 = legTerms(draft, "entries", { poster: ctx.poster, dates, oracle: { kind: "oracle", address: ctx.oracle } });
|
|
263785
|
+
const entries2 = legTerms(draft, "entries", { poster: ctx.poster, dates, oracle: { kind: "oracle", address: ctx.oracle }, share: ctx.share });
|
|
263513
263786
|
const checkBase = ctx.checkerLegBase(entries2);
|
|
263514
|
-
const legs = legOrder(draft.fields).map((leg) => legPlan(draft.fields, leg, checkBase));
|
|
263515
|
-
return { legs, totalBase: legs.reduce((sum, one) => sum + one.escrowBase, 0), dates };
|
|
263787
|
+
const legs = legOrder(draft.fields).map((leg) => legPlan(draft.fields, leg, checkBase, ctx.share, ctx.feeInReward));
|
|
263788
|
+
return { legs, totalBase: legs.reduce((sum, one) => sum + one.escrowBase, 0), dates, share: ctx.share };
|
|
263789
|
+
}
|
|
263790
|
+
function capWords(legs, capBase, symbol2) {
|
|
263791
|
+
const at = (base5) => payWords(base5, symbol2);
|
|
263792
|
+
const fitting = (base5) => Math.floor(base5 / 1e4) * 1e4;
|
|
263793
|
+
const raise = "or raise OPENHANDS_MAX_PER_ASK_USD where this server is configured, and restart it";
|
|
263794
|
+
return legs.filter((leg) => overCap(leg, capBase)).map((leg) => {
|
|
263795
|
+
const over = `${leg.leg === "entries" ? "The entries" : leg.leg === "prize" ? "The pick's" : "The runners-up"} leg locks ${at(leg.escrowBase)}, over this server's ${at(capBase)} per-ask cap (OPENHANDS_MAX_PER_ASK_USD): post_call will refuse it.`;
|
|
263796
|
+
if (leg.leg === "prize") return `${over} Fits: a prize of at most ${at(fitting(capBase))}; ${raise}.`;
|
|
263797
|
+
const each = fitting(Math.floor(capBase / leg.escrowSpots * leg.payBase / leg.legBase));
|
|
263798
|
+
const most = Math.floor(capBase / leg.legBase);
|
|
263799
|
+
const fits = [most > 0 ? `${most} at ${at(leg.payBase)}` : "", each > 0 ? `${leg.escrowSpots} at ${at(each)}` : ""].filter(Boolean);
|
|
263800
|
+
return `${over} Fits: ${fits.length ? fits.join(", or ") : "nothing at this server's cap"}; ${raise}.`;
|
|
263801
|
+
});
|
|
263516
263802
|
}
|
|
263517
263803
|
function callCoin(draft, currency, network2, fallback) {
|
|
263518
263804
|
const started = Object.values(draft.posted).some(Boolean) || Boolean(draft.inFlight);
|
|
263805
|
+
const asky = draft.fields.kind === "review" ? askyChecker(network2) : null;
|
|
263806
|
+
if (asky) {
|
|
263807
|
+
const symbol2 = symbolOf(asky.fee.denom);
|
|
263808
|
+
if (currency?.trim() && currency.trim().toUpperCase() !== symbol2 && currency.trim() !== asky.fee.denom) return { refused: `an Expert Review pays in ${symbol2} on ${network2}: leave currency out, or pass "${symbol2}"` };
|
|
263809
|
+
if (started && draft.coin && draft.coin !== asky.fee.denom) return { refused: `this review already pays in ${symbolOf(draft.coin)}; start a new one to pay in ${symbol2}` };
|
|
263810
|
+
return asky.fee.denom;
|
|
263811
|
+
}
|
|
263519
263812
|
const was = draft.coin ?? (started ? fallback : void 0);
|
|
263520
263813
|
const coin = pickCoin(currency, network2, was ?? fallback);
|
|
263521
263814
|
if (typeof coin !== "string") return coin;
|
|
@@ -263543,9 +263836,9 @@ async function realSteps() {
|
|
|
263543
263836
|
async function preCheck(plan, ctx) {
|
|
263544
263837
|
const who = ctx.acting?.principal ?? ctx.poster;
|
|
263545
263838
|
if (ctx.acting) {
|
|
263546
|
-
const otherCoin = capCoinRefusal(ctx.acting, ctx.askDenom);
|
|
263839
|
+
const otherCoin = capCoinRefusal(ctx.acting, ctx.askDenom, ctx.coinFixed ? `${ctx.site}/connect` : void 0);
|
|
263547
263840
|
if (otherCoin) return `Refused: ${otherCoin}. Nothing was posted.`;
|
|
263548
|
-
const left = ctx.acting
|
|
263841
|
+
const left = Number(capIn(ctx.acting, ctx.askDenom)?.remainingBase ?? 0);
|
|
263549
263842
|
if (left < plan.escrowBase) return `Refused: your cap has ${ctx.face(left)} left; this leg locks ${ctx.face(plan.escrowBase)}. Raise it on ${ctx.site}/connect. Nothing was posted.`;
|
|
263550
263843
|
const held = await ctx.balanceBase(who, ctx.askDenom).catch(() => -1);
|
|
263551
263844
|
if (held >= 0 && held < plan.escrowBase) return `Refused: the account holds ${ctx.face(held)}; this leg locks ${ctx.face(plan.escrowBase)}. Nothing was posted.`;
|
|
@@ -263650,7 +263943,10 @@ async function postNextLegNow(slug, ctx) {
|
|
|
263650
263943
|
const shortPoster = `${poster.slice(0, 10)}\u2026${poster.slice(-4)}`;
|
|
263651
263944
|
const { checkerFeeDenom: checkerFeeDenom2 } = await Promise.resolve().then(() => (init_money(), money_exports));
|
|
263652
263945
|
const { network: network2 } = await Promise.resolve().then(() => (init_network(), network_exports));
|
|
263653
|
-
const
|
|
263946
|
+
const split3 = !callShares(draft.fields) ? null : ctx.feeSplit !== void 0 ? ctx.feeSplit : await (await Promise.resolve().then(() => (init_query43(), query_exports43))).feeSplitOrNull();
|
|
263947
|
+
const priced = callShare(draft.fields, split3);
|
|
263948
|
+
if ("unread" in priced) throw new PostRefused(SHARE_UNREAD);
|
|
263949
|
+
const { legs, dates } = callPlan(draft, { poster: shortPoster, checkerLegBase: (terms2) => ctx.fee ? ctx.fee.base : ctx.perCheck ? 0 : checkerLegBase2(checkerFeeDenom2(network2()), terms2, ctx.checkReward), oracle: ctx.checker, share: priced.share, feeInReward: Boolean(ctx.fee) }, ctx.now);
|
|
263654
263950
|
if (settled?.state === "landed") {
|
|
263655
263951
|
ctx.nudge?.("hire", settled.id);
|
|
263656
263952
|
return { leg: settled.leg, id: settled.id, tx: null, plan: legs.find((one) => one.leg === settled.leg), terms: null, draft, resumed: true };
|
|
@@ -263683,7 +263979,7 @@ async function postNextLegNow(slug, ctx) {
|
|
|
263683
263979
|
if (ctx.acting && legs.some((one) => one.feeBase > 0)) throw new Error(callTwoCoins);
|
|
263684
263980
|
const plan = legs.find((one) => one.leg === leg);
|
|
263685
263981
|
const oracle = { kind: "oracle", address: ctx.checker, rewardUixo: plan.checkBase || legs.find((one) => one.leg === "entries").checkBase };
|
|
263686
|
-
const terms = legTerms(draft, leg, { poster: shortPoster, dates, oracle, approver: ctx.approver ?? null });
|
|
263982
|
+
const terms = legTerms(draft, leg, { poster: shortPoster, dates, oracle, approver: ctx.approver ?? null, share: priced.share });
|
|
263687
263983
|
const screen = await steps.screen(ctx.site, terms.task, terms);
|
|
263688
263984
|
if (screen?.verdict === "refuse") throw new Error(refusedWords(screen.reason));
|
|
263689
263985
|
await steps.fund(actor.address, ctx.site);
|
|
@@ -263722,13 +264018,14 @@ async function postNextLegNow(slug, ctx) {
|
|
|
263722
264018
|
title: terms.task,
|
|
263723
264019
|
terms,
|
|
263724
264020
|
doneMeans: published,
|
|
263725
|
-
|
|
264021
|
+
/* The leg, not the quote: on a private call it is grossed up, and the approval leg carries the chain's split (openAskMessages). */
|
|
264022
|
+
amountUixo: plan.legBase,
|
|
263726
264023
|
quota: plan.quota,
|
|
263727
264024
|
days: legDays(dates, leg, ctx.now),
|
|
263728
264025
|
denom: ctx.askDenom,
|
|
263729
264026
|
gateAddress: ctx.gate || void 0,
|
|
263730
264027
|
/* The entries leg is the oracle's to judge, so it posts with its rules anchored or not at all. The picks are the poster's. */
|
|
263731
|
-
...leg === "entries" ? { checker: ctx.checker, checkRewardUixo: plan.checkBase, requireRubric: true } : { escrowSpots: plan.escrowSpots },
|
|
264028
|
+
...leg === "entries" ? { checker: ctx.checker, checkRewardUixo: plan.checkBase, requireRubric: true, ...ctx.fee ? { feeDenom: ctx.fee.denom } : {} } : { escrowSpots: plan.escrowSpots },
|
|
263732
264029
|
...campaign ? { campaign } : {},
|
|
263733
264030
|
...ctx.acting ? { as: { address: ctx.acting.principal, did: ctx.acting.did, pubkey: await steps.pubkey(ctx.acting.principal) } } : {}
|
|
263734
264031
|
},
|
|
@@ -263772,7 +264069,7 @@ function confirms(said3, totalBase, symbol2) {
|
|
|
263772
264069
|
const figure = said3.replace(/[$,\s]|USDC|PAY|IXO/gi, "");
|
|
263773
264070
|
return /^\d+(\.\d+)?$/.test(figure) && Math.round(Number(figure) * MICRO3) === totalBase;
|
|
263774
264071
|
}
|
|
263775
|
-
var MICRO3, callsDir, fileOf, askInvitesFile, freshDraft, L, ENTRIES_MAX, INVITES_MAX, INVITE_NOTE_MAX, ADDRESS2, HANDLE_ITEM, isInviteItem, BREAKS, KEEPS_LINES, oneLine, manyLines, within, picture, linesOf, reviewStart, isReady, legOrder, accessOf, nextLeg, toBase2, callTwoCoins, SETTLE_MS, chainCheck, InFlightError, PostRefused, said2, indexLookupWith, indexLookup, posting, isAskPending, isTxFailed, tagOf, TESTNET_CALL_DEFAULTS, payWords;
|
|
264072
|
+
var MICRO3, callsDir, fileOf, askInvitesFile, freshDraft, L, ENTRIES_MAX, INVITES_MAX, INVITE_NOTE_MAX, ADDRESS2, HANDLE_ITEM, isInviteItem, BREAKS, KEEPS_LINES, oneLine, manyLines, within, picture, linesOf, nudgeAtFor, reviewStart, isReady, legOrder, accessOf, nextLeg, toBase2, callShares, SHARE_UNREAD, overCap, callTwoCoins, SETTLE_MS, chainCheck, InFlightError, PostRefused, said2, indexLookupWith, indexLookup, posting, isAskPending, isTxFailed, tagOf, TESTNET_CALL_DEFAULTS, payWords;
|
|
263776
264073
|
var init_call2 = __esm({
|
|
263777
264074
|
"src/call.ts"() {
|
|
263778
264075
|
"use strict";
|
|
@@ -263783,6 +264080,7 @@ var init_call2 = __esm({
|
|
|
263783
264080
|
init_hq();
|
|
263784
264081
|
init_money();
|
|
263785
264082
|
init_networks();
|
|
264083
|
+
init_checkers();
|
|
263786
264084
|
init_callRead();
|
|
263787
264085
|
MICRO3 = 1e6;
|
|
263788
264086
|
callsDir = () => join6(process.env.OPENHANDS_HOME || join6(homedir3(), ".openhands"), currentNetwork(), "calls");
|
|
@@ -263816,6 +264114,10 @@ var init_call2 = __esm({
|
|
|
263816
264114
|
};
|
|
263817
264115
|
picture = (one, what) => !isHttps2(one.url) ? `${what}: "${one.url.slice(0, 80)}" is not an https address` : within(oneLine(one.alt), L.alt, `${what}'s words`) ?? (one.caption ? within(oneLine(one.caption), L.caption, `${what}'s caption`) : null);
|
|
263818
264116
|
linesOf = (fields) => fields.lines ?? (fields.kind === "review" ? [...REVIEW_LINES] : void 0);
|
|
264117
|
+
nudgeAtFor = (network2, judge) => {
|
|
264118
|
+
const asky = askyChecker(network2);
|
|
264119
|
+
return asky && judge === asky.address ? { url: asky.url } : null;
|
|
264120
|
+
};
|
|
263819
264121
|
reviewStart = (title) => (
|
|
263820
264122
|
/* The person copies this into their agent, so it is in their words: no tool names (expert prompts review, 2.6). */
|
|
263821
264123
|
`I'm taking part in the IXO Expert Review "${title ?? "\u2026"}". Show me what the review asks for, then help me try each scenario and keep notes and screenshots as I go: what I did, what I expected and what I saw. Write up my findings with me, each with how serious it is and how to reproduce it, and my recommendations. Show me all of it, and hand it in as my report only when I say so.`
|
|
@@ -263825,6 +264127,9 @@ var init_call2 = __esm({
|
|
|
263825
264127
|
accessOf = (fields) => fields.access === "apply" || fields.access === "invite" ? fields.access : void 0;
|
|
263826
264128
|
nextLeg = (draft) => legOrder(draft.fields).find((leg) => !draft.posted[leg]) ?? null;
|
|
263827
264129
|
toBase2 = (display) => Math.round(display * MICRO3);
|
|
264130
|
+
callShares = (fields) => sharedCall({ access: accessOf(fields), call: { kind: fields.kind } });
|
|
264131
|
+
SHARE_UNREAD = "Refused: this call is a hire by invitation or application, which carries the network's share, and the chain's split could not be read just now, so its leg cannot be priced. Nothing was posted. Try again in a minute.";
|
|
264132
|
+
overCap = (leg, capBase) => leg.escrowBase > capBase;
|
|
263828
264133
|
callTwoCoins = "this call's reviews escrow PAY beside its IXO or USDC rewards, and the connection's allowance covers the reward coin only. Use a reviewer that bills per check (Pay for reviews)";
|
|
263829
264134
|
SETTLE_MS = 10 * 60 * 1e3;
|
|
263830
264135
|
chainCheck = {
|
|
@@ -264007,7 +264312,7 @@ var init_inviteMessages = __esm({
|
|
|
264007
264312
|
callsMessage = (address2, now3 = Date.now()) => `calls:${address2}:${now3}`;
|
|
264008
264313
|
noticesMessage = (address2, now3 = Date.now()) => `notices:${address2}:${now3}`;
|
|
264009
264314
|
tellMessage = (collectionId, address2, now3 = Date.now()) => `tell:${collectionId}:${address2}:${now3}`;
|
|
264010
|
-
NOTICE_KINDS = ["application", "link-opened", "admitted", "declined", "invited"];
|
|
264315
|
+
NOTICE_KINDS = ["application", "link-opened", "admitted", "declined", "invited", "ok-waiting", "ok-reminder"];
|
|
264011
264316
|
handsMessage = (address2, prefAt, digest2) => `hands:${address2}:${prefAt}:${digest2}`;
|
|
264012
264317
|
vettingMineMessage = (address2, now3 = Date.now()) => `vetting-mine:${address2}:${now3}`;
|
|
264013
264318
|
vettingQueueMessage = (by, now3 = Date.now()) => `vetting-queue:${by}:${now3}`;
|
|
@@ -264355,6 +264660,7 @@ __export(invites_exports, {
|
|
|
264355
264660
|
boardHas: () => boardHas,
|
|
264356
264661
|
checkAct: () => checkAct,
|
|
264357
264662
|
decideApplication: () => decideApplication,
|
|
264663
|
+
doorLine: () => doorLine,
|
|
264358
264664
|
inviteItemsOf: () => inviteItemsOf,
|
|
264359
264665
|
markNoticesRead: () => markNoticesRead,
|
|
264360
264666
|
myInvitations: () => myInvitations,
|
|
@@ -264495,7 +264801,10 @@ async function readStanding(site, signer2, collectionId, fetchImpl) {
|
|
|
264495
264801
|
}
|
|
264496
264802
|
function standingWords(standing, context) {
|
|
264497
264803
|
const label = `Admission${context.actingFor ? ` (for ${context.actingFor}, the account you act for)` : ""}: `;
|
|
264498
|
-
if ("poster" in standing)
|
|
264804
|
+
if ("poster" in standing) {
|
|
264805
|
+
if (context.access === "invite") return `${label}you posted this ask, by invitation. call_invites shows the list and which links were opened; invite_to_call adds people (ixo1 addresses, @handles, or "link" for a single-use link).`;
|
|
264806
|
+
return context.access === "apply" ? `${label}you posted this ask, by application. call_invites shows who applied; decide_application says yes or no.` : "";
|
|
264807
|
+
}
|
|
264499
264808
|
if ("refused" in standing) return `${label}could not check just now (${standing.refused}). submit_work says whether you are admitted.`;
|
|
264500
264809
|
const access2 = standing.access ?? context.access;
|
|
264501
264810
|
if (!access2) return "";
|
|
@@ -264513,6 +264822,12 @@ function standingWords(standing, context) {
|
|
|
264513
264822
|
if (application.decision === "no") return `${label}the poster said no to your application. submit_work is refused.`;
|
|
264514
264823
|
return `${label}the poster said yes, then took you off the list. submit_work is refused.`;
|
|
264515
264824
|
}
|
|
264825
|
+
function doorLine(collectionId, sources) {
|
|
264826
|
+
const door = sources.worker ?? sources.draft ?? sources.terms ?? null;
|
|
264827
|
+
if (!door) return `#${collectionId} \xB7 who may enter is not known yet: the board has not read this ask's terms (it does within a minute of posting). The list below already gates; call again shortly.`;
|
|
264828
|
+
const words4 = door === "invite" ? "by invitation" : door === "apply" ? "by application" : "open to anyone";
|
|
264829
|
+
return `#${collectionId} \xB7 ${words4}${!sources.worker && door !== "public" ? " (the board reads the terms within a minute; the list already gates)" : ""}`;
|
|
264830
|
+
}
|
|
264516
264831
|
async function setPage(site, signer2, profile, fetchImpl) {
|
|
264517
264832
|
const owner = signer2.principal ?? signer2.address;
|
|
264518
264833
|
const prefAt = Date.now();
|
|
@@ -264948,7 +265263,7 @@ var init_receipt2 = __esm({
|
|
|
264948
265263
|
// ../../app/lib/reviewerPick.ts
|
|
264949
265264
|
var reviewerPick_exports = {};
|
|
264950
265265
|
__export(reviewerPick_exports, {
|
|
264951
|
-
ASK_THE_WORLD_CHECKERS: () =>
|
|
265266
|
+
ASK_THE_WORLD_CHECKERS: () => ASK_THE_WORLD_CHECKERS2,
|
|
264952
265267
|
NETWORK_CHECKER_ROLE: () => NETWORK_CHECKER_ROLE,
|
|
264953
265268
|
defaultReviewer: () => defaultReviewer,
|
|
264954
265269
|
goodFor: () => goodFor,
|
|
@@ -264968,18 +265283,18 @@ function pickReviewers(oracles, args, cap = 6) {
|
|
|
264968
265283
|
return kept.map((oracle, at) => ({ oracle, at })).sort((a, b) => Number(decided(b.oracle) > 0) - Number(decided(a.oracle) > 0) || a.at - b.at).slice(0, cap).map((one) => one.oracle);
|
|
264969
265284
|
}
|
|
264970
265285
|
function defaultReviewer(oracles, fallback, off) {
|
|
264971
|
-
return oracles.find((oracle) =>
|
|
265286
|
+
return oracles.find((oracle) => ASK_THE_WORLD_CHECKERS2.has(oracle.address) && !oracle.unavailable && !off?.has(oracle.address)) ?? fallback;
|
|
264972
265287
|
}
|
|
264973
265288
|
function goodFor(address2, named) {
|
|
264974
|
-
if (
|
|
265289
|
+
if (ASK_THE_WORLD_CHECKERS2.has(address2)) return "Good for photos, a quick look somewhere and short written answers. The default for an ordinary ask";
|
|
264975
265290
|
if (named) return "Good for cleanups, before-and-after photos and site work. The default for those";
|
|
264976
265291
|
return null;
|
|
264977
265292
|
}
|
|
264978
|
-
var NETWORK_CHECKER_ROLE, plainReviewerName, isWorkAsk;
|
|
265293
|
+
var ASK_THE_WORLD_CHECKERS2, NETWORK_CHECKER_ROLE, plainReviewerName, isWorkAsk;
|
|
264979
265294
|
var init_reviewerPick = __esm({
|
|
264980
265295
|
"../../app/lib/reviewerPick.ts"() {
|
|
264981
265296
|
"use strict";
|
|
264982
|
-
|
|
265297
|
+
ASK_THE_WORLD_CHECKERS2 = /* @__PURE__ */ new Set(["ixo1qrk9dp4r2u8q5l9cs42yh4dne4pj3wynp4enwq", "ixo12mvzayzrzsvaud86jf9shy6q2nvkea3tygxhsh"]);
|
|
264983
265298
|
NETWORK_CHECKER_ROLE = "The default reviewer for cleanups and site work. An ordinary ask defaults to the Ask the World reviewer where this network carries it";
|
|
264984
265299
|
plainReviewerName = (name8) => name8.replace(/\boracle\b/gi, (word) => word[0] === "O" ? "Reviewer" : "reviewer");
|
|
264985
265300
|
isWorkAsk = (terms) => terms.deliverable.type === "photo-pair" || terms.deliverable.type === "mess-report" || Boolean(terms.site || terms.campaign);
|
|
@@ -290953,7 +291268,7 @@ import { randomBytes as randomBytes7 } from "node:crypto";
|
|
|
290953
291268
|
// package.json
|
|
290954
291269
|
var package_default = {
|
|
290955
291270
|
name: "@ixo/asks-mcp",
|
|
290956
|
-
version: "1.5.0-dev.
|
|
291271
|
+
version: "1.5.0-dev.18",
|
|
290957
291272
|
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.",
|
|
290958
291273
|
license: "Apache-2.0",
|
|
290959
291274
|
repository: {
|
|
@@ -291452,6 +291767,7 @@ init_world();
|
|
|
291452
291767
|
init_networks();
|
|
291453
291768
|
init_env();
|
|
291454
291769
|
init_net();
|
|
291770
|
+
init_given();
|
|
291455
291771
|
init_money();
|
|
291456
291772
|
|
|
291457
291773
|
// ../../packages/openhands-sdk/src/data/plans.ts
|
|
@@ -291469,6 +291785,17 @@ function claimFormIn(env) {
|
|
|
291469
291785
|
}
|
|
291470
291786
|
var askProtocolChosenHere = () => Boolean(ownEnv().NEXT_PUBLIC_ASK_PROTOCOL_DID?.trim());
|
|
291471
291787
|
var relayerChosenHere = () => Boolean(ownEnv().NEXT_PUBLIC_RELAYER?.trim() || ownEnv().NEXT_PUBLIC_RELAYER_NODE_DID?.trim());
|
|
291788
|
+
var FEE_SPLIT_ENV = "OPENHANDS_FEE_SPLIT";
|
|
291789
|
+
function feeSplitIn(raw) {
|
|
291790
|
+
const parts = (raw ?? "").split(",").map((one) => one.trim());
|
|
291791
|
+
if (parts.length !== 2 || parts.some((one) => !/^\d+(\.\d+)?$/.test(one))) return null;
|
|
291792
|
+
const [network2, node] = parts.map(Number);
|
|
291793
|
+
return network2 + node < 100 ? { network: network2, node } : null;
|
|
291794
|
+
}
|
|
291795
|
+
var servedSplit = (served) => {
|
|
291796
|
+
const { network: network2, node } = served ?? {};
|
|
291797
|
+
return typeof network2 === "number" && typeof node === "number" && network2 >= 0 && node >= 0 && network2 + node < 100 ? { network: network2, node } : null;
|
|
291798
|
+
};
|
|
291472
291799
|
function fromEnv() {
|
|
291473
291800
|
const env = ownEnv();
|
|
291474
291801
|
return {
|
|
@@ -291486,6 +291813,7 @@ function fromEnv() {
|
|
|
291486
291813
|
relayerNodeDid: relayerChosenHere() ? relayerNodeIfConfigured() ?? "" : "",
|
|
291487
291814
|
claimForm: claimFormIn(env).form,
|
|
291488
291815
|
askProtocolDid: askProtocolChosenHere() ? askProtocolDidIfConfigured() ?? "" : "",
|
|
291816
|
+
feeSplit: feeSplitIn(env[FEE_SPLIT_ENV]),
|
|
291489
291817
|
from: "env"
|
|
291490
291818
|
};
|
|
291491
291819
|
}
|
|
@@ -291536,6 +291864,8 @@ async function deployment() {
|
|
|
291536
291864
|
relayerNodeDid: relayerChosenHere() ? env.relayerNodeDid : answer.relayer?.did?.trim() || "",
|
|
291537
291865
|
claimForm: mergedClaimForm(own2, answer.claimForm),
|
|
291538
291866
|
askProtocolDid: env.askProtocolDid || (/^did:ixo:entity:[0-9a-f]{32}$/.test(answer.askProtocolDid?.trim() ?? "") ? answer.askProtocolDid.trim() : ""),
|
|
291867
|
+
/* The chain's split, as the site read it: the fallback when this process cannot read the chain itself (the chain wins). A pin here wins over the site's. */
|
|
291868
|
+
feeSplit: env.feeSplit ?? servedSplit(answer.feeSplit),
|
|
291539
291869
|
from: "site"
|
|
291540
291870
|
};
|
|
291541
291871
|
}
|
|
@@ -291571,6 +291901,14 @@ function adoptAskProtocol(facts) {
|
|
|
291571
291901
|
if (askProtocolChosenHere() || !facts.askProtocolDid) return;
|
|
291572
291902
|
adopt({ askProtocolDid: facts.askProtocolDid });
|
|
291573
291903
|
}
|
|
291904
|
+
function adoptFeeSplit(facts) {
|
|
291905
|
+
const split3 = facts.feeSplit ? { network: facts.feeSplit.network, node: facts.feeSplit.node } : void 0;
|
|
291906
|
+
const scope2 = activeScope();
|
|
291907
|
+
const next = scope2 ? scope2.given : { ...givenConfig() };
|
|
291908
|
+
if (split3) next.feeSplit = split3;
|
|
291909
|
+
else delete next.feeSplit;
|
|
291910
|
+
if (!scope2) setGivenConfig(next);
|
|
291911
|
+
}
|
|
291574
291912
|
function adoptRelayer(facts) {
|
|
291575
291913
|
if (relayerChosenHere() || !facts.relayerNodeDid) return;
|
|
291576
291914
|
adopt({ relayerNodeDid: facts.relayerNodeDid });
|
|
@@ -292099,6 +292437,14 @@ function engineGateLines(decision, indent3 = " ") {
|
|
|
292099
292437
|
return `${indent3}${MARK[gate.outcome]} ${gate.code}. ${why}`;
|
|
292100
292438
|
});
|
|
292101
292439
|
}
|
|
292440
|
+
function juryLines(criteria) {
|
|
292441
|
+
const judged = (criteria ?? []).filter((line2) => line2.id.endsWith("-JUDGED"));
|
|
292442
|
+
if (judged.length === 0) return [];
|
|
292443
|
+
const passed = judged.filter((line2) => line2.outcome === "pass").length;
|
|
292444
|
+
const word = (outcome) => outcome === "pass" ? "pass" : outcome === "fail" ? "FAIL" : "not reached";
|
|
292445
|
+
const must = (line2) => (line2.outcome === "fail" ? line2.text : line2.text.replace(/\s+Fail this only if[\s\S]*$/, "")).trim();
|
|
292446
|
+
return [`The jury, line by line: ${passed} of ${judged.length} passed`, ...judged.map((line2) => ` ${word(line2.outcome)} \xB7 ${must(line2)}`)];
|
|
292447
|
+
}
|
|
292102
292448
|
function engineLines(decision, options = {}) {
|
|
292103
292449
|
const indent3 = options.indent ?? "";
|
|
292104
292450
|
const cid = decision.cid ?? options.cid ?? null;
|
|
@@ -292397,7 +292743,7 @@ var MAX_FILES = 12;
|
|
|
292397
292743
|
var MAX_FILE_BYTES = 1e7;
|
|
292398
292744
|
var reportInput = {
|
|
292399
292745
|
report: external_exports.record(external_exports.string(), external_exports.unknown()).optional().describe(
|
|
292400
|
-
"For an ask that wants a review report: { summary: { product, build?, date, environment?, target?, scope, outcome }, steps: [{ id, what, expected, observed, result: passed|failed|blocked|not_tested|excluded, notes?, evidence?: [file ids] }], findings: [{ id, title, steps?: [step ids], observed, expected, impact, severity: blocker|major|minor, severity_why, how_to_reproduce (major; a blocker may give cannot_reproduce instead), uncertainty?, advice?, evidence? }], recommendations: [{ text, priority: high|medium|low, findings?: [finding ids], target?, done_when, advice? }], limitations: [lines], sections?: { heading: text } } with every section the ask names. The person approves it in a dialog before anything is sent."
|
|
292746
|
+
"For an ask that wants a review report: { summary: { product, build?, date, environment?, target?, scope, outcome }, steps: [{ id, what, expected, observed, result: passed|failed|blocked|not_tested|excluded, notes?, evidence?: [file ids] }], findings: [{ id, title, steps?: [step ids], observed, expected, impact, severity: blocker|major|minor, severity_why, how_to_reproduce (major, and every severity on an Expert Review; a blocker may give cannot_reproduce instead), uncertainty?, advice?, evidence? (required on an Expert Review) }], recommendations: [{ text, priority: high|medium|low, findings?: [finding ids], target?, done_when, advice? }], limitations: [lines] (at least one on an Expert Review), sections?: { heading: text } } with every section the ask names. The person approves it in a dialog before anything is sent."
|
|
292401
292747
|
),
|
|
292402
292748
|
uses_memory: external_exports.boolean().optional().describe("true when any part of the report came from what you remember about the person or from earlier chats. Ask them first; they are asked again in a dialog before it is used."),
|
|
292403
292749
|
files: external_exports.array(external_exports.string().min(1).max(500)).max(MAX_FILES).optional().describe(`With report: screenshots or a PDF on this machine (png, jpg, webp or pdf, up to ${MAX_FILE_BYTES / 1e6} MB each, at most ${MAX_FILES}). A file's id, for evidence, is its name without the extension.`)
|
|
@@ -292465,7 +292811,7 @@ function summaryOf2(report, files, digest2) {
|
|
|
292465
292811
|
`Digest: ${digest2}`
|
|
292466
292812
|
];
|
|
292467
292813
|
}
|
|
292468
|
-
var receiptLine = (site, collectionId, claimId, reviewSlug) => `Receipt: ${reviewSlug ? `${expertOrigin(site)}/expert/reviews/${
|
|
292814
|
+
var receiptLine = (site, collectionId, claimId, reviewSlug) => `Receipt: ${reviewSlug ? `${expertOrigin(site)}/expert/reviews/${collectionId}/report/${encodeURIComponent(claimId)}` : `${site}/r/${collectionId}/trace/${encodeURIComponent(claimId)}`}`;
|
|
292469
292815
|
async function sendReport(send, world) {
|
|
292470
292816
|
for (const path of send.paths) {
|
|
292471
292817
|
if (!isAbsolute(path) || CONTROL.test(path)) return `Refused: give each file as a full path (starting with /), with no line breaks in it. Nothing was sent.`;
|
|
@@ -292824,6 +293170,70 @@ async function sendFields(send, world) {
|
|
|
292824
293170
|
|
|
292825
293171
|
// src/server.ts
|
|
292826
293172
|
init_report();
|
|
293173
|
+
|
|
293174
|
+
// ../../packages/openhands-sdk/src/rubric/reportTemplate.ts
|
|
293175
|
+
var REVIEW_CHECKS = [
|
|
293176
|
+
"It covers the ask's scenarios (or steps)",
|
|
293177
|
+
"Every finding has evidence: a screenshot, recording or trace",
|
|
293178
|
+
"Every problem says how to reproduce it",
|
|
293179
|
+
"Every problem has a severity: blocker, major or minor",
|
|
293180
|
+
"Every recommendation says what to change",
|
|
293181
|
+
"The limitations are stated"
|
|
293182
|
+
];
|
|
293183
|
+
var REVIEW_REFUSED = "A report is turned down by the checker only when it is clearly not one: no report, a report of something other than this ask, or no evidence at all. Anything else goes to the ask's owner, who gives the final OK before you are paid.";
|
|
293184
|
+
var REVIEW_REPORT_SECTIONS = [
|
|
293185
|
+
{
|
|
293186
|
+
title: "What was tested",
|
|
293187
|
+
field: "summary",
|
|
293188
|
+
items: [
|
|
293189
|
+
{ say: "The ask and what you reviewed", field: "summary.product" },
|
|
293190
|
+
{ say: "The version or build", field: "summary.build" },
|
|
293191
|
+
{ say: "Where: environment, URL, device, build", field: "summary.environment" },
|
|
293192
|
+
{ say: "The scenarios you covered", field: "summary.scope" },
|
|
293193
|
+
{ say: "The date", field: "summary.date" },
|
|
293194
|
+
{ say: "The outcome, in one sentence", field: "summary.outcome" }
|
|
293195
|
+
]
|
|
293196
|
+
},
|
|
293197
|
+
{
|
|
293198
|
+
title: "Steps",
|
|
293199
|
+
field: "steps",
|
|
293200
|
+
items: [{ say: "One per scenario or step: what you did, what you expected, what you observed", field: "what, expected, observed" }, { say: "Its result: passed, failed, blocked or not tested", field: "result: passed, failed, blocked, not_tested" }]
|
|
293201
|
+
},
|
|
293202
|
+
{
|
|
293203
|
+
title: "Findings",
|
|
293204
|
+
field: "findings",
|
|
293205
|
+
items: [
|
|
293206
|
+
{ say: "Each problem: what happened", field: "title, observed, expected" },
|
|
293207
|
+
{ say: "Its evidence: a screenshot, recording or trace, attached and named", field: "evidence" },
|
|
293208
|
+
{ say: "How to reproduce it (a blocker you cannot reproduce says what is missing)", field: "how_to_reproduce, cannot_reproduce" },
|
|
293209
|
+
{ say: "Its severity, blocker, major or minor, and why", field: "severity, severity_why" },
|
|
293210
|
+
{ say: "Its impact on the person using it", field: "impact" }
|
|
293211
|
+
]
|
|
293212
|
+
},
|
|
293213
|
+
{
|
|
293214
|
+
title: "Recommendations",
|
|
293215
|
+
field: "recommendations",
|
|
293216
|
+
items: [{ say: "Each: what to change", field: "text" }, { say: "Its priority: high, medium or low", field: "priority" }, { say: "How to tell it is done", field: "done_when" }]
|
|
293217
|
+
},
|
|
293218
|
+
{
|
|
293219
|
+
title: "Limitations",
|
|
293220
|
+
field: "limitations",
|
|
293221
|
+
items: [{ say: "What you could not test, and why the result may not hold", field: "limitations" }]
|
|
293222
|
+
}
|
|
293223
|
+
];
|
|
293224
|
+
function reviewReportTemplate(options = {}) {
|
|
293225
|
+
return [
|
|
293226
|
+
"Review report",
|
|
293227
|
+
"",
|
|
293228
|
+
...REVIEW_REPORT_SECTIONS.flatMap((section) => [`## ${section.title}`, ...section.items.map((item) => `- ${item.say}${options.fields && item.field ? ` (${item.field})` : ""}`), ""]),
|
|
293229
|
+
"What the checker looks at:",
|
|
293230
|
+
...REVIEW_CHECKS.map((check2, index) => `${index + 1}. ${check2}`),
|
|
293231
|
+
"",
|
|
293232
|
+
REVIEW_REFUSED
|
|
293233
|
+
].join("\n");
|
|
293234
|
+
}
|
|
293235
|
+
|
|
293236
|
+
// src/server.ts
|
|
292827
293237
|
init_site();
|
|
292828
293238
|
var VERSION6 = package_default.version;
|
|
292829
293239
|
var onSite = (url4) => {
|
|
@@ -292962,6 +293372,7 @@ async function build2(options, server2, parts) {
|
|
|
292962
293372
|
adoptAskProtocol(DEPLOYMENT);
|
|
292963
293373
|
adoptReviewBilling(DEPLOYMENT);
|
|
292964
293374
|
adoptOracleUrl(DEPLOYMENT);
|
|
293375
|
+
if (local) adoptFeeSplit(DEPLOYMENT);
|
|
292965
293376
|
const OWN_FORM_ENV = Object.fromEntries(CLAIM_FORM_ENV.map((name8) => [name8, ownEnv()[name8]]));
|
|
292966
293377
|
if (local) adoptClaimForm(DEPLOYMENT);
|
|
292967
293378
|
let CLAIM_FORM = DEPLOYMENT.claimForm;
|
|
@@ -292979,6 +293390,7 @@ async function build2(options, server2, parts) {
|
|
|
292979
293390
|
adoptAskProtocol(fresh2);
|
|
292980
293391
|
adoptReviewBilling(fresh2);
|
|
292981
293392
|
adoptOracleUrl(fresh2);
|
|
293393
|
+
adoptFeeSplit(fresh2);
|
|
292982
293394
|
adoptClaimForm(fresh2);
|
|
292983
293395
|
CLAIM_FORM = fresh2.claimForm;
|
|
292984
293396
|
applyDeployment(fresh2);
|
|
@@ -293017,6 +293429,7 @@ async function build2(options, server2, parts) {
|
|
|
293017
293429
|
const FUNDER = ownEnv().OPENHANDS_FUNDER?.trim() || void 0;
|
|
293018
293430
|
const FOLLOW_PAY_MAX = 10;
|
|
293019
293431
|
const MAX_PER_ASK = CAPS.perAsk;
|
|
293432
|
+
const CAP_BASE = Math.round(MAX_PER_ASK * MICRO4);
|
|
293020
293433
|
const MAX_PER_DAY = CAPS.perDay;
|
|
293021
293434
|
const MAX_PER_DAY_TOTAL = CAPS.total;
|
|
293022
293435
|
const ALL_TOOLS = "all";
|
|
@@ -293251,7 +293664,9 @@ Each is its own ask and pays on its own. Read one with read_ask before deciding.
|
|
|
293251
293664
|
const slug = tag ? slugOfTag2(tag) : null;
|
|
293252
293665
|
if (!tag || !slug) return;
|
|
293253
293666
|
const group = await read9(`/api/board/campaign/${tag}`);
|
|
293254
|
-
|
|
293667
|
+
const entries2 = group?.rows?.find((one) => /^(Open call|Expert review): /.test(one.title)) ?? null;
|
|
293668
|
+
const shared = entries2 ? (await askReceipt(entries2.id))?.payments?.["approval"]?.is_oracle_payment === true : false;
|
|
293669
|
+
calls.set(tag, { slug, entries: entries2, shared });
|
|
293255
293670
|
})
|
|
293256
293671
|
);
|
|
293257
293672
|
const callLine = (row, call) => {
|
|
@@ -293259,11 +293674,13 @@ Each is its own ask and pays on its own. Read one with read_ask before deciding.
|
|
|
293259
293674
|
const review = isReviewTitle(call.entries?.title);
|
|
293260
293675
|
const title = call.entries?.title.replace(/^(Open call|Expert review): /, "") ?? null;
|
|
293261
293676
|
if (title) taint2(title);
|
|
293262
|
-
const
|
|
293677
|
+
const facts = row.callSummary;
|
|
293678
|
+
const shares = call.shared;
|
|
293679
|
+
const entryPays = shares && facts?.entryEach !== void 0 && call.entries?.pays ? `${faceOf2({ value: facts.entryEach, symbol: call.entries.pays.symbol })?.text} (the network's share is on top of it)` : call.entries?.pays ? `${faceOf2(call.entries.pays)?.text}${shares ? ", less the network's share" : ""}` : void 0;
|
|
293263
293680
|
return [
|
|
293264
293681
|
`${review ? "Expert review" : "Open call"} "${call.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`,
|
|
293265
293682
|
title ? asData("ask-title", title) : "",
|
|
293266
|
-
`${review ? "A specialist's report on the review's scenarios, assessed against its requirements. A report that meets them qualifies for payment, after the builder's final approval when they give one." : "A written entry assessed against five requirements. Entries that meet all five qualify for payment. For competitions, the poster also chooses a prize winner."} ${call.entries ? `Read it with read_ask "${call.entries.id}"; the page is` : "Read its legs on the page:"} ${review ? `${EXPERT_SITE}/expert/reviews/${call.slug}` : `${SITE}/opencall/${call.slug}`}`
|
|
293683
|
+
`${review ? "A specialist's report on the review's scenarios, assessed against its requirements. A report that meets them qualifies for payment, after the builder's final approval when they give one." : "A written entry assessed against five requirements. Entries that meet all five qualify for payment. For competitions, the poster also chooses a prize winner."} ${call.entries ? `Read it with read_ask "${call.entries.id}"; the page is` : "Read its legs on the page:"} ${review ? `${EXPERT_SITE}/expert/reviews/${call.entries?.id ?? call.slug}` : `${SITE}/opencall/${call.slug}`}`
|
|
293267
293684
|
].filter(Boolean).join("\n");
|
|
293268
293685
|
};
|
|
293269
293686
|
const lines2 = board.rows.filter(within2).map((row) => {
|
|
@@ -293321,7 +293738,8 @@ ${[...folded, ...hidden].join("\n")}${folded.length || hidden.length ? "\n\n" :
|
|
|
293321
293738
|
if (!receipt) return text4(`Could not read ask ${collectionId}.`);
|
|
293322
293739
|
const { coinDisplay: coinDisplay2, faceOf: faceOf2 } = await Promise.resolve().then(() => (init_format(), format_exports));
|
|
293323
293740
|
const { fetchDoc: fetchDoc2 } = await Promise.resolve().then(() => (init_docs(), docs_exports));
|
|
293324
|
-
const
|
|
293741
|
+
const shown2 = coinDisplay2(receipt.payments?.["approval"]?.amount);
|
|
293742
|
+
const pays = shown2?.symbol === "PAY" ? { text: `${shown2.value} PAY` } : faceOf2(shown2);
|
|
293325
293743
|
const already = receipt.claims?.some((claim3) => ours.includes(claim3.agentAddress));
|
|
293326
293744
|
let offChain = null;
|
|
293327
293745
|
if (!pays && receipt.payout) {
|
|
@@ -293332,6 +293750,7 @@ ${[...folded, ...hidden].join("\n")}${folded.length || hidden.length ? "\n\n" :
|
|
|
293332
293750
|
}
|
|
293333
293751
|
let terms = "(this ask published no terms. The title is all there is)";
|
|
293334
293752
|
let parsed = null;
|
|
293753
|
+
let postedShare = null;
|
|
293335
293754
|
if (receipt.doneMeansCid) {
|
|
293336
293755
|
const doc = await fetchDoc2(receipt.doneMeansCid, { timeoutMs: 15e3, fetchImpl: fetch2, at: receipt.doneMeansUrl }).then((r) => r.ok ? r.text() : null).catch(() => null);
|
|
293337
293756
|
if (doc) {
|
|
@@ -293344,7 +293763,8 @@ ${[...folded, ...hidden].join("\n")}${folded.length || hidden.length ? "\n\n" :
|
|
|
293344
293763
|
const read9 = parsed ? parseTerms2(parsed) : null;
|
|
293345
293764
|
if (read9?.call) {
|
|
293346
293765
|
const { callReadout: callReadout2 } = await Promise.resolve().then(() => (init_call2(), call_exports2));
|
|
293347
|
-
terms = callReadout2(read9, { id: collectionId, symbol: ASK_SYMBOL, site: SITE });
|
|
293766
|
+
terms = callReadout2(read9, { id: collectionId, symbol: shown2?.symbol ?? ASK_SYMBOL, site: SITE });
|
|
293767
|
+
postedShare = read9.call.share ?? null;
|
|
293348
293768
|
}
|
|
293349
293769
|
}
|
|
293350
293770
|
}
|
|
@@ -293353,14 +293773,16 @@ ${[...folded, ...hidden].join("\n")}${folded.length || hidden.length ? "\n\n" :
|
|
|
293353
293773
|
taint2(terms);
|
|
293354
293774
|
const fit = fitFromTerms(parsed);
|
|
293355
293775
|
const declared = parsed?.access;
|
|
293356
|
-
const
|
|
293776
|
+
const drafted = local ? (await Promise.resolve().then(() => (init_call2(), call_exports2))).draftOfEntries(collectionId)?.fields.access : void 0;
|
|
293777
|
+
const access2 = receipt.access ?? (declared === "apply" || declared === "invite" ? declared : drafted === "apply" || drafted === "invite" ? drafted : null);
|
|
293357
293778
|
const admitted = access2 && admission ? await admission(receipt, access2) : "";
|
|
293358
293779
|
const judge = parsed?.judge;
|
|
293359
293780
|
const reviewer = await oracleWordsFor({ did: receipt.payout?.oracle ?? null, address: judge?.kind === "oracle" && typeof judge.address === "string" ? judge.address : null });
|
|
293360
293781
|
taint2(reviewer);
|
|
293782
|
+
const shared = pays ? await sharedPays(receipt.payments?.["approval"], postedShare) : null;
|
|
293361
293783
|
return text4(
|
|
293362
293784
|
[
|
|
293363
|
-
offChain ? `Ask #${collectionId} \xB7 pays ${offChain}` : `Ask #${collectionId} \xB7 pays ${pays ? `${pays.text}` : "nothing"} per approved answer`,
|
|
293785
|
+
offChain ? `Ask #${collectionId} \xB7 pays ${offChain}` : `Ask #${collectionId} \xB7 pays ${shared ?? (pays ? `${pays.text}` : "nothing")} per approved answer`,
|
|
293364
293786
|
`Standing: ${receipt.standing ?? (receipt.openness?.open ? "open" : "not accepting answers")}`,
|
|
293365
293787
|
/* A call's readout says its own door (callRead.ts); this line is for every other ask whose terms carry one. */
|
|
293366
293788
|
!parsed?.call && receipt.access === "invite" ? "By invitation: only the addresses the poster listed are admitted (a link from the poster goes in submit_work's invite)." : !parsed?.call && receipt.access === "apply" ? "By application: apply_to_call first; the poster's yes admits you." : "",
|
|
@@ -293372,7 +293794,10 @@ ${[...folded, ...hidden].join("\n")}${folded.length || hidden.length ? "\n\n" :
|
|
|
293372
293794
|
|
|
293373
293795
|
${terms}`),
|
|
293374
293796
|
"",
|
|
293375
|
-
`Fit: ${fit.fit}. ${fit.because}
|
|
293797
|
+
`Fit: ${fit.fit}. ${fit.because}`,
|
|
293798
|
+
/* An Expert Review: the same template and checks the submit page shows, for the report submit_work sends. */
|
|
293799
|
+
...parsed?.call?.kind === "review" ? ["", `Write the report to this template (submit_work's report fields in brackets):
|
|
293800
|
+
${reviewReportTemplate({ fields: true })}`] : []
|
|
293376
293801
|
].filter(Boolean).join("\n")
|
|
293377
293802
|
);
|
|
293378
293803
|
}
|
|
@@ -293448,6 +293873,7 @@ ${terms}`),
|
|
|
293448
293873
|
if (expertAsk && (!fields || deliverable || report)) return text4(`Refused: ${expertAsk.checker.name} checks this ask by its own form. Pass fields (and no deliverable or report): ${questionsLine(expertAsk.check.fields)}. Nothing was sent.`);
|
|
293449
293874
|
let requirement = null;
|
|
293450
293875
|
let reviewSlug = null;
|
|
293876
|
+
let judgeAddress = null;
|
|
293451
293877
|
const rubricTerms = await Promise.resolve().then(() => (init_terms(), terms_exports));
|
|
293452
293878
|
if (receipt.doneMeansCid && !expertAsk) {
|
|
293453
293879
|
const { readDocJson: readDocJson2 } = await Promise.resolve().then(() => (init_src5(), src_exports4));
|
|
@@ -293458,9 +293884,13 @@ ${terms}`),
|
|
|
293458
293884
|
if (photo) return text4(photo);
|
|
293459
293885
|
const siteReport = terms?.report;
|
|
293460
293886
|
if (!raw && !terms && report) return text4("Refused: this ask's terms could not be read just now, so the report could not be checked against them. Nothing was sent; try again in a minute.");
|
|
293887
|
+
const judge = (raw ?? terms)?.judge;
|
|
293888
|
+
judgeAddress = judge?.kind === "oracle" && typeof judge.address === "string" ? judge.address : null;
|
|
293461
293889
|
reviewSlug = reviewSlugOf(raw ? rubricTerms.parseTerms(raw)?.call ?? {} : terms?.call ?? {});
|
|
293462
|
-
requirement = raw ? rubricTerms.parseTerms(raw)?.report ?? null : siteReport ? { sections: Array.isArray(siteReport.sections) ? siteReport.sections.filter((one) => typeof one === "string") : [] } : null;
|
|
293463
|
-
if (requirement && !report) return text4(`Refused: this ask wants a review report. Pass report (and files for screenshots or a PDF), or answer on the website: ${SITE}/submit/${collectionId}. Nothing was sent
|
|
293890
|
+
requirement = raw ? rubricTerms.parseTerms(raw)?.report ?? null : siteReport ? { sections: Array.isArray(siteReport.sections) ? siteReport.sections.filter((one) => typeof one === "string") : [], ...siteReport.v === 2 ? { v: 2 } : {} } : null;
|
|
293891
|
+
if (requirement && !report) return text4(`Refused: this ask wants a review report. Pass report (and files for screenshots or a PDF), or answer on the website: ${SITE}/submit/${collectionId}. Nothing was sent.${requirement.v === 2 ? `
|
|
293892
|
+
|
|
293893
|
+
${reviewReportTemplate({ fields: true })}` : ""}`);
|
|
293464
293894
|
if (report) {
|
|
293465
293895
|
const problems = reportProblems(report, requirement, (files ?? []).map(fileId));
|
|
293466
293896
|
if (problems.length) return text4(`Refused: the report is not ready. Nothing was sent.
|
|
@@ -293551,7 +293981,7 @@ You cannot complete it, and trying would spend the gate's gas to be rejected. Wh
|
|
|
293551
293981
|
};
|
|
293552
293982
|
const who = { submitter, ...acting ? { delegate: actor.address } : {}, ...alias ? { alias } : {} };
|
|
293553
293983
|
const said3 = 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);
|
|
293554
|
-
if (said3.startsWith("Answered")) nudge("scan", collectionId, expertAsk?.checker);
|
|
293984
|
+
if (said3.startsWith("Answered")) nudge("scan", collectionId, expertAsk?.checker ?? (await Promise.resolve().then(() => (init_call2(), call_exports2))).nudgeAtFor(NETWORK2, judgeAddress));
|
|
293555
293985
|
return text4(expertAsk && said3.startsWith("Answered") ? said3.replace(/^(Answered #\d+ as \S+)\./, `$1, for ${expertAsk.checker.name} to check.`) : said3);
|
|
293556
293986
|
}
|
|
293557
293987
|
const refusedToPrepare = await prepare2();
|
|
@@ -293615,8 +294045,8 @@ Receipt: ${answerPage(SITE, collectionId, stored.cid, { kind: reviewSlug ? "revi
|
|
|
293615
294045
|
if (!who.url) return { refused: `${who.name} has no address to be hired at` };
|
|
293616
294046
|
const billing = await Promise.resolve().then(() => (init_reviewBilling(), reviewBilling_exports));
|
|
293617
294047
|
if (who.perReview && billing.reviewsBilledPerCheck() && what.priceBase !== null) return { ...picked, leg: 0, feeDenom: FEE_DENOM, perCheck: { price: what.priceBase, oracleUrl: who.url } };
|
|
293618
|
-
const { ASK_THE_WORLD_CHECKERS:
|
|
293619
|
-
const feeCoin = feeCoinOf2(what.priceDenom,
|
|
294048
|
+
const { ASK_THE_WORLD_CHECKERS: ASK_THE_WORLD_CHECKERS3, feeCoinOf: feeCoinOf2 } = await Promise.resolve().then(() => (init_checkers(), checkers_exports));
|
|
294049
|
+
const feeCoin = feeCoinOf2(what.priceDenom, ASK_THE_WORLD_CHECKERS3.has(who.address) || CHECKER !== "" && who.address === CHECKER);
|
|
293620
294050
|
if ("refused" in feeCoin) return feeCoin;
|
|
293621
294051
|
if (what.priceBase === null) return { refused: `${who.name} does not say what "${what.name}" costs` };
|
|
293622
294052
|
return { ...picked, leg: what.priceBase, feeDenom: feeCoin.denom, perCheck: null };
|
|
@@ -293931,8 +294361,22 @@ ${SITE}/t/${earlier.id}`);
|
|
|
293931
294361
|
let ENGINE_ORACLE = DEPLOYMENT.engine.oracle;
|
|
293932
294362
|
let ENGINE_MODE = DEPLOYMENT.engine.live;
|
|
293933
294363
|
const engineLive = () => ENGINE_MODE && Boolean(ENGINE_ORACLE);
|
|
293934
|
-
const callPerCheck = async () => (await Promise.resolve().then(() => (init_reviewBilling(), reviewBilling_exports))).deploymentBillsPerCheck(
|
|
293935
|
-
const
|
|
294364
|
+
const callPerCheck = async (checker = CHECKER) => (await Promise.resolve().then(() => (init_reviewBilling(), reviewBilling_exports))).deploymentBillsPerCheck(checker).catch(() => false);
|
|
294365
|
+
const callChecker2 = async (review) => (await Promise.resolve().then(() => (init_call2(), call_exports2))).callChecker(NETWORK2, review, CHECKER);
|
|
294366
|
+
const callSplit = async () => (await Promise.resolve().then(() => (init_query43(), query_exports43))).feeSplitOrNull();
|
|
294367
|
+
async function sharedPays(leg, posted) {
|
|
294368
|
+
if (leg?.is_oracle_payment !== true || !leg.amount?.[0]) return null;
|
|
294369
|
+
const { coinDisplay: coinDisplay2, faceOf: faceOf2 } = await Promise.resolve().then(() => (init_format(), format_exports));
|
|
294370
|
+
const { netOf: netOf2 } = await Promise.resolve().then(() => (init_share(), share_exports));
|
|
294371
|
+
const { shareWords: shareWords2 } = await Promise.resolve().then(() => (init_callRead(), callRead_exports));
|
|
294372
|
+
const { denom, amount: amount4 } = leg.amount[0];
|
|
294373
|
+
const said3 = (base5) => faceOf2(coinDisplay2([{ denom, amount: String(base5) }]))?.text ?? `${base5} ${denom}`;
|
|
294374
|
+
const split3 = posted ?? await callSplit();
|
|
294375
|
+
if (!split3) return `${said3(Number(amount4))} less the network's share (the chain's split could not be read just now)`;
|
|
294376
|
+
const receives = netOf2(Number(amount4), split3);
|
|
294377
|
+
return `${said3(receives)} (the leg is ${said3(Number(amount4))}; the network keeps ${said3(Number(amount4) - receives)}: ${shareWords2(split3, posted ? "as posted" : "today")})`;
|
|
294378
|
+
}
|
|
294379
|
+
const callLocks = (rewardBase, feeBase, symbol2 = ASK_SYMBOL) => `${symbol2 === "PAY" ? feeWords(rewardBase, "PAY") : face(rewardBase / MICRO4, symbol2)}${feeBase > 0 ? ` and ${feeWords(feeBase)} for reviews` : ""}`;
|
|
293936
294380
|
function escrowTotal(pay, spots, legBase, symbol2 = ASK_SYMBOL, sameCoin = true, feeSymbol = FEE_SYMBOL) {
|
|
293937
294381
|
const leg = legBase / MICRO4;
|
|
293938
294382
|
if (!sameCoin && leg > 0) {
|
|
@@ -294277,6 +294721,8 @@ ${SITE}/t/${earlier.id}`);
|
|
|
294277
294721
|
"",
|
|
294278
294722
|
...evidenceLines2(evidence),
|
|
294279
294723
|
"",
|
|
294724
|
+
/* How each judged line went, in the ask's own words (#44101). */
|
|
294725
|
+
...proof.cid ? juryLines((await readJson3(`${SITE}/api/check/${encodeURIComponent(proof.cid)}`))?.criteria) : [],
|
|
294280
294726
|
gates.length ? `Machine: ${gates.join(" \xB7 ")}` : "",
|
|
294281
294727
|
`Answered by ${approved.agentAddress}`,
|
|
294282
294728
|
/* The answer's own page: a link that unfurls as the work-done card, wherever an agent posts it. */
|
|
@@ -294825,10 +295271,24 @@ They can disconnect at ${SITE}/connect.`);
|
|
|
294825
295271
|
}
|
|
294826
295272
|
);
|
|
294827
295273
|
async function checkVerdict(collectionId, mine, filedFor, mint) {
|
|
294828
|
-
const
|
|
295274
|
+
const agents = [mine, ...filedFor ? [filedFor] : []];
|
|
295275
|
+
const { receiptWithOurs: receiptWithOurs2 } = await Promise.resolve().then(() => (init_connect(), connect_exports));
|
|
295276
|
+
const read9 = await receiptWithOurs2(
|
|
295277
|
+
() => askReceipt(collectionId, agents),
|
|
295278
|
+
mine,
|
|
295279
|
+
filedFor,
|
|
295280
|
+
async () => {
|
|
295281
|
+
const { receiptQuery: receiptQuery2 } = await Promise.resolve().then(() => (init_receipt2(), receipt_exports2));
|
|
295282
|
+
const { gqlAt: gqlAt2 } = await Promise.resolve().then(() => (init_gql(), gql_exports));
|
|
295283
|
+
const { graphqlUrl: graphqlUrl4 } = await Promise.resolve().then(() => (init_env(), env_exports));
|
|
295284
|
+
const data = await gqlAt2(graphqlUrl4(), receiptQuery2(collectionId, { size: 1, waiting: false, agents }), { revalidate: null, fetchImpl: fetch2 });
|
|
295285
|
+
return data.claimCollection?.named?.nodes ?? [];
|
|
295286
|
+
}
|
|
295287
|
+
);
|
|
295288
|
+
const receipt = read9.receipt;
|
|
294829
295289
|
if (!receipt) return text4(`Could not read ask ${collectionId}.`);
|
|
294830
295290
|
const claims = receipt.claims ?? [];
|
|
294831
|
-
const ours =
|
|
295291
|
+
const ours = read9.ours;
|
|
294832
295292
|
if (!ours) {
|
|
294833
295293
|
return text4(
|
|
294834
295294
|
claims.length > 0 ? `Nothing of yours on #${collectionId}. ${claims.length} other answer(s) are there.` : `Nothing on #${collectionId} yet. If you have just sent an answer, the public index trails the chain by a few seconds. Check again shortly.`
|
|
@@ -294841,6 +295301,7 @@ They can disconnect at ${SITE}/connect.`);
|
|
|
294841
295301
|
const facts = verdictFacts2(ours.evaluationByClaimId, onChain);
|
|
294842
295302
|
const said3 = verdictSays2(facts.status);
|
|
294843
295303
|
const paid = faceOf2(coinDisplay2(facts.amount ?? void 0));
|
|
295304
|
+
const arrived = paid && facts.amount?.length ? await sharedPays({ amount: facts.amount, is_oracle_payment: receipt.payments?.["approval"]?.is_oracle_payment }, null) : null;
|
|
294844
295305
|
const proofRaw = facts.verificationProof;
|
|
294845
295306
|
const { proofRef: proofRef2 } = await Promise.resolve().then(() => (init_proof(), proof_exports));
|
|
294846
295307
|
const { engineDecisionFor: engineDecisionFor2 } = await Promise.resolve().then(() => (init_engine(), engine_exports));
|
|
@@ -294849,7 +295310,7 @@ They can disconnect at ${SITE}/connect.`);
|
|
|
294849
295310
|
const tail = engine ? ["", ...engineLines(engine, { cid: signed.cid ?? null })] : signed.kind === "udid-url" && signed.cid ? [`signed ${SITE}/v1/receipts/${signed.cid}?format=json. Check it rather than taking our word`] : [];
|
|
294850
295311
|
const steps = await traceBlock(collectionId, ours, receipt, engine);
|
|
294851
295312
|
const why = await whyBlock(ours.claimId, proofRaw, ours.agentAddress === mine ? mint : void 0);
|
|
294852
|
-
return text4([`#${collectionId}: ${said3}.${paid ? ` Paid ${paid.text}.` : ""}`, `answer ${ours.claimId}`, `${SITE}/r/${collectionId}/trace/${encodeURIComponent(ours.claimId)}`, ...why, ...steps, ...tail].join("\n"));
|
|
295313
|
+
return text4([`#${collectionId}: ${said3}.${paid ? ` Paid ${arrived ?? paid.text}.` : ""}`, `answer ${ours.claimId}`, `${SITE}/r/${collectionId}/trace/${encodeURIComponent(ours.claimId)}`, ...why, ...steps, ...tail].join("\n"));
|
|
294853
295314
|
}
|
|
294854
295315
|
if (local) {
|
|
294855
295316
|
server2.registerTool(
|
|
@@ -295009,14 +295470,14 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
295009
295470
|
{
|
|
295010
295471
|
...meta3("draft_call"),
|
|
295011
295472
|
inputSchema: {
|
|
295012
|
-
slug: external_exports.string().max(40).optional().describe("The call's name, for its page: lowercase letters, digits and dashes, starting with a letter. Omit for call-<
|
|
295473
|
+
slug: external_exports.string().max(40).optional().describe("The call's name, for its page: lowercase letters, digits and dashes, starting with a letter. Omit for a random call-<hex> name; then use the name the answer gives."),
|
|
295013
295474
|
title: external_exports.string().max(160).optional().describe("The call, in one sentence."),
|
|
295014
295475
|
lede: external_exports.string().max(500).optional().describe("Two or three sentences under the title."),
|
|
295015
295476
|
poster: external_exports.string().max(80).optional().describe("How the poster wants to be named on the call."),
|
|
295016
295477
|
brief: external_exports.array(external_exports.string().max(1500)).max(8).optional().describe("The story, up to eight short paragraphs, in the person's words."),
|
|
295017
295478
|
lines: external_exports.array(external_exports.object({ text: external_exports.string().max(300), fail: external_exports.string().max(300).optional() })).max(5).optional().describe('The five lines the jury rules on: each a must a good entry passes (text) and what fails it (fail). The fail is the end of the sentence "Fail this only if \u2026" \u2014 e.g. "it names no page" \u2014 not a sentence of its own. All five, together.'),
|
|
295018
295479
|
mode: external_exports.enum(["competition", "hire"]).optional().describe("competition: a pick and runners-up beside the paid entries. hire: every entry that passes is paid the same, up to a number, and nobody is picked."),
|
|
295019
|
-
kind: external_exports.literal("review").optional().describe("review: an expert review of an app or an agent (IXO Expert Reviews). Specialists try the scenarios and hand in review reports; every report that passes the lines is paid the same (a hire); by invitation or by application, never open to anyone; the five lines default to the review's own unless given."),
|
|
295480
|
+
kind: external_exports.literal("review").optional().describe("review: an expert review of an app or an agent (IXO Expert Reviews). Specialists try the scenarios and hand in review reports; every report that passes the lines is paid the same (a hire); by invitation or by application, never open to anyone; the five lines default to the review's own unless given. Where Asky Checker judges reviews (testnet), a review pays in PAY: the reward and Asky's 1 PAY a check."),
|
|
295020
295481
|
subject: external_exports.object({ name: external_exports.string().max(120), version: external_exports.string().max(40).optional(), where: external_exports.string().max(2048).optional() }).optional().describe("A review: what is reviewed, the version to test, and where a specialist finds it (a public address). Private access goes in the invitation note, never here."),
|
|
295021
295482
|
scenarios: external_exports.array(external_exports.string().max(300)).max(8).optional().describe("A review: the scenarios to try, one line each; every report must cover each with a step."),
|
|
295022
295483
|
report: external_exports.array(external_exports.string().max(60)).max(5).optional().describe("A review: extra section headings every report must have, besides the standard summary, steps, findings, recommendations and limitations. Empty is fine."),
|
|
@@ -295052,11 +295513,11 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
295052
295513
|
const changing = clear || Object.values(input).some((value) => value !== void 0);
|
|
295053
295514
|
if (posted && changing) return text4(`Call "${slug}" is already on chain: its terms were frozen with the money. Start a new call with another slug.`);
|
|
295054
295515
|
const start = clear || !existing ? call.freshDraft(slug) : existing;
|
|
295055
|
-
const coin = call.callCoin(start, currency, NETWORK2, ASK_DENOM);
|
|
295056
|
-
if (typeof coin !== "string") return text4(`Refused: ${coin.refused}. Nothing was saved.`);
|
|
295057
295516
|
const merged = call.mergeDraft(start, input);
|
|
295517
|
+
const coin = call.callCoin(merged.draft, currency, NETWORK2, ASK_DENOM);
|
|
295518
|
+
if (typeof coin !== "string") return text4(`Refused: ${coin.refused}. Nothing was saved.`);
|
|
295058
295519
|
const { refused: refused2 } = merged;
|
|
295059
|
-
const draft = currency ? { ...merged.draft, coin } : merged.draft;
|
|
295520
|
+
const draft = currency || coin !== ASK_DENOM ? { ...merged.draft, coin } : merged.draft;
|
|
295060
295521
|
call.writeDraft(draft);
|
|
295061
295522
|
const coinSymbol = symbolOf(coin);
|
|
295062
295523
|
const acting = await principal2();
|
|
@@ -295078,18 +295539,34 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
295078
295539
|
const { checkerLegBase: checkerLegBase2 } = await Promise.resolve().then(() => (init_leg(), leg_exports));
|
|
295079
295540
|
const poster = acting?.principal ?? await address2();
|
|
295080
295541
|
const shortPoster = `${poster.slice(0, 10)}\u2026${poster.slice(-4)}`;
|
|
295081
|
-
const
|
|
295082
|
-
|
|
295542
|
+
const checker = await callChecker2(draft.fields.kind === "review");
|
|
295543
|
+
if (checker.fee && checker.fee.denom !== coin) return text4(`Refused: ${checker.name} is paid in ${symbolOf(checker.fee.denom)}, so a review pays in it too: pass currency "${symbolOf(checker.fee.denom)}".`);
|
|
295544
|
+
const perCheck = checker.fee ? false : await callPerCheck(checker.address);
|
|
295545
|
+
const priced = call.callShare(draft.fields, call.callShares(draft.fields) ? await callSplit() : null);
|
|
295546
|
+
if ("unread" in priced) {
|
|
295547
|
+
out.push("", "Not priced yet: this call is a hire by invitation or application, which carries the network's share, and the chain's split could not be read just now. The draft is saved; call draft_call again in a minute.");
|
|
295548
|
+
return text4(out.join("\n"));
|
|
295549
|
+
}
|
|
295550
|
+
const plan = call.callPlan(draft, { poster: shortPoster, checkerLegBase: (terms) => checker.fee ? checker.fee.base : perCheck ? 0 : checkerLegBase2(FEE_DENOM, terms, CHECK_REWARD), oracle: checker.address || "the oracle", share: priced.share, feeInReward: Boolean(checker.fee) });
|
|
295083
295551
|
const feeTotal = plan.legs.reduce((sum, one) => sum + one.feeBase, 0);
|
|
295084
|
-
const preview = call.legTerms(draft, "entries", { poster: shortPoster, dates: plan.dates, oracle: { kind: "oracle", address:
|
|
295552
|
+
const preview = call.legTerms(draft, "entries", { poster: shortPoster, dates: plan.dates, oracle: { kind: "oracle", address: checker.address || "the oracle" }, share: plan.share });
|
|
295085
295553
|
const twoCoins = acting && feeTotal > 0 ? `Can't post as ${acting.principal}: ${call.callTwoCoins}.` : null;
|
|
295086
|
-
const
|
|
295554
|
+
const { capCoinRefusal: capCoinRefusal2, capIn: capIn2 } = await Promise.resolve().then(() => (init_hq(), hq_exports));
|
|
295555
|
+
const otherCoin = capCoinRefusal2(acting, coin, checker.fee ? `${SITE}/connect` : void 0);
|
|
295556
|
+
const capped3 = call.capWords(plan.legs, CAP_BASE, coinSymbol);
|
|
295557
|
+
const keyOnly = !acting && feeTotal > 0;
|
|
295558
|
+
const blocked = capped3.length > 0 || Boolean(otherCoin) || Boolean(twoCoins) && draft.fields.kind !== "review";
|
|
295087
295559
|
const m = draft.fields.money;
|
|
295560
|
+
const { shareWords: shareWords2 } = await Promise.resolve().then(() => (init_callRead(), callRead_exports));
|
|
295561
|
+
const who = draft.fields.kind === "review" ? "specialist" : "hired person";
|
|
295562
|
+
const onTop = (leg) => plan.share ? `; the network's share (${shareWords2(plan.share, "today")}) is added on top, so the leg pays ${call.payWords(leg.legBase, coinSymbol)}` : "";
|
|
295088
295563
|
const legRows = plan.legs.map(
|
|
295089
|
-
(leg) => leg.leg === "prize" ? ` The pick ${call.payWords(leg.payBase, coinSymbol)} to one entry; its ask takes ${leg.quota} claims (the pick and two spare) \xB7 locks ${call.payWords(leg.escrowBase, coinSymbol)}` : leg.leg === "runnersUp" ? ` Runners-up ${call.payWords(leg.payBase, coinSymbol)} to each of ${m.runnersN} \xB7 locks ${call.payWords(leg.escrowBase, coinSymbol)}` : ` Entries ${call.payWords(leg.payBase, coinSymbol)} to each entry that passes all ${draft.fields.kind === "review" ? "six" : "five"} lines, up to ${leg.quota}${leg.checkBase > 0 ? `, plus the oracle's ${feeWords(leg.checkBase)} per ruling` : ", the oracle billed per check from credits"} \xB7 locks ${callLocks(leg.escrowBase, leg.feeBase)}`
|
|
295564
|
+
(leg) => leg.leg === "prize" ? ` The pick ${call.payWords(leg.payBase, coinSymbol)} to one entry${onTop(leg)}; its ask takes ${leg.quota} claims (the pick and two spare) \xB7 locks ${call.payWords(leg.escrowBase, coinSymbol)}` : leg.leg === "runnersUp" ? ` Runners-up ${call.payWords(leg.payBase, coinSymbol)} to each of ${m.runnersN}${onTop(leg)} \xB7 locks ${call.payWords(leg.escrowBase, coinSymbol)}` : plan.share ? ` Entries each ${who} receives ${call.payWords(leg.payBase, coinSymbol)} for an entry that passes all ${draft.fields.kind === "review" ? "six" : "five"} lines${onTop(leg)} \xB7 up to ${leg.quota}${checker.fee ? `, plus ${call.payWords(leg.checkBase, coinSymbol)} per check to ${checker.name}` : leg.checkBase > 0 ? `, plus the oracle's ${feeWords(leg.checkBase)} per ruling` : ", the oracle billed per check from credits"} \xB7 locks ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}` : ` Entries ${call.payWords(leg.payBase, coinSymbol)} to each entry that passes all ${draft.fields.kind === "review" ? "six" : "five"} lines, up to ${leg.quota}${checker.fee ? `, plus ${call.payWords(leg.checkBase, coinSymbol)} per check to ${checker.name}` : leg.checkBase > 0 ? `, plus the oracle's ${feeWords(leg.checkBase)} per ruling` : ", the oracle billed per check from credits"} \xB7 locks ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}`
|
|
295090
295565
|
);
|
|
295566
|
+
const shareTotal = plan.legs.reduce((sum, one) => sum + one.shareBase * one.escrowSpots, 0);
|
|
295091
295567
|
const hire = draft.fields.mode === "hire";
|
|
295092
295568
|
const warnings2 = [
|
|
295569
|
+
...capped3,
|
|
295093
295570
|
twoCoins ?? "",
|
|
295094
295571
|
otherCoin ? `Can't post as it stands: ${otherCoin}.` : "",
|
|
295095
295572
|
!hire && m.prize < m.entryEach ? `The prize (${m.prize} ${coinSymbol}) is less than one entry earns (${m.entryEach} ${coinSymbol}).` : "",
|
|
@@ -295097,29 +295574,32 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
295097
295574
|
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." : "",
|
|
295098
295575
|
held !== null && held.reward < plan.totalBase ? `The account holds ${holds}; the call locks ${call.payWords(plan.totalBase, coinSymbol)}. It will be refused before anything moves.` : "",
|
|
295099
295576
|
held !== null && feeTotal > 0 && held.fee < feeTotal ? `The account holds ${feeWords(held.fee)}; the reviews need ${feeWords(feeTotal)}. It will be refused before anything moves; top_up buys PAY.` : "",
|
|
295100
|
-
acting?.cap && !otherCoin && Number(acting
|
|
295101
|
-
!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.` : ""
|
|
295577
|
+
acting?.cap && !otherCoin && Number(capIn2(acting, coin)?.remainingBase ?? 0) < plan.totalBase ? `Their cap has ${call.payWords(Number(capIn2(acting, coin)?.remainingBase ?? 0), coinSymbol)} left; the call locks ${call.payWords(plan.totalBase, coinSymbol)}. They raise it at ${SITE}/connect.` : "",
|
|
295578
|
+
keyOnly ? `Not connected, and a connection would not carry this call: ${call.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.` : ""
|
|
295102
295579
|
].filter(Boolean);
|
|
295103
295580
|
out.push(
|
|
295104
295581
|
"",
|
|
295105
|
-
"Ready. This is the call as an entrant's AI will read it:",
|
|
295582
|
+
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:",
|
|
295106
295583
|
"",
|
|
295107
295584
|
call.callReadout(preview, { id: "(the entries ask, once posted)", symbol: coinSymbol }),
|
|
295108
295585
|
"",
|
|
295109
295586
|
"What each leg locks on chain:",
|
|
295110
295587
|
...legRows,
|
|
295111
|
-
` Total ${callLocks(plan.totalBase, feeTotal)}`,
|
|
295588
|
+
` Total ${callLocks(plan.totalBase, feeTotal, coinSymbol)}`,
|
|
295589
|
+
...plan.share ? [
|
|
295590
|
+
` Network's share ${call.payWords(shareTotal, coinSymbol)} of that, if every spot is paid (${shareWords2(plan.share, "today")}): the chain splits it off each approval and pays the rest to the person. A call by invitation or application is a hire; the network keeps its share of what each hired person earns. Asks and public calls carry no share.`
|
|
295591
|
+
] : [],
|
|
295112
295592
|
"",
|
|
295113
|
-
`${actingNote(acting) ?? `Not connected; with plain_key this key posts as itself, ${await address2()}.`} The account holds ${holds ?? "an amount nobody could read"}${held !== null && feeTotal > 0 ? ` and ${feeWords(held.fee)}` : ""}; this call locks ${callLocks(plan.totalBase, feeTotal)}.`,
|
|
295593
|
+
`${actingNote(acting) ?? `Not connected; with plain_key this key posts as itself, ${await address2()}.`} The account holds ${holds ?? "an amount nobody could read"}${held !== null && feeTotal > 0 ? ` and ${feeWords(held.fee)}` : ""}; this call locks ${callLocks(plan.totalBase, feeTotal, coinSymbol)}.`,
|
|
295114
295594
|
hire ? `The clock: entries close ${new Date(plan.dates.closes).toUTCString()}; every passing entry is paid as it is judged, and nothing waits for a pick.` : `The clock: entries close ${new Date(plan.dates.closes).toUTCString()}; the shortlist shows ${new Date(plan.dates.drop).toUTCString()}; the pick by ${new Date(plan.dates.pick).toUTCString()}.`,
|
|
295115
295595
|
`Who may enter: ${draft.fields.access === "invite" ? `by invitation only${draft.fields.invite?.length ? ` \u2014 ${draft.fields.invite.length} to invite when the entries post${draft.fields.inviteNote ? ", each with your private note" : ""}` : ""}` : draft.fields.access === "apply" ? "by application, listed on the board" : "anyone, listed on the board"}.`,
|
|
295116
295596
|
...draft.fields.kind === "review" ? [
|
|
295117
|
-
`A review: every entry is a review report with screenshots (submit_work's report and files), checked by the AI on the lines${acting ? `, then ${acting.principal} gives final approval before anyone is paid` :
|
|
295118
|
-
`Its page: ${EXPERT_SITE}/expert/reviews/${
|
|
295597
|
+
`A review: 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`}.`,
|
|
295598
|
+
draft.posted.entries ? `Its page: ${EXPERT_SITE}/expert/reviews/${draft.posted.entries.id}` : "Its page is named by the review's ask number, given once it posts."
|
|
295119
295599
|
] : [],
|
|
295120
295600
|
...warnings2.length ? ["", "Warnings:", ...warnings2.map((one) => ` - ${one}`)] : [],
|
|
295121
295601
|
"",
|
|
295122
|
-
`Show this to the person and get a yes. Then: post_call slug: "${slug}", confirm: "${call.payWords(plan.totalBase, coinSymbol)}"${acting ? "" : ", plain_key: true \u2014 or connect_account first and leave plain_key out, to post as the person"}. One leg per call; call again until it says everything is posted.`
|
|
295602
|
+
blocked ? "Do not ask the person for a yes on these terms: post_call would refuse them. Fix what the warnings name (through draft_call), then preview again." : `Show this to the person and get a yes. Then: post_call slug: "${slug}", confirm: "${call.payWords(plan.totalBase, coinSymbol)}"${acting ? "" : keyOnly ? ", plain_key: true (a connected person cannot post this call; the warnings say why)" : ", plain_key: true \u2014 or connect_account first and leave plain_key out, to post as the person"}. One leg per call; call again until it says everything is posted.`
|
|
295123
295603
|
);
|
|
295124
295604
|
return text4(out.join("\n"));
|
|
295125
295605
|
}
|
|
@@ -295141,16 +295621,17 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
295141
295621
|
const found = call.readDraft(slug);
|
|
295142
295622
|
if (!found) return text4(`No draft called "${slug}". Start one with draft_call.`);
|
|
295143
295623
|
const review = found.fields.kind === "review";
|
|
295144
|
-
const
|
|
295624
|
+
const checker = await callChecker2(review);
|
|
295625
|
+
const linkOf = (posted2) => review ? `${EXPERT_SITE}/expert/reviews/${posted2.entries?.id ?? slug}` : `${SITE}/opencall/${slug}`;
|
|
295145
295626
|
const settled = found.inFlight ? await call.settleInFlight(slug, call.indexLookup) : null;
|
|
295146
295627
|
if (settled?.state === "pending") return text4(settled.words);
|
|
295147
295628
|
if (settled?.state === "landed") {
|
|
295148
|
-
nudge("hire", settled.id);
|
|
295629
|
+
nudge("hire", settled.id, checker.at);
|
|
295149
295630
|
const after2 = call.nextLeg(settled.draft);
|
|
295150
295631
|
return text4(
|
|
295151
295632
|
[
|
|
295152
295633
|
`The earlier post landed: ${LEG_WORDS[settled.leg]} is #${settled.id}. It is recorded, and nothing was posted twice.`,
|
|
295153
|
-
after2 ? `Call post_call again for ${LEG_WORDS[after2]}.` : await liveLine(settled.id,
|
|
295634
|
+
after2 ? `Call post_call again for ${LEG_WORDS[after2]}.` : await liveLine(settled.id, linkOf(settled.draft.posted))
|
|
295154
295635
|
].join("\n")
|
|
295155
295636
|
);
|
|
295156
295637
|
}
|
|
@@ -295162,11 +295643,11 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
295162
295643
|
const next = call.nextLeg(draft);
|
|
295163
295644
|
const ids = ["prize", "runnersUp", "entries"].flatMap((leg2) => draft.posted[leg2] ? [`${LEG_WORDS[leg2]} #${draft.posted[leg2].id}`] : []);
|
|
295164
295645
|
if (!next) return text4(`Everything is posted: ${ids.join(", ")}.
|
|
295165
|
-
The call: ${
|
|
295646
|
+
The call: ${linkOf(draft.posted)}`);
|
|
295166
295647
|
if (!call.isReady(draft.fields)) return text4(`"${slug}" is not ready: ${call.missingOf(draft.fields, { symbol: coinSymbol, holds: null }).map((one) => one.field).join(", ")} still missing. Finish it with draft_call.`);
|
|
295167
295648
|
const cannot = await unjudged();
|
|
295168
295649
|
if (cannot) return text4(cannot);
|
|
295169
|
-
if (!
|
|
295650
|
+
if (!checker.address) return text4("No oracle is configured on this deployment, so nothing could judge the entries. Refusing rather than posting a call nobody can settle.");
|
|
295170
295651
|
const acting = plain_key && review ? null : await principal2();
|
|
295171
295652
|
if (!acting && !plain_key) {
|
|
295172
295653
|
return text4(`Not connected. A call uses the connected account as its poster and funding source. Ask them to connect this key first:
|
|
@@ -295175,8 +295656,12 @@ Then call post_call again. Nothing was posted.`);
|
|
|
295175
295656
|
}
|
|
295176
295657
|
const { checkerLegBase: checkerLegBase2 } = await Promise.resolve().then(() => (init_leg(), leg_exports));
|
|
295177
295658
|
const poster = acting?.principal ?? await address2();
|
|
295178
|
-
|
|
295179
|
-
const
|
|
295659
|
+
if (checker.fee && checker.fee.denom !== coin) return text4(`Refused: ${checker.name} is paid in ${symbolOf(checker.fee.denom)}, so a review pays in it too: pass currency "${symbolOf(checker.fee.denom)}". Nothing was posted.`);
|
|
295660
|
+
const perCheck = checker.fee ? false : await callPerCheck(checker.address);
|
|
295661
|
+
const split3 = call.callShares(draft.fields) ? await callSplit() : null;
|
|
295662
|
+
const priced = call.callShare(draft.fields, split3);
|
|
295663
|
+
if ("unread" in priced) return text4(call.SHARE_UNREAD);
|
|
295664
|
+
const plan = call.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) });
|
|
295180
295665
|
const feeTotal = plan.legs.reduce((sum, one) => sum + one.feeBase, 0);
|
|
295181
295666
|
const total = call.payWords(plan.totalBase, coinSymbol);
|
|
295182
295667
|
if (acting && feeTotal > 0) return text4(`Refused: ${call.callTwoCoins}.${review ? ` ${PLAIN_REVIEW}` : ""} Nothing was posted.`);
|
|
@@ -295188,19 +295673,24 @@ Then call post_call again. Nothing was posted.`);
|
|
|
295188
295673
|
const leg = plan.legs.find((one) => one.leg === next);
|
|
295189
295674
|
const order2 = plan.legs.map((one) => one.leg);
|
|
295190
295675
|
if (!confirm) {
|
|
295676
|
+
const { shareWords: shareWords2 } = await Promise.resolve().then(() => (init_callRead(), callRead_exports));
|
|
295677
|
+
const shareTotal = plan.legs.reduce((sum, one) => sum + one.shareBase * one.escrowSpots, 0);
|
|
295191
295678
|
return text4(
|
|
295192
295679
|
[
|
|
295193
|
-
`Call "${slug}" locks ${callLocks(plan.totalBase, feeTotal)} in ${order2.length} asks, posted one per call: ${order2.map((one) => LEG_WORDS[one]).join(", then ")}.${ids.length ? ` Posted already: ${ids.join(", ")}.` : ""}`,
|
|
295194
|
-
|
|
295680
|
+
`Call "${slug}" locks ${callLocks(plan.totalBase, feeTotal, coinSymbol)} in ${order2.length} asks, posted one per call: ${order2.map((one) => LEG_WORDS[one]).join(", then ")}.${ids.length ? ` Posted already: ${ids.join(", ")}.` : ""}`,
|
|
295681
|
+
/* A private call: the share is in that total, on top of what each person receives, and said before the yes. */
|
|
295682
|
+
...plan.share ? [`Of that, the network's share is ${call.payWords(shareTotal, coinSymbol)} if every spot is paid (${shareWords2(plan.share, "today")}), on top of what each person receives: ${call.payWords(plan.legs.find((one) => one.leg === "entries").payBase, coinSymbol)} for each passing entry.`] : [],
|
|
295683
|
+
`Next: ${LEG_WORDS[next]}, locking ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}, plus a little IXO for gas.`,
|
|
295195
295684
|
actingNote(acting) ?? (review ? "Posting from your own wallet (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}.`),
|
|
295196
295685
|
`Spent today (call): ${spentWords("call")}. Every tool together: ${spentAllWords()}.`,
|
|
295686
|
+
...call.capWords(plan.legs.filter((one) => !draft.posted[one.leg]), CAP_BASE, coinSymbol),
|
|
295197
295687
|
"",
|
|
295198
295688
|
`To go ahead, call again with confirm: "${total}".`
|
|
295199
295689
|
].join("\n")
|
|
295200
295690
|
);
|
|
295201
295691
|
}
|
|
295202
295692
|
if (!call.confirms(confirm, plan.totalBase, coinSymbol)) return text4(`Refused: confirm said "${confirm}" but the call locks ${total}. Preview it again.`);
|
|
295203
|
-
if (leg
|
|
295693
|
+
if (call.overCap(leg, CAP_BASE)) return text4(`Refused: this leg locks ${call.payWords(leg.escrowBase, coinSymbol)}, over this server's ${face(MAX_PER_ASK, coinSymbol)} per-ask cap (OPENHANDS_MAX_PER_ASK_USD).`);
|
|
295204
295694
|
if (ids.length === 0) {
|
|
295205
295695
|
const taken = await fetch2(`${SITE}/api/board?campaign=${encodeURIComponent(call.tagOf(draft))}&size=5`, { signal: AbortSignal.timeout(15e3) }).then((response) => response.ok ? response.json() : null).catch(() => null);
|
|
295206
295696
|
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.`);
|
|
@@ -295214,6 +295704,7 @@ Then call post_call again. Nothing was posted.`);
|
|
|
295214
295704
|
balanceBase: async (who, denom) => Number((await balancesOfStrict2(who))[denom] ?? 0),
|
|
295215
295705
|
face: (base5) => call.payWords(base5, coinSymbol),
|
|
295216
295706
|
feeFace: feeWords,
|
|
295707
|
+
coinFixed: Boolean(checker.fee),
|
|
295217
295708
|
site: SITE
|
|
295218
295709
|
});
|
|
295219
295710
|
if (refusedBefore) return text4(refusedBefore);
|
|
@@ -295225,15 +295716,17 @@ Then call post_call again. Nothing was posted.`);
|
|
|
295225
295716
|
posted = await call.postNextLeg(slug, {
|
|
295226
295717
|
site: SITE,
|
|
295227
295718
|
askDenom: coin,
|
|
295228
|
-
checker:
|
|
295719
|
+
checker: checker.address,
|
|
295229
295720
|
gate: GATE,
|
|
295230
295721
|
checkReward: CHECK_REWARD,
|
|
295231
295722
|
perCheck,
|
|
295723
|
+
fee: checker.fee,
|
|
295232
295724
|
acting,
|
|
295233
295725
|
approver,
|
|
295234
295726
|
mnemonic: key.mnemonic,
|
|
295235
|
-
nudge,
|
|
295236
|
-
charge: (escrowBase) => chargeDay("call", escrowBase / MICRO4)
|
|
295727
|
+
nudge: (event, id) => nudge(event, id, checker.at),
|
|
295728
|
+
charge: (escrowBase) => chargeDay("call", escrowBase / MICRO4),
|
|
295729
|
+
feeSplit: split3
|
|
295237
295730
|
});
|
|
295238
295731
|
} catch (error54) {
|
|
295239
295732
|
if (error54 instanceof call.InFlightError || error54 instanceof call.PostRefused) return text4(error54.message);
|
|
@@ -295246,7 +295739,7 @@ Then call post_call again. Nothing was posted.`);
|
|
|
295246
295739
|
);
|
|
295247
295740
|
}
|
|
295248
295741
|
if ("done" in posted) return text4(`Everything is posted.
|
|
295249
|
-
The call: ${
|
|
295742
|
+
The call: ${linkOf(posted.draft.posted)}`);
|
|
295250
295743
|
const done = order2.filter((one) => posted.draft.posted[one]).length;
|
|
295251
295744
|
const after = call.nextLeg(posted.draft);
|
|
295252
295745
|
const hire = posted.draft.fields.mode === "hire";
|
|
@@ -295257,10 +295750,10 @@ The call: ${link5}`);
|
|
|
295257
295750
|
`${done} of ${order2.length} posted: ${LEG_WORDS[posted.leg]}, #${posted.id}${acting ? `, as ${acting.principal}` : ""}, locking ${call.payWords(posted.plan.escrowBase, coinSymbol)}.`,
|
|
295258
295751
|
held ?? "",
|
|
295259
295752
|
after ? `Call post_call again for ${LEG_WORDS[after]}.` : [
|
|
295260
|
-
held ? `The call is posted but not yet open: ${
|
|
295753
|
+
held ? `The call is posted but not yet open: ${linkOf(posted.draft.posted)} says so until a person clears the entries. Once it is open:` : await liveLine(posted.id, linkOf(posted.draft.posted)),
|
|
295261
295754
|
posted.draft.fields.access === "invite" ? `By invitation: only the people on its list can enter. Entrants' AI read it with read_ask "${posted.id}" and enter with submit_work (a link goes in submit_work's invite).` : posted.draft.fields.access === "apply" ? `By application: people apply on the page or with apply_to_call; say yes with decide_application. Entrants' AI read it with read_ask "${posted.id}" and enter with submit_work once admitted.` : `Entrants' AI read it with read_ask "${posted.id}" and enter with submit_work.`,
|
|
295262
|
-
review ? approver ? `Every report is checked by the AI on the lines, then waits for your OK, which pays it. Switch your checks on now:
|
|
295263
|
-
${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` :
|
|
295755
|
+
review ? approver ? `Every report is checked by ${checker.name ?? "the AI"} on the lines, then waits for your OK, which pays it. Switch your checks on now:
|
|
295756
|
+
${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every report that passes the lines is paid as ${checker.name ?? "the AI"} rules; no final OK is needed.` : hire ? "Every entry that passes is paid as the jury rules; there is no pick." : `The pick is yours: approve the picked entry's claim on ${originOf(NETWORK2)}/t/${posted.draft.posted.prize?.id ?? ""}.`
|
|
295264
295757
|
].join("\n"),
|
|
295265
295758
|
...invited ? ["", ...invited] : []
|
|
295266
295759
|
].filter(Boolean).join("\n")
|
|
@@ -295328,6 +295821,15 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : "Every rep
|
|
|
295328
295821
|
].filter(Boolean);
|
|
295329
295822
|
}
|
|
295330
295823
|
const isReview = async (draft, entriesId) => draft ? draft.fields.kind === "review" : isReviewTitle((await askReceipt(entriesId))?.entityName);
|
|
295824
|
+
const termsDoor = async (collectionId) => {
|
|
295825
|
+
const receipt = await askReceipt(collectionId);
|
|
295826
|
+
if (receipt?.access) return receipt.access;
|
|
295827
|
+
if (!receipt?.doneMeansCid) return null;
|
|
295828
|
+
const { readDocJson: readDocJson2 } = await Promise.resolve().then(() => (init_docs(), docs_exports));
|
|
295829
|
+
const terms = await readDocJson2(receipt.doneMeansCid, { timeoutMs: 15e3, at: receipt.doneMeansUrl ?? void 0 });
|
|
295830
|
+
if (!terms) return null;
|
|
295831
|
+
return terms.access === "apply" || terms.access === "invite" ? terms.access : "public";
|
|
295832
|
+
};
|
|
295331
295833
|
if (offered("invite_to_call")) server2.registerTool(
|
|
295332
295834
|
"invite_to_call",
|
|
295333
295835
|
{
|
|
@@ -295389,22 +295891,25 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : "Every rep
|
|
|
295389
295891
|
const acting = await principal2();
|
|
295390
295892
|
const answer = await invitesModule.readInvites(SITE, await inviteSigner(acting), entriesId);
|
|
295391
295893
|
if ("refused" in answer) return text4(`Refused: ${answer.refused}`);
|
|
295392
|
-
const
|
|
295393
|
-
const
|
|
295894
|
+
const fromHere = draft ?? callModule.draftOfEntries(entriesId);
|
|
295895
|
+
const review = await isReview(fromHere, entriesId);
|
|
295896
|
+
const links = [...fromHere?.invites ?? [], ...callModule.readAskInvites(entriesId)].filter((one) => one.via === "link" && one.collectionId === entriesId && one.token);
|
|
295394
295897
|
const opened = new Set(answer.invites.filter((one) => one.via === "link" && one.bound_at).map((one) => one.id));
|
|
295395
295898
|
const rows2 = answer.invites.map(
|
|
295396
295899
|
(one) => ` ${one.revoked_at ? "(revoked) " : ""}${one.kind === "exclude" ? "turned away" : one.via}${one.handle ? ` @${one.handle}` : ""}${one.address ? ` ${one.address}` : one.via === "link" ? ` link #${one.id}, ${one.bound_at ? `opened ${one.bound_at}` : "not opened yet"}` : ""}${one.note ? ` \u2014 ${one.note}` : ""}`
|
|
295397
295900
|
);
|
|
295398
295901
|
const applications = answer.applications.map((one) => ` ${one.address}${one.note ? ` \u2014 ${one.note}` : ""} \xB7 ${one.decision ? `${one.decision} (${one.decided_at})` : "waiting for your decision"}`);
|
|
295399
|
-
const
|
|
295902
|
+
const drafted = fromHere?.fields.access ?? null;
|
|
295903
|
+
const terms = answer.access || drafted ? null : await termsDoor(entriesId);
|
|
295904
|
+
const door = answer.access ?? drafted ?? terms;
|
|
295400
295905
|
return text4(
|
|
295401
295906
|
[
|
|
295402
|
-
|
|
295907
|
+
invitesModule.doorLine(entriesId, { worker: answer.access, draft: drafted, terms }),
|
|
295403
295908
|
rows2.length ? "The list:" : "The list is empty.",
|
|
295404
295909
|
...rows2,
|
|
295405
295910
|
links.length ? "Links kept here (each for one person):" : "",
|
|
295406
295911
|
...links.map((one) => ` ${inviteLink(SITE, one.token, review)}${one.id !== void 0 && opened.has(one.id) ? " (opened)" : ""}`),
|
|
295407
|
-
applications.length ? "Applications:" :
|
|
295912
|
+
applications.length ? "Applications:" : door === "apply" ? "No applications yet." : "",
|
|
295408
295913
|
...applications
|
|
295409
295914
|
].filter(Boolean).join("\n")
|
|
295410
295915
|
);
|
|
@@ -295878,7 +296383,7 @@ Open the profile and the evidence. Decline with decide_check. Approving happens
|
|
|
295878
296383
|
if (screen?.verdict === "hold") held.push(`${check2.id}: ${heldWords(screen.reason)}`);
|
|
295879
296384
|
}
|
|
295880
296385
|
const { cost, reviewsBase } = await priceOf2(plan, world, coin);
|
|
295881
|
-
const
|
|
296386
|
+
const overCap2 = plans.planCapRefusal(plan, cost, PLAN_CAPS, money2);
|
|
295882
296387
|
const published = await participant.publishJson(plan, "market-plan");
|
|
295883
296388
|
if (!published) return text4("The store would not take the plan, and a plan nobody can read back is not worth funding. Try again shortly.");
|
|
295884
296389
|
const longest = Math.max(...plan.checks.map((check2) => check2.hours));
|
|
@@ -295895,7 +296400,7 @@ Open the profile and the evidence. Decline with decide_check. Approving happens
|
|
|
295895
296400
|
...held.length ? ["", ...held] : [],
|
|
295896
296401
|
"",
|
|
295897
296402
|
`Stored, frozen: ${published.cid}`,
|
|
295898
|
-
|
|
296403
|
+
overCap2 ? `This cannot be funded here: ${overCap2} Lower the pay, fewer answers per place or fewer places, or a higher cap set by the person who runs this server.` : PLANS ? `To post it once they approve: fund_plan plan: "${published.cid}". It previews first; nothing is posted without confirm.` : "This deployment runs no plans, so this plan can be read but not bought.",
|
|
295899
296404
|
"",
|
|
295900
296405
|
plans.APPROVAL_STEP
|
|
295901
296406
|
].join("\n")
|
|
@@ -295929,8 +296434,8 @@ Open the profile and the evidence. Decline with decide_check. Approving happens
|
|
|
295929
296434
|
const world = await askTheWorldPriced();
|
|
295930
296435
|
if (!world) return text4(UNPRICED);
|
|
295931
296436
|
const { cost, reviewsBase } = await priceOf2(doc, world, coin);
|
|
295932
|
-
const
|
|
295933
|
-
if (
|
|
296437
|
+
const overCap2 = plans.planCapRefusal(doc, cost, PLAN_CAPS, money2);
|
|
296438
|
+
if (overCap2) return text4(`Refused: ${overCap2} Nothing was posted.`);
|
|
295934
296439
|
const acting = await principal2();
|
|
295935
296440
|
const poster = acting?.principal ?? await address2();
|
|
295936
296441
|
const started = planPost.readProgress(doc.slug);
|