diff --git a/src/components/dashboard/delegation/DelegationModelRoutingWidget.test.tsx b/src/components/dashboard/delegation/DelegationModelRoutingWidget.test.tsx
index c67533f1..8f56021f 100644
--- a/src/components/dashboard/delegation/DelegationModelRoutingWidget.test.tsx
+++ b/src/components/dashboard/delegation/DelegationModelRoutingWidget.test.tsx
@@ -46,7 +46,7 @@ describe('DelegationModelRoutingWidget', () => {
,
);
- expect(await screen.findByText('Qwen3-Coder-30B')).toBeInTheDocument();
+ expect(await screen.findByText('qwen3-coder-30b')).toBeInTheDocument();
expect(screen.getByText('claude-sonnet-4-6')).toBeInTheDocument();
});
@@ -57,7 +57,7 @@ describe('DelegationModelRoutingWidget', () => {
,
);
- await screen.findByText('Qwen3-Coder-30B');
+ await screen.findByText('qwen3-coder-30b');
expect(screen.getByText(/312 total delegations/i)).toBeInTheDocument();
});
@@ -68,7 +68,7 @@ describe('DelegationModelRoutingWidget', () => {
,
);
- await screen.findByText('Qwen3-Coder-30B');
+ await screen.findByText('qwen3-coder-30b');
expect(screen.getByText('Model')).toBeInTheDocument();
expect(screen.getByText('N')).toBeInTheDocument();
expect(screen.getByText('Frequency')).toBeInTheDocument();
@@ -85,7 +85,7 @@ describe('DelegationModelRoutingWidget', () => {
,
);
- await screen.findByText('Qwen3-Coder-30B');
+ await screen.findByText('qwen3-coder-30b');
// Fixture provides task_types including 'code-review'
expect(screen.getAllByText('code-review').length).toBeGreaterThan(0);
});
@@ -97,7 +97,7 @@ describe('DelegationModelRoutingWidget', () => {
,
);
- await screen.findByText('Qwen3-Coder-30B');
+ await screen.findByText('qwen3-coder-30b');
expect(screen.getByText(/upstream-blocked/i)).toBeInTheDocument();
});
});
diff --git a/src/components/dashboard/delegation/DelegationQualityGateWidget.test.tsx b/src/components/dashboard/delegation/DelegationQualityGateWidget.test.tsx
index f17d660d..3d818fba 100644
--- a/src/components/dashboard/delegation/DelegationQualityGateWidget.test.tsx
+++ b/src/components/dashboard/delegation/DelegationQualityGateWidget.test.tsx
@@ -174,9 +174,9 @@ describe('DelegationQualityGateWidget', () => {
describe('recent checks table', () => {
it('renders recent checks table with task type, model, and pass/fail when decisions data is available', async () => {
const decisions = [
- { id: '1', task_type: 'code-review', model_name: 'Qwen3-Coder-30B', delegated_to: null, quality_gate_passed: 1, quality_gate_detail: 'schema_valid', created_at: '2026-05-05T10:00:00Z' },
- { id: '2', task_type: 'summarization', model_name: 'glm-4-plus', delegated_to: null, quality_gate_passed: 0, quality_gate_detail: 'output_too_short', created_at: '2026-05-05T09:00:00Z' },
- { id: '3', task_type: 'classification', model_name: null, delegated_to: 'codex-cli', quality_gate_passed: 1, quality_gate_detail: null, created_at: '2026-05-05T08:00:00Z' },
+ { id: '1', task_type: 'code-review', model_name: 'qwen3-coder-30b', delegated_to: null, quality_gate_passed: 1, quality_gate_detail: 'schema_valid', created_at: '2026-05-05T10:00:00Z' },
+ { id: '2', task_type: 'summarization', model_name: 'deepseek-r1-14b', delegated_to: null, quality_gate_passed: 0, quality_gate_detail: 'output_too_short', created_at: '2026-05-05T09:00:00Z' },
+ { id: '3', task_type: 'classification', model_name: null, delegated_to: 'openrouter-glm-flash', quality_gate_passed: 1, quality_gate_detail: null, created_at: '2026-05-05T08:00:00Z' },
];
mockFetchForQualityGateWithDecisions([buildDelegationQualityGate()], decisions);
render(
@@ -191,7 +191,7 @@ describe('DelegationQualityGateWidget', () => {
expect(screen.getByText('classification')).toBeInTheDocument();
// Model names and failure categories may appear in both the recent
// checks table and other sections, so use getAllByText.
- expect(screen.getAllByText('Qwen3-Coder-30B').length).toBeGreaterThanOrEqual(1);
+ expect(screen.getAllByText('qwen3-coder-30b').length).toBeGreaterThanOrEqual(1);
expect(screen.getAllByText('output_too_short').length).toBeGreaterThanOrEqual(1);
expect(screen.getByText('schema_valid')).toBeInTheDocument();
});
@@ -243,11 +243,11 @@ describe('DelegationQualityGateWidget', () => {
);
await screen.findByText('Automated checks');
expect(screen.getByText('Tokens-to-compliance by model')).toBeInTheDocument();
- // The fixture seeds Qwen3-Coder-30B at 3,120 tokens (lowest, first row).
- const models = screen.getAllByText(/Qwen3-Coder-30B|glm-4-plus|codex-cli|gemini-cli/);
+ // The fixture seeds qwen3-coder-30b at 3,120 tokens (lowest, first row).
+ const models = screen.getAllByText(/qwen3-coder-30b|deepseek-r1-14b|openrouter-glm-flash|claude-sonnet-4-6/);
// Sorted ascending → most efficient first.
- expect(models[0].textContent).toBe('Qwen3-Coder-30B');
- expect(models[models.length - 1].textContent).toBe('gemini-cli');
+ expect(models[0].textContent).toBe('qwen3-coder-30b');
+ expect(models[models.length - 1].textContent).toBe('claude-sonnet-4-6');
});
});
});
diff --git a/src/components/dashboard/delegation/DelegationSavingsWidget.tsx b/src/components/dashboard/delegation/DelegationSavingsWidget.tsx
index f534228b..3855e133 100644
--- a/src/components/dashboard/delegation/DelegationSavingsWidget.tsx
+++ b/src/components/dashboard/delegation/DelegationSavingsWidget.tsx
@@ -56,6 +56,11 @@ export interface DelegationSavingsConfig {
// Used when cost_savings_usd / savings_usd is 0 but token counts are present.
// Prices in USD per token.
+// Client-side estimation fallback — used only when the backend projection
+// returns zero for savings_usd / cloud_cost_usd / local_cost_usd.
+// Authoritative savings are computed server-side via the pricing manifest
+// (omnimarket/src/omnimarket/pricing.py). These constants should NOT be
+// treated as the source of truth for cost calculations.
const OPUS_INPUT_PRICE = 15.0 / 1_000_000; // $15/M tokens
const OPUS_OUTPUT_PRICE = 75.0 / 1_000_000; // $75/M tokens
const SONNET_INPUT_PRICE = 3.0 / 1_000_000;
diff --git a/src/components/dashboard/delegation/DelegationTokenUsageWidget.test.tsx b/src/components/dashboard/delegation/DelegationTokenUsageWidget.test.tsx
index 06bc5984..168cab66 100644
--- a/src/components/dashboard/delegation/DelegationTokenUsageWidget.test.tsx
+++ b/src/components/dashboard/delegation/DelegationTokenUsageWidget.test.tsx
@@ -60,8 +60,8 @@ describe('DelegationTokenUsageWidget', () => {
,
);
await screen.findByText('Total tokens');
- expect(screen.getByText('Qwen3-Coder-30B')).toBeInTheDocument();
- expect(screen.getByText('claude-sonnet-4-6')).toBeInTheDocument();
+ expect(screen.getByText('qwen3-coder-30b')).toBeInTheDocument();
+ expect(screen.getByText('deepseek-r1-14b')).toBeInTheDocument();
});
it('renders provenance badges when showProvenance is true', async () => {
diff --git a/src/storybook/fixtures/delegation-routing.ts b/src/storybook/fixtures/delegation-routing.ts
index 3c87468b..6a4b0758 100644
--- a/src/storybook/fixtures/delegation-routing.ts
+++ b/src/storybook/fixtures/delegation-routing.ts
@@ -23,7 +23,7 @@ const SESSION_IDS = [
];
const SESSION_TASK_TYPES = ['code-review', 'pattern-match', 'document-summarize', 'classification', 'code-review'];
-const SESSION_MODELS = ['Qwen3-Coder-30B', 'glm-4-plus', 'Qwen3-Coder-30B', 'codex-cli', 'claude-sonnet-4-6'];
+const SESSION_MODELS = ['qwen3-coder-30b', 'deepseek-r1-14b', 'qwen3-coder-30b', 'openrouter-glm-flash', 'claude-sonnet-4-6'];
export function buildDelegationSavings(opts: BuildDelegationSavingsOptions = {}): DelegationSavingsProjection {
const {
@@ -87,7 +87,7 @@ export interface BuildDelegationModelRoutingOptions {
provisioned?: boolean;
}
-const ROUTING_MODELS = ['Qwen3-Coder-30B', 'claude-sonnet-4-6', 'glm-4-plus', 'codex-cli'];
+const ROUTING_MODELS = ['qwen3-coder-30b', 'deepseek-r1-14b', 'openrouter-glm-flash', 'claude-sonnet-4-6'];
const TASK_TYPES = ['code-review', 'classification', 'summarization', 'pattern-match'];
export function buildDelegationModelRouting(
@@ -218,10 +218,10 @@ export function buildDelegationQualityGate(
median_tokens_to_compliance: 3_950,
avg_compliance_attempts: 1.32,
tokens_to_compliance_by_model: [
- { model_name: 'Qwen3-Coder-30B', avg_tokens: 3_120, avg_attempts: 1.18, sample_count: 142 },
- { model_name: 'glm-4-plus', avg_tokens: 4_640, avg_attempts: 1.34, sample_count: 96 },
- { model_name: 'codex-cli', avg_tokens: 5_280, avg_attempts: 1.51, sample_count: 64 },
- { model_name: 'gemini-cli', avg_tokens: 6_910, avg_attempts: 1.78, sample_count: 38 },
+ { model_name: 'qwen3-coder-30b', avg_tokens: 3_120, avg_attempts: 1.18, sample_count: 142 },
+ { model_name: 'deepseek-r1-14b', avg_tokens: 4_640, avg_attempts: 1.34, sample_count: 96 },
+ { model_name: 'openrouter-glm-flash', avg_tokens: 5_280, avg_attempts: 1.51, sample_count: 64 },
+ { model_name: 'claude-sonnet-4-6', avg_tokens: 6_910, avg_attempts: 1.78, sample_count: 38 },
],
}
: {}),
@@ -237,10 +237,10 @@ export interface BuildDelegationTokenUsageOptions {
}
const TOKEN_MODELS: Array<{ id: string; name: string; promptRatio: number; costPerToken: number; provenance: TokenProvenance }> = [
- { id: 'qwen3-coder-30b', name: 'Qwen3-Coder-30B', promptRatio: 0.78, costPerToken: 0, provenance: 'measured' },
- { id: 'claude-sonnet-4-6', name: 'claude-sonnet-4-6', promptRatio: 0.72, costPerToken: 0.000003, provenance: 'measured' },
- { id: 'glm-4-plus', name: 'glm-4-plus', promptRatio: 0.68, costPerToken: 0.0000015, provenance: 'estimated' },
- { id: 'codex-cli', name: 'codex-cli', promptRatio: 0.65, costPerToken: 0.000002, provenance: 'estimated' },
+ { id: 'qwen3-coder-30b', name: 'qwen3-coder-30b', promptRatio: 0.78, costPerToken: 0, provenance: 'measured' },
+ { id: 'deepseek-r1-14b', name: 'deepseek-r1-14b', promptRatio: 0.72, costPerToken: 0.000003, provenance: 'measured' },
+ { id: 'openrouter-glm-flash', name: 'openrouter-glm-flash', promptRatio: 0.68, costPerToken: 0.0000015, provenance: 'estimated' },
+ { id: 'claude-sonnet-4-6', name: 'claude-sonnet-4-6', promptRatio: 0.65, costPerToken: 0.000002, provenance: 'estimated' },
];
export function buildDelegationTokenUsage(
diff --git a/src/storybook/fixtures/delegation.ts b/src/storybook/fixtures/delegation.ts
index 97c5bfa3..02401ac4 100644
--- a/src/storybook/fixtures/delegation.ts
+++ b/src/storybook/fixtures/delegation.ts
@@ -21,7 +21,7 @@ export interface BuildDelegationMetricsOptions {
}
const TASK_TYPES = ['code-review', 'pattern-match', 'document-summarize', 'classification'];
-const MODELS = ['Qwen3-Coder-30B', 'glm-4-plus', 'codex-cli', 'gemini-cli'];
+const MODELS = ['qwen3-coder-30b', 'deepseek-r1-14b', 'openrouter-glm-flash', 'claude-sonnet-4-6'];
/**
* Build a single `DelegationSummary` record. Story callers should