diff --git a/src/resources/extensions/gsd/auto-dashboard.ts b/src/resources/extensions/gsd/auto-dashboard.ts index da90e8a19..91672ef6d 100644 --- a/src/resources/extensions/gsd/auto-dashboard.ts +++ b/src/resources/extensions/gsd/auto-dashboard.ts @@ -460,6 +460,7 @@ export function updateProgressWidget( sp.push(`\u26A1${hitRate}%`); } if (cumulativeCost) sp.push(`$${cumulativeCost.toFixed(3)}`); + else if (autoTotals?.apiRequests) sp.push(`${autoTotals.apiRequests} reqs`); const cxDisplay = cxPct === "?" ? `?/${formatWidgetTokens(cxWindow)}` diff --git a/src/resources/extensions/gsd/dashboard-overlay.ts b/src/resources/extensions/gsd/dashboard-overlay.ts index 48917f941..7399b4a0b 100644 --- a/src/resources/extensions/gsd/dashboard-overlay.ts +++ b/src/resources/extensions/gsd/dashboard-overlay.ts @@ -479,8 +479,12 @@ export class GSDDashboardOverlay { lines.push(row(th.fg("text", th.bold("Cost & Usage")))); lines.push(blank()); + // Show cost or request count (for copilot/subscription users where cost is 0) + const costOrReqs = totals.cost > 0 + ? `${th.fg("warning", formatCost(totals.cost))} total` + : `${th.fg("text", String(totals.apiRequests))} requests`; lines.push(row(fitColumns([ - `${th.fg("warning", formatCost(totals.cost))} total`, + costOrReqs, `${th.fg("text", formatTokenCount(totals.tokens.total))} tokens`, `${th.fg("text", String(totals.toolCalls))} tools`, `${th.fg("text", String(totals.units))} units`, diff --git a/src/resources/extensions/gsd/metrics.ts b/src/resources/extensions/gsd/metrics.ts index 85dc89f38..805c8df71 100644 --- a/src/resources/extensions/gsd/metrics.ts +++ b/src/resources/extensions/gsd/metrics.ts @@ -43,6 +43,7 @@ export interface UnitMetrics { toolCalls: number; assistantMessages: number; userMessages: number; + apiRequests?: number; // total API requests made (useful for copilot users where cost is always 0) // Budget fields (optional — absent in pre-M009 metrics data) contextWindowTokens?: number; truncationSections?: number; @@ -179,6 +180,7 @@ export function snapshotUnitMetrics( toolCalls, assistantMessages, userMessages, + apiRequests: assistantMessages, // each assistant message = one API request ...(opts?.tier ? { tier: opts.tier } : {}), ...(opts?.modelDowngraded !== undefined ? { modelDowngraded: opts.modelDowngraded } : {}), ...(opts?.contextWindowTokens !== undefined ? { contextWindowTokens: opts.contextWindowTokens } : {}), @@ -247,6 +249,7 @@ export interface ProjectTotals { toolCalls: number; assistantMessages: number; userMessages: number; + apiRequests: number; totalTruncationSections: number; continueHereFiredCount: number; } @@ -330,6 +333,7 @@ export function getProjectTotals(units: UnitMetrics[]): ProjectTotals { toolCalls: 0, assistantMessages: 0, userMessages: 0, + apiRequests: 0, totalTruncationSections: 0, continueHereFiredCount: 0, }; @@ -340,6 +344,7 @@ export function getProjectTotals(units: UnitMetrics[]): ProjectTotals { totals.toolCalls += u.toolCalls; totals.assistantMessages += u.assistantMessages; totals.userMessages += u.userMessages; + totals.apiRequests += u.apiRequests ?? u.assistantMessages; // fallback for pre-existing data totals.totalTruncationSections += u.truncationSections ?? 0; if (u.continueHereFired) totals.continueHereFiredCount++; } diff --git a/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts b/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts index b475c46be..b4bea28a8 100644 --- a/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +++ b/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts @@ -68,6 +68,7 @@ function mockData(overrides: Partial = {}): VisualizerData { userMessages: 12, totalTruncationSections: 2, continueHereFiredCount: 1, + apiRequests: 20, }, byPhase: [ { phase: "execution", units: 4, tokens: mockTokens(), cost: 2.50, duration: 3_600_000 }, diff --git a/src/resources/extensions/gsd/tests/visualizer-views.test.ts b/src/resources/extensions/gsd/tests/visualizer-views.test.ts index 55ae77622..6d7ff4698 100644 --- a/src/resources/extensions/gsd/tests/visualizer-views.test.ts +++ b/src/resources/extensions/gsd/tests/visualizer-views.test.ts @@ -387,6 +387,7 @@ console.log("\n=== renderMetricsView ==="); userMessages: 5, totalTruncationSections: 0, continueHereFiredCount: 0, + apiRequests: 5, }, byPhase: [ { @@ -653,7 +654,7 @@ console.log("\n=== renderHealthView ==="); units: 10, tokens: { input: 5000, output: 2000, cacheRead: 1000, cacheWrite: 500, total: 8500 }, cost: 5.00, duration: 120000, toolCalls: 50, assistantMessages: 30, userMessages: 15, - totalTruncationSections: 3, continueHereFiredCount: 1, + totalTruncationSections: 3, continueHereFiredCount: 1, apiRequests: 30, }, health: { budgetCeiling: 20.00,