[object Object]

← back to Model Arena

add DeepSeek V3 + R1 to model-arena via OpenRouter

83c932f02a5f9916002c8dc484c2a560ebe9c307 · 2026-09-08 14:17:58 -0700 · Steve Abrams

New MODELS entries (openrouter provider, OpenAI-compatible path), openrouter
base URL added to both provider maps, PRICING row, key routed from secrets.
V3 uses the tool loop; R1 uses the design pack (its tool-calling is unreliable).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012k7pnZxHquVVfKE9REX9vL

Files touched

Diff

commit 83c932f02a5f9916002c8dc484c2a560ebe9c307
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Sep 8 14:17:58 2026 -0700

    add DeepSeek V3 + R1 to model-arena via OpenRouter
    
    New MODELS entries (openrouter provider, OpenAI-compatible path), openrouter
    base URL added to both provider maps, PRICING row, key routed from secrets.
    V3 uses the tool loop; R1 uses the design pack (its tool-calling is unreliable).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_012k7pnZxHquVVfKE9REX9vL
---
 server.js | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/server.js b/server.js
index ae59108..a63c5bb 100644
--- a/server.js
+++ b/server.js
@@ -90,6 +90,9 @@ const MODELS = [
   { id: 'gpt',        label: 'GPT-5.1',        kind: 'metered', provider: 'openai',    model: process.env.OPENAI_MODEL || 'gpt-5.1', envKey: 'OPENAI_API_KEY', estCost: 0.10, tools: true },
   { id: 'codex',      label: 'Codex GPT-5.3',  kind: 'metered', provider: 'openai',    model: process.env.CODEX_MODEL || 'gpt-5.3-codex', envKey: 'OPENAI_API_KEY', estCost: 0.10, responses: true, dtdRef: 'Codex' },
   { id: 'grok',       label: 'Grok 4.5',       kind: 'metered', provider: 'xai',       model: process.env.GROK_MODEL || 'grok-4.5', envKey: 'XAI_API_KEY', estCost: 0.10, tools: true, dtdRef: 'Grok' },
+  // DeepSeek via OpenRouter (OpenAI-compatible). V3 = general/coding (tool loop); R1 = reasoner (design pack — R1 tool-calling is unreliable).
+  { id: 'deepseek-v3', label: 'DeepSeek V3',   kind: 'metered', provider: 'openrouter', model: process.env.DEEPSEEK_V3_MODEL || 'deepseek/deepseek-chat', envKey: 'OPENROUTER_API_KEY', estCost: 0.01, tools: true, dtdRef: 'DeepSeek' },
+  { id: 'deepseek-r1', label: 'DeepSeek R1',   kind: 'metered', provider: 'openrouter', model: process.env.DEEPSEEK_R1_MODEL || 'deepseek/deepseek-r1', envKey: 'OPENROUTER_API_KEY', estCost: 0.03, dtdRef: 'DeepSeek-R1' },
 ];
 
 // Claude via the Claude Code CLI — runs on Steve's Max SUBSCRIPTION (OAuth), not
@@ -298,7 +301,7 @@ async function generateLocal(m, prompt) {
 
 // metered pricing per 1M tokens [in, out] — rough, for the cost line
 const PRICING = {
-  anthropic: [5, 25], moonshot: [0.6, 2.5], openai: [1.75, 14], xai: [3, 15],
+  anthropic: [5, 25], moonshot: [0.6, 2.5], openai: [1.75, 14], xai: [3, 15], openrouter: [0.5, 2],
 };
 function meteredCost(provider, inTok, outTok) {
   const [pi, po] = PRICING[provider] || [0, 0];
@@ -324,7 +327,7 @@ async function generateMetered(m, prompt) {
     text = r.json.output_text || r.json.output.flatMap(o => o.content || []).map(c => c.text || '').join('');
     inTok = (r.json.usage && r.json.usage.input_tokens) || 0; outTok = (r.json.usage && r.json.usage.output_tokens) || 0;
   } else {
-    const base = { moonshot: 'https://api.moonshot.ai/v1', openai: 'https://api.openai.com/v1', xai: 'https://api.x.ai/v1' }[m.provider];
+    const base = { moonshot: 'https://api.moonshot.ai/v1', openai: 'https://api.openai.com/v1', xai: 'https://api.x.ai/v1', openrouter: 'https://openrouter.ai/api/v1' }[m.provider];
     // gpt-5 family only accepts max_completion_tokens (not max_tokens) and only
     // the default temperature; moonshot/xai take the classic max_tokens+temperature.
     const body = m.provider === 'openai'
@@ -357,7 +360,7 @@ async function runDesignTool(name, args, calls) {
 async function generateMeteredTools(m, prompt) {
   const key = process.env[m.envKey];
   if (!key) throw new Error(m.envKey + ' not set — metered model unavailable');
-  const base = { moonshot: 'https://api.moonshot.ai/v1', openai: 'https://api.openai.com/v1', xai: 'https://api.x.ai/v1' }[m.provider];
+  const base = { moonshot: 'https://api.moonshot.ai/v1', openai: 'https://api.openai.com/v1', xai: 'https://api.x.ai/v1', openrouter: 'https://openrouter.ai/api/v1' }[m.provider];
   if (!base) return generateMetered(m, prompt); // anthropic et al: no tool loop wired — plain path
   const messages = [{ role: 'user', content: prompt }];
   const calls = [];

← d2334fb auto-data-snapshot: 2026-09-08T07:45:26 (2 data files) — dat  ·  back to Model Arena  ·  add OpenAI Astra 6.0 (gpt-6-astra) to model-arena via OpenRo cd49868 →