diff --git a/src/renderer/components/report/sections/CostSection.tsx b/src/renderer/components/report/sections/CostSection.tsx
index f0316403..3e65ee47 100644
--- a/src/renderer/components/report/sections/CostSection.tsx
+++ b/src/renderer/components/report/sections/CostSection.tsx
@@ -182,17 +182,17 @@ export const CostSection = ({
{modelEntries.map(([model, cost]) => {
const stats = tokensByModel[model];
- const isExpanded = expandedModel === model;
+ const isExpanded = expandedModel === model && !!stats;
const pricing = getPricing(model);
return (
setExpandedModel(isExpanded ? null : model)}
+ className={`border-border/50 border-b ${stats ? 'hover:bg-surface-raised/50 cursor-pointer' : ''}`}
+ onClick={() => stats && setExpandedModel(isExpanded ? null : model)}
>
|
- {isExpanded ? '\u25BC' : '\u25B6'}
+ {stats ? (isExpanded ? '\u25BC' : '\u25B6') : ''}
{model}
|
diff --git a/src/renderer/store/slices/tabSlice.ts b/src/renderer/store/slices/tabSlice.ts
index 1735c03e..677733a0 100644
--- a/src/renderer/store/slices/tabSlice.ts
+++ b/src/renderer/store/slices/tabSlice.ts
@@ -387,6 +387,7 @@ export const createTabSlice: StateCreator = (set, ge
const allTabs = getAllTabs(state.paneLayout);
const sourceTab = allTabs.find((t) => t.id === sourceTabId);
if (sourceTab?.type !== 'session') return;
+ if (!sourceTab.sessionId || !sourceTab.projectId) return;
const tabData = state.tabSessionData[sourceTabId];
const firstMsg = tabData?.sessionDetail?.session.firstMessage;
diff --git a/src/renderer/utils/sessionAnalyzer.ts b/src/renderer/utils/sessionAnalyzer.ts
index 93b65ae3..46773633 100644
--- a/src/renderer/utils/sessionAnalyzer.ts
+++ b/src/renderer/utils/sessionAnalyzer.ts
@@ -104,9 +104,10 @@ const DEFAULT_PRICING: ModelPricing = {
};
export function getPricing(modelName: string): ModelPricing {
- const name = modelName.toLowerCase();
+ const nameTokens: string[] = modelName.toLowerCase().match(/[a-z0-9]+/g) ?? [];
for (const [key, pricing] of Object.entries(MODEL_PRICING)) {
- if (name.includes(key)) return pricing;
+ const keyTokens: string[] = key.match(/[a-z0-9]+/g) ?? [];
+ if (keyTokens.every((t) => nameTokens.includes(t))) return pricing;
}
return DEFAULT_PRICING;
}
@@ -454,7 +455,9 @@ export function analyzeSession(detail: SessionDetail): SessionReport {
}
// --- Token usage, cache economics, and cost ---
- if (m.usage && m.model) {
+ // Skip sidechain messages to avoid double-counting (subagent costs are
+ // accounted for separately via processSubagentCost).
+ if (m.usage && m.model && !m.isSidechain) {
const model = m.model;
const u = m.usage;
const inpTok = u.input_tokens ?? 0;