@garuda-agent/garuda 0.16.1 → 0.18.0
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/CHANGELOG.md +319 -0
- package/README.md +56 -1074
- package/SECURITY.md +9 -2
- package/dist/{acpCommand-OTAYW7BS.js → acpCommand-IUZPLPLI.js} +25 -23
- package/dist/{anthropic-NQDBCHJU.js → anthropic-NQIZLD64.js} +12 -6
- package/dist/{chunk-NP6RIC25.js → chunk-2FIV2VZP.js} +11 -7
- package/dist/{chunk-YQTGMCU6.js → chunk-3MRQJKUO.js} +29 -5
- package/dist/{chunk-HE2K657U.js → chunk-4BVCYCQT.js} +47 -16
- package/dist/{chunk-WMOLXTBU.js → chunk-4LFJFDCF.js} +2 -1
- package/dist/{chunk-44QN5SWZ.js → chunk-55CFEEIN.js} +22 -2
- package/dist/{chunk-USCUXCAU.js → chunk-5B5HDTUR.js} +3 -3
- package/dist/chunk-65NUEOI7.js +143 -0
- package/dist/{chunk-TUUEBHG2.js → chunk-6XHON3Q6.js} +2 -2
- package/dist/chunk-7KBOIPUT.js +157 -0
- package/dist/{chunk-B6FA4I7Q.js → chunk-7TH3NHCQ.js} +2 -2
- package/dist/{chunk-OUCV3FCT.js → chunk-AOGFYUKG.js} +3 -3
- package/dist/{chunk-GXZACJUI.js → chunk-B4SJY7KT.js} +322 -39
- package/dist/{chunk-3EQU2GUX.js → chunk-BHZ6G65V.js} +5 -1
- package/dist/chunk-C57GHLKP.js +9 -0
- package/dist/chunk-DOCDCQVM.js +484 -0
- package/dist/chunk-FOPBOB7W.js +332 -0
- package/dist/{chunk-TILFPYWO.js → chunk-NHWHG3SW.js} +1930 -992
- package/dist/{chunk-BQTUOO4G.js → chunk-OQ26W5L4.js} +81 -32
- package/dist/{chunk-HUIK3WXO.js → chunk-P6XWWIEK.js} +20 -3
- package/dist/chunk-Q4P3W657.js +6372 -0
- package/dist/{chunk-ZAE25JM2.js → chunk-QANRZW7W.js} +8 -1
- package/dist/chunk-UIRJOQQS.js +118 -0
- package/dist/chunk-UKIE4AAM.js +472 -0
- package/dist/{chunk-KKB5W47S.js → chunk-VTMD5IHD.js} +26 -2
- package/dist/cli/index.js +148 -57
- package/dist/config-WV2H64TF.js +23 -0
- package/dist/{create-VXIH2GUZ.js → create-W6BV75QX.js} +18 -12
- package/dist/{deadline-F5RJJ2QW.js → deadline-TP7ZGLT2.js} +4 -2
- package/dist/evalCommand-SKJQ6CW2.js +686 -0
- package/dist/evalTune-CZRCPSZ3.js +295 -0
- package/dist/{export-HN3CT7AV.js → export-SJ3DUP6W.js} +2 -2
- package/dist/{inkChat-WEDGQMCY.js → inkChat-WYYAFZXD.js} +20 -19
- package/dist/install-TKWN5AYH.js +19 -0
- package/dist/{job-3NYDMP2M.js → job-7JOI4YIQ.js} +6 -2
- package/dist/jobCommand-2ODQLHB3.js +33 -0
- package/dist/{launchd-SSX362VG.js → launchd-3A3ONEW5.js} +9 -8
- package/dist/{lspCommand-JRXKRSL7.js → lspCommand-ZZ6R4PA2.js} +7 -6
- package/dist/{manager-773PUDFE.js → manager-TCYTA5XU.js} +15 -14
- package/dist/{nightCommand-65MUEV32.js → nightCommand-WJU6VZA6.js} +26 -20
- package/dist/{openaiCompatible-CJWVJP5M.js → openaiCompatible-6TLDDW5U.js} +29 -15
- package/dist/{policy-EJPLEEXP.js → policy-ZJ7RMOFN.js} +10 -4
- package/dist/{remove-6GDSTAIO.js → remove-42WQNVPX.js} +8 -7
- package/dist/{run-ML6GSPN4.js → run-PTMRQCIU.js} +5 -5
- package/dist/{server-NGKVIQEV.js → server-VEYIJHEU.js} +2 -2
- package/dist/{setupCommand-VA7D5MZK.js → setupCommand-YMF6I3MD.js} +45 -13
- package/dist/text-LS35WSRL.js +17 -0
- package/dist/tune-YVI2KWQF.js +31 -0
- package/native/bin/garuda-reap +0 -0
- package/native/garuda-reap.c +113 -0
- package/package.json +39 -13
- package/dist/chunk-EIXUSVFX.js +0 -116
- package/dist/chunk-R7I2NBPX.js +0 -71
- package/dist/chunk-ULAJPMY7.js +0 -107
- package/dist/chunk-VBZCNMUD.js +0 -9
- package/dist/evalCommand-RGMZRYDR.js +0 -2812
- package/dist/install-EWDSPFFZ.js +0 -18
- package/dist/jobCommand-ACSGSBQ4.js +0 -32
- package/dist/text-J2GD647J.js +0 -11
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
compareReports,
|
|
4
|
+
costPerPass,
|
|
5
|
+
formatComparison,
|
|
6
|
+
taskHash
|
|
7
|
+
} from "./chunk-DOCDCQVM.js";
|
|
8
|
+
|
|
9
|
+
// src/evals/tune.ts
|
|
10
|
+
import { readFile } from "fs/promises";
|
|
11
|
+
var ADDENDUM_MAX_CHARS = 4e3;
|
|
12
|
+
var CHECK_TAIL_LINES = 40;
|
|
13
|
+
var REJECTED = [
|
|
14
|
+
/\b(skip|disable|ignore|bypass|weaken)\b[^.\n]{0,40}\b(tests?|checks?|assert\w*|sandbox|protect\w*)/i,
|
|
15
|
+
/\b(edit|change|modify|delete|remove|rewrite)\b[^.\n]{0,40}\b(the )?(tests?|test files?|checks?|protected files?)\b/i,
|
|
16
|
+
/\boutside_sandbox\b/i,
|
|
17
|
+
/\b(hard-?code|special-?case)\b[^.\n]{0,40}\b(expected|test|check)/i,
|
|
18
|
+
/\.check\//i
|
|
19
|
+
];
|
|
20
|
+
async function readAddendum(path, missingIsEmpty = false) {
|
|
21
|
+
let text;
|
|
22
|
+
try {
|
|
23
|
+
text = await readFile(path, "utf8");
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (missingIsEmpty && error.code === "ENOENT") return { text: "" };
|
|
26
|
+
return { problem: `--addendum ${path}: ${error.message}` };
|
|
27
|
+
}
|
|
28
|
+
if (text.length > ADDENDUM_MAX_CHARS) {
|
|
29
|
+
return {
|
|
30
|
+
problem: `--addendum ${path}: ${text.length} characters; the limit is ${ADDENDUM_MAX_CHARS}.`
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return { text };
|
|
34
|
+
}
|
|
35
|
+
function rejectReason(text) {
|
|
36
|
+
if (text.trim() === "") return "the addendum is empty";
|
|
37
|
+
if (text.length > ADDENDUM_MAX_CHARS) {
|
|
38
|
+
return `the addendum has ${text.length} characters; the limit is ${ADDENDUM_MAX_CHARS}`;
|
|
39
|
+
}
|
|
40
|
+
for (const clause of text.split(/[.;!?](?=\s|$)|\n/)) {
|
|
41
|
+
for (const pattern of REJECTED) {
|
|
42
|
+
const hit = pattern.exec(clause);
|
|
43
|
+
if (hit === null || NEGATION.test(clause.slice(0, hit.index + hit[0].length))) continue;
|
|
44
|
+
return `the addendum asks to get around the grading ("${hit[0]}")`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
var NEGATION = /\b(never|not|don't|do not|no|without)\b/i;
|
|
50
|
+
function groupRuns(results) {
|
|
51
|
+
const out = /* @__PURE__ */ new Map();
|
|
52
|
+
for (const r of results) out.set(r.id, [...out.get(r.id) ?? [], r]);
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
var asReport = (path, results, tasks) => ({
|
|
56
|
+
path,
|
|
57
|
+
schema: 2,
|
|
58
|
+
model: void 0,
|
|
59
|
+
seed: void 0,
|
|
60
|
+
tasks: tasks === void 0 ? void 0 : Object.fromEntries(tasks.map((t) => [t.id, taskHash(t)])),
|
|
61
|
+
results: [...results]
|
|
62
|
+
});
|
|
63
|
+
function decide(current, candidate, options) {
|
|
64
|
+
const passesCurrent = current.filter((r) => r.passed).length;
|
|
65
|
+
const passesCandidate = candidate.filter((r) => r.passed).length;
|
|
66
|
+
const runs = candidate.length;
|
|
67
|
+
const base = { passesCurrent, passesCandidate, runs };
|
|
68
|
+
const before = groupRuns(current);
|
|
69
|
+
const after = groupRuns(candidate);
|
|
70
|
+
const lost = [...before.entries()].filter(([, rs]) => rs.length > 0 && rs.every((r) => r.passed)).filter(([id]) => {
|
|
71
|
+
const now = after.get(id) ?? [];
|
|
72
|
+
return now.length > 0 && now.every((r) => !r.passed);
|
|
73
|
+
}).map(([id]) => id);
|
|
74
|
+
if (lost.length > 0) {
|
|
75
|
+
return {
|
|
76
|
+
...base,
|
|
77
|
+
kept: false,
|
|
78
|
+
reason: `dropped: ${lost.join(", ")} went from all runs passed to none`
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const compared = compareReports(asReport("current", current), asReport("candidate", candidate), {
|
|
82
|
+
seed: options.seed
|
|
83
|
+
});
|
|
84
|
+
const ratio = "problems" in compared || compared.comparison.costRatio === void 0 ? void 0 : compared.comparison.costRatio;
|
|
85
|
+
const costRatio = ratio === void 0 ? void 0 : { value: ratio.value, low: ratio.low, high: ratio.high };
|
|
86
|
+
const withCost = costRatio === void 0 ? base : { ...base, costRatio };
|
|
87
|
+
const gain = passesCandidate - passesCurrent;
|
|
88
|
+
if (gain >= options.margin) {
|
|
89
|
+
return {
|
|
90
|
+
...withCost,
|
|
91
|
+
kept: true,
|
|
92
|
+
reason: `kept: ${gain} more passing run(s) (margin ${options.margin})`
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (gain >= 0 && costRatio !== void 0 && costRatio.high < 1) {
|
|
96
|
+
return {
|
|
97
|
+
...withCost,
|
|
98
|
+
kept: true,
|
|
99
|
+
reason: `kept: as many passes or more, and cost per accepted change \xD7${costRatio.value.toFixed(2)} (95% interval \xD7${costRatio.low.toFixed(2)} to \xD7${costRatio.high.toFixed(2)})`
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const cost = costRatio === void 0 ? "cost ratio unknown" : `cost \xD7${costRatio.value.toFixed(2)} (\xD7${costRatio.low.toFixed(2)} to \xD7${costRatio.high.toFixed(2)})`;
|
|
103
|
+
return {
|
|
104
|
+
...withCost,
|
|
105
|
+
kept: false,
|
|
106
|
+
reason: `dropped: ${gain >= 0 ? "+" : ""}${gain} passing run(s) (margin ${options.margin}), ${cost}`
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function proposerInput(addendum, tasks, results, history) {
|
|
110
|
+
const prompts = new Map(tasks.map((t) => [t.id, t.prompt]));
|
|
111
|
+
const lines = [
|
|
112
|
+
"# The current addendum",
|
|
113
|
+
"",
|
|
114
|
+
addendum.trim() === "" ? "(empty)" : addendum.trim(),
|
|
115
|
+
""
|
|
116
|
+
];
|
|
117
|
+
const failed = results.filter((r) => !r.passed);
|
|
118
|
+
if (failed.length > 0) {
|
|
119
|
+
lines.push(`# Failed runs (${failed.length} of ${results.length})`, "");
|
|
120
|
+
for (const r of failed) {
|
|
121
|
+
const tail = (r.reason ?? "").split("\n").slice(-CHECK_TAIL_LINES).join("\n");
|
|
122
|
+
lines.push(
|
|
123
|
+
`## ${r.id} (run ${r.attempt ?? 1}): ${r.stopReason}, ${r.steps} steps`,
|
|
124
|
+
"",
|
|
125
|
+
"Task prompt:",
|
|
126
|
+
prompts.get(r.id) ?? "(unknown)",
|
|
127
|
+
"",
|
|
128
|
+
"Why it failed (last lines):",
|
|
129
|
+
"```",
|
|
130
|
+
tail,
|
|
131
|
+
"```",
|
|
132
|
+
...r.unexpected !== void 0 && r.unexpected.length > 0 ? ["", `Unexpected changes: ${r.unexpected.join(", ")}`] : [],
|
|
133
|
+
""
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
} else {
|
|
137
|
+
lines.push(`# Every run passed (${results.length}). Lower the cost: what each task took`, "");
|
|
138
|
+
for (const [id, rs] of groupRuns(results)) {
|
|
139
|
+
const mean = (f) => rs.reduce((s, r) => s + f(r), 0) / rs.length;
|
|
140
|
+
const costliest = [...rs].sort((a, b) => (b.costUsd ?? 0) - (a.costUsd ?? 0))[0];
|
|
141
|
+
lines.push(
|
|
142
|
+
`- ${id}: ${mean((r) => r.steps).toFixed(1)} steps, ${Math.round(mean((r) => r.tokens))} tokens, $${mean((r) => r.costUsd ?? 0).toFixed(4)} a run; tools of the costliest run: ${(costliest?.tools ?? []).join(", ") || "(none recorded)"}`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
lines.push("");
|
|
146
|
+
}
|
|
147
|
+
if (history.length > 0) {
|
|
148
|
+
lines.push("# Earlier proposals", "");
|
|
149
|
+
for (const h of history) {
|
|
150
|
+
lines.push(
|
|
151
|
+
`- round ${h.round} (${h.version}): ${h.rejected === void 0 ? h.decision?.reason ?? "" : `rejected before a run: ${h.rejected}`}. The proposer's reason: ${h.reason}`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
lines.push("");
|
|
155
|
+
}
|
|
156
|
+
return lines.join("\n");
|
|
157
|
+
}
|
|
158
|
+
var PROPOSER_SYSTEM = [
|
|
159
|
+
"You improve a coding agent. The agent gets a short text, the addendum, at the end of its system",
|
|
160
|
+
"prompt. You see the current addendum and the agent's results on development tasks. Write a",
|
|
161
|
+
"complete new addendum that should make the agent pass more tasks, or pass them at a lower cost.",
|
|
162
|
+
"",
|
|
163
|
+
"Rules:",
|
|
164
|
+
`- At most ${ADDENDUM_MAX_CHARS} characters. General advice about how to work, not about one task:`,
|
|
165
|
+
" the addendum is measured later on tasks you never see.",
|
|
166
|
+
"- Never tell the agent to skip, weaken or edit tests or checks, to touch protected files, or to",
|
|
167
|
+
" leave the sandbox. Such a text is refused without a run.",
|
|
168
|
+
"",
|
|
169
|
+
"Answer in exactly this form:",
|
|
170
|
+
"<addendum>",
|
|
171
|
+
"the complete new addendum",
|
|
172
|
+
"</addendum>",
|
|
173
|
+
"<reason>one paragraph: what you changed and why</reason>"
|
|
174
|
+
].join("\n");
|
|
175
|
+
function parseProposal(text) {
|
|
176
|
+
const addendum = /<addendum>\n?([\s\S]*?)\n?<\/addendum>/.exec(text)?.[1];
|
|
177
|
+
const reason = /<reason>([\s\S]*?)<\/reason>/.exec(text)?.[1];
|
|
178
|
+
if (addendum === void 0) return void 0;
|
|
179
|
+
return { addendum: addendum.trim(), reason: (reason ?? "").trim() };
|
|
180
|
+
}
|
|
181
|
+
var costOf = (results) => {
|
|
182
|
+
const c = costPerPass(results);
|
|
183
|
+
if (c.kind === "unknown") return void 0;
|
|
184
|
+
return results.reduce((s, r) => s + (r.costUsd ?? 0), 0);
|
|
185
|
+
};
|
|
186
|
+
async function tune(options) {
|
|
187
|
+
const history = [];
|
|
188
|
+
let spent = 0;
|
|
189
|
+
let current = options.start;
|
|
190
|
+
let version = 0;
|
|
191
|
+
await options.save("v0.md", current);
|
|
192
|
+
options.log(`Scoring v0 on ${options.devTasks.length} dev task(s) \xD7 ${options.repeat}.`);
|
|
193
|
+
let currentResults = await options.score(current, options.devTasks, options.repeat, "v0");
|
|
194
|
+
let lastScoreCost = costOf(currentResults);
|
|
195
|
+
if (lastScoreCost === void 0) {
|
|
196
|
+
return { final: current, history, spentUsd: spent, stopped: "unknown cost" };
|
|
197
|
+
}
|
|
198
|
+
spent += lastScoreCost;
|
|
199
|
+
let stopped = "rounds";
|
|
200
|
+
let lastProposalCost = 0;
|
|
201
|
+
for (let round = 1; round <= options.rounds; round++) {
|
|
202
|
+
if (spent + lastScoreCost + lastProposalCost > options.maxCostUsd) {
|
|
203
|
+
stopped = "cost";
|
|
204
|
+
options.log(
|
|
205
|
+
`Stopping before round ${round}: $${spent.toFixed(2)} spent, and the next round would pass --max-cost $${options.maxCostUsd}.`
|
|
206
|
+
);
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
const input = proposerInput(current, options.devTasks, currentResults, history);
|
|
210
|
+
const name = `v${round}`;
|
|
211
|
+
await options.save(`${name}.input.md`, input);
|
|
212
|
+
let proposal = await options.propose(input);
|
|
213
|
+
if (proposal.costUsd === void 0) {
|
|
214
|
+
stopped = "unknown cost";
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
let proposalCost = proposal.costUsd;
|
|
218
|
+
let rejected = rejectReason(proposal.addendum);
|
|
219
|
+
let refusedFirst;
|
|
220
|
+
if (rejected !== void 0) {
|
|
221
|
+
refusedFirst = rejected;
|
|
222
|
+
await options.save(`${name}.refused.md`, proposal.addendum);
|
|
223
|
+
options.log(`Round ${round}: ${name} refused (${rejected}); asking once more.`);
|
|
224
|
+
const again = await options.propose(
|
|
225
|
+
`${input}
|
|
226
|
+
# Your last answer was refused
|
|
227
|
+
|
|
228
|
+
${rejected}. Write the complete addendum again without that phrase. Do not tell the agent to skip, change or delete tests or checks, even as an example of what to avoid.
|
|
229
|
+
`
|
|
230
|
+
);
|
|
231
|
+
if (again.costUsd === void 0) {
|
|
232
|
+
stopped = "unknown cost";
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
proposalCost += again.costUsd;
|
|
236
|
+
proposal = again;
|
|
237
|
+
rejected = rejectReason(proposal.addendum);
|
|
238
|
+
}
|
|
239
|
+
spent += proposalCost;
|
|
240
|
+
lastProposalCost = proposalCost;
|
|
241
|
+
await options.save(`${name}.md`, proposal.addendum);
|
|
242
|
+
if (rejected !== void 0) {
|
|
243
|
+
history.push({
|
|
244
|
+
round,
|
|
245
|
+
version: name,
|
|
246
|
+
reason: proposal.reason,
|
|
247
|
+
rejected,
|
|
248
|
+
costUsd: proposalCost
|
|
249
|
+
});
|
|
250
|
+
options.log(`Round ${round}: ${name} rejected before a run: ${rejected}.`);
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
options.log(`Round ${round}: scoring ${name}.`);
|
|
254
|
+
const candidate = await options.score(
|
|
255
|
+
proposal.addendum,
|
|
256
|
+
options.devTasks,
|
|
257
|
+
options.repeat,
|
|
258
|
+
name
|
|
259
|
+
);
|
|
260
|
+
const scoreCost = costOf(candidate);
|
|
261
|
+
if (scoreCost === void 0) {
|
|
262
|
+
stopped = "unknown cost";
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
spent += scoreCost;
|
|
266
|
+
lastScoreCost = scoreCost;
|
|
267
|
+
const decision = decide(currentResults, candidate, {
|
|
268
|
+
margin: options.margin,
|
|
269
|
+
seed: options.seed
|
|
270
|
+
});
|
|
271
|
+
history.push({
|
|
272
|
+
round,
|
|
273
|
+
version: name,
|
|
274
|
+
reason: proposal.reason,
|
|
275
|
+
decision,
|
|
276
|
+
costUsd: proposalCost + scoreCost,
|
|
277
|
+
...refusedFirst === void 0 ? {} : { refusedFirst }
|
|
278
|
+
});
|
|
279
|
+
options.log(`Round ${round}: ${name} ${decision.reason}.`);
|
|
280
|
+
if (decision.kept) {
|
|
281
|
+
current = proposal.addendum;
|
|
282
|
+
currentResults = candidate;
|
|
283
|
+
version = round;
|
|
284
|
+
}
|
|
285
|
+
await options.save("history.json", `${JSON.stringify(history, null, 2)}
|
|
286
|
+
`);
|
|
287
|
+
}
|
|
288
|
+
await options.save("history.json", `${JSON.stringify(history, null, 2)}
|
|
289
|
+
`);
|
|
290
|
+
await options.save("final.md", current);
|
|
291
|
+
let heldOut;
|
|
292
|
+
if (options.heldOutTasks.length > 0 && version > 0) {
|
|
293
|
+
options.log(
|
|
294
|
+
`Held-out: the empty addendum (A) against v${version} (B), \xD7 ${options.heldoutRepeat}.`
|
|
295
|
+
);
|
|
296
|
+
const a = await options.score("", options.heldOutTasks, options.heldoutRepeat, "heldout-empty");
|
|
297
|
+
const b = await options.score(
|
|
298
|
+
current,
|
|
299
|
+
options.heldOutTasks,
|
|
300
|
+
options.heldoutRepeat,
|
|
301
|
+
"heldout-final"
|
|
302
|
+
);
|
|
303
|
+
spent += (costOf(a) ?? 0) + (costOf(b) ?? 0);
|
|
304
|
+
const ra = asReport("held-out, empty addendum", a, options.heldOutTasks);
|
|
305
|
+
const rb = asReport(`held-out, v${version}`, b, options.heldOutTasks);
|
|
306
|
+
const compared = compareReports(ra, rb, { seed: options.seed });
|
|
307
|
+
heldOut = "problems" in compared ? compared.problems.join("\n") : formatComparison(ra, rb, compared.comparison);
|
|
308
|
+
await options.save("heldout.txt", `${heldOut}
|
|
309
|
+
`);
|
|
310
|
+
} else if (version === 0) {
|
|
311
|
+
options.log("No version was kept: no held-out measurement.");
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
final: current,
|
|
315
|
+
history,
|
|
316
|
+
spentUsd: spent,
|
|
317
|
+
stopped,
|
|
318
|
+
...heldOut === void 0 ? {} : { heldOut }
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export {
|
|
323
|
+
ADDENDUM_MAX_CHARS,
|
|
324
|
+
readAddendum,
|
|
325
|
+
rejectReason,
|
|
326
|
+
decide,
|
|
327
|
+
proposerInput,
|
|
328
|
+
PROPOSER_SYSTEM,
|
|
329
|
+
parseProposal,
|
|
330
|
+
tune
|
|
331
|
+
};
|
|
332
|
+
//# sourceMappingURL=chunk-FOPBOB7W.js.map
|