@ixo/asks-mcp 2.0.0-dev.3 → 2.0.0-dev.4
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 +74 -70
- package/package.json +1 -1
package/dist/asks-mcp.mjs
CHANGED
|
@@ -259536,10 +259536,10 @@ __export(connect_exports, {
|
|
|
259536
259536
|
workOf: () => workOf
|
|
259537
259537
|
});
|
|
259538
259538
|
function noteIgnored(agent, pinned, others, log) {
|
|
259539
|
-
const
|
|
259540
|
-
if (!
|
|
259541
|
-
for (const one of
|
|
259542
|
-
log(`asks-mcp: ignoring ${
|
|
259539
|
+
const fresh3 = others.filter((one) => !told.has(`${agent}:${pinned}:${one}`));
|
|
259540
|
+
if (!fresh3.length) return;
|
|
259541
|
+
for (const one of fresh3) told.add(`${agent}:${pinned}:${one}`);
|
|
259542
|
+
log(`asks-mcp: ignoring ${fresh3.length === 1 ? "a connection" : "connections"} to this key from ${fresh3.join(", ")}: it is pinned to ${pinned === SELF ? "itself" : pinned}, and only connect_account changes that.`);
|
|
259543
259543
|
}
|
|
259544
259544
|
async function actingFor(agent, reads2 = chainReads, pins2 = keyPins) {
|
|
259545
259545
|
const pinned = pinOf(agent, pins2);
|
|
@@ -260189,17 +260189,17 @@ function laneStore(deps) {
|
|
|
260189
260189
|
const bearer = (can) => laneInvocation({ agent: deps.agent, pass: deps.pass, entityDid: deps.entityDid, collectionId: deps.collectionId, can });
|
|
260190
260190
|
async function put(bytes3, mediaType, name8) {
|
|
260191
260191
|
const deadline = Date.now() + (deps.settleMs ?? 6e4);
|
|
260192
|
-
let
|
|
260192
|
+
let fresh3 = false;
|
|
260193
260193
|
for (let pause2 = 2e3; ; pause2 = Math.min(pause2 * 2, 8e3)) {
|
|
260194
260194
|
try {
|
|
260195
|
-
return await uploadToLane(bytes3, mediaType, { bearer: await bearer("fs/write"), entityDid: deps.entityDid, collectionId: deps.collectionId, name: laneName(deps.person, bytes3, name8,
|
|
260195
|
+
return await uploadToLane(bytes3, mediaType, { bearer: await bearer("fs/write"), entityDid: deps.entityDid, collectionId: deps.collectionId, name: laneName(deps.person, bytes3, name8, fresh3) });
|
|
260196
260196
|
} catch (error54) {
|
|
260197
|
-
if (error54 instanceof LaneRefused && error54.status === 409 && !
|
|
260197
|
+
if (error54 instanceof LaneRefused && error54.status === 409 && !fresh3) {
|
|
260198
260198
|
if (bytes3.byteLength <= RAW_CID_MAX) {
|
|
260199
260199
|
const cid = cidOfBytes(bytes3);
|
|
260200
260200
|
return { cid, url: laneCidUrl(cid) };
|
|
260201
260201
|
}
|
|
260202
|
-
|
|
260202
|
+
fresh3 = true;
|
|
260203
260203
|
continue;
|
|
260204
260204
|
}
|
|
260205
260205
|
if (!passing(error54) || Date.now() + pause2 > deadline) return null;
|
|
@@ -260276,7 +260276,7 @@ ${shareLink(site, collectionId, approver)}` : "";
|
|
|
260276
260276
|
BOX_TTL_MS = 10 * 6e4;
|
|
260277
260277
|
newBoxId = () => randomBytes5(16).toString("hex");
|
|
260278
260278
|
safeName = (name8) => name8.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[.-]+/, "").slice(-80) || "file";
|
|
260279
|
-
laneName = (person, bytes3, name8,
|
|
260279
|
+
laneName = (person, bytes3, name8, fresh3 = false) => `${person}/${createHash5("sha256").update(bytes3).digest("hex").slice(0, 24)}${fresh3 ? `-${randomBytes5(3).toString("hex")}` : ""}-${safeName(name8)}`;
|
|
260280
260280
|
RAW_CID_MAX = 1024 * 1024;
|
|
260281
260281
|
passing = (error54) => !(error54 instanceof LaneRefused) || error54.status === 403 || error54.status === 429 || error54.status >= 500;
|
|
260282
260282
|
ENVELOPE_LIMIT = 200 * 1024;
|
|
@@ -261831,8 +261831,8 @@ function senderFor(deps) {
|
|
|
261831
261831
|
let signerData = deps.signerData ? await deps.signerData() : void 0;
|
|
261832
261832
|
let fee = "auto";
|
|
261833
261833
|
try {
|
|
261834
|
-
const simulated = await simulateWithChainSequence({ client: client2, address: address2, messages, memo, signerData, warn, onCorrected: (
|
|
261835
|
-
signerData =
|
|
261834
|
+
const simulated = await simulateWithChainSequence({ client: client2, address: address2, messages, memo, signerData, warn, onCorrected: (fresh3) => {
|
|
261835
|
+
signerData = fresh3;
|
|
261836
261836
|
} });
|
|
261837
261837
|
const priced = (0, import_stargate7.calculateFee)(Math.round(simulated.gas * 1.8), GAS_PRICE2);
|
|
261838
261838
|
const granter = await deps.granterFor(messages.map((one) => one.typeUrl), Number(priced.amount[0]?.amount ?? 0));
|
|
@@ -263686,7 +263686,9 @@ var init_callTerms = __esm({
|
|
|
263686
263686
|
var feeLine_exports = {};
|
|
263687
263687
|
__export(feeLine_exports, {
|
|
263688
263688
|
MAINNET_SPLIT: () => MAINNET_SPLIT,
|
|
263689
|
-
feeLine: () => feeLine
|
|
263689
|
+
feeLine: () => feeLine,
|
|
263690
|
+
feeSentence: () => feeSentence,
|
|
263691
|
+
feeWords: () => feeWords
|
|
263690
263692
|
});
|
|
263691
263693
|
function feeLine(args) {
|
|
263692
263694
|
const { split: split3, symbol: symbol2 } = args;
|
|
@@ -263694,12 +263696,12 @@ function feeLine(args) {
|
|
|
263694
263696
|
const receives = `Each pro receives ${amountWords(args.net, symbol2)}.`;
|
|
263695
263697
|
const locked2 = `${amountWords(leg / 1e6, symbol2)} is locked per report`;
|
|
263696
263698
|
if (split3.network + split3.node === 0) {
|
|
263697
|
-
if (args.network === "mainnet") return `${receives} Nothing is taken
|
|
263698
|
-
return `${receives} In the sandbox nothing is added: ${amountWords(leg / 1e6, symbol2)} is held per report
|
|
263699
|
+
if (args.network === "mainnet") return `${receives} Nothing is taken: ${locked2}.`;
|
|
263700
|
+
return `${receives} In the sandbox nothing is added: ${amountWords(leg / 1e6, symbol2)} is held per report. On the real network, ${feeWords(MAINNET_SPLIT)}`;
|
|
263699
263701
|
}
|
|
263700
|
-
return `${receives} ${locked2}
|
|
263702
|
+
return `${receives} ${locked2}. ${feeWords(split3)}`;
|
|
263701
263703
|
}
|
|
263702
|
-
var MAINNET_SPLIT, percentWords, amountWords;
|
|
263704
|
+
var MAINNET_SPLIT, percentWords, feeWords, feeSentence, amountWords;
|
|
263703
263705
|
var init_feeLine = __esm({
|
|
263704
263706
|
"../../packages/openhands-sdk/src/rubric/feeLine.ts"() {
|
|
263705
263707
|
"use strict";
|
|
@@ -263707,6 +263709,8 @@ var init_feeLine = __esm({
|
|
|
263707
263709
|
init_share();
|
|
263708
263710
|
MAINNET_SPLIT = { network: 10, node: 10 };
|
|
263709
263711
|
percentWords = (value) => `${Number(value.toFixed(6))} %`;
|
|
263712
|
+
feeWords = (split3, who = "The pro") => `${percentWords(split3.network + split3.node)} of what you pay runs asks.world. ${who} gets the rest.`;
|
|
263713
|
+
feeSentence = (split3, network2, who = "The pro") => split3.network + split3.node === 0 && network2 !== "mainnet" ? `In the sandbox nothing is added. On the real network, ${feeWords(MAINNET_SPLIT, who)}` : feeWords(split3, who);
|
|
263710
263714
|
amountWords = (value, symbol2) => ["USDC", "USD", "PAY", "$"].includes(symbol2) ? dollars(value) : `${Number(value.toFixed(6))} ${symbol2}`;
|
|
263711
263715
|
}
|
|
263712
263716
|
});
|
|
@@ -263773,7 +263777,7 @@ function callReadout(terms, ctx) {
|
|
|
263773
263777
|
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.";
|
|
263774
263778
|
const review = call3.kind === "review";
|
|
263775
263779
|
const shared = call3.share ? sharedPay(m.entryEach, call3.share) : null;
|
|
263776
|
-
const shareLine2 = shared && call3.share ? `each ${review ? "pro" : hire ? "hired person" : "entry paid"} receives ${amount3(shared.receives, ctx.symbol)} (the leg is ${amount3(shared.leg, ctx.symbol)}; the network keeps ${amount3(shared.keeps, ctx.symbol)}: ${shareWords(call3.share, "as posted")})${hire ? "" : "; the pick's and the runners-up's legs carry the same share
|
|
263780
|
+
const shareLine2 = shared && call3.share ? `each ${review ? "pro" : hire ? "hired person" : "entry paid"} receives ${amount3(shared.receives, ctx.symbol)} (the leg is ${amount3(shared.leg, ctx.symbol)}; the network keeps ${amount3(shared.keeps, ctx.symbol)}: ${shareWords(call3.share, "as posted")})${hire ? "" : "; the pick's and the runners-up's legs carry the same share"}` : "";
|
|
263777
263781
|
const proMoney = review && call3.share && hire ? `Money: ${feeLine({ split: call3.share, net: m.entryEach, symbol: ctx.symbol, network: ctx.network ?? "mainnet" })} Up to ${m.entryUpTo} ${m.entryUpTo === 1 ? "report is" : "reports are"} paid, each one that passes all ${n} lines; there is no pick. Held on the ask's own account before anyone enters.` : null;
|
|
263778
263782
|
const out = [
|
|
263779
263783
|
`${review ? "Pro ask" : hire ? "Hiring call" : "Open call"} "${call3.slug}" \xB7 posted by ${call3.poster} \xB7 ${stageWords(call3, ctx.now)}`,
|
|
@@ -267120,11 +267124,11 @@ function roomRows(counts) {
|
|
|
267120
267124
|
case "proAsks":
|
|
267121
267125
|
return { ...room, ...counted(counts.proAsks ?? null, null) };
|
|
267122
267126
|
case "work":
|
|
267123
|
-
return { ...room, ...
|
|
267127
|
+
return { ...room, ...fresh2(counts.work, "waiting") };
|
|
267124
267128
|
case "messages":
|
|
267125
|
-
return { ...room, ...
|
|
267129
|
+
return { ...room, ...fresh2(counts.unread, "unread") };
|
|
267126
267130
|
case "inbox":
|
|
267127
|
-
return { ...room, ...
|
|
267131
|
+
return { ...room, ...fresh2(counts.inbox, "new") };
|
|
267128
267132
|
case "money":
|
|
267129
267133
|
return { ...room, figure: counts.money.available, money: true, after: counts.money.onAsks ? `${counts.money.onAsks} on asks` : null };
|
|
267130
267134
|
case "agents":
|
|
@@ -267134,7 +267138,7 @@ function roomRows(counts) {
|
|
|
267134
267138
|
}
|
|
267135
267139
|
});
|
|
267136
267140
|
}
|
|
267137
|
-
var ROOMS, counted, roomLines;
|
|
267141
|
+
var ROOMS, counted, fresh2, roomLines;
|
|
267138
267142
|
var init_meRooms = __esm({
|
|
267139
267143
|
"../../app/lib/meRooms.ts"() {
|
|
267140
267144
|
"use strict";
|
|
@@ -267149,6 +267153,7 @@ var init_meRooms = __esm({
|
|
|
267149
267153
|
{ key: "settings", word: "Settings", href: "/me/settings" }
|
|
267150
267154
|
];
|
|
267151
267155
|
counted = (value, after) => value ? { figure: String(value), after } : { figure: null, after: null };
|
|
267156
|
+
fresh2 = (value, after) => ({ ...counted(value, after), ...value ? { fresh: true } : {} });
|
|
267152
267157
|
roomLines = (counts) => roomRows(counts).map((row) => `${row.word}: ${row.chip ?? (row.verify ? "not verified yet" : [row.figure, row.after].filter(Boolean).join(row.money ? " \xB7 " : " ") || (row.key === "settings" ? "sign-in, recovery, currency, identity" : "nothing waiting"))}`);
|
|
267153
267158
|
}
|
|
267154
267159
|
});
|
|
@@ -292360,7 +292365,7 @@ import { randomBytes as randomBytes7 } from "node:crypto";
|
|
|
292360
292365
|
// package.json
|
|
292361
292366
|
var package_default = {
|
|
292362
292367
|
name: "@ixo/asks-mcp",
|
|
292363
|
-
version: "2.0.0-dev.
|
|
292368
|
+
version: "2.0.0-dev.4",
|
|
292364
292369
|
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.",
|
|
292365
292370
|
license: "Apache-2.0",
|
|
292366
292371
|
repository: {
|
|
@@ -292650,7 +292655,7 @@ var TOOLS = {
|
|
|
292650
292655
|
},
|
|
292651
292656
|
draft_call: {
|
|
292652
292657
|
title: "Set up an open call or a pro ask",
|
|
292653
|
-
description: 'Draft an open call or a pro ask. An open call is a brief people answer with their own AI, checked against five requirements: a competition picks a winner; a hire pays every entry that passes, up to a number, and picks nobody; open to anyone, by application (you say yes to each), or by invitation (your list: addresses, @handles, single-use links). A software-review Ask (`kind: "review"`) is one specialised work type on Pro Asks: verified pros you invite try the scenarios and send reports; always a hire, by invitation only; Asky Pro Checker, the verifier, checks each report. Interviews in order: give what the person said, and the answer lists what is still missing, each with the question to ask them. Kept on disk between calls, so never re-send what was already taken. When nothing is missing it shows the whole call, what each leg holds (a pro ask\'s money in one sentence: what each pro receives, what is held per report, and the fee: 20 %
|
|
292658
|
+
description: 'Draft an open call or a pro ask. An open call is a brief people answer with their own AI, checked against five requirements: a competition picks a winner; a hire pays every entry that passes, up to a number, and picks nobody; open to anyone, by application (you say yes to each), or by invitation (your list: addresses, @handles, single-use links). A software-review Ask (`kind: "review"`) is one specialised work type on Pro Asks: verified pros you invite try the scenarios and send reports; always a hire, by invitation only; Asky Pro Checker, the verifier, checks each report. Interviews in order: give what the person said, and the answer lists what is still missing, each with the question to ask them. Kept on disk between calls, so never re-send what was already taken. When nothing is missing it shows the whole call, what each leg holds (a pro ask\'s money in one sentence: what each pro receives, what is held per report, and the fee: 20 % of what you pay runs asks.world, the pro gets the rest) and the clock, for the person to approve. Spends nothing.',
|
|
292654
292659
|
spends: false,
|
|
292655
292660
|
hosted: false,
|
|
292656
292661
|
/* It writes the draft file, and nothing else anywhere. */
|
|
@@ -294493,18 +294498,18 @@ async function build2(options, server2, parts) {
|
|
|
294493
294498
|
const refreshDeployment = async () => {
|
|
294494
294499
|
if (!local || options.deployment || Date.now() - siteReadAt < (CLAIM_FORM && !DEPLOYMENT.note ? SITE_REREAD_MS : 1e4)) return;
|
|
294495
294500
|
siteReadAt = Date.now();
|
|
294496
|
-
const
|
|
294497
|
-
if (!
|
|
294498
|
-
DEPLOYMENT =
|
|
294499
|
-
adoptRelayer(
|
|
294500
|
-
adoptAskProtocol(
|
|
294501
|
-
adoptReviewBilling(
|
|
294502
|
-
adoptOracleUrl(
|
|
294503
|
-
adoptFeeSplit(
|
|
294504
|
-
adoptAskDenom(
|
|
294505
|
-
adoptClaimForm(
|
|
294506
|
-
CLAIM_FORM =
|
|
294507
|
-
applyDeployment(
|
|
294501
|
+
const fresh3 = await deployment().catch(() => null);
|
|
294502
|
+
if (!fresh3 || fresh3.note) return;
|
|
294503
|
+
DEPLOYMENT = fresh3;
|
|
294504
|
+
adoptRelayer(fresh3);
|
|
294505
|
+
adoptAskProtocol(fresh3);
|
|
294506
|
+
adoptReviewBilling(fresh3);
|
|
294507
|
+
adoptOracleUrl(fresh3);
|
|
294508
|
+
adoptFeeSplit(fresh3);
|
|
294509
|
+
adoptAskDenom(fresh3);
|
|
294510
|
+
adoptClaimForm(fresh3);
|
|
294511
|
+
CLAIM_FORM = fresh3.claimForm;
|
|
294512
|
+
applyDeployment(fresh3);
|
|
294508
294513
|
};
|
|
294509
294514
|
const unjudged = async () => {
|
|
294510
294515
|
await refreshDeployment();
|
|
@@ -294535,7 +294540,7 @@ async function build2(options, server2, parts) {
|
|
|
294535
294540
|
const cap = capCoinRefusal2(acting, coin);
|
|
294536
294541
|
return cap ? { refused: cap } : coin;
|
|
294537
294542
|
};
|
|
294538
|
-
const
|
|
294543
|
+
const feeWords2 = (base6, symbol2 = FEE_SYMBOL) => dollarsOf(base6, symbol2, NETWORK2);
|
|
294539
294544
|
const FUNDER = ownEnv().OPENHANDS_FUNDER?.trim() || void 0;
|
|
294540
294545
|
const FOLLOW_PAY_MAX = 10;
|
|
294541
294546
|
const MAX_PER_ASK = CAPS.perAsk;
|
|
@@ -294791,7 +294796,7 @@ Each is its own ask and pays on its own. Read one with read_ask before deciding.
|
|
|
294791
294796
|
if (title) taint2(title);
|
|
294792
294797
|
const facts = row.callSummary;
|
|
294793
294798
|
const shares = call3.shared;
|
|
294794
|
-
const entryPays = shares && facts?.entryEach !== void 0 && call3.entries?.pays ?
|
|
294799
|
+
const entryPays = shares && facts?.entryEach !== void 0 && call3.entries?.pays ? faceOf2({ value: facts.entryEach, symbol: call3.entries.pays.symbol }, SANDBOX)?.text : call3.entries?.pays ? `${faceOf2(call3.entries.pays, SANDBOX)?.text}${shares ? ", less the network's share" : ""}` : void 0;
|
|
294795
294800
|
return [
|
|
294796
294801
|
`${review ? "Expert review" : "Open call"} "${call3.slug}" \xB7 ${summary.open} of ${summary.places} legs open${entryPays ? ` \xB7 every ${review ? "report" : "entry"} that meets the bar is paid ${entryPays}` : ""} \xB7 needs-a-human`,
|
|
294797
294802
|
title ? asData("ask-title", title) : "",
|
|
@@ -295398,15 +295403,15 @@ Never open it yourself.`);
|
|
|
295398
295403
|
amount: offChain ? `${offChain.amount} ${offChain.currency}` : face(pay, symbol2),
|
|
295399
295404
|
quota: spots,
|
|
295400
295405
|
total: offChain ? `${(Number(offChain.amount) * spots).toFixed(2)} ${offChain.currency}` : rewardsFace,
|
|
295401
|
-
fee:
|
|
295402
|
-
feeTotal:
|
|
295406
|
+
fee: feeWords2(perCheck ? perCheck.price : legBase),
|
|
295407
|
+
feeTotal: feeWords2(legBase * spots),
|
|
295403
295408
|
perReview: Boolean(perCheck),
|
|
295404
295409
|
own: !perCheck && legBase === 0 && !orgAsk.oracle.url,
|
|
295405
295410
|
free: !perCheck && legBase === 0 && Boolean(orgAsk.oracle.url)
|
|
295406
295411
|
}).map((line2) => `- ${line2.label}: ${line2.text}`).join("\n") : "";
|
|
295407
295412
|
const { total, what: preview, details: costDetails } = orgAsk ? { total: 0, what: `nothing from this key (${orgName} pays)`, details: `What this costs ${orgName}:
|
|
295408
|
-
${orgCosts}` } : { total: onChain.total, what: perCheck ? `${onChain.what}. Review fee: ${billing.creditsCopy(null,
|
|
295409
|
-
const orgToken = orgAsk ? (await Promise.resolve().then(() => (init_hq(), hq_exports))).orgConfirmToken({ offChainTotal: offChain ? `${(Number(offChain.amount) * spots).toFixed(2)} ${offChain.currency}` : null, rewards: rewardsFace, feesSetAside: !perCheck && legBase > 0 ?
|
|
295413
|
+
${orgCosts}` } : { total: onChain.total, what: perCheck ? `${onChain.what}. Review fee: ${billing.creditsCopy(null, feeWords2(perCheck.price))}` : onChain.what, details: "" };
|
|
295414
|
+
const orgToken = orgAsk ? (await Promise.resolve().then(() => (init_hq(), hq_exports))).orgConfirmToken({ offChainTotal: offChain ? `${(Number(offChain.amount) * spots).toFixed(2)} ${offChain.currency}` : null, rewards: rewardsFace, feesSetAside: !perCheck && legBase > 0 ? feeWords2(legBase * spots) : null }) : void 0;
|
|
295410
295415
|
const payDraft = card ? await Promise.resolve().then(() => (init_payDraft(), payDraft_exports)) : null;
|
|
295411
295416
|
const quote = payDraft?.quoteOf(Number(baseFromPay2(pay)) * spots, legBase * spots);
|
|
295412
295417
|
const cardWords = payDraft && quote ? payDraft.cardPreview(quote) : null;
|
|
@@ -295435,7 +295440,7 @@ ${orgCosts}` } : { total: onChain.total, what: perCheck ? `${onChain.what}. Revi
|
|
|
295435
295440
|
card ? null : actingNote(acting),
|
|
295436
295441
|
pick2,
|
|
295437
295442
|
expert ? expertNote(expert) : checkingNote(terms, acting?.principal ?? null),
|
|
295438
|
-
expert ? null : orgAsk ? `Reviewed by ${await oracleWordsFor({ did: orgAsk.oracle.did, address: orgAsk.oracle.address })}.` : reviewer && reviewer !== CHECKER ? `Reviewed by ${await oracleWordsFor({ address: reviewer })}.` : reviewer ? `Checked by asks.world verifier, ${
|
|
295443
|
+
expert ? null : orgAsk ? `Reviewed by ${await oracleWordsFor({ did: orgAsk.oracle.did, address: orgAsk.oracle.address })}.` : reviewer && reviewer !== CHECKER ? `Reviewed by ${await oracleWordsFor({ address: reviewer })}.` : reviewer ? `Checked by asks.world verifier, ${feeWords2(perCheck ? perCheck.price : legBase)} per check.` : null,
|
|
295439
295444
|
doorWords(door2.access, door2.invite.length),
|
|
295440
295445
|
inCampaign ? `In campaign ${inCampaign.protocolDid}, checked by its shared rules (${inCampaign.claimProtocolDid}).` : null,
|
|
295441
295446
|
picture2 && !("refused" in picture2) ? `Picture: ${picture2.contentType.slice(6)}, ${Math.ceil(picture2.bytes.byteLength / 1024)} KB, uploaded through your account connection with the ask.` : null,
|
|
@@ -295535,12 +295540,12 @@ ${SITE}/t/${earlier.id}`);
|
|
|
295535
295540
|
if (bare2) return said4(receives);
|
|
295536
295541
|
return `${said4(receives)} (the leg is ${said4(Number(amount3))}; the network keeps ${said4(Number(amount3) - receives)}: ${shareWords2(split3, posted ? "as posted" : "today")})`;
|
|
295537
295542
|
}
|
|
295538
|
-
const callLocks = (rewardBase, feeBase, symbol2 = ASK_SYMBOL) => `${pays(rewardBase, symbol2)}${feeBase > 0 ? ` and ${
|
|
295543
|
+
const callLocks = (rewardBase, feeBase, symbol2 = ASK_SYMBOL) => `${pays(rewardBase, symbol2)}${feeBase > 0 ? ` and ${feeWords2(feeBase)} for reviews` : ""}`;
|
|
295539
295544
|
function escrowTotal(pay, spots, legBase, symbol2 = ASK_SYMBOL, sameCoin = true, feeSymbol = FEE_SYMBOL) {
|
|
295540
295545
|
const leg = legBase / MICRO6;
|
|
295541
295546
|
if (!sameCoin && leg > 0) {
|
|
295542
295547
|
const total2 = pay * spots;
|
|
295543
|
-
return { total: total2, what: `${face(total2, symbol2)} and ${
|
|
295548
|
+
return { total: total2, what: `${face(total2, symbol2)} and ${feeWords2(legBase * spots, feeSymbol)}. A ${face(pay, symbol2)} reward for each of ${spots} ${spots === 1 ? "answer" : "answers"}, plus ${feeWords2(legBase, feeSymbol)} for each review. Held now` };
|
|
295544
295549
|
}
|
|
295545
295550
|
const total = (pay + leg) * spots;
|
|
295546
295551
|
return {
|
|
@@ -295647,7 +295652,7 @@ ${SITE}/t/${earlier.id}`);
|
|
|
295647
295652
|
const billing = await Promise.resolve().then(() => (init_reviewBilling(), reviewBilling_exports));
|
|
295648
295653
|
const escrowed = escrowTotal(pay, spots, legBase, coinSymbol, coin === (expert?.feeDenom ?? FEE_DENOM), symbolOf(expert?.feeDenom ?? FEE_DENOM));
|
|
295649
295654
|
const total = escrowed.total;
|
|
295650
|
-
const what = perCheck ? `${escrowed.what}. Review fee: ${billing.creditsCopy(null,
|
|
295655
|
+
const what = perCheck ? `${escrowed.what}. Review fee: ${billing.creditsCopy(null, feeWords2(perCheck.price))}` : escrowed.what;
|
|
295651
295656
|
const guard = spendGuard({
|
|
295652
295657
|
bucket: "world",
|
|
295653
295658
|
task: question,
|
|
@@ -296488,7 +296493,7 @@ ${pending.link}`);
|
|
|
296488
296493
|
The review fee's coin, where it is not the reward's (mainnet: USDC rewards, PAY fees), is what covers the next
|
|
296489
296494
|
ask's checks, so it is said when there is any. In dollars, as every amount. The network fee is the gate's to
|
|
296490
296495
|
cover for an account that holds money, so it is not a line here. */
|
|
296491
|
-
`Available: ${pays(Number(held[ASK_DENOM] ?? 0), ASK_DENOM)} \xB7 On your asks ${onAsks === null ? "(could not be read just now)" : pays(onAsks, "upay")}${ASK_DENOM !== FEE_DENOM && Number(held[FEE_DENOM] ?? 0) > 0 ? ` \xB7 ${
|
|
296496
|
+
`Available: ${pays(Number(held[ASK_DENOM] ?? 0), ASK_DENOM)} \xB7 On your asks ${onAsks === null ? "(could not be read just now)" : pays(onAsks, "upay")}${ASK_DENOM !== FEE_DENOM && Number(held[FEE_DENOM] ?? 0) > 0 ? ` \xB7 ${feeWords2(Number(held[FEE_DENOM]))} set aside for checks` : ""}`,
|
|
296492
296497
|
done ? `Work: ${done.submitted ?? 0} answers \xB7 ${done.approved ?? 0} approved${done.earned ? ` \xB7 ${face(done.earned.value, done.earned.symbol)} earned` : ""}` : "",
|
|
296493
296498
|
/* Whose money this would spend, and how much of it is left. An agent
|
|
296494
296499
|
funded by somebody's allowance should be able to say so — and an
|
|
@@ -296654,7 +296659,7 @@ ${settings}`
|
|
|
296654
296659
|
const unread = await unreadable(terms);
|
|
296655
296660
|
if (unread) return text4(unread);
|
|
296656
296661
|
const { total } = escrowTotal(pin_pay, pins2, legBase, coinSymbol, coin === FEE_DENOM);
|
|
296657
|
-
const preview = `${face(total, coinSymbol)} to open "${name8}". ${pins2} ${pins2 === 1 ? "report" : "reports"} at ${face(pin_pay, coinSymbol)} each, plus ${
|
|
296662
|
+
const preview = `${face(total, coinSymbol)} to open "${name8}". ${pins2} ${pins2 === 1 ? "report" : "reports"} at ${face(pin_pay, coinSymbol)} each, plus ${feeWords2(legBase)} to whoever checks each one. Mapping stays open ${open} days, and two pins closer than ${apart} m are the same mess`;
|
|
296658
296663
|
const guard = spendGuard({ bucket: "organise", task: `campaign ${tag}`, total, ...confirm ? { confirm } : {}, what: preview, symbol: coinSymbol });
|
|
296659
296664
|
if (guard) {
|
|
296660
296665
|
return text4(
|
|
@@ -296801,12 +296806,12 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
296801
296806
|
const keyOnly = !acting && feeTotal > 0;
|
|
296802
296807
|
const blocked = capped4.length > 0 || Boolean(otherCoin) || Boolean(twoCoins) && draft.fields.kind !== "review";
|
|
296803
296808
|
const m = draft.fields.money;
|
|
296804
|
-
const {
|
|
296809
|
+
const { feeSentence: feeSentence2 } = await Promise.resolve().then(() => (init_feeLine(), feeLine_exports));
|
|
296805
296810
|
const proMoney = proAsk && Boolean(plan.share);
|
|
296806
296811
|
const who = draft.fields.kind === "review" ? "pro" : "hired person";
|
|
296807
|
-
const
|
|
296812
|
+
const legPays = (leg) => plan.share && !proMoney ? `, so the leg pays ${pays(leg.legBase, coinSymbol)}` : "";
|
|
296808
296813
|
const legRows = plan.legs.map(
|
|
296809
|
-
(leg) => leg.leg === "prize" ? ` The pick ${pays(leg.payBase, coinSymbol)} to one entry${
|
|
296814
|
+
(leg) => leg.leg === "prize" ? ` The pick ${pays(leg.payBase, coinSymbol)} to one entry${legPays(leg)}; its ask takes ${leg.quota} claims (the pick and two spare) \xB7 locks ${pays(leg.escrowBase, coinSymbol)}` : leg.leg === "runnersUp" ? ` Runners-up ${pays(leg.payBase, coinSymbol)} to each of ${m.runnersN}${legPays(leg)} \xB7 locks ${pays(leg.escrowBase, coinSymbol)}` : plan.share ? ` Entries each ${who} receives ${pays(leg.payBase, coinSymbol)} for an entry that passes all ${draft.fields.kind === "review" ? "six" : "five"} lines${legPays(leg)} \xB7 up to ${leg.quota}${checker.fee ? `, plus ${pays(leg.checkBase, coinSymbol)} per check to ${checker.name}` : leg.checkBase > 0 ? `, plus the verifier's ${feeWords2(leg.checkBase)} per ruling` : ", the verifier billed per check from credits"} \xB7 locks ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}` : ` Entries ${pays(leg.payBase, coinSymbol)} to each entry that passes all ${draft.fields.kind === "review" ? "six" : "five"} lines, up to ${leg.quota}${checker.fee ? `, plus ${pays(leg.checkBase, coinSymbol)} per check to ${checker.name}` : leg.checkBase > 0 ? `, plus the verifier's ${feeWords2(leg.checkBase)} per ruling` : ", the verifier billed per check from credits"} \xB7 locks ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}`
|
|
296810
296815
|
);
|
|
296811
296816
|
const shareTotal = plan.legs.reduce((sum2, one) => sum2 + one.shareBase * one.escrowSpots, 0);
|
|
296812
296817
|
const hire = draft.fields.mode === "hire";
|
|
@@ -296817,7 +296822,7 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
296817
296822
|
!hire && m.prize < m.entryEach ? `The prize (${face(m.prize, coinSymbol)}) is less than one entry earns (${face(m.entryEach, coinSymbol)}).` : "",
|
|
296818
296823
|
draft.fields.access === "invite" && !draft.fields.invite?.length ? proAsk ? "Nobody invited yet: find_pro suggests verified pros; add them with invite now, or invite_to_call after it posts." : 'By invitation, and nobody invited yet: add invite (addresses, @handles, "link") now, or invite_to_call after it posts.' : "",
|
|
296819
296824
|
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." : "",
|
|
296820
|
-
...call3.balanceWarnings(held, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
|
|
296825
|
+
...call3.balanceWarnings(held, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords: feeWords2 }),
|
|
296821
296826
|
acting?.cap && !otherCoin && Number(capIn2(acting, coin)?.remainingBase ?? 0) < plan.totalBase ? `Their cap has ${pays(Number(capIn2(acting, coin)?.remainingBase ?? 0), coinSymbol)} left; the call locks ${pays(plan.totalBase, coinSymbol)}. They raise it at ${SITE}/connect.` : "",
|
|
296822
296827
|
keyOnly ? `Not connected, and a connection would not carry this call: ${call3.callTwoCoins}. With plain_key: true it posts as this key itself, ${await address2()}, from its own money.` : !acting ? `Not connected: post_call refuses until the person connects this key (connect_account gives them the link). For a rehearsal, plain_key: true posts as this key itself, ${await address2()}, from its own money.` : ""
|
|
296823
296828
|
].filter(Boolean);
|
|
@@ -296831,10 +296836,10 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
|
|
|
296831
296836
|
...legRows,
|
|
296832
296837
|
` Total ${callLocks(plan.totalBase, feeTotal, coinSymbol)}`,
|
|
296833
296838
|
...plan.share && !proMoney ? [
|
|
296834
|
-
` Network's share ${pays(shareTotal, coinSymbol)} of that, if every spot is paid
|
|
296839
|
+
` Network's share ${pays(shareTotal, coinSymbol)} of that, if every spot is paid. ${feeSentence2(plan.share, NETWORK2, "Each hired person")} Asks and public calls carry no share.`
|
|
296835
296840
|
] : [],
|
|
296836
296841
|
"",
|
|
296837
|
-
`${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 ${
|
|
296842
|
+
`${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 ${feeWords2(held.fee)}` : ""}; this call locks ${callLocks(plan.totalBase, feeTotal, coinSymbol)}.`,
|
|
296838
296843
|
hire ? `The clock: entries close ${new Date(plan.dates.closes).toUTCString()}; ${finalOk ? `every passing report is paid once ${finalOk} gives the final OK` : "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()}.`,
|
|
296839
296844
|
`Who may enter: ${draft.fields.access === "invite" ? `by invitation only${draft.fields.invite?.length ? `. ${draft.fields.invite.length} people will be invited when the Ask is posted${draft.fields.inviteNote ? ", each with your private note" : ""}` : ""}` : draft.fields.access === "apply" ? "by application, listed on the board" : "anyone, listed on the board"}.`,
|
|
296840
296845
|
...draft.fields.kind === "review" ? [
|
|
@@ -296933,20 +296938,19 @@ Then call post_call again. Nothing was posted.`);
|
|
|
296933
296938
|
return text4(await payDraft.saveDraft(SITE, { kind: "call", terms, quote, network: NETWORK2 }, fetch2));
|
|
296934
296939
|
}
|
|
296935
296940
|
if (!confirm) {
|
|
296936
|
-
const {
|
|
296937
|
-
const shareTotal = plan.legs.reduce((sum2, one) => sum2 + one.shareBase * one.escrowSpots, 0);
|
|
296941
|
+
const { feeSentence: feeSentence2 } = await Promise.resolve().then(() => (init_feeLine(), feeLine_exports));
|
|
296938
296942
|
const held2 = await heldBy(acting, coin);
|
|
296939
296943
|
return text4(
|
|
296940
296944
|
[
|
|
296941
296945
|
`Call "${slug}" locks ${callLocks(plan.totalBase, feeTotal, coinSymbol)} in ${order2.length} ${order2.length === 1 ? "Ask" : "Asks"}, posted one per call: ${order2.map((one) => LEG_WORDS[one]).join(", then ")}.${ids.length ? ` Posted already: ${ids.join(", ")}.` : ""}`,
|
|
296942
|
-
/* A private call: the
|
|
296943
|
-
...moneySentence ? [moneySentence] : plan.share ? [`
|
|
296946
|
+
/* A private call: the fee is in that total, said before the yes in one figure of what the poster pays; a pro ask says it in its one sentence. */
|
|
296947
|
+
...moneySentence ? [moneySentence] : plan.share ? [`Each hired person receives ${pays(plan.legs.find((one) => one.leg === "entries").payBase, coinSymbol)} for each passing entry. ${feeSentence2(plan.share, NETWORK2, "Each hired person")}`] : [],
|
|
296944
296948
|
`Next: ${LEG_WORDS[next]}, locking ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}, plus a small network fee.`,
|
|
296945
296949
|
actingNote(acting) ?? (review ? "Posting from your own account (this key), not the person's account; the AI decides each report alone, with no final OK from the person." : `Posting as this key, ${poster}.`),
|
|
296946
296950
|
...pick2 ? [pick2] : [],
|
|
296947
296951
|
`Spent today (call): ${spentWords("call", coinSymbol)}. Every tool together: ${spentAllWords()}.`,
|
|
296948
296952
|
...call3.capWords(plan.legs.filter((one) => !draft.posted[one.leg]), CAP_BASE, coinSymbol, NETWORK2),
|
|
296949
|
-
...call3.balanceWarnings(held2, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
|
|
296953
|
+
...call3.balanceWarnings(held2, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords: feeWords2 }),
|
|
296950
296954
|
"",
|
|
296951
296955
|
`To go ahead, call again with confirm: "${total}".`
|
|
296952
296956
|
].join("\n")
|
|
@@ -296966,7 +296970,7 @@ Then call post_call again. Nothing was posted.`);
|
|
|
296966
296970
|
feeDenom: FEE_DENOM,
|
|
296967
296971
|
balanceBase: async (who, denom) => Number((await balancesOfStrict2(who))[denom] ?? 0),
|
|
296968
296972
|
face: (base6) => pays(base6, coinSymbol),
|
|
296969
|
-
feeFace:
|
|
296973
|
+
feeFace: feeWords2,
|
|
296970
296974
|
coinFixed: Boolean(checker.fee),
|
|
296971
296975
|
site: SITE
|
|
296972
296976
|
});
|
|
@@ -297677,15 +297681,15 @@ ${asData("linkedin", JSON.stringify(prefill, null, 2))}`
|
|
|
297677
297681
|
}
|
|
297678
297682
|
};
|
|
297679
297683
|
let PLANS = DEPLOYMENT.plans;
|
|
297680
|
-
function applyDeployment(
|
|
297681
|
-
ASK_DENOM =
|
|
297684
|
+
function applyDeployment(fresh3) {
|
|
297685
|
+
ASK_DENOM = fresh3.askDenom;
|
|
297682
297686
|
ASK_SYMBOL = symbolOf(ASK_DENOM);
|
|
297683
|
-
CHECKER =
|
|
297684
|
-
GATE =
|
|
297685
|
-
CHECK_REWARD =
|
|
297686
|
-
ENGINE_ORACLE =
|
|
297687
|
-
ENGINE_MODE =
|
|
297688
|
-
PLANS =
|
|
297687
|
+
CHECKER = fresh3.checker;
|
|
297688
|
+
GATE = fresh3.gate;
|
|
297689
|
+
CHECK_REWARD = fresh3.checkRewardBase;
|
|
297690
|
+
ENGINE_ORACLE = fresh3.engine.oracle;
|
|
297691
|
+
ENGINE_MODE = fresh3.engine.live;
|
|
297692
|
+
PLANS = fresh3.plans;
|
|
297689
297693
|
}
|
|
297690
297694
|
const MAX_PER_PLAN = CAPS.perPlan;
|
|
297691
297695
|
const PLAN_CAPS = { perAsk: MAX_PER_ASK, perPlan: MAX_PER_PLAN, perDayTotal: MAX_PER_DAY_TOTAL };
|
|
@@ -297696,8 +297700,8 @@ ${asData("linkedin", JSON.stringify(prefill, null, 2))}`
|
|
|
297696
297700
|
return { cost: planCost2(plan, { reviewUsd: sameCoin ? world.leg / MICRO6 : 0, feeRate: 0 }), reviewsBase: sameCoin ? 0 : world.leg * planAnswerCount2(plan) };
|
|
297697
297701
|
}
|
|
297698
297702
|
async function reviewWords(world, reviewsBase) {
|
|
297699
|
-
if (world.perCheck) return `Review fee: ${(await Promise.resolve().then(() => (init_reviewBilling(), reviewBilling_exports))).creditsCopy(null,
|
|
297700
|
-
return reviewsBase > 0 ? `Reviews: ${
|
|
297703
|
+
if (world.perCheck) return `Review fee: ${(await Promise.resolve().then(() => (init_reviewBilling(), reviewBilling_exports))).creditsCopy(null, feeWords2(world.perCheck.price))}`;
|
|
297704
|
+
return reviewsBase > 0 ? `Reviews: ${feeWords2(reviewsBase)} on top, ${feeWords2(world.leg)} for each answer, escrowed beside the rewards.` : "";
|
|
297701
297705
|
}
|
|
297702
297706
|
const UNPRICED = "The verifier could not be priced just now, so no plan can be bought. Try again shortly. Nothing was posted.";
|
|
297703
297707
|
async function registerPlan(cid, poster) {
|
|
@@ -297895,7 +297899,7 @@ ${asData("linkedin", JSON.stringify(prefill, null, 2))}`
|
|
|
297895
297899
|
}
|
|
297896
297900
|
if (confirm.trim() !== money3(cost.totalUsd)) return text4(`Refused: confirm said "${confirm}" but the total is ${money3(cost.totalUsd)}. Preview it again.`);
|
|
297897
297901
|
if (!resuming) {
|
|
297898
|
-
if (acting && reviewsBase > 0) return text4(`Refused: this plan's reviews escrow ${
|
|
297902
|
+
if (acting && reviewsBase > 0) return text4(`Refused: this plan's reviews escrow ${feeWords2(reviewsBase)} beside its ${coinSymbol} rewards, and ${acting.principal}'s allowance covers ${coinSymbol} only. Use a verifier that bills per check (Pay for reviews), or post from this key. Nothing was posted.`);
|
|
297899
297903
|
const otherCoin = (await Promise.resolve().then(() => (init_hq(), hq_exports))).capCoinRefusal(acting, coin);
|
|
297900
297904
|
if (otherCoin) return text4(`Refused: ${otherCoin}. Draft the plan again with draft_plan in that coin. Nothing was posted.`);
|
|
297901
297905
|
if (acting) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ixo/asks-mcp",
|
|
3
|
-
"version": "2.0.0-dev.
|
|
3
|
+
"version": "2.0.0-dev.4",
|
|
4
4
|
"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.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|