clementine-agent 1.18.88 → 1.18.90
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/cli/cron.js +3 -0
- package/dist/cli/dashboard.js +141 -5
- package/dist/gateway/cron-scheduler.js +6 -0
- package/dist/gateway/router.d.ts +2 -0
- package/dist/gateway/router.js +1 -0
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
package/dist/cli/cron.js
CHANGED
|
@@ -149,6 +149,7 @@ export async function cmdCronRun(jobName) {
|
|
|
149
149
|
// to the Event store.
|
|
150
150
|
const sideChannel = gateway.consumeLastCronRunMetadata?.();
|
|
151
151
|
const runIdFromGateway = sideChannel?.runId;
|
|
152
|
+
const totalCostFromGateway = sideChannel?.totalCostUsd;
|
|
152
153
|
const entry = {
|
|
153
154
|
jobName: job.name,
|
|
154
155
|
startedAt: startedAt.toISOString(),
|
|
@@ -159,6 +160,8 @@ export async function cmdCronRun(jobName) {
|
|
|
159
160
|
outputPreview: response ? response.slice(0, 200) : undefined,
|
|
160
161
|
trigger,
|
|
161
162
|
...(runIdFromGateway ? { id: runIdFromGateway } : {}),
|
|
163
|
+
// 1.18.89: per-run cost for the dashboard Cost column / Health Strip tile.
|
|
164
|
+
...(totalCostFromGateway != null ? { totalCostUsd: totalCostFromGateway } : {}),
|
|
162
165
|
};
|
|
163
166
|
// PRD Phase 1.1: goal-orientation evaluator (mirrors the daemon path).
|
|
164
167
|
if (job.successSchema || (job.successCriteriaText && job.successCriteriaText.trim())) {
|
package/dist/cli/dashboard.js
CHANGED
|
@@ -20217,7 +20217,10 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
20217
20217
|
<h4>What it does</h4>
|
|
20218
20218
|
<p class="cron-section-desc">The instruction the agent receives. Long prompts are fine — drag the corner to resize.</p>
|
|
20219
20219
|
<div class="form-group">
|
|
20220
|
-
<label class="form-label">
|
|
20220
|
+
<label class="form-label" style="display:flex;align-items:center;gap:8px">
|
|
20221
|
+
Prompt
|
|
20222
|
+
<a href="#" id="cron-prompt-history-link" onclick="event.preventDefault();openPromptHistory()" style="display:none;font-size:11px;font-weight:normal;color:var(--text-muted);text-decoration:none;border-bottom:1px dotted var(--border)">View prompt history</a>
|
|
20223
|
+
</label>
|
|
20221
20224
|
<textarea id="cron-prompt" class="cron-prompt-textarea" placeholder="What should the AI do when this task runs?"></textarea>
|
|
20222
20225
|
<div class="form-hint">The instruction sent to the AI agent when this task fires.</div>
|
|
20223
20226
|
</div>
|
|
@@ -20450,6 +20453,29 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
20450
20453
|
|
|
20451
20454
|
<!-- (legacy standalone Preview modal removed in 1.18.70 — preview now lives as a tab inside the cron modal) -->
|
|
20452
20455
|
|
|
20456
|
+
<!-- ═══ Prompt History Modal — PRD §11 / 1.18.90 ═══
|
|
20457
|
+
Lists every past prompt revision for the currently-edited task.
|
|
20458
|
+
Each row shows ts + changedBy + a preview, expandable to full
|
|
20459
|
+
content. "Restore" copies the old prompt back into the editor —
|
|
20460
|
+
it does NOT auto-save, so the user reviews + clicks Save Changes
|
|
20461
|
+
to commit. The current draft in the editor is preserved if the
|
|
20462
|
+
user closes without restoring. -->
|
|
20463
|
+
<div class="modal-overlay" id="prompt-history-modal">
|
|
20464
|
+
<div class="modal" style="max-width:720px;width:96vw;max-height:88vh;display:flex;flex-direction:column">
|
|
20465
|
+
<div class="modal-header">
|
|
20466
|
+
<h3>Prompt history</h3>
|
|
20467
|
+
<button class="btn-ghost btn-sm" onclick="closePromptHistory()">×</button>
|
|
20468
|
+
</div>
|
|
20469
|
+
<div class="modal-body" style="padding:0;flex:1;min-height:0;overflow-y:auto">
|
|
20470
|
+
<div id="prompt-history-list" style="padding:18px"></div>
|
|
20471
|
+
</div>
|
|
20472
|
+
<div class="modal-footer">
|
|
20473
|
+
<span style="flex:1;font-size:11px;color:var(--text-muted)">Restore copies a version into the editor. You still need to click <strong>Save Changes</strong> to commit it.</span>
|
|
20474
|
+
<button onclick="closePromptHistory()">Close</button>
|
|
20475
|
+
</div>
|
|
20476
|
+
</div>
|
|
20477
|
+
</div>
|
|
20478
|
+
|
|
20453
20479
|
<!-- ═══ MCP Server Edit Modal — PRD Phase 2.1 ═══ -->
|
|
20454
20480
|
<div class="modal-overlay" id="mcp-edit-modal">
|
|
20455
20481
|
<div class="modal" style="max-width:640px;width:96vw">
|
|
@@ -23835,9 +23861,24 @@ async function refreshHealthStrip() {
|
|
|
23835
23861
|
: successRate >= 95 ? 'var(--green)'
|
|
23836
23862
|
: successRate >= 80 ? 'var(--yellow)'
|
|
23837
23863
|
: 'var(--red)';
|
|
23864
|
+
// 1.18.89: cost tile. Sums totalCostUsd across the 24h window. Runs that
|
|
23865
|
+
// pre-date 1.18.89 don't have the field — they contribute 0 (the user
|
|
23866
|
+
// sees a partial number that grows as new runs land).
|
|
23867
|
+
var totalCost = 0;
|
|
23868
|
+
var runsWithCost = 0;
|
|
23869
|
+
for (var ci = 0; ci < last24.length; ci++) {
|
|
23870
|
+
if (typeof last24[ci].totalCostUsd === 'number') {
|
|
23871
|
+
totalCost += last24[ci].totalCostUsd;
|
|
23872
|
+
runsWithCost++;
|
|
23873
|
+
}
|
|
23874
|
+
}
|
|
23875
|
+
var costLabel = runsWithCost === 0 ? '—' : (totalCost < 0.01 ? '$' + totalCost.toFixed(4) : '$' + totalCost.toFixed(2));
|
|
23876
|
+
var costSub = runsWithCost === 0 ? 'no priced runs yet' : runsWithCost + ' of ' + last24.length + ' runs priced';
|
|
23877
|
+
|
|
23838
23878
|
var html = '';
|
|
23839
23879
|
html += tile('Runs · 24h', last24.length, ok + ' ok · ' + failed + ' failed');
|
|
23840
23880
|
html += tile('Success rate', successRate === null ? '—' : (successRate + '%'), null, srColor);
|
|
23881
|
+
html += tile('Cost · 24h', costLabel, costSub);
|
|
23841
23882
|
html += tile('P50 latency', p50 === null ? '—' : formatDurationMs(p50), 'median run time');
|
|
23842
23883
|
html += tile('P95 latency', p95 === null ? '—' : formatDurationMs(p95), '95th percentile');
|
|
23843
23884
|
html += tile('Running now', activeRuns, activeRuns === 0 ? 'idle' : 'live');
|
|
@@ -23981,10 +24022,10 @@ function renderRunListBody(allRuns) {
|
|
|
23981
24022
|
return html;
|
|
23982
24023
|
}
|
|
23983
24024
|
// Table — same shape as the Recent History list on the Tasks page,
|
|
23984
|
-
// but sortable and with a Trigger column.
|
|
24025
|
+
// but sortable and with a Trigger + Cost column.
|
|
23985
24026
|
html += '<div style="background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius)">';
|
|
23986
|
-
html += '<div style="display:grid;grid-template-columns:24px 24px minmax(180px,1.2fr)
|
|
23987
|
-
+ '<div></div><div title="Goal verdict">Goal</div><div>Task</div><div>Trigger</div><div>Started</div><div>Duration</div><div></div>'
|
|
24027
|
+
html += '<div style="display:grid;grid-template-columns:24px 24px minmax(180px,1.2fr) 80px minmax(160px,1fr) 70px 70px auto;gap:10px;padding:8px 14px;border-bottom:1px solid var(--border);font-size:11px;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.04em;font-weight:500">'
|
|
24028
|
+
+ '<div></div><div title="Goal verdict">Goal</div><div>Task</div><div>Trigger</div><div>Started</div><div>Duration</div><div title="Total cost in USD">Cost</div><div></div>'
|
|
23988
24029
|
+ '</div>';
|
|
23989
24030
|
for (var i = 0; i < filtered.length; i++) {
|
|
23990
24031
|
var entry = filtered[i] || {};
|
|
@@ -24032,7 +24073,14 @@ function renderRunListBody(allRuns) {
|
|
|
24032
24073
|
} else if (entry.outputPreview) {
|
|
24033
24074
|
preview = '<div style="font-size:11px;color:var(--text-muted);margin-top:2px;word-break:break-word">' + esc(String(entry.outputPreview).slice(0, 120)) + '</div>';
|
|
24034
24075
|
}
|
|
24035
|
-
|
|
24076
|
+
// 1.18.89: cost label. Showing 4 decimals for sub-penny costs (Haiku
|
|
24077
|
+
// runs land in fractions of a cent), 2 decimals when ≥ $0.01.
|
|
24078
|
+
var costLabel = '—';
|
|
24079
|
+
if (entry.totalCostUsd != null) {
|
|
24080
|
+
var c = entry.totalCostUsd;
|
|
24081
|
+
costLabel = c < 0.01 ? '$' + c.toFixed(4) : '$' + c.toFixed(2);
|
|
24082
|
+
}
|
|
24083
|
+
html += '<div class="history-row" data-trace-job="' + esc(jobName) + '" style="display:grid;grid-template-columns:24px 24px minmax(180px,1.2fr) 80px minmax(160px,1fr) 70px 70px auto;gap:10px;align-items:start;padding:8px 14px;border-bottom:1px solid var(--border);cursor:pointer">'
|
|
24036
24084
|
+ '<div style="color:' + statusColor + ';font-size:14px;line-height:18px;text-align:center" title="' + esc(status) + '">' + statusIcon + '</div>'
|
|
24037
24085
|
+ goalCell
|
|
24038
24086
|
+ '<div style="min-width:0">'
|
|
@@ -24043,6 +24091,7 @@ function renderRunListBody(allRuns) {
|
|
|
24043
24091
|
+ '<div style="font-size:11px;color:' + triggerColor + ';line-height:18px">' + esc(triggerLabel) + '</div>'
|
|
24044
24092
|
+ '<div style="font-size:12px;color:var(--text-secondary);line-height:18px">' + esc(startedLabel) + '</div>'
|
|
24045
24093
|
+ '<div style="font-size:12px;color:var(--text-muted);line-height:18px">' + esc(durationLabel) + '</div>'
|
|
24094
|
+
+ '<div style="font-size:12px;color:var(--text-muted);line-height:18px;font-family:\\x27JetBrains Mono\\x27,monospace">' + esc(costLabel) + '</div>'
|
|
24046
24095
|
+ '<div style="display:flex;gap:6px;align-items:center"><button class="btn-sm" onclick="event.stopPropagation();openRunOrTrace(\\x27' + safeName + '\\x27,' + (entry.id ? '\\x27' + jsStr(entry.id) + '\\x27' : 'null') + ')" style="font-size:11px;padding:3px 8px">' + (entry.id ? 'Open run' : 'Trace') + '</button></div>'
|
|
24047
24096
|
+ '</div>';
|
|
24048
24097
|
}
|
|
@@ -25942,6 +25991,87 @@ async function loadCronPreviewIntoTab(jobName) {
|
|
|
25942
25991
|
// Mark the preview as stale (call after save so next tab visit refetches).
|
|
25943
25992
|
function markCronPreviewDirty() { _cronPreviewLoadedFor = null; }
|
|
25944
25993
|
|
|
25994
|
+
// ── PRD §11 / 1.18.90: Prompt history viewer ────────────────────────
|
|
25995
|
+
// Reads /api/cron/:job/prompt-history (already populated on every PUT
|
|
25996
|
+
// since 1.18.x). Each version is the OLD prompt at the moment of a save,
|
|
25997
|
+
// so rolling back means picking the version that was AFTER the change
|
|
25998
|
+
// you want to undo (or the current saved value if you want the most
|
|
25999
|
+
// recent committed state).
|
|
26000
|
+
async function openPromptHistory() {
|
|
26001
|
+
if (!editingCronJob) {
|
|
26002
|
+
toast('Save the task first, then prompt history will be available.', 'info');
|
|
26003
|
+
return;
|
|
26004
|
+
}
|
|
26005
|
+
var modal = document.getElementById('prompt-history-modal');
|
|
26006
|
+
var list = document.getElementById('prompt-history-list');
|
|
26007
|
+
if (!modal || !list) return;
|
|
26008
|
+
list.innerHTML = '<div style="padding:24px;color:var(--text-muted);text-align:center">Loading prompt history…</div>';
|
|
26009
|
+
modal.classList.add('show');
|
|
26010
|
+
try {
|
|
26011
|
+
var r = await apiFetch('/api/cron/' + encodeURIComponent(editingCronJob) + '/prompt-history');
|
|
26012
|
+
var d = await r.json();
|
|
26013
|
+
var versions = (d && d.versions) || [];
|
|
26014
|
+
if (versions.length === 0) {
|
|
26015
|
+
list.innerHTML = '<div style="padding:36px 24px;color:var(--text-muted);text-align:center;line-height:1.6">'
|
|
26016
|
+
+ '<div style="font-weight:500;color:var(--text-secondary);margin-bottom:8px">No prior prompt versions yet</div>'
|
|
26017
|
+
+ '<div style="font-size:12px">A version is recorded each time you save a different prompt. The first edit you make to this task will create version 1.</div>'
|
|
26018
|
+
+ '</div>';
|
|
26019
|
+
return;
|
|
26020
|
+
}
|
|
26021
|
+
var html = '<div style="font-size:11px;color:var(--text-muted);margin-bottom:12px">Newest first. Each entry is the prompt as it was BEFORE that save — restoring rolls the editor back to the version that was active before that change landed.</div>';
|
|
26022
|
+
for (var i = 0; i < versions.length; i++) {
|
|
26023
|
+
var v = versions[i];
|
|
26024
|
+
var ts = v.timestamp ? new Date(v.timestamp).toLocaleString() : 'unknown time';
|
|
26025
|
+
var who = v.changedBy || 'dashboard';
|
|
26026
|
+
var prompt = String(v.prompt || '');
|
|
26027
|
+
var preview = prompt.slice(0, 200).replace(/\\s+/g, ' ');
|
|
26028
|
+
var rowId = 'pmt-hist-' + i;
|
|
26029
|
+
var promptB64 = btoa(unescape(encodeURIComponent(prompt))); // safe transport for restore
|
|
26030
|
+
html += '<div style="background:var(--bg-secondary);border:1px solid var(--border);border-radius:8px;padding:14px;margin-bottom:10px">';
|
|
26031
|
+
html += '<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px">';
|
|
26032
|
+
html += '<span style="font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.04em">v' + esc(v.version || (versions.length - i)) + '</span>';
|
|
26033
|
+
html += '<span style="font-size:12px;color:var(--text-primary)">' + esc(ts) + '</span>';
|
|
26034
|
+
html += '<span style="font-size:11px;color:var(--text-muted)">· by ' + esc(who) + '</span>';
|
|
26035
|
+
html += '<span style="flex:1"></span>';
|
|
26036
|
+
html += '<button class="btn-sm" onclick="document.getElementById(\\x27' + rowId + '\\x27).style.display=document.getElementById(\\x27' + rowId + '\\x27).style.display===\\x27none\\x27?\\x27block\\x27:\\x27none\\x27" style="font-size:11px;padding:3px 8px">Show full</button>';
|
|
26037
|
+
html += '<button class="btn-sm btn-primary" onclick="restorePromptVersion(\\x27' + promptB64 + '\\x27)" style="font-size:11px;padding:3px 10px">Restore</button>';
|
|
26038
|
+
html += '</div>';
|
|
26039
|
+
html += '<div style="font-size:12px;color:var(--text-secondary);line-height:1.5;font-family:\\x27JetBrains Mono\\x27,monospace">' + esc(preview) + (prompt.length > 200 ? '…' : '') + '</div>';
|
|
26040
|
+
html += '<pre id="' + rowId + '" style="display:none;margin-top:10px;font-size:11px;font-family:\\x27JetBrains Mono\\x27,monospace;background:var(--bg-tertiary);border:1px solid var(--border);padding:10px;border-radius:6px;white-space:pre-wrap;word-break:break-word;max-height:280px;overflow-y:auto">' + esc(prompt) + '</pre>';
|
|
26041
|
+
html += '</div>';
|
|
26042
|
+
}
|
|
26043
|
+
list.innerHTML = html;
|
|
26044
|
+
} catch (e) {
|
|
26045
|
+
list.innerHTML = '<div style="padding:24px;color:var(--red)">Failed to load history: ' + esc(String(e)) + '</div>';
|
|
26046
|
+
}
|
|
26047
|
+
}
|
|
26048
|
+
|
|
26049
|
+
function closePromptHistory() {
|
|
26050
|
+
var modal = document.getElementById('prompt-history-modal');
|
|
26051
|
+
if (modal) modal.classList.remove('show');
|
|
26052
|
+
}
|
|
26053
|
+
|
|
26054
|
+
// Restore copies the old prompt back into the editor's textarea. Doesn't
|
|
26055
|
+
// auto-save — the user must click Save Changes to commit, which keeps the
|
|
26056
|
+
// dirty-guard semantics intact and gives them a chance to back out.
|
|
26057
|
+
function restorePromptVersion(promptB64) {
|
|
26058
|
+
try {
|
|
26059
|
+
var prompt = decodeURIComponent(escape(atob(promptB64)));
|
|
26060
|
+
var ta = document.getElementById('cron-prompt');
|
|
26061
|
+
if (!ta) return;
|
|
26062
|
+
if (ta.value !== prompt && ta.value.trim() && !confirm('Replace the current prompt with this restored version? Your unsaved edits will be discarded.')) {
|
|
26063
|
+
return;
|
|
26064
|
+
}
|
|
26065
|
+
ta.value = prompt;
|
|
26066
|
+
// Switch to the Prompt tab so the user sees what just changed.
|
|
26067
|
+
if (typeof switchCronConfigTab === 'function') switchCronConfigTab('prompt');
|
|
26068
|
+
closePromptHistory();
|
|
26069
|
+
toast('Prompt restored. Click Save Changes to commit it.', 'info');
|
|
26070
|
+
} catch (e) {
|
|
26071
|
+
toast('Failed to restore: ' + String(e), 'error');
|
|
26072
|
+
}
|
|
26073
|
+
}
|
|
26074
|
+
|
|
25945
26075
|
// PRD Phase 1.3a: inner Configure pane tabs. Sets the data-active-config-tab
|
|
25946
26076
|
// attribute on #cron-tab-configure; CSS handles section visibility via
|
|
25947
26077
|
// data-config-tab attributes on each section. JS-light by design.
|
|
@@ -26237,6 +26367,9 @@ function openCreateCronModal(agentSlug) {
|
|
|
26237
26367
|
if (lastRunBtn) lastRunBtn.setAttribute('disabled', 'disabled');
|
|
26238
26368
|
var runOnceBtn = document.getElementById('cron-run-once-btn');
|
|
26239
26369
|
if (runOnceBtn) runOnceBtn.style.display = 'none';
|
|
26370
|
+
// PRD §11 / 1.18.90: prompt history link only meaningful for existing tasks.
|
|
26371
|
+
var historyLinkNew = document.getElementById('cron-prompt-history-link');
|
|
26372
|
+
if (historyLinkNew) historyLinkNew.style.display = 'none';
|
|
26240
26373
|
var host = document.getElementById('cron-legacy-banner-host');
|
|
26241
26374
|
if (host) host.innerHTML = '';
|
|
26242
26375
|
// Reset the "Use a cron expression" link in case it was hidden last time.
|
|
@@ -26337,6 +26470,9 @@ function openEditCronModal(jobName) {
|
|
|
26337
26470
|
// Show "Run task once" only for saved tasks.
|
|
26338
26471
|
var runOnceBtnEdit = document.getElementById('cron-run-once-btn');
|
|
26339
26472
|
if (runOnceBtnEdit) runOnceBtnEdit.style.display = '';
|
|
26473
|
+
// 1.18.90: surface prompt history link for saved tasks.
|
|
26474
|
+
var historyLinkEdit = document.getElementById('cron-prompt-history-link');
|
|
26475
|
+
if (historyLinkEdit) historyLinkEdit.style.display = '';
|
|
26340
26476
|
// Render the most recent run from the loaded job into the Last run tab so
|
|
26341
26477
|
// the user sees something the moment they switch to it (rather than a
|
|
26342
26478
|
// dead empty pane). The pane updates live when Run task once fires.
|
|
@@ -1210,6 +1210,9 @@ export class CronScheduler {
|
|
|
1210
1210
|
trigger,
|
|
1211
1211
|
// 1.18.85: stable UUID linking this run to its Event store entries.
|
|
1212
1212
|
...(cronMetadata?.runId ? { id: cronMetadata.runId } : {}),
|
|
1213
|
+
// 1.18.89: per-run cost for the Run list + Health Strip. Comes from
|
|
1214
|
+
// SDK's ResultMessage.total_cost_usd via runAgent's side-channel.
|
|
1215
|
+
...(cronMetadata?.totalCostUsd != null ? { totalCostUsd: cronMetadata.totalCostUsd } : {}),
|
|
1213
1216
|
// Trick capability metadata — surfaced by the dashboard's
|
|
1214
1217
|
// "ran with: …" line. Omit empty arrays to keep the JSONL light.
|
|
1215
1218
|
...(cronMetadata?.skillsApplied?.length ? { skillsApplied: cronMetadata.skillsApplied } : {}),
|
|
@@ -1306,6 +1309,9 @@ export class CronScheduler {
|
|
|
1306
1309
|
// can show trigger + open the partial Event log if any.
|
|
1307
1310
|
trigger,
|
|
1308
1311
|
...(errCronMetadata?.runId ? { id: errCronMetadata.runId } : {}),
|
|
1312
|
+
// 1.18.89: cost on the error path too — partial-completion runs may
|
|
1313
|
+
// still have spent budget before the throw.
|
|
1314
|
+
...(errCronMetadata?.totalCostUsd != null ? { totalCostUsd: errCronMetadata.totalCostUsd } : {}),
|
|
1309
1315
|
...(errCronMetadata?.skillsApplied?.length ? { skillsApplied: errCronMetadata.skillsApplied } : {}),
|
|
1310
1316
|
...(errCronMetadata?.skillsMissing?.length ? { skillsMissing: errCronMetadata.skillsMissing } : {}),
|
|
1311
1317
|
...(errCronMetadata?.allowedToolsApplied?.length ? { allowedToolsApplied: errCronMetadata.allowedToolsApplied } : {}),
|
package/dist/gateway/router.d.ts
CHANGED
|
@@ -239,6 +239,8 @@ export declare class Gateway {
|
|
|
239
239
|
mcpServersApplied: string[];
|
|
240
240
|
/** PRD §6 / 1.18.85: run UUID from runAgent. */
|
|
241
241
|
runId?: string;
|
|
242
|
+
/** PRD §12 / 1.18.89: total cost in USD from runAgent's SDK result. */
|
|
243
|
+
totalCostUsd?: number;
|
|
242
244
|
} | undefined;
|
|
243
245
|
requestApproval(descriptionOrId: string, explicitId?: string): Promise<boolean | string>;
|
|
244
246
|
resolveApproval(requestId: string, result: boolean | string): void;
|
package/dist/gateway/router.js
CHANGED
|
@@ -2024,6 +2024,7 @@ export class Gateway {
|
|
|
2024
2024
|
allowedToolsApplied: cronResult.allowedToolsApplied,
|
|
2025
2025
|
mcpServersApplied: cronResult.mcpServersApplied,
|
|
2026
2026
|
runId: cronResult.runId,
|
|
2027
|
+
totalCostUsd: cronResult.totalCostUsd,
|
|
2027
2028
|
};
|
|
2028
2029
|
logger.info({
|
|
2029
2030
|
jobName,
|
package/dist/types.d.ts
CHANGED
|
@@ -514,6 +514,11 @@ export interface CronRunEntry {
|
|
|
514
514
|
* whose status indicates a failure (error/timeout/lost/cancelled). The
|
|
515
515
|
* Run list filter chip and Run detail header read from this field. */
|
|
516
516
|
failureCategory?: RunFailureCategory;
|
|
517
|
+
/** PRD §12 / 1.18.89: total cost in USD as reported by the SDK's
|
|
518
|
+
* ResultMessage.total_cost_usd. Stamped on success/error entries by
|
|
519
|
+
* the scheduler from the runAgent result side-channel. Powers the
|
|
520
|
+
* Run list Cost column and the Health Strip's 24h cost tile. */
|
|
521
|
+
totalCostUsd?: number;
|
|
517
522
|
/** PRD Phase 1: did the run accomplish what it was supposed to?
|
|
518
523
|
* Computed at run-end when the Task has successSchema or successCriteriaText.
|
|
519
524
|
* - status='pass' both configured checks passed (or the only one configured did)
|