@ordewell/core 0.10.8 → 0.10.10
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/{IFileSystem-C4_mpfze.d.ts → IFileSystem-1PqRCjhu.d.mts} +23 -3
- package/dist/{IFileSystem-DUgeWWQN.d.mts → IFileSystem-lTRL_G9Z.d.ts} +23 -3
- package/dist/{ModeResolver-4qNjxcDs.d.mts → ModeResolver-6TQXVsde.d.mts} +1 -1
- package/dist/{ModeResolver-DGK2rWHE.d.ts → ModeResolver-CoJAJD-f.d.ts} +1 -1
- package/dist/{Task-C0o4i3Nn.d.mts → Task-CfBM0wkV.d.mts} +100 -24
- package/dist/{Task-C0o4i3Nn.d.ts → Task-CfBM0wkV.d.ts} +100 -24
- package/dist/{chunk-H7QX32BH.mjs → chunk-24EL4Z2W.mjs} +2 -2
- package/dist/{chunk-DMG4ISUG.mjs → chunk-ESKK5I4F.mjs} +145 -21
- package/dist/chunk-ESKK5I4F.mjs.map +1 -0
- package/dist/{chunk-LTHKFBKM.mjs → chunk-KWS3VEER.mjs} +3 -3
- package/dist/{chunk-EEE2GBLG.mjs → chunk-PFH7WFIB.mjs} +1 -1
- package/dist/chunk-PFH7WFIB.mjs.map +1 -0
- package/dist/index.d.mts +145 -20
- package/dist/index.d.ts +145 -20
- package/dist/index.js +668 -112
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +537 -96
- package/dist/index.mjs.map +1 -1
- package/dist/parsing.d.mts +2 -2
- package/dist/parsing.d.ts +2 -2
- package/dist/parsing.js.map +1 -1
- package/dist/parsing.mjs +3 -3
- package/dist/plan-utils.d.mts +4 -4
- package/dist/plan-utils.d.ts +4 -4
- package/dist/plan-utils.js +144 -18
- package/dist/plan-utils.js.map +1 -1
- package/dist/plan-utils.mjs +22 -4
- package/dist/{runSettingsText-BgOmLxdw.d.mts → runSettingsText-C1i9wBG1.d.mts} +61 -21
- package/dist/{runSettingsText-BgXvajj2.d.ts → runSettingsText-CWNrmF5U.d.ts} +61 -21
- package/dist/testing.d.mts +7 -2
- package/dist/testing.d.ts +7 -2
- package/dist/testing.js +11 -0
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +12 -1
- package/dist/testing.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-DMG4ISUG.mjs.map +0 -1
- package/dist/chunk-EEE2GBLG.mjs.map +0 -1
- /package/dist/{chunk-H7QX32BH.mjs.map → chunk-24EL4Z2W.mjs.map} +0 -0
- /package/dist/{chunk-LTHKFBKM.mjs.map → chunk-KWS3VEER.mjs.map} +0 -0
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
stripTrailingCommas,
|
|
16
16
|
taggedReadOnlyMode,
|
|
17
17
|
taskWhere
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-24EL4Z2W.mjs";
|
|
19
19
|
import {
|
|
20
20
|
addTaskToPlan,
|
|
21
21
|
canSetDependencies,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
titledTaskRefOf,
|
|
37
37
|
updateTaskInPlan,
|
|
38
38
|
walkPlan
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-PFH7WFIB.mjs";
|
|
40
40
|
|
|
41
41
|
// src/models/Usage.ts
|
|
42
42
|
function partedPromptUsage(parts) {
|
|
@@ -55,25 +55,66 @@ function addUsage(totals, record) {
|
|
|
55
55
|
}
|
|
56
56
|
if (record.reportedCost) {
|
|
57
57
|
const { amount, currency } = record.reportedCost;
|
|
58
|
-
|
|
58
|
+
const provenance = record.reportedCost.kind || record.sessionBilling ? {
|
|
59
|
+
kind: record.reportedCost.kind ?? "unknown",
|
|
60
|
+
billing: record.sessionBilling?.type ?? "unknown",
|
|
61
|
+
...record.reportedCost.basis ? { basis: record.reportedCost.basis } : {}
|
|
62
|
+
} : void 0;
|
|
63
|
+
addCost(next, currency, amount, provenance);
|
|
59
64
|
}
|
|
60
65
|
return next;
|
|
61
66
|
}
|
|
67
|
+
function addCost(totals, currency, amount, provenance) {
|
|
68
|
+
const hadCost = totals.reportedCost?.[currency] !== void 0;
|
|
69
|
+
const previous = totals.costProvenance?.[currency];
|
|
70
|
+
totals.reportedCost = { ...totals.reportedCost, [currency]: (totals.reportedCost?.[currency] ?? 0) + amount };
|
|
71
|
+
if (!previous && !provenance) return;
|
|
72
|
+
const unknown = { kind: "unknown", billing: "unknown" };
|
|
73
|
+
const a = previous ?? unknown;
|
|
74
|
+
const b = provenance ?? unknown;
|
|
75
|
+
const merged = !hadCost ? b : {
|
|
76
|
+
kind: a.kind === "estimate" || b.kind === "estimate" ? "estimate" : a.kind === "billed" && b.kind === "billed" ? "billed" : "unknown",
|
|
77
|
+
billing: a.billing === b.billing ? a.billing : "mixed",
|
|
78
|
+
...a.basis && a.basis === b.basis ? { basis: a.basis } : {}
|
|
79
|
+
};
|
|
80
|
+
totals.costProvenance = { ...totals.costProvenance, [currency]: merged };
|
|
81
|
+
}
|
|
62
82
|
function addPlannerUsage(usage, record) {
|
|
63
|
-
|
|
83
|
+
if (record.compacted) {
|
|
84
|
+
if (record.subagentId || record.aggregate) return usage;
|
|
85
|
+
const next2 = { ...usage };
|
|
86
|
+
if (record.source !== void 0) next2.source = record.source;
|
|
87
|
+
if (record.model !== void 0) {
|
|
88
|
+
if (record.source !== usage.source || record.model !== usage.model) delete next2.contextWindow;
|
|
89
|
+
next2.model = record.model;
|
|
90
|
+
}
|
|
91
|
+
if (record.contextTokens !== void 0) next2.lastPromptTokens = record.contextTokens;
|
|
92
|
+
else delete next2.lastPromptTokens;
|
|
93
|
+
if (record.contextWindow !== void 0) next2.contextWindow = record.contextWindow > 0 ? record.contextWindow : void 0;
|
|
94
|
+
return next2;
|
|
95
|
+
}
|
|
96
|
+
if (record.sessionBilling && !record.reportedCost && record.inputTokens === void 0 && record.outputTokens === void 0 && record.cachedInputTokens === void 0 && record.contextWindow === void 0) {
|
|
97
|
+
return record.subagentId ? usage : { ...usage, sessionBilling: record.sessionBilling, source: record.source };
|
|
98
|
+
}
|
|
99
|
+
record = { ...record, sessionBilling: record.sessionBilling ?? (usage.source === void 0 || record.source === usage.source ? usage.sessionBilling : void 0) };
|
|
100
|
+
const next = { ...usage, ...!record.subagentId && record.sessionBilling ? { sessionBilling: record.sessionBilling } : {}, totals: addUsage(usage.totals, record), byModel: addModelUsage(usage.byModel ?? [], record) };
|
|
64
101
|
if (record.subagentId) {
|
|
65
102
|
next.bySubagent = { ...usage.bySubagent, [record.subagentId]: addUsage(usage.bySubagent?.[record.subagentId] ?? {}, record) };
|
|
66
103
|
return next;
|
|
67
104
|
}
|
|
68
|
-
if (
|
|
69
|
-
if (record.source !== usage.source
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
next.
|
|
74
|
-
next.
|
|
105
|
+
if (record.aggregate) {
|
|
106
|
+
if (record.source !== usage.source && !record.sessionBilling) delete next.sessionBilling;
|
|
107
|
+
return next;
|
|
108
|
+
}
|
|
109
|
+
if (record.source !== usage.source || record.model !== usage.model) {
|
|
110
|
+
delete next.lastPromptTokens;
|
|
111
|
+
delete next.contextWindow;
|
|
75
112
|
}
|
|
76
|
-
if (record.
|
|
113
|
+
if (record.source !== usage.source && !record.sessionBilling) delete next.sessionBilling;
|
|
114
|
+
next.source = record.source;
|
|
115
|
+
next.model = record.model;
|
|
116
|
+
const used = record.contextTokens ?? record.inputTokens;
|
|
117
|
+
if (used !== void 0) next.lastPromptTokens = used;
|
|
77
118
|
if (record.contextWindow !== void 0) next.contextWindow = record.contextWindow > 0 ? record.contextWindow : void 0;
|
|
78
119
|
return next;
|
|
79
120
|
}
|
|
@@ -84,6 +125,7 @@ function usageLine(usage) {
|
|
|
84
125
|
const contextFill = plannerContextFill(usage);
|
|
85
126
|
return {
|
|
86
127
|
totals: usage.totals,
|
|
128
|
+
...usage.sessionBilling ? { sessionBilling: usage.sessionBilling } : {},
|
|
87
129
|
...usage.byModel ? { byModel: usage.byModel } : {},
|
|
88
130
|
...usage.model ? { model: usage.model } : {},
|
|
89
131
|
...usage.bySubagent ? { bySubagent: usage.bySubagent } : {},
|
|
@@ -91,8 +133,8 @@ function usageLine(usage) {
|
|
|
91
133
|
};
|
|
92
134
|
}
|
|
93
135
|
function plannerContextFill(usage) {
|
|
94
|
-
if (usage.lastPromptTokens === void 0
|
|
95
|
-
return { usedTokens: usage.lastPromptTokens, windowTokens: usage.contextWindow };
|
|
136
|
+
if (usage.lastPromptTokens === void 0) return void 0;
|
|
137
|
+
return { usedTokens: usage.lastPromptTokens, ...usage.contextWindow !== void 0 && usage.contextWindow > 0 ? { windowTokens: usage.contextWindow } : {} };
|
|
96
138
|
}
|
|
97
139
|
function addModelUsage(models, record) {
|
|
98
140
|
const index = models.findIndex((m) => m.source === record.source && m.model === record.model);
|
|
@@ -104,13 +146,14 @@ function startAttemptUsage(attempt, runner, startedAt) {
|
|
|
104
146
|
}
|
|
105
147
|
function addAttemptUsage(usage, record, now) {
|
|
106
148
|
const folded = addPlannerUsage(usage, record);
|
|
107
|
-
return { ...usage, ...folded, lastPromptTokens: folded.lastPromptTokens, contextWindow: folded.contextWindow, wallTimeMs: Math.max(0, Date.parse(now) - Date.parse(usage.startedAt)) };
|
|
149
|
+
return { ...usage, ...folded, lastPromptTokens: folded.lastPromptTokens, contextWindow: folded.contextWindow, wallTimeMs: Math.max(0, Date.parse(usage.endedAt ?? now) - Date.parse(usage.startedAt)) };
|
|
108
150
|
}
|
|
109
151
|
function endAttemptUsage(usage, now, runnerSessionCost, sessionId) {
|
|
152
|
+
const endedAt = usage.endedAt ?? now;
|
|
110
153
|
return {
|
|
111
154
|
...usage,
|
|
112
|
-
endedAt
|
|
113
|
-
wallTimeMs: Math.max(0, Date.parse(
|
|
155
|
+
endedAt,
|
|
156
|
+
wallTimeMs: Math.max(0, Date.parse(endedAt) - Date.parse(usage.startedAt)),
|
|
114
157
|
...sessionId ? { sessionId } : {},
|
|
115
158
|
...runnerSessionCost ? { runnerSessionCost } : {}
|
|
116
159
|
};
|
|
@@ -123,8 +166,8 @@ function resumedSessionWindow(attempts, runner, attempt, sessionId) {
|
|
|
123
166
|
return last ? { source: last.source, model: last.model, contextWindow: last.contextWindow } : void 0;
|
|
124
167
|
}
|
|
125
168
|
function addUsageTotals(totals, addition) {
|
|
126
|
-
|
|
127
|
-
for (const [currency, amount] of Object.entries(addition.reportedCost ?? {}))
|
|
169
|
+
const next = addUsage(totals, { source: "", inputTokens: addition.inputTokens, outputTokens: addition.outputTokens, cachedInputTokens: addition.cachedInputTokens });
|
|
170
|
+
for (const [currency, amount] of Object.entries(addition.reportedCost ?? {})) addCost(next, currency, amount, addition.costProvenance?.[currency]);
|
|
128
171
|
return next;
|
|
129
172
|
}
|
|
130
173
|
function planUsage(tasks) {
|
|
@@ -159,6 +202,71 @@ function taskUsageSummary(task) {
|
|
|
159
202
|
...contextFill ? { contextFill } : {}
|
|
160
203
|
};
|
|
161
204
|
}
|
|
205
|
+
function formatTokenCount(n) {
|
|
206
|
+
if (n < 1e3) return String(n);
|
|
207
|
+
if (n < 1e4) return `${(n / 1e3).toFixed(1).replace(/\.0$/, "")}k`;
|
|
208
|
+
if (n < 999500) return `${Math.round(n / 1e3)}k`;
|
|
209
|
+
return `${(n / 1e6).toFixed(1).replace(/\.0$/, "")}M`;
|
|
210
|
+
}
|
|
211
|
+
function formatCost(currency, amount) {
|
|
212
|
+
const value = amount >= 1 ? amount.toFixed(2) : (([whole, frac = ""]) => `${whole}.${frac.padEnd(2, "0")}`)(amount.toFixed(4).replace(/0+$/, "").split("."));
|
|
213
|
+
return currency.toLowerCase() === "usd" ? `$${value}` : `${value} ${currency.toUpperCase()}`;
|
|
214
|
+
}
|
|
215
|
+
function contextMeterText(fill) {
|
|
216
|
+
if (!fill) return null;
|
|
217
|
+
const used = `ctx ${formatTokenCount(fill.usedTokens)}`;
|
|
218
|
+
if (!fill.windowTokens) return used;
|
|
219
|
+
const share = fill.usedTokens / fill.windowTokens * 100;
|
|
220
|
+
return `${used} (${share < 1 ? "<1" : Math.round(share)}%)`;
|
|
221
|
+
}
|
|
222
|
+
function contextMeterTitle(fill) {
|
|
223
|
+
const used = fill.usedTokens.toLocaleString("en-US");
|
|
224
|
+
return fill.windowTokens ? `${used} of ${fill.windowTokens.toLocaleString("en-US")} tokens` : `${used} tokens`;
|
|
225
|
+
}
|
|
226
|
+
function costParts(totals) {
|
|
227
|
+
const rank = (currency) => currency.toLowerCase() === "usd" ? "" : currency.toUpperCase();
|
|
228
|
+
return Object.entries(totals.reportedCost ?? {}).sort(([a], [b]) => rank(a).localeCompare(rank(b))).map(([currency, amount]) => {
|
|
229
|
+
const provenance = totals.costProvenance?.[currency];
|
|
230
|
+
const equivalent = provenance?.billing === "subscription";
|
|
231
|
+
return `${provenance?.kind === "estimate" || equivalent ? "\u2248" : ""}${formatCost(currency, amount)}${equivalent ? " API-equivalent" : ""}`;
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
function costText(totals) {
|
|
235
|
+
const parts = costParts(totals);
|
|
236
|
+
return parts.length > 0 ? parts.join(" \xB7 ") : null;
|
|
237
|
+
}
|
|
238
|
+
function usageText(usage) {
|
|
239
|
+
const parts = [contextMeterText(usage.contextFill), costText(usage.totals)].filter((p) => p !== null);
|
|
240
|
+
return parts.length > 0 ? parts.join(" \xB7 ") : null;
|
|
241
|
+
}
|
|
242
|
+
function modelCostTitle(byModel) {
|
|
243
|
+
const lines2 = byModel.flatMap((m) => {
|
|
244
|
+
const cost = costParts(m.totals);
|
|
245
|
+
const descriptions = [...new Set(Object.values(m.totals.costProvenance ?? {}).map((p) => {
|
|
246
|
+
const source = m.source === "claude-code" ? "Claude Code" : m.source === "opencode" ? "OpenCode" : m.source === "openrouter" ? "OpenRouter" : m.source;
|
|
247
|
+
const basis = p.basis === "list" ? " at list price" : p.basis === "managed" ? " at managed price" : "";
|
|
248
|
+
const kind = p.kind === "estimate" ? `${source}'s estimate${basis}` : p.kind === "billed" ? `Amount billed by ${source}` : "Reported cost";
|
|
249
|
+
return `${kind}${p.billing === "subscription" ? "; not billed on a subscription" : ""}`;
|
|
250
|
+
}))];
|
|
251
|
+
return cost.length > 0 ? [`${m.source} / ${m.model ?? "unattributed"}: ${cost.join(" \xB7 ")}${descriptions.length ? ` \u2014 ${descriptions.join("; ")}` : ""}`] : [];
|
|
252
|
+
});
|
|
253
|
+
return lines2.length > 0 ? lines2.join("\n") : void 0;
|
|
254
|
+
}
|
|
255
|
+
function subagentCostTitle(bySubagent) {
|
|
256
|
+
return Object.entries(bySubagent).map(([id, totals]) => `${id}: ${costParts(totals).join(" \xB7 ") || "reported no cost"}`).join("\n");
|
|
257
|
+
}
|
|
258
|
+
function runnersOf(tasks) {
|
|
259
|
+
return tasks.flatMap((task) => [...task.attemptUsage ?? [], ...runnersOf(task.subtasks ?? [])]);
|
|
260
|
+
}
|
|
261
|
+
function tasksTotalText(tasks) {
|
|
262
|
+
const attempts = runnersOf(tasks);
|
|
263
|
+
if (attempts.length === 0) return null;
|
|
264
|
+
const costed = (a) => Object.keys(a.totals.reportedCost ?? {}).length > 0;
|
|
265
|
+
const costless = [...new Set(attempts.filter((a) => a.endedAt !== void 0 && isMeasured(a.totals)).map((a) => a.runner))].filter((runner) => !attempts.some((a) => a.runner === runner && costed(a)));
|
|
266
|
+
const note = costless.length === 0 ? [] : [`${costless.length === 1 ? costless[0] : `${costless.slice(0, -1).join(", ")} and ${costless.at(-1)}`} ${costless.length === 1 ? "reports" : "report"} no cost`];
|
|
267
|
+
const parts = [...costParts(planUsage(tasks).totals), ...note];
|
|
268
|
+
return parts.length > 0 ? `Tasks total: ${parts.join(" \xB7 ")}` : null;
|
|
269
|
+
}
|
|
162
270
|
|
|
163
271
|
// src/services/harness/agentTools.ts
|
|
164
272
|
var KNOWN_TOOLS = {
|
|
@@ -1972,6 +2080,12 @@ function withoutIsolation(tasks) {
|
|
|
1972
2080
|
function handoffOf({ type: _type, ...handoff }) {
|
|
1973
2081
|
return handoff;
|
|
1974
2082
|
}
|
|
2083
|
+
function stillToMerge(handoff, runMerge) {
|
|
2084
|
+
if (!handoff?.landed.length) return handoff;
|
|
2085
|
+
if (!runMerge) return null;
|
|
2086
|
+
const same = runMerge.landed.length === handoff.landed.length && runMerge.landed.every((t, i) => t.taskId === handoff.landed[i].taskId);
|
|
2087
|
+
return same ? handoff : { ...handoff, repos: runMerge.repos, landed: runMerge.landed };
|
|
2088
|
+
}
|
|
1975
2089
|
function planTasks(plan) {
|
|
1976
2090
|
if ("tasks" in plan) return plan.tasks;
|
|
1977
2091
|
return rejoinPlanTree(plan.pendingTasks, plan.phase === "executing" ? plan.executionLog : []);
|
|
@@ -1992,6 +2106,7 @@ function reduceRun(view, input) {
|
|
|
1992
2106
|
...view,
|
|
1993
2107
|
tasks: applyStatus(view.tasks, new Map(input.tasks.map((t) => [t.id, t]))),
|
|
1994
2108
|
runMerge: input.runMerge ?? null,
|
|
2109
|
+
handoff: stillToMerge(view.handoff, input.runMerge),
|
|
1995
2110
|
usage: input.usage
|
|
1996
2111
|
};
|
|
1997
2112
|
case "task_started":
|
|
@@ -2068,7 +2183,7 @@ function openTurn(view, { turnId, prompt = "", skills = [], wakeUps = [], forced
|
|
|
2068
2183
|
wakeUps = wakeUps.slice(adopted.wakeUps);
|
|
2069
2184
|
if (wakeUps.length === 0) return adopted.prompt || prompt === "" && adopted.wakeUps > 0 ? view : promptLine(view, turnId, prompt, skills, forced);
|
|
2070
2185
|
const said = prompt === "" || adopted.prompt ? view : promptLine(view, turnId, prompt, skills, forced);
|
|
2071
|
-
const at = prompt === "" ? said.blocks.length : findLastIndex(said.blocks, (b) => b.type === "message" && b.role === "user" && b.turnId === turnId);
|
|
2186
|
+
const at = prompt === "" ? said.blocks.length - (said.blocks.at(-1)?.type === "usage" ? 1 : 0) : findLastIndex(said.blocks, (b) => b.type === "message" && b.role === "user" && b.turnId === turnId);
|
|
2072
2187
|
const updates = wakeUps.map((text2, n) => settledMessage(`b${said.nextId + n}`, "wake_up", text2, turnId));
|
|
2073
2188
|
return { ...said, blocks: [...said.blocks.slice(0, at), ...updates, ...said.blocks.slice(at)], nextId: said.nextId + updates.length };
|
|
2074
2189
|
}
|
|
@@ -2742,6 +2857,15 @@ export {
|
|
|
2742
2857
|
addUsageTotals,
|
|
2743
2858
|
planUsage,
|
|
2744
2859
|
taskUsageSummary,
|
|
2860
|
+
formatTokenCount,
|
|
2861
|
+
formatCost,
|
|
2862
|
+
contextMeterText,
|
|
2863
|
+
contextMeterTitle,
|
|
2864
|
+
costText,
|
|
2865
|
+
usageText,
|
|
2866
|
+
modelCostTitle,
|
|
2867
|
+
subagentCostTitle,
|
|
2868
|
+
tasksTotalText,
|
|
2745
2869
|
sameMessage,
|
|
2746
2870
|
mapAgentTool,
|
|
2747
2871
|
normalizeAgentArgs,
|
|
@@ -2835,4 +2959,4 @@ export {
|
|
|
2835
2959
|
pastGateConfirmation,
|
|
2836
2960
|
newTaskFields
|
|
2837
2961
|
};
|
|
2838
|
-
//# sourceMappingURL=chunk-
|
|
2962
|
+
//# sourceMappingURL=chunk-ESKK5I4F.mjs.map
|