<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://oakimov.github.io/claude-code-router/blog</id>
    <title>Claude Code Router Blog</title>
    <updated>2026-06-01T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://oakimov.github.io/claude-code-router/blog"/>
    <subtitle>Claude Code Router Blog</subtitle>
    <icon>https://oakimov.github.io/claude-code-router/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[Fork Changelog — What We've Added]]></title>
        <id>https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog</id>
        <link href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog"/>
        <updated>2026-06-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This fork of claude-code-router adds several provider integrations, UI improvements, and infrastructure changes. Here's the timeline of what was added and when.]]></summary>
        <content type="html"><![CDATA[<p>This fork of claude-code-router adds several provider integrations, UI improvements, and infrastructure changes. Here's the timeline of what was added and when.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="january-2026--mistral-integration">January 2026 — Mistral Integration<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#january-2026--mistral-integration" class="hash-link" aria-label="Direct link to January 2026 — Mistral Integration" title="Direct link to January 2026 — Mistral Integration" translate="no">​</a></h2>
<p>Added the <strong>Mistral AI transformer</strong> with direct API support, including reasoning parameter handling and dedicated Docker Compose configuration. Decoupled Mistral transformation logic into shared utilities.</p>
<ul>
<li class=""><code>feat: add Mistral transformer for direct API support</code></li>
<li class=""><code>fix: correctly handle reasoning parameter for Mistral API</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="april-2026--gemini-stability-code-quality--build-pipeline">April 2026 — Gemini Stability, Code Quality &amp; Build Pipeline<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#april-2026--gemini-stability-code-quality--build-pipeline" class="hash-link" aria-label="Direct link to April 2026 — Gemini Stability, Code Quality &amp; Build Pipeline" title="Direct link to April 2026 — Gemini Stability, Code Quality &amp; Build Pipeline" translate="no">​</a></h2>
<p>Major improvements to Gemini/Gemma streaming reliability. Fixed Gemini 500 errors caused by malformed <code>thoughtSignature</code> placement in request bodies and tool use failures in multi-turn conversations. The project was fully localized (all comments translated to English). The <strong>UI package was integrated into the Docker build</strong> process so the management interface is served directly from the container.</p>
<ul>
<li class=""><code>build: include UI package in Docker build process</code></li>
<li class=""><code>refactor: localize codebase by translating all comments to English</code></li>
<li class=""><code>fix: resolve Gemini 500 errors and tool use failures</code></li>
<li class=""><code>feat: add ThinkingSequencer for ordered Gemini streaming</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="may-7--deepseek-reasoning-replay">May 7 — DeepSeek Reasoning Replay<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#may-7--deepseek-reasoning-replay" class="hash-link" aria-label="Direct link to May 7 — DeepSeek Reasoning Replay" title="Direct link to May 7 — DeepSeek Reasoning Replay" translate="no">​</a></h2>
<p>Implemented <strong>mandatory reasoning replay</strong> for DeepSeek models. DeepSeek requires previous assistant reasoning content to be included in subsequent requests — without this, the model loses coherence across multi-turn conversations. The <code>reasoning</code> transformer captures reasoning output from responses and replays it automatically.</p>
<ul>
<li class=""><code>feat: implement mandatory reasoning replay for DeepSeek provider</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="may-7--codex-chatgpt-integration">May 7 — Codex (ChatGPT) Integration<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#may-7--codex-chatgpt-integration" class="hash-link" aria-label="Direct link to May 7 — Codex (ChatGPT) Integration" title="Direct link to May 7 — Codex (ChatGPT) Integration" translate="no">​</a></h2>
<p>Added the <strong>Codex transformer</strong> supporting OpenAI's Responses API, with OAuth authentication via PKCE flow (<code>ccr codex-auth</code>). Supports SSE streaming, reasoning/thinking content, tool calls, web search, and image handling. Requires a ChatGPT Plus or Pro subscription.</p>
<ul>
<li class=""><code>feat: add Codex transformer and support for Codex authentication</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="may-8--model-discovery">May 8 — Model Discovery<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#may-8--model-discovery" class="hash-link" aria-label="Direct link to May 8 — Model Discovery" title="Direct link to May 8 — Model Discovery" translate="no">​</a></h2>
<p>Added <strong>non-interactive model discovery</strong> (<code>ccr model get</code>). Fetches remote models from any provider's API, parses custom JSON structures, and appends missing models to the local configuration without modifying existing entries.</p>
<ul>
<li class=""><code>feat: add support for custom provider model discovery</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="may-10--chrome-on-device-gemini-nano">May 10 — Chrome On-Device (Gemini Nano)<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#may-10--chrome-on-device-gemini-nano" class="hash-link" aria-label="Direct link to May 10 — Chrome On-Device (Gemini Nano)" title="Direct link to May 10 — Chrome On-Device (Gemini Nano)" translate="no">​</a></h2>
<p>Added the <strong>Chrome On-Device bridge and transformer</strong> for Chrome's built-in Gemini Nano model (~4GB local LLM). Communicates via the Chrome DevTools Protocol (CDP) and provides zero-cost, zero-latency local inference. Features include stall recovery with dynamic temperature scaling, structured JSON output via <code>responseConstraint</code>, and full SSE streaming.</p>
<ul>
<li class=""><code>feat: add Chrome on-device bridge and transformer for Gemini Nano</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="may-12--bridge-stability-improvements">May 12 — Bridge Stability Improvements<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#may-12--bridge-stability-improvements" class="hash-link" aria-label="Direct link to May 12 — Bridge Stability Improvements" title="Direct link to May 12 — Bridge Stability Improvements" translate="no">​</a></h2>
<p>Enhanced the Chrome bridge with a multi-session dashboard, idle eviction for stale sessions, improved tool-loop prevention via reflexive detection, and optimized system prompts for tool interaction consistency.</p>
<ul>
<li class=""><code>feat(bridge): add multi-session dashboard, idle eviction</code></li>
<li class=""><code>refactor: migrate bridge to explicit &lt;tool_result&gt; XML tags</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="may-18--passthrough-mode--deepseek-thinking-fix">May 18 — Passthrough Mode &amp; DeepSeek Thinking Fix<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#may-18--passthrough-mode--deepseek-thinking-fix" class="hash-link" aria-label="Direct link to May 18 — Passthrough Mode &amp; DeepSeek Thinking Fix" title="Direct link to May 18 — Passthrough Mode &amp; DeepSeek Thinking Fix" translate="no">​</a></h2>
<p>Added per-provider passthrough mode for direct Anthropic-style auth handling, and fixed DeepSeek thinking without requiring the client to send a reasoning parameter.</p>
<ul>
<li class=""><code>feat: add per-provider passthrough mode</code></li>
<li class=""><code>fix: enable DeepSeek thinking without client reasoning param</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="may-25--codex-fixes--anthropic-effort-passthrough">May 25 — Codex Fixes &amp; Anthropic Effort Passthrough<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#may-25--codex-fixes--anthropic-effort-passthrough" class="hash-link" aria-label="Direct link to May 25 — Codex Fixes &amp; Anthropic Effort Passthrough" title="Direct link to May 25 — Codex Fixes &amp; Anthropic Effort Passthrough" translate="no">​</a></h2>
<p>Fixed Codex transformer arguments for tool calls, restored streaming usage calculation, and passed Claude Code's effort parameter directly instead of mapping through budget_tokens.</p>
<ul>
<li class=""><code>fix(anthropic): pass through Claude Code effort directly</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="june-1--qwen-chat-integration">June 1 — Qwen Chat Integration<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#june-1--qwen-chat-integration" class="hash-link" aria-label="Direct link to June 1 — Qwen Chat Integration" title="Direct link to June 1 — Qwen Chat Integration" translate="no">​</a></h2>
<p>Added the <strong>Qwen Chat auth transformer</strong> with JWT-based authentication (<code>ccr qwen-auth</code>) and a browser-based auth page at <code>/qwen/auth</code> supporting a bookmarklet for easy token extraction from <code>chat.qwen.ai</code>. Automatic token rotation and stripping of Qwen's trailing <code>&lt;details&gt;...&lt;/details&gt;</code> metadata block.</p>
<ul>
<li class=""><code>feat(qwen): add Qwen Chat auth (ccr qwen-auth) and provider transformer</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="documentation">Documentation<a href="https://oakimov.github.io/claude-code-router/blog/2026/06/01/fork-changelog#documentation" class="hash-link" aria-label="Direct link to Documentation" title="Direct link to Documentation" translate="no">​</a></h2>
<p>All features have dedicated integration guides in the docs:</p>
<ul>
<li class=""><a class="" href="https://oakimov.github.io/claude-code-router/docs/server/guides/codex">Codex Integration</a></li>
<li class=""><a class="" href="https://oakimov.github.io/claude-code-router/docs/server/guides/qwen">Qwen Chat Integration</a></li>
<li class=""><a class="" href="https://oakimov.github.io/claude-code-router/docs/server/guides/chrome-on-device">Chrome On-Device</a></li>
<li class=""><a class="" href="https://oakimov.github.io/claude-code-router/docs/server/guides/deepseek-reasoning">DeepSeek Reasoning Replay</a></li>
<li class=""><a class="" href="https://oakimov.github.io/claude-code-router/docs/server/guides/model-discovery">Model Discovery</a></li>
</ul>]]></content>
        <category label="changelog" term="changelog"/>
        <category label="fork" term="fork"/>
        <category label="features" term="features"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[GLM-4.6 Supports Reasoning and Interleaved Thinking]]></title>
        <id>https://oakimov.github.io/claude-code-router/blog/2025/11/18/glm-reasoning</id>
        <link href="https://oakimov.github.io/claude-code-router/blog/2025/11/18/glm-reasoning"/>
        <updated>2025-11-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Enabling Reasoning in Claude Code with GLM-4.6]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="enabling-reasoning-in-claude-code-with-glm-46">Enabling Reasoning in Claude Code with GLM-4.6<a href="https://oakimov.github.io/claude-code-router/blog/2025/11/18/glm-reasoning#enabling-reasoning-in-claude-code-with-glm-46" class="hash-link" aria-label="Direct link to Enabling Reasoning in Claude Code with GLM-4.6" title="Direct link to Enabling Reasoning in Claude Code with GLM-4.6" translate="no">​</a></h2>
<p>Starting from version 4.5, GLM has supported Claude Code. I've been following its progress closely, and many users have reported that reasoning could not be enabled within Claude Code. Recently, thanks to sponsorship from Zhipu, I decided to investigate this issue in depth. According to the <a href="https://docs.z.ai/api-reference/llm/chat-completion" target="_blank" rel="noopener noreferrer" class="">official documentation</a>, the<code>/chat/completions</code> endpoint has reasoning enabled by default, but the model itself decides whether to think:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">thinking.type enum&lt;string&gt; default:enabled</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Whether to enable the chain of thought(When enabled, GLM-4.6, GLM-4.5 and others will automatically determine whether to think, while GLM-4.5V will think compulsorily), default: enabled</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Available options: enabled, disabled</span><br></div></code></pre></div></div>
<p>However, within Claude Code, its heavy system prompt interference disrupts GLM's internal reasoning judgment, causing the model to rarely think.
Therefore, we need to explicitly guide the model to believe reasoning is required. Since claude-code-router functions as a proxy, the only feasible approach is modifying prompts or parameters.</p>
<p>Initially, I tried completely removing Claude Code's system prompt — and indeed, the model started reasoning — but that broke Claude Code's workflow.
So instead, I used prompt injection to clearly instruct the model to think step by step.</p>
<div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// transformer.ts</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> UnifiedChatRequest </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"../types/llm"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> Transformer </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"../types/transformer"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">ForceReasoningTransformer</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">implements</span><span class="token plain"> </span><span class="token class-name">Transformer</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  name </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"forcereasoning"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">transformRequestIn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">request</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> UnifiedChatRequest</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Promise</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">UnifiedChatRequest</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> systemMessage </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">messages</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">find</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">item</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> item</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">role </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"system"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Array</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">isArray</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">systemMessage</span><span class="token operator" style="color:#393A34">?.</span><span class="token plain">content</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      systemMessage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">content</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"text"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">text</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"You are an expert reasoning model.\nAlways think step by step before answering. Even if the problem seems simple, always write down your reasoning process explicitly.\nNever skip your chain of thought.\nUse the following output format:\n&lt;reasoning_content&gt;(Write your full detailed thinking here.)&lt;/reasoning_content&gt;\n\nWrite your final conclusion here."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> lastMessage </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">messages</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">messages</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">length </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lastMessage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">role </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"user"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> Array</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">isArray</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lastMessage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">content</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      lastMessage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">content</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"text"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">text</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"You are an expert reasoning model.\nAlways think step by step before answering. Even if the problem seems simple, always write down your reasoning process explicitly.\nNever skip your chain of thought.\nUse the following output format:\n&lt;reasoning_content&gt;(Write your full detailed thinking here.)&lt;/reasoning_content&gt;\n\nWrite your final conclusion here."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lastMessage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">role </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"tool"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">messages</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"user"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">content</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"text"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token literal-property property" style="color:#36acaa">text</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"You are an expert reasoning model.\nAlways think step by step before answering. Even if the problem seems simple, always write down your reasoning process explicitly.\nNever skip your chain of thought.\nUse the following output format:\n&lt;reasoning_content&gt;(Write your full detailed thinking here.)&lt;/reasoning_content&gt;\n\nWrite your final conclusion here."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> request</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Why use <code>&lt;reasoning_content&gt;</code> instead of the <code>&lt;think&gt;</code> tag? Two reasons:</p>
<ol>
<li class="">
<p>Using the <code>&lt;think&gt;</code> tag doesn't effectively trigger reasoning — likely because the model was trained on data where <code>&lt;think&gt;</code> had special behavior.</p>
</li>
<li class="">
<p>If we use <code>&lt;think&gt;</code>, the reasoning output is split into a separate field, which directly relates to the chain-of-thought feedback problem discussed below.</p>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="chain-of-thought-feedback">Chain-of-Thought Feedback<a href="https://oakimov.github.io/claude-code-router/blog/2025/11/18/glm-reasoning#chain-of-thought-feedback" class="hash-link" aria-label="Direct link to Chain-of-Thought Feedback" title="Direct link to Chain-of-Thought Feedback" translate="no">​</a></h2>
<p>Recently, Minimax released <code>Minimax-m2</code>, along with <a href="https://www.minimaxi.com/news/why-is-interleaved-thinking-important-for-m2" target="_blank" rel="noopener noreferrer" class="">an article</a> explaining interleaved thinking.
While the idea isn't entirely new, it's a good opportunity to analyze it.</p>
<p>Why do we need to interleaved thinking?
Minimax's article mentions that the Chat Completion API does not support passing reasoning content between requests.
We know ChatGPT was the first to support reasoning, but OpenAI initially didn't expose the chain of thought to users.
Therefore, the Chat Completion API didn't need to support it. Even the CoT field was first introduced by DeepSeek.</p>
<p>Do we really need explicit CoT fields? What happens if we don't have them? Will it affect reasoning?
By inspecting <a href="https://github.com/sgl-project/sglang/blob/main/python/sglang/srt/parser/reasoning_parser.py" target="_blank" rel="noopener noreferrer" class="">sglang's source code</a>, we can see that reasoning content is naturally emitted in messages with specific markers.
If we don't split it out, the next-round conversation will naturally include it.
Thus, the only reason we need interleaved thinking is because we separated the reasoning content from the normal messages.</p>
<p>With fewer than 40 lines of code above, I implemented a simple exploration of enabling reasoning and chain-of-thought feedback for GLM-4.5/4.6.
(It's only simple because I haven't implemented parsing logic yet — you could easily modify the transformer to split reasoning output on response and merge it back on request, improving Claude Code's frontend display compatibility.)</p>
<p>If you have better ideas, feel free to reach out — I'd love to discuss further.</p>]]></content>
        <category label="glm" term="glm"/>
        <category label="reasoning" term="reasoning"/>
        <category label="chain-of-thought" term="chain-of-thought"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Maybe We Can Do More with the Router]]></title>
        <id>https://oakimov.github.io/claude-code-router/blog/2025/11/18/router-exploration</id>
        <link href="https://oakimov.github.io/claude-code-router/blog/2025/11/18/router-exploration"/>
        <updated>2025-11-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Since the release of claude-code-router, I've received a lot of user feedback, and quite a few issues are still open. Most of them are related to support for different providers and the lack of tool usage from the deepseek model.]]></summary>
        <content type="html"><![CDATA[<p>Since the release of <code>claude-code-router</code>, I've received a lot of user feedback, and quite a few issues are still open. Most of them are related to support for different providers and the lack of tool usage from the deepseek model.</p>
<p>Originally, I created this project for personal use, mainly to access claude code at a lower cost. So, multi-provider support wasn't part of the initial design. But during troubleshooting, I discovered that even though most providers claim to be compatible with the OpenAI-style <code>/chat/completions</code> interface, there are many subtle differences. For example:</p>
<ol>
<li class="">
<p>When Gemini's tool parameter type is string, the <code>format</code> field only supports <code>date</code> and <code>date-time</code>, and there's no tool call ID.</p>
</li>
<li class="">
<p>OpenRouter requires <code>cache_control</code> for caching.</p>
</li>
<li class="">
<p>The official DeepSeek API has a <code>max_output</code> of 8192, but Volcano Engine's limit is even higher.</p>
</li>
</ol>
<p>Aside from these, smaller providers often have quirks in their parameter handling. So I decided to create a new project, <a href="https://github.com/musistudio/llms" target="_blank" rel="noopener noreferrer" class="">musistudio/llms</a>, to deal with these compatibility issues. It uses the OpenAI format as a base and introduces a generic Transformer interface for transforming both requests and responses.</p>
<p>Once a <code>Transformer</code> is implemented for each provider, it becomes possible to mix-and-match requests between them. For example, I implemented bidirectional conversion between Anthropic and OpenAI formats in <code>AnthropicTransformer</code>, which listens to the <code>/v1/messages</code> endpoint. Similarly, <code>GeminiTransformer</code> handles Gemini &lt;-&gt; OpenAI format conversions and listens to <code>/v1beta/models/:modelAndAction</code>.</p>
<p>When both requests and responses are transformed into a common format, they can interoperate seamlessly:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">AnthropicRequest -&gt; AnthropicTransformer -&gt; OpenAIRequest -&gt; GeminiTransformer -&gt; GeminiRequest -&gt; GeminiServer</span><br></div></code></pre></div></div>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">GeminiResponse -&gt; GeminiTransformer -&gt; OpenAIResponse -&gt; AnthropicTransformer -&gt; AnthropicResponse</span><br></div></code></pre></div></div>
<p>Using a middleware layer to smooth out differences may introduce some performance overhead, but the main goal here is to enable <code>claude-code-router</code> to support multiple providers.</p>
<p>As for the issue of DeepSeek's lackluster tool usage — I found that it stems from poor instruction adherence in long conversations. Initially, the model actively calls tools, but after several rounds, it starts responding with plain text instead. My first workaround was injecting a system prompt to remind the model to use tools proactively. But in long contexts, the model tends to forget this instruction.</p>
<p>After reading the DeepSeek documentation, I noticed it supports the <code>tool_choice</code> parameter, which can be set to <code>"required"</code> to force the model to use at least one tool. I tested this by enabling the parameter, and it significantly improved the model's tool usage. We can remove the setting when it's no longer necessary. With the help of the <code>Transformer</code> interface in <a href="https://github.com/musistudio/llms" target="_blank" rel="noopener noreferrer" class="">musistudio/llms</a>, we can modify the request before it's sent and adjust the response after it's received.</p>
<p>Inspired by the Plan Mode in <code>claude code</code>, I implemented a similar Tool Mode for DeepSeek:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name maybe-class-name">TooluseTransformer</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">implements</span><span class="token plain"> </span><span class="token class-name maybe-class-name">Transformer</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  name </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"tooluse"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">transformRequestIn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">request</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">UnifiedChatRequest</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">UnifiedChatRequest</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">tools</span><span class="token operator" style="color:#393A34">?.</span><span class="token plain">length</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">messages</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"system"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        content</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">&lt;system-reminder&gt;Tool mode is active. The user expects you to proactively execute the most suitable tool to help complete the task.</span><br></div><div class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">Before invoking a tool, you must carefully evaluate whether it matches the current task. If no available tool is appropriate for the task, you MUST call the \`ExitTool\` to exit tool mode — this is the only valid way to terminate tool mode.</span><br></div><div class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">Always prioritize completing the user's task effectively and efficiently by using tools whenever appropriate.&lt;/system-reminder&gt;</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">tool_choice</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"required"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">tools</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">unshift</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"function"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">function</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"ExitTool"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">Use this tool when you are in tool mode and have completed the task. This is the only valid way to exit tool mode.</span><br></div><div class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">IMPORTANT: Before using this tool, ensure that none of the available tools are applicable to the current task. You must evaluate all available options — only if no suitable tool can help you complete the task should you use ExitTool to terminate tool mode.</span><br></div><div class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">Examples:</span><br></div><div class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">1. Task: "Use a tool to summarize this document" — Do not use ExitTool if a summarization tool is available.</span><br></div><div class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">2. Task: "What's the weather today?" — If no tool is available to answer, use ExitTool after reasoning that none can fulfill the task.</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          parameters</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"object"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            properties</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              response</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"string"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                  </span><span class="token string" style="color:#e3116c">"Your response will be forwarded to the user exactly as returned — the tool will not modify or post-process it in any way."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            required</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"response"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> request</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">transformResponseOut</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">response</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Response</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Promise</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">Response</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">headers</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Content-Type"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?.</span><span class="token method function property-access" style="color:#d73a49">includes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"application/json"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> jsonResponse </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">json</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        jsonResponse</span><span class="token operator" style="color:#393A34">?.</span><span class="token plain">choices</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">?.</span><span class="token plain">message</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">tool_calls</span><span class="token operator" style="color:#393A34">?.</span><span class="token plain">length </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        jsonResponse</span><span class="token operator" style="color:#393A34">?.</span><span class="token plain">choices</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">?.</span><span class="token plain">message</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">tool_calls</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">?.</span><span class="token plain">function</span><span class="token operator" style="color:#393A34">?.</span><span class="token plain">name </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token string" style="color:#e3116c">"ExitTool"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> toolArguments </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">JSON</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">toolCall</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">function</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">arguments</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"{}"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        jsonResponse</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">choices</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">message</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">content</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> toolArguments</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">response</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">delete</span><span class="token plain"> jsonResponse</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">choices</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">message</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">tool_calls</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// Handle non-streaming response if needed</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name maybe-class-name">Response</span><span class="token punctuation" style="color:#393A34">(</span><span class="token known-class-name class-name">JSON</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">stringify</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">jsonResponse</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        status</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">status</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        statusText</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">statusText</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        headers</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">headers</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">headers</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Content-Type"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">?.</span><span class="token method function property-access" style="color:#d73a49">includes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"stream"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> response</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>This transformer ensures the model calls at least one tool. If no tools are appropriate or the task is finished, it can exit using <code>ExitTool</code>. Since this relies on the <code>tool_choice</code> parameter, it only works with models that support it.</p>
<p>In practice, this approach noticeably improves tool usage for DeepSeek. The tradeoff is that sometimes the model may invoke irrelevant or unnecessary tools, which could increase latency and token usage.</p>
<p>This update is just a small experiment — adding an <code>"agent"</code> to the router. Maybe there are more interesting things we can explore from here.</p>]]></content>
        <category label="router" term="router"/>
        <category label="transformer" term="transformer"/>
        <category label="deepseek" term="deepseek"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Project Motivation and Principles]]></title>
        <id>https://oakimov.github.io/claude-code-router/blog/2025/02/25/project-motivation</id>
        <link href="https://oakimov.github.io/claude-code-router/blog/2025/02/25/project-motivation"/>
        <updated>2025-02-25T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[As early as the day after Claude Code was released (2025-02-25), I began and completed a reverse engineering attempt of the project. At that time, using Claude Code required registering for an Anthropic account, applying for a waitlist, and waiting for approval. However, due to well-known reasons, Anthropic blocks users from mainland China, making it impossible for me to use the service through normal means. Based on known information, I discovered the following:]]></summary>
        <content type="html"><![CDATA[<p>As early as the day after Claude Code was released (2025-02-25), I began and completed a reverse engineering attempt of the project. At that time, using Claude Code required registering for an Anthropic account, applying for a waitlist, and waiting for approval. However, due to well-known reasons, Anthropic blocks users from mainland China, making it impossible for me to use the service through normal means. Based on known information, I discovered the following:</p>
<ol>
<li class="">Claude Code is installed via npm, so it's very likely developed with Node.js.</li>
<li class="">Node.js offers various debugging methods: simple <code>console.log</code> usage, launching with <code>--inspect</code> to hook into Chrome DevTools, or even debugging obfuscated code using <code>d8</code>.</li>
</ol>
<p>My goal was to use Claude Code without an Anthropic account. I didn't need the full source code—just a way to intercept and reroute requests made by Claude Code to Anthropic's models to my own custom endpoint. So I started the reverse engineering process:</p>
<ol>
<li class="">First, install Claude Code:</li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">npm</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-g</span><span class="token plain"> @anthropic-ai/claude-code</span><br></div></code></pre></div></div>
<ol start="2">
<li class="">
<p>After installation, the project is located at <code>~/.nvm/versions/node/v20.10.0/lib/node_modules/@anthropic-ai/claude-code</code>(this may vary depending on your Node version manager and version).</p>
</li>
<li class="">
<p>Open the package.json to analyze the entry point:</p>
</li>
</ol>
<div class="language-package.json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-package.json codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">{</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "name": "@anthropic-ai/claude-code",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "version": "1.0.24",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "main": "sdk.mjs",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "types": "sdk.d.ts",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "bin": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "claude": "cli.js"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "engines": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "node": "&gt;=18.0.0"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "type": "module",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "author": "Boris Cherny &lt;boris@anthropic.com&gt;",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "license": "SEE LICENSE IN README.md",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "description": "Use Claude, Anthropic's AI assistant, right from your terminal. Claude can understand your codebase, edit files, run terminal commands, and handle entire workflows for you.",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "homepage": "https://github.com/anthropics/claude-code",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "bugs": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "url": "https://github.com/anthropics/claude-code/issues"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "scripts": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "prepare": "node -e \"if (!process.env.AUTHORIZED) { console.error('ERROR: Direct publishing is not allowed.\\nPlease use the publish-external.sh script to publish this package.'); process.exit(1); }\"",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "preinstall": "node scripts/preinstall.js"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  },</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "dependencies": {},</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "optionalDependencies": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "@img/sharp-darwin-arm64": "^0.33.5",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "@img/sharp-darwin-x64": "^0.33.5",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "@img/sharp-linux-arm": "^0.33.5",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "@img/sharp-linux-arm64": "^0.33.5",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "@img/sharp-linux-x64": "^0.33.5",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "@img/sharp-win32-x64": "^0.33.5"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>The key entry is <code>"claude": "cli.js"</code>. Opening cli.js, you'll see the code is minified and obfuscated. But using WebStorm's <code>Format File</code> feature, you can reformat it for better readability:
<img decoding="async" loading="lazy" alt="webstorm-formate-file" src="https://oakimov.github.io/claude-code-router/assets/images/webstorm-formate-file-6f0d9de12c63cc99d85bc36522b53c5a.png" width="3218" height="2082" class="img_ev3q"></p>
<p>Now you can begin understanding Claude Code's internal logic and prompt structure by reading the code. To dig deeper, you can insert console.log statements or launch in debug mode with Chrome DevTools using:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token assign-left variable" style="color:#36acaa">NODE_OPTIONS</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"--inspect-brk=9229"</span><span class="token plain"> claude</span><br></div></code></pre></div></div>
<p>This command starts Claude Code in debug mode and opens port 9229. Visit chrome://inspect/ in Chrome and click inspect to begin debugging:
<img decoding="async" loading="lazy" alt="chrome-devtools" src="https://oakimov.github.io/claude-code-router/assets/images/chrome-inspect-38499e7f3ad61207e7f7a402d1c07c4d.png" width="3098" height="1716" class="img_ev3q">
<img decoding="async" loading="lazy" alt="chrome-devtools" src="https://oakimov.github.io/claude-code-router/assets/images/chrome-devtools-9fb03a216664e64b9358877c6dcd21ee.png" width="3248" height="1922" class="img_ev3q"></p>
<p>By searching for the keyword api.anthropic.com, you can easily locate where Claude Code makes its API calls. From the surrounding code, it's clear that baseURL can be overridden with the <code>ANTHROPIC_BASE_URL</code> environment variable, and <code>apiKey</code> and <code>authToken</code> can be configured similarly:
<img decoding="async" loading="lazy" alt="search" src="https://oakimov.github.io/claude-code-router/assets/images/search-8bab61f834826571afe5c7ac34db708c.png" width="3248" height="1922" class="img_ev3q"></p>
<p>So far, we've discovered some key information:</p>
<ol>
<li class="">
<p>Environment variables can override Claude Code's <code>baseURL</code> and <code>apiKey</code>.</p>
</li>
<li class="">
<p>Claude Code adheres to the Anthropic API specification.</p>
</li>
</ol>
<p>Therefore, we need:</p>
<ol>
<li class="">
<p>A service to convert OpenAI API-compatible requests into Anthropic API format.</p>
</li>
<li class="">
<p>Set the environment variables before launching Claude Code to redirect requests to this service.</p>
</li>
</ol>
<p>Thus, <code>claude-code-router</code> was born. This project uses <code>Express.js</code> to implement the <code>/v1/messages</code> endpoint. It leverages middlewares to transform request/response formats and supports request rewriting (useful for prompt tuning per model).</p>
<p>Back in February, the full DeepSeek model series had poor support for Function Calling, so I initially used <code>qwen-max</code>. It worked well—but without KV cache support, it consumed a large number of tokens and couldn't provide the native <code>Claude Code</code> experience.</p>
<p>So I experimented with a Router-based mode using a lightweight model to dispatch tasks. The architecture included four roles: <code>router</code>, <code>tool</code>, <code>think</code>, and <code>coder</code>. Each request passed through a free lightweight model that would decide whether the task involved reasoning, coding, or tool usage. Reasoning and coding tasks looped until a tool was invoked to apply changes. However, the lightweight model lacked the capability to route tasks accurately, and architectural issues prevented it from effectively driving Claude Code.</p>
<p>Everything changed at the end of May when the official Claude Code was launched, and <code>DeepSeek-R1</code> model (released 2025-05-28) added Function Call support. I redesigned the system. With the help of AI pair programming, I fixed earlier request/response transformation issues—especially the handling of models that return JSON instead of Function Call outputs.</p>
<p>This time, I used the <code>DeepSeek-V3</code>  model. It performed better than expected: supporting most tool calls, handling task decomposition and stepwise planning, and—most importantly—costing less than one-tenth the price of Claude 3.5 Sonnet.</p>
<p>The official Claude Code organizes agents differently from the beta version, so I restructured my Router mode to include four roles: the default model, <code>background</code>, <code>think</code>, and <code>longContext</code>.</p>
<ul>
<li class="">
<p>The default model handles general tasks and acts as a fallback.</p>
</li>
<li class="">
<p>The <code>background</code> model manages lightweight background tasks. According to Anthropic, Claude Haiku 3.5 is often used here, so I routed this to a local <code>ollama</code> service.</p>
</li>
<li class="">
<p>The <code>think</code> model is responsible for reasoning and planning mode tasks. I use <code>DeepSeek-R1</code> here, though it doesn't support cost control, so <code>Think</code> and <code>UltraThink</code> behave identically.</p>
</li>
<li class="">
<p>The <code>longContext</code> model handles long-context scenarios. The router uses <code>tiktoken</code> to calculate token lengths in real time, and if the context exceeds 32K, it switches to this model to compensate for DeepSeek's long-context limitations.</p>
</li>
</ul>
<p>This describes the evolution and reasoning behind the project. By cleverly overriding environment variables, we can forward and modify requests without altering Claude Code's source—allowing us to benefit from official updates while using our own models and custom prompts.</p>
<p>This project offers a practical approach to running Claude Code under Anthropic's regional restrictions, balancing <code>cost</code>, <code>performance</code>, and <code>customizability</code>. That said, the official <code>Max Plan</code> still offers the best experience if available.</p>]]></content>
        <category label="claude-code" term="claude-code"/>
        <category label="reverse-engineering" term="reverse-engineering"/>
        <category label="tutorial" term="tutorial"/>
    </entry>
</feed>