@yemi33/minions 0.1.91 → 0.1.92
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 +9 -0
- package/dashboard/js/render-other.js +5 -3
- package/engine/lifecycle.js +6 -5
- package/engine/shared.js +12 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -142,12 +142,14 @@ function renderTokenUsage(metrics) {
|
|
|
142
142
|
const agentsWithUsage = agents.filter(([, m]) => (m.totalCostUsd || 0) > 0);
|
|
143
143
|
if (agentsWithUsage.length > 0) {
|
|
144
144
|
html += '<div style="font-size:10px;color:var(--muted);margin:12px 0 4px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px">Agent Usage</div>';
|
|
145
|
-
html += '<table class="token-agent-table"><thead><tr><th>Agent</th><th>Cost</th><th>Input</th><th>Output</th><th>Cache</th><th>$/task</th></tr></thead><tbody>';
|
|
145
|
+
html += '<table class="token-agent-table"><thead><tr><th>Agent</th><th>Model</th><th>Cost</th><th>Input</th><th>Output</th><th>Cache</th><th>$/task</th></tr></thead><tbody>';
|
|
146
146
|
for (const [id, m] of agentsWithUsage.sort((a, b) => (b[1].totalCostUsd || 0) - (a[1].totalCostUsd || 0))) {
|
|
147
147
|
const tasks = (m.tasksCompleted || 0) + (m.tasksErrored || 0);
|
|
148
148
|
const perTask = tasks > 0 ? fmtCost((m.totalCostUsd || 0) / tasks) : '-';
|
|
149
|
+
const modelLabel = (m.model || '').replace(/^claude-/, '').replace(/\[.*\]$/, '') || '-';
|
|
149
150
|
html += '<tr>' +
|
|
150
151
|
'<td style="font-weight:600">' + escHtml(id) + '</td>' +
|
|
152
|
+
'<td style="color:var(--muted);font-size:10px">' + escHtml(modelLabel) + '</td>' +
|
|
151
153
|
'<td>' + fmtCost(m.totalCostUsd || 0) + '</td>' +
|
|
152
154
|
'<td>' + fmtTokens(m.totalInputTokens || 0) + '</td>' +
|
|
153
155
|
'<td>' + fmtTokens(m.totalOutputTokens || 0) + '</td>' +
|
|
@@ -161,8 +163,8 @@ function renderTokenUsage(metrics) {
|
|
|
161
163
|
// Engine (Haiku) usage table
|
|
162
164
|
const engineEntries = Object.entries(engine).filter(([, e]) => (e.costUsd || 0) > 0 || (e.calls || 0) > 0);
|
|
163
165
|
if (engineEntries.length > 0) {
|
|
164
|
-
const labels = { 'consolidation': 'Consolidation', 'command-center': 'Command Center', 'doc-chat': 'Doc Chat' };
|
|
165
|
-
html += '<div style="font-size:10px;color:var(--muted);margin:12px 0 4px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px">Engine Usage
|
|
166
|
+
const labels = { 'consolidation': 'Consolidation', 'command-center': 'Command Center', 'doc-chat': 'Doc Chat', 'kb-sweep': 'KB Sweep', 'schedule-parse': 'Schedule Parse' };
|
|
167
|
+
html += '<div style="font-size:10px;color:var(--muted);margin:12px 0 4px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px">Engine Usage</div>';
|
|
166
168
|
html += '<table class="token-agent-table"><thead><tr><th>Operation</th><th>Cost</th><th>Calls</th><th>Input</th><th>Output</th><th>$/call</th></tr></thead><tbody>';
|
|
167
169
|
for (const [cat, e] of engineEntries.sort((a, b) => (b[1].costUsd || 0) - (a[1].costUsd || 0))) {
|
|
168
170
|
const perCall = (e.calls || 0) > 0 ? fmtCost((e.costUsd || 0) / e.calls) : '-';
|
package/engine/lifecycle.js
CHANGED
|
@@ -880,7 +880,7 @@ function createReviewFeedbackForAuthor(reviewerAgentId, pr, config) {
|
|
|
880
880
|
log('info', `Created review feedback for ${authorAgentId} from ${reviewerAgentId} on ${pr.id}`);
|
|
881
881
|
}
|
|
882
882
|
|
|
883
|
-
function updateMetrics(agentId, dispatchItem, result, taskUsage, prsCreatedCount) {
|
|
883
|
+
function updateMetrics(agentId, dispatchItem, result, taskUsage, prsCreatedCount, model) {
|
|
884
884
|
|
|
885
885
|
const metricsPath = path.join(ENGINE_DIR, 'metrics.json');
|
|
886
886
|
const metrics = safeJson(metricsPath) || {};
|
|
@@ -891,6 +891,7 @@ function updateMetrics(agentId, dispatchItem, result, taskUsage, prsCreatedCount
|
|
|
891
891
|
const m = metrics[agentId];
|
|
892
892
|
m.lastTask = dispatchItem.task;
|
|
893
893
|
m.lastCompleted = ts();
|
|
894
|
+
if (model) m.model = model;
|
|
894
895
|
if (result === 'success') {
|
|
895
896
|
m.tasksCompleted++;
|
|
896
897
|
if (prsCreatedCount > 0) m.prsCreated = (m.prsCreated || 0) + prsCreatedCount;
|
|
@@ -930,8 +931,8 @@ function updateMetrics(agentId, dispatchItem, result, taskUsage, prsCreatedCount
|
|
|
930
931
|
// ─── Agent Output Parsing ────────────────────────────────────────────────────
|
|
931
932
|
|
|
932
933
|
function parseAgentOutput(stdout) {
|
|
933
|
-
const { text, usage, sessionId } = shared.parseStreamJsonOutput(stdout, { maxTextLength: 2000 });
|
|
934
|
-
return { resultSummary: text, taskUsage: usage, sessionId };
|
|
934
|
+
const { text, usage, sessionId, model } = shared.parseStreamJsonOutput(stdout, { maxTextLength: 2000 });
|
|
935
|
+
return { resultSummary: text, taskUsage: usage, sessionId, model };
|
|
935
936
|
}
|
|
936
937
|
|
|
937
938
|
/**
|
|
@@ -1016,7 +1017,7 @@ function runPostCompletionHooks(dispatchItem, agentId, code, stdout, config) {
|
|
|
1016
1017
|
const meta = dispatchItem.meta;
|
|
1017
1018
|
const isSuccess = code === 0;
|
|
1018
1019
|
const result = isSuccess ? 'success' : 'error';
|
|
1019
|
-
const { resultSummary, taskUsage, sessionId } = parseAgentOutput(stdout);
|
|
1020
|
+
const { resultSummary, taskUsage, sessionId, model } = parseAgentOutput(stdout);
|
|
1020
1021
|
|
|
1021
1022
|
// Save session for potential resume on next dispatch
|
|
1022
1023
|
if (isSuccess && sessionId && agentId && !agentId.startsWith('temp-')) {
|
|
@@ -1179,7 +1180,7 @@ function runPostCompletionHooks(dispatchItem, agentId, code, stdout, config) {
|
|
|
1179
1180
|
// Don't count auto-retries as errors in metrics — only count final outcomes
|
|
1180
1181
|
const isAutoRetry = !isSuccess && meta?.item?.id && (meta.item._retryCount || 0) < 3;
|
|
1181
1182
|
const metricsResult = isAutoRetry ? 'retry' : result;
|
|
1182
|
-
updateMetrics(agentId, dispatchItem, metricsResult, taskUsage, prsCreatedCount);
|
|
1183
|
+
updateMetrics(agentId, dispatchItem, metricsResult, taskUsage, prsCreatedCount, model);
|
|
1183
1184
|
|
|
1184
1185
|
return { resultSummary, taskUsage };
|
|
1185
1186
|
}
|
package/engine/shared.js
CHANGED
|
@@ -205,6 +205,7 @@ function parseStreamJsonOutput(raw, { maxTextLength = 0 } = {}) {
|
|
|
205
205
|
let text = '';
|
|
206
206
|
let usage = null;
|
|
207
207
|
let sessionId = null;
|
|
208
|
+
let model = null;
|
|
208
209
|
|
|
209
210
|
function extractResult(obj) {
|
|
210
211
|
if (obj.type !== 'result') return false;
|
|
@@ -225,6 +226,16 @@ function parseStreamJsonOutput(raw, { maxTextLength = 0 } = {}) {
|
|
|
225
226
|
}
|
|
226
227
|
|
|
227
228
|
const lines = raw.split('\n');
|
|
229
|
+
// Scan forward for model from init message (appears early in output)
|
|
230
|
+
for (let i = 0; i < Math.min(lines.length, 10); i++) {
|
|
231
|
+
const line = lines[i].trim();
|
|
232
|
+
if (!line || !line.startsWith('{')) continue;
|
|
233
|
+
try {
|
|
234
|
+
const obj = JSON.parse(line);
|
|
235
|
+
if (obj.type === 'system' && obj.subtype === 'init' && obj.model) { model = obj.model; break; }
|
|
236
|
+
} catch {}
|
|
237
|
+
}
|
|
238
|
+
// Scan backward for result (appears at end of output)
|
|
228
239
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
229
240
|
const line = lines[i].trim();
|
|
230
241
|
if (!line) continue;
|
|
@@ -245,7 +256,7 @@ function parseStreamJsonOutput(raw, { maxTextLength = 0 } = {}) {
|
|
|
245
256
|
} catch {}
|
|
246
257
|
}
|
|
247
258
|
}
|
|
248
|
-
return { text, usage, sessionId };
|
|
259
|
+
return { text, usage, sessionId, model };
|
|
249
260
|
}
|
|
250
261
|
|
|
251
262
|
// ── Knowledge Base ──────────────────────────────────────────────────────────
|
package/package.json
CHANGED