<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>DeepSeek Harness on RockB</title><link>https://baeseokjae.github.io/tags/deepseek-harness/</link><description>Recent content in DeepSeek Harness on RockB</description><image><title>RockB</title><url>https://baeseokjae.github.io/images/og-default.png</url><link>https://baeseokjae.github.io/images/og-default.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 20 Aug 2026 07:02:10 +0000</lastBuildDate><atom:link href="https://baeseokjae.github.io/tags/deepseek-harness/index.xml" rel="self" type="application/rss+xml"/><item><title>TencentCloud AgentObs SDK for DeepSeek Harness: Zero-Collector GenAI Trace Observability</title><link>https://baeseokjae.github.io/posts/tencentcloud-agentobs-dsh-genai-traces/</link><pubDate>Thu, 20 Aug 2026 07:02:10 +0000</pubDate><guid>https://baeseokjae.github.io/posts/tencentcloud-agentobs-dsh-genai-traces/</guid><description>Add deepseek harness observability without an OTLP collector: the TencentCloud AgentObs DSH plugin pushes GenAI traces straight to CLS.</description><content:encoded><![CDATA[<p>DeepSeek Harness observability usually means standing up an OpenTelemetry collector, a tracing backend, and code instrumentation. The TencentCloud AgentObs SDK for DSH eliminates all of that: it is a DeepSeek Harness plugin that observes the harness&rsquo;s native session, agent-loop, LLM-stream, and tool lifecycles and uploads GenAI trace spans directly to Tencent Cloud Log Service (CLS) using Protobuf. There is no OTLP collector, no sidecar, and no extra service to deploy. If you already run agents on Tencent Cloud, this is the fastest path from &ldquo;where did my agent spend its tokens?&rdquo; to a dashboards-and-alerts answer.</p>
<h2 id="what-is-the-tencentcloud-agentobs-sdk-for-deepseek-harness">What is the TencentCloud AgentObs SDK for DeepSeek Harness?</h2>
<p>The TencentCloud AgentObs SDK for DSH (<code>tencentcloud-agentobs-sdk-dsh</code>) is a first-party observability plugin for DeepSeek Harness. Rather than treating DSH as a black box that you instrument from the outside, it hooks directly into the harness&rsquo;s own lifecycle events. Those events — a session starting, an agent being invoked, each ReAct round, an LLM stream, and every tool execution — are converted into spans that follow Tencent Cloud&rsquo;s AI Agent observability specification, then shipped to CLS through the official <code>tencentcloud-cls-sdk-js</code> transport.</p>
<p>The key architectural decision is that the plugin is transport-native to a cloud vendor&rsquo;s log service. Where most DSH observability plugins speak OpenTelemetry and require an OTLP endpoint, this one talks Protobuf directly to Tencent Cloud Log Service. For teams already paying for CLS, that removes an entire class of operational burden.</p>
<h2 id="how-does-dsh-genai-trace-observability-work-without-a-collector">How does DSH GenAI trace observability work without a collector?</h2>
<p>The zero-collector architecture is the plugin&rsquo;s defining feature. The data path is short and self-contained:</p>
<ol>
<li>DeepSeek Harness fires native lifecycle events during a session.</li>
<li>The AgentObs plugin&rsquo;s CLS Trace Coordinator receives those events.</li>
<li>Each event is normalized into Tencent Cloud&rsquo;s 5-layer span model.</li>
<li>Spans are batched and serialized with <code>tencentcloud-cls-sdk-js</code> (Protobuf).</li>
<li>Batches are uploaded directly to a CLS topic over HTTPS.</li>
</ol>
<p>There is no OpenTelemetry Collector to run, no Jaeger or SigNoz backend to maintain, and no sidecar container to schedule. Contrast that with the standard OpenTelemetry DeepSeek approach, which requires you to deploy an OTLP receiver and run <code>opentelemetry-distro</code> instrumentation on top of an OpenAI-compatible SDK. That approach is portable and vendor-neutral, but it is also infrastructure you must operate. The Tencent plugin trades portability for a dramatically simpler deploy.</p>
<h2 id="what-is-the-5-layer-span-model-for-ai-agent-observability">What is the 5-layer span model for AI agent observability?</h2>
<p>Tencent Cloud&rsquo;s AI Agent observability spec organizes traces into a five-layer span hierarchy: entry, agent, step, chat, and tool. The plugin maps DSH&rsquo;s native lifecycle onto that model, so a single DSH turn produces a nested trace:</p>



<div class="goat svg-container ">
  
    <svg
      xmlns="http://www.w3.org/2000/svg"
      font-family="Menlo,Lucida Console,monospace"
      
        viewBox="0 0 336 89"
      >
      <g transform='translate(8,16)'>
<text text-anchor='middle' x='0' y='4' fill='currentColor' style='font-size:1em'>E</text>
<text text-anchor='middle' x='0' y='20' fill='currentColor' style='font-size:1em'>└</text>
<text text-anchor='middle' x='8' y='4' fill='currentColor' style='font-size:1em'>N</text>
<text text-anchor='middle' x='8' y='20' fill='currentColor' style='font-size:1em'>─</text>
<text text-anchor='middle' x='16' y='4' fill='currentColor' style='font-size:1em'>T</text>
<text text-anchor='middle' x='16' y='20' fill='currentColor' style='font-size:1em'>─</text>
<text text-anchor='middle' x='24' y='4' fill='currentColor' style='font-size:1em'>R</text>
<text text-anchor='middle' x='32' y='4' fill='currentColor' style='font-size:1em'>Y</text>
<text text-anchor='middle' x='32' y='20' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='32' y='36' fill='currentColor' style='font-size:1em'>└</text>
<text text-anchor='middle' x='40' y='20' fill='currentColor' style='font-size:1em'>G</text>
<text text-anchor='middle' x='40' y='36' fill='currentColor' style='font-size:1em'>─</text>
<text text-anchor='middle' x='48' y='20' fill='currentColor' style='font-size:1em'>E</text>
<text text-anchor='middle' x='48' y='36' fill='currentColor' style='font-size:1em'>─</text>
<text text-anchor='middle' x='56' y='20' fill='currentColor' style='font-size:1em'>N</text>
<text text-anchor='middle' x='64' y='20' fill='currentColor' style='font-size:1em'>T</text>
<text text-anchor='middle' x='64' y='36' fill='currentColor' style='font-size:1em'>S</text>
<text text-anchor='middle' x='64' y='52' fill='currentColor' style='font-size:1em'>├</text>
<text text-anchor='middle' x='64' y='68' fill='currentColor' style='font-size:1em'>└</text>
<text text-anchor='middle' x='72' y='36' fill='currentColor' style='font-size:1em'>T</text>
<text text-anchor='middle' x='72' y='52' fill='currentColor' style='font-size:1em'>─</text>
<text text-anchor='middle' x='72' y='68' fill='currentColor' style='font-size:1em'>─</text>
<text text-anchor='middle' x='80' y='20' fill='currentColor' style='font-size:1em'>(</text>
<text text-anchor='middle' x='80' y='36' fill='currentColor' style='font-size:1em'>E</text>
<text text-anchor='middle' x='80' y='52' fill='currentColor' style='font-size:1em'>─</text>
<text text-anchor='middle' x='80' y='68' fill='currentColor' style='font-size:1em'>─</text>
<text text-anchor='middle' x='88' y='20' fill='currentColor' style='font-size:1em'>i</text>
<text text-anchor='middle' x='88' y='36' fill='currentColor' style='font-size:1em'>P</text>
<text text-anchor='middle' x='96' y='20' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='96' y='52' fill='currentColor' style='font-size:1em'>C</text>
<text text-anchor='middle' x='96' y='68' fill='currentColor' style='font-size:1em'>T</text>
<text text-anchor='middle' x='104' y='20' fill='currentColor' style='font-size:1em'>v</text>
<text text-anchor='middle' x='104' y='36' fill='currentColor' style='font-size:1em'>(</text>
<text text-anchor='middle' x='104' y='52' fill='currentColor' style='font-size:1em'>H</text>
<text text-anchor='middle' x='104' y='68' fill='currentColor' style='font-size:1em'>O</text>
<text text-anchor='middle' x='112' y='20' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='112' y='36' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='112' y='52' fill='currentColor' style='font-size:1em'>A</text>
<text text-anchor='middle' x='112' y='68' fill='currentColor' style='font-size:1em'>O</text>
<text text-anchor='middle' x='120' y='20' fill='currentColor' style='font-size:1em'>k</text>
<text text-anchor='middle' x='120' y='36' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='120' y='52' fill='currentColor' style='font-size:1em'>T</text>
<text text-anchor='middle' x='120' y='68' fill='currentColor' style='font-size:1em'>L</text>
<text text-anchor='middle' x='128' y='20' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='128' y='36' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='136' y='20' fill='currentColor' style='font-size:1em'>_</text>
<text text-anchor='middle' x='136' y='36' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='136' y='52' fill='currentColor' style='font-size:1em'>(</text>
<text text-anchor='middle' x='136' y='68' fill='currentColor' style='font-size:1em'>(</text>
<text text-anchor='middle' x='144' y='20' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='144' y='36' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='144' y='52' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='144' y='68' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='152' y='20' fill='currentColor' style='font-size:1em'>g</text>
<text text-anchor='middle' x='152' y='52' fill='currentColor' style='font-size:1em'>h</text>
<text text-anchor='middle' x='152' y='68' fill='currentColor' style='font-size:1em'>x</text>
<text text-anchor='middle' x='160' y='20' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='160' y='36' fill='currentColor' style='font-size:1em'>r</text>
<text text-anchor='middle' x='160' y='52' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='160' y='68' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='168' y='20' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='168' y='36' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='168' y='52' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='168' y='68' fill='currentColor' style='font-size:1em'>c</text>
<text text-anchor='middle' x='176' y='20' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='176' y='36' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='176' y='68' fill='currentColor' style='font-size:1em'>u</text>
<text text-anchor='middle' x='184' y='20' fill='currentColor' style='font-size:1em'>)</text>
<text text-anchor='middle' x='184' y='36' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='184' y='52' fill='currentColor' style='font-size:1em'>m</text>
<text text-anchor='middle' x='184' y='68' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='192' y='36' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='192' y='52' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='192' y='68' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='200' y='36' fill='currentColor' style='font-size:1em'>_</text>
<text text-anchor='middle' x='200' y='52' fill='currentColor' style='font-size:1em'>d</text>
<text text-anchor='middle' x='200' y='68' fill='currentColor' style='font-size:1em'>_</text>
<text text-anchor='middle' x='208' y='36' fill='currentColor' style='font-size:1em'>N</text>
<text text-anchor='middle' x='208' y='52' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='208' y='68' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='216' y='36' fill='currentColor' style='font-size:1em'>)</text>
<text text-anchor='middle' x='216' y='52' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='216' y='68' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='224' y='52' fill='currentColor' style='font-size:1em'>_</text>
<text text-anchor='middle' x='224' y='68' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='232' y='52' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='232' y='68' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='240' y='52' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='248' y='52' fill='currentColor' style='font-size:1em'>m</text>
<text text-anchor='middle' x='248' y='68' fill='currentColor' style='font-size:1em'>t</text>
<text text-anchor='middle' x='256' y='52' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='256' y='68' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='264' y='52' fill='currentColor' style='font-size:1em'>)</text>
<text text-anchor='middle' x='264' y='68' fill='currentColor' style='font-size:1em'>o</text>
<text text-anchor='middle' x='272' y='68' fill='currentColor' style='font-size:1em'>l</text>
<text text-anchor='middle' x='280' y='68' fill='currentColor' style='font-size:1em'>_</text>
<text text-anchor='middle' x='288' y='68' fill='currentColor' style='font-size:1em'>n</text>
<text text-anchor='middle' x='296' y='68' fill='currentColor' style='font-size:1em'>a</text>
<text text-anchor='middle' x='304' y='68' fill='currentColor' style='font-size:1em'>m</text>
<text text-anchor='middle' x='312' y='68' fill='currentColor' style='font-size:1em'>e</text>
<text text-anchor='middle' x='320' y='68' fill='currentColor' style='font-size:1em'>)</text>
</g>

    </svg>
  
</div>
<p>This nesting is what makes the trace useful. Instead of a flat list of spans, you see the whole shape of an agent turn: which round of ReAct a tool call happened in, which model answered which prompt, and where the time and tokens actually went. When you open a trace in CLS, you can drill from the top-level entry down to a single tool invocation in a specific reasoning step.</p>
<h2 id="what-span-semantics-are-recorded-under-the-hood">What span semantics are recorded under the hood?</h2>
<p>The plugin does not invent a proprietary trace format; it aligns with OpenTelemetry conventions. Each span carries the standard identifiers and metadata you would expect from a well-behaved tracer:</p>
<ul>
<li><code>traceID</code> as a 32-hex-character string</li>
<li><code>spanID</code> and <code>parentSpanID</code> as 16-hex-character strings</li>
<li>OpenTelemetry span kinds (<code>INTERNAL</code>, <code>CLIENT</code>, <code>SERVER</code>)</li>
<li>Status codes (<code>OK</code>, <code>ERROR</code>, <code>UNSET</code>)</li>
<li>Nanosecond-precision start, end, and duration fields</li>
<li>Token usage and model identifiers on chat spans</li>
</ul>
<p>This OTel alignment matters for two reasons. First, it keeps the data recognizable to engineers already comfortable with distributed tracing. Second, it makes correlation possible inside Tencent Cloud: because spans live in CLS, you can join GenAI traces against logs, metrics, and cost analytics in the same log platform, enabling session-to-token-cost analysis without a separate tracing database.</p>
<h2 id="how-do-i-install-the-dsh-plugin">How do I install the DSH plugin?</h2>
<p>Installation uses DeepSeek Harness&rsquo;s native plugin mechanism. You add the plugin to whichever profile you are running, then restart the harness for it to take effect:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>dsh plugin --profile web add tencentcloud-agentobs-sdk-dsh
</span></span><span style="display:flex;"><span><span style="color:#75715e"># or</span>
</span></span><span style="display:flex;"><span>dsh plugin --profile headless add tencentcloud-agentobs-sdk-dsh
</span></span><span style="display:flex;"><span><span style="color:#75715e"># or</span>
</span></span><span style="display:flex;"><span>dsh plugin --profile harness add tencentcloud-agentobs-sdk-dsh
</span></span></code></pre></div><p>Because the profile flag selects where the plugin applies, you can enable tracing only on the headless automation profile and leave interactive sessions untouched — or vice versa. The restart requirement is worth remembering: adding the plugin is not enough, DeepSeek Harness must be restarted before the observer attaches.</p>
<p>One installation pitfall applies to pnpm v9 or later. The plugin depends on <code>protobufjs</code>, which has a build script. Modern pnpm blocks build scripts by default, so you must approve them or the Protobuf serialization layer will not build:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>pnpm approve-builds
</span></span></code></pre></div><h2 id="how-do-i-configure-the-plugin">How do I configure the plugin?</h2>
<p>Configuration is handled either through environment variables or through a <code>cordis.patch.yml</code> file in the profile directory. The environment variable path is the quickest for a single deployment:</p>
<table>
  <thead>
      <tr>
          <th>Setting</th>
          <th>Environment variable</th>
          <th>Default</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CLS endpoint</td>
          <td><code>CLS_ENDPOINT</code></td>
          <td>—</td>
      </tr>
      <tr>
          <td>CLS topic ID</td>
          <td><code>CLS_TOPIC_ID</code></td>
          <td>—</td>
      </tr>
      <tr>
          <td>Secret ID</td>
          <td><code>CLS_SECRET_ID</code></td>
          <td>—</td>
      </tr>
      <tr>
          <td>Secret key</td>
          <td><code>CLS_SECRET_KEY</code></td>
          <td>—</td>
      </tr>
      <tr>
          <td>Service name</td>
          <td><code>CLS_SERVICE_NAME</code></td>
          <td>—</td>
      </tr>
      <tr>
          <td>Content capture</td>
          <td><code>OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT</code></td>
          <td><code>true</code></td>
      </tr>
  </tbody>
</table>
<p>The four credentials — endpoint, topic, secret ID, and secret key — are mandatory; without them the plugin has nowhere to write spans. The service name is how you identify this deployment inside CLS, so give it a value that distinguishes environments, for example <code>dsh-prod-web</code>.</p>
<p>For teams that prefer declarative config checked into the repo, <code>cordis.patch.yml</code> under the profile is the alternative. It carries the same options in YAML form and keeps secrets out of shell history — though you should still externalize the actual secret values through your secret manager rather than committing them.</p>
<h2 id="should-i-capture-prompts-responses-and-tool-content">Should I capture prompts, responses, and tool content?</h2>
<p>Content capture is on by default, and this is the feature that demands the most attention. With capture enabled, the plugin attaches prompts, LLM responses, and tool arguments and results to their spans. That gives you searchable, debuggable traces — but it also means credentials, source code, and personally identifiable information can be shipped to CLS as part of a trace.</p>
<p>The trade-off is real, and the brief is unambiguous: content capture can leak sensitive data into a cloud log service. You control the blast radius with two levers:</p>
<ul>
<li><code>captureContent: false</code> (or <code>OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=false</code>) disables content attachment entirely, leaving only span structure, timing, and metadata.</li>
<li><code>contentMaxChars</code>, defaulting to 128000, caps how much content a single span carries so a pathological tool result does not bloat a topic.</li>
</ul>
<p>For anything that touches production data, plan a content policy before you enable the plugin. Trace structure and timing usually survive with capture off; if you need content, apply the same redaction rules you use for your application logs.</p>
<h2 id="how-do-batching-buffering-and-retries-behave">How do batching, buffering, and retries behave?</h2>
<p>The plugin buffers spans in memory and flushes them in batches to avoid hammering CLS with a request per span. Four knobs control that behavior:</p>
<table>
  <thead>
      <tr>
          <th>Option</th>
          <th>Default</th>
          <th>Purpose</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>batchMaxSize</code></td>
          <td>32</td>
          <td>Maximum spans per upload</td>
      </tr>
      <tr>
          <td><code>maxQueueSize</code></td>
          <td>2048</td>
          <td>In-memory queue cap; oldest span is dropped when full</td>
      </tr>
      <tr>
          <td><code>flushIntervalMs</code></td>
          <td>5000</td>
          <td>How often buffered spans are flushed</td>
      </tr>
      <tr>
          <td><code>retryTimes</code></td>
          <td>3</td>
          <td>Retries per failed upload</td>
      </tr>
  </tbody>
</table>
<p>The most important implication is the drop policy. When the in-memory queue hits <code>maxQueueSize</code>, the plugin drops the oldest span rather than blocking the agent. That is a deliberate availability choice: observability must never stall the harness. Under normal load 2048 buffered spans is generous, but a burst of heavy tool calls can fill it, so treat dropped spans as a signal that batching needs tuning or the flush interval needs lowering.</p>
<h2 id="what-are-the-compatibility-requirements">What are the compatibility requirements?</h2>
<p>The plugin targets a specific window of DeepSeek Harness releases and a recent Node.js runtime:</p>
<table>
  <thead>
      <tr>
          <th>Component</th>
          <th>Requirement</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>DeepSeek Harness</td>
          <td><code>&gt;=0.1.0-rc.6</code> and <code>&lt;0.2.0</code></td>
      </tr>
      <tr>
          <td>Node.js</td>
          <td><code>&gt;=18.0.0</code></td>
      </tr>
      <tr>
          <td>Language</td>
          <td>TypeScript</td>
      </tr>
      <tr>
          <td>License</td>
          <td>Apache-2.0</td>
      </tr>
      <tr>
          <td>Package manager note</td>
          <td>pnpm v9+ needs <code>approve-builds</code></td>
      </tr>
  </tbody>
</table>
<p>The version pin matters. Because the plugin hooks DSH&rsquo;s internal lifecycle events, it depends on the event shapes of a particular harness generation. If you are on a Harness older than <code>0.1.0-rc.6</code> or have already moved to <code>0.2.0</code> and beyond, verify plugin compatibility before assuming your traces will appear.</p>
<h2 id="how-does-the-tencent-plugin-compare-to-other-dsh-observability-options">How does the Tencent plugin compare to other DSH observability options?</h2>
<p>DeepSeek Harness already has an observability ecosystem, and the Tencent plugin is not the only choice. The realistic decision is less &ldquo;which tracer&rdquo; and more &ldquo;which architecture&rdquo;:</p>
<table>
  <thead>
      <tr>
          <th>Approach</th>
          <th>Transport</th>
          <th>Collector needed?</th>
          <th>Best for</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>TencentCloud AgentObs DSH</td>
          <td>Protobuf → CLS</td>
          <td>No</td>
          <td>Teams already on Tencent Cloud wanting CLS-native dashboards</td>
      </tr>
      <tr>
          <td>dsh-plugin-langfuse</td>
          <td>OpenTelemetry → Langfuse</td>
          <td>Langfuse self-host or cloud</td>
          <td>Teams standardizing on Langfuse as the LLM observability platform</td>
      </tr>
      <tr>
          <td>dsh-Agentlink</td>
          <td>OTel bridge to Codex</td>
          <td>OTLP endpoint</td>
          <td>Cross-framework observability bridging</td>
      </tr>
      <tr>
          <td>dsh-plugin-opentelemetry-tracing</td>
          <td>OTel → generic OTLP</td>
          <td>OTLP backend (e.g., SigNoz, Jaeger)</td>
          <td>Vendor-neutral, self-hosted stacks</td>
      </tr>
  </tbody>
</table>
<p>The structural difference is collector versus no collector. <code>dsh-plugin-langfuse</code> and the generic OpenTelemetry plugin both lean on OTLP and expect an endpoint you run or subscribe to. Langfuse, the incumbent open-source LLM observability platform, also auto-traces OpenAI-compatible DeepSeek API calls through <code>langfuse.openai</code>, but it still requires running Langfuse as a backend. The Tencent plugin is the first DSH plugin that targets a specific cloud vendor&rsquo;s native log service, so it carries no collector and no extra backend — you only need the CLS topic you already pay for.</p>
<h2 id="who-should-use-it-and-who-should-skip-it">Who should use it, and who should skip it?</h2>
<p>This plugin is a strong fit for teams that are already invested in Tencent Cloud. If your infrastructure, log pipeline, and alerting all live in CLS, pushing GenAI traces into the same platform gives you unified dashboards, cost correlation, and retention policy management without introducing a second observability silo. The zero-collector setup is genuinely attractive for a small agent fleet where running an OTLP stack is disproportionate overhead.</p>
<p>It is a less obvious fit when you are not on Tencent Cloud. The plugin locks your trace data to a single vendor&rsquo;s log service, and if your organization standardizes on OpenTelemetry or a self-hosted stack, <code>dsh-plugin-langfuse</code> or the generic OTel plugin keeps you portable. If your DeepSeek Harness version has drifted outside the supported window, portability also wins. In short: Tencent Cloud users get the cleanest setup; everyone else should weigh vendor lock-in against the convenience.</p>
<h2 id="hands-on-from-install-to-your-first-cls-trace">Hands-on: from install to your first CLS trace</h2>
<p>A minimal end-to-end run looks like this. First, add the plugin to the profile you run:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>dsh plugin --profile harness add tencentcloud-agentobs-sdk-dsh
</span></span><span style="display:flex;"><span>pnpm approve-builds   <span style="color:#75715e"># required on pnpm v9+</span>
</span></span></code></pre></div><p>Second, set the CLS credentials. With environment variables:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>export CLS_ENDPOINT<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;ap-guangzhou.cls.tencentcs.com&#34;</span>
</span></span><span style="display:flex;"><span>export CLS_TOPIC_ID<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;your-topic-id&#34;</span>
</span></span><span style="display:flex;"><span>export CLS_SECRET_ID<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;your-secret-id&#34;</span>
</span></span><span style="display:flex;"><span>export CLS_SECRET_KEY<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;your-secret-key&#34;</span>
</span></span><span style="display:flex;"><span>export CLS_SERVICE_NAME<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;dsh-prod&#34;</span>
</span></span></code></pre></div><p>Third, restart DeepSeek Harness so the observer attaches. Fourth, run a session that invokes the agent and at least one tool. Within the flush interval, spans will appear in your CLS topic, nested as entry → agent → step → chat → tool. From there, build a dashboard for token usage and per-tool latency, and add an alert on ERROR-status spans — you now have deepseek harness observability without a single extra service to run.</p>
<h2 id="what-pitfalls-should-i-watch-for">What pitfalls should I watch for?</h2>
<p>The practical gotchas cluster around configuration, privacy, and environment:</p>
<ul>
<li><strong>Content leakage.</strong> Capture is on by default; disable it or set <code>contentMaxChars</code> before tracing anything sensitive.</li>
<li><strong>pnpm build scripts.</strong> On pnpm v9+, forgetting <code>pnpm approve-builds</code> breaks the Protobuf layer silently at build time.</li>
<li><strong>Restart required.</strong> Adding the plugin does not attach it; you must restart DeepSeek Harness.</li>
<li><strong>Queue overflow drops.</strong> At <code>maxQueueSize</code> the oldest span is dropped to keep the harness responsive — not a sign of a network failure.</li>
<li><strong>Version drift.</strong> Outside <code>&gt;=0.1.0-rc.6 &lt;0.2.0</code> the lifecycle hooks may not fire, so traces can silently not appear.</li>
<li><strong>Secrets in config.</strong> Prefer a secret manager for <code>CLS_SECRET_ID</code> / <code>CLS_SECRET_KEY</code> over committing them to <code>cordis.patch.yml</code>.</li>
</ul>
<h2 id="faq">FAQ</h2>
<h3 id="what-does-deepseek-harness-observability-mean-in-practice">What does deepseek harness observability mean in practice?</h3>
<p>It means capturing the full lifecycle of a DeepSeek Harness run — session, agent invocation, each ReAct step, LLM calls, and tool executions — as structured trace spans so you can inspect latency, token usage, and errors per agent turn.</p>
<h3 id="does-the-tencentcloud-agentobs-sdk-require-an-otlp-collector">Does the TencentCloud AgentObs SDK require an OTLP collector?</h3>
<p>No. It uploads GenAI trace spans directly to Tencent Cloud Log Service via Protobuf using <code>tencentcloud-cls-sdk-js</code>. There is no OTLP collector, sidecar, or extra backend to deploy.</p>
<h3 id="what-span-hierarchy-does-the-plugin-produce-for-a-single-dsh-turn">What span hierarchy does the plugin produce for a single DSH turn?</h3>
<p>Each turn produces an ENTRY span containing an AGENT span, which contains STEP spans per ReAct round. Each STEP in turn has CHAT (model) and TOOL (tool execution) children, following Tencent Cloud&rsquo;s 5-layer entry → agent → step → chat → tool model.</p>
<h3 id="is-prompt-and-tool-content-captured-by-default">Is prompt and tool content captured by default?</h3>
<p>Yes, content capture is enabled by default, attaching prompts, responses, and tool arguments to spans. Disable it with <code>captureContent: false</code> or the <code>OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=false</code> environment variable.</p>
<h3 id="which-deepseek-harness-versions-does-the-plugin-support">Which DeepSeek Harness versions does the plugin support?</h3>
<p>It supports DeepSeek Harness <code>&gt;=0.1.0-rc.6</code> and <code>&lt;0.2.0</code>, with Node.js <code>&gt;=18.0.0</code>. It is Apache-2.0 licensed and written in TypeScript.</p>
]]></content:encoded></item><item><title>dsh whale meter tokens: Track DeepSeek Harness Token Usage &amp; Cost Tiers</title><link>https://baeseokjae.github.io/posts/dsh-whale-meter-token-usage-cost/</link><pubDate>Mon, 17 Aug 2026 16:13:59 +0000</pubDate><guid>https://baeseokjae.github.io/posts/dsh-whale-meter-token-usage-cost/</guid><description>dsh-whale-meter shows your DeepSeek Harness token usage in 5 gamified tiers and estimates cost in CNY or USD, fully on-device with no telemetry.</description><content:encoded><![CDATA[<p><strong>dsh-whale-meter is a one-line-install, zero-configuration plugin for DeepSeek Harness (DSH) that turns your raw token usage into five gamified tiers — from 🐟 small fry to 🐳 blue whale — and estimates your spend in CNY or USD, all stored locally on your machine with no telemetry and no network calls.</strong> It went from a nice-to-have to a budgeting necessity on August 17, 2026, when DeepSeek raised v4-flash and v4-pro prices and introduced peak/off-peak billing. This guide explains exactly what it tracks, how the new pricing works, and whether it beats the alternative cost-tracking tools.</p>
<h2 id="what-is-dsh-whale-meter-and-why-you-need-it-now-post-8-17-price-hike-context">What Is dsh-whale-meter and Why You Need It Now (Post-8-17 Price Hike Context)</h2>
<p>DeepSeek Harness is a powerful agentic coding harness, but for a long time it gave users almost no visibility into how many tokens they were actually consuming or what those tokens cost. That gap is exactly what dsh-whale-meter (仓库: <code>Shiye-10Pages/dsh-whale-meter</code>) was built to close. It is a native DSH plugin written in TypeScript under an MIT License, released on August 16, 2026, with a design goal of &ldquo;one-line install, zero config, all data local.&rdquo;</p>
<p>The timing is not accidental. On <strong>August 17, 2026</strong>, DeepSeek raised the prices of v4-flash and v4-pro and, for the first time, introduced <strong>peak/off-peak billing</strong> in China. That single change turned token spend from a background curiosity into a line item you must actively manage. As the broader industry scramble shows, teams are routinely blowing through their token budgets — TechCrunch reported in June 2026 that many teams were running at <strong>3x their 2026 token budgets by April</strong>, with individual engineers seeing monthly token spikes in the <strong>$40,000 range</strong>. The days of &ldquo;just let the model run&rdquo; are over.</p>
<p>dsh-whale-meter answers the three questions every heavy DSH user now asks daily: <em>How many tokens am I using?</em> <em>What am I actually spending?</em> <em>Is my usage tier creeping toward the top?</em></p>
<h2 id="key-features--token-usage-tiers-cost-dashboard-and-the-whale-score-card">Key Features — Token Usage Tiers, Cost Dashboard, and the Whale Score Card</h2>
<p>The headline feature is a <strong>gamified usage ladder</strong> with five tiers:</p>
<table>
  <thead>
      <tr>
          <th>Tier</th>
          <th>Emoji</th>
          <th>Meaning</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Small fry</td>
          <td>🐟</td>
          <td>Light usage</td>
      </tr>
      <tr>
          <td>Tropical fish</td>
          <td>🐠</td>
          <td>Moderate usage</td>
      </tr>
      <tr>
          <td>Dolphin</td>
          <td>🐬</td>
          <td>Above-average usage</td>
      </tr>
      <tr>
          <td>Humpback</td>
          <td>🐋</td>
          <td>Heavy usage</td>
      </tr>
      <tr>
          <td>Blue whale</td>
          <td>🐳</td>
          <td>Extreme usage</td>
      </tr>
  </tbody>
</table>
<p>Each tier carries an <strong>estimated percentile</strong> — the project is careful to label this as an estimate, not a claimed global rank — plus a playful magnitude conversion that frames your usage as &ldquo;≈ N reads of Three-Body.&rdquo; It turns an abstract number of tokens into something you can actually feel.</p>
<p>The <strong>cost dashboard</strong> is the practical workhorse. It reports spend across four time windows — <strong>today, yesterday, month, and cumulative</strong> — in CNY by default, swappable to USD. Costs are estimated from the official DeepSeek pricing pages, so they track the real tariff rather than a stale hardcoded rate.</p>
<p>Two features make the dashboard genuinely useful rather than decorative:</p>
<ul>
<li><strong>8-17 price-hike comparison.</strong> The same usage is priced side-by-side under the old and new tariffs. Pre-August-17 usage is shown as a <em>preview</em> of what it would have cost under the new rate; post-August-17 usage gets a <em>retroactive back-calculation</em> of what it would have cost under the old rate. This makes the real impact of the hike measurable in one glance.</li>
<li><strong>Cross-price-day correctness.</strong> Price tables are organized by effective date ranges, so historical bills are never mis-computed against today&rsquo;s rates.</li>
</ul>
<h2 id="how-the-8-17-price-change-works-v4-flash--v4-pro-peak-vs-off-peak-before-after-compare">How the 8-17 Price Change Works (v4-flash / v4-pro, Peak vs Off-Peak, Before-After Compare)</h2>
<p>The August 17 change has two parts: a <strong>price hike</strong> and a <strong>new peak/off-peak structure</strong>. Both are baked into the whale-meter&rsquo;s built-in price table (version 2026-08-16 already contains the new rates).</p>
<p>For <strong>v4-flash</strong> (per million tokens, cache miss), the changes are:</p>
<table>
  <thead>
      <tr>
          <th>Cost component</th>
          <th>Before 8-17</th>
          <th>Peak (after 8-17)</th>
          <th>Off-peak (after 8-17)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cache hit</td>
          <td>¥0.02</td>
          <td>¥0.10</td>
          <td>¥0.05</td>
      </tr>
      <tr>
          <td>Cache miss</td>
          <td>¥1</td>
          <td>¥3</td>
          <td>¥1.50</td>
      </tr>
      <tr>
          <td>Output</td>
          <td>¥2</td>
          <td>¥9</td>
          <td>¥4.50</td>
      </tr>
  </tbody>
</table>
<p><strong>v4-pro</strong> adjusted in parallel: peak pricing of ¥0.30 / ¥9 / ¥27 (hit / miss / output), with off-peak exactly half. <strong>Peak hours are Beijing 9:00–12:00 and 14:00–18:00.</strong></p>
<p>The <strong>non-obvious point most guides get wrong</strong> is this: even if you run entirely off-peak, the off-peak rate is <strong>still more expensive than the old flat pre-8-17 price</strong>. Look at the v4-flash table above — the off-peak miss rate of ¥1.50 beats the old ¥1.00 flat rate, and off-peak output at ¥4.50 is more than double the old ¥2.00. Off-peak is a discount <em>relative to the new peak rate</em>, not a return to the old prices. The whale-meter makes this visible with a <strong>⚡½ badge</strong> shown during off-peak hours, and its before/after comparison panel surfaces exactly how much the hike costs you even on the cheapest schedule.</p>
<h2 id="multi-vendor-precision-pricing-46-models-across-6-providers-including-china-tiered-rates">Multi-Vendor Precision Pricing: 46 Models Across 6 Providers, Including China Tiered Rates</h2>
<p>whale-meter is not limited to DeepSeek. It ships with a pricing database covering <strong>46 models across 6 vendors</strong>: DeepSeek, Anthropic, OpenAI, Google, Zhipu GLM, and Moonshot Kimi. Every model is itemized against the official pricing pages.</p>
<p>What sets it apart from most generic cost tools is how it handles <strong>tiered pricing from Chinese vendors</strong>, which most trackers simply ignore:</p>
<ul>
<li><strong>GLM-5.1</strong> input is priced by context length: <strong>&lt;32K tokens costs ¥6, ≥32K costs ¥8</strong> per million.</li>
<li><strong>GLM-4.7</strong> sub-divides even further, tiering by output length.</li>
</ul>
<p>Because the tier boundary depends on per-call context size, a flat price-table lookup produces wrong numbers. whale-meter applies the correct tier per call. When a model is not yet in the table, it is explicitly marked <strong>unpriced</strong> rather than silently estimated — an honest design choice that prevents fabricated cost figures.</p>
<h2 id="privacy--data-locality-fully-on-device-no-telemetry-raw-token-only-storage">Privacy &amp; Data Locality: Fully On-Device, No Telemetry, Raw-Token-Only Storage</h2>
<p>Privacy is a first-class design constraint, and it is the sharpest contrast with cloud-based dashboards. Everything runs on-device:</p>
<ul>
<li>Usage is stored in <code>~/.dsh/whale-meter/usage-YYYY-MM.jsonl</code>.</li>
<li>Only <strong>raw token counts</strong> are persisted — monetary amounts are recomputed on read, so no dollar figures are ever frozen into storage.</li>
<li>There are <strong>no network requests</strong> except the optional balance query you explicitly enable.</li>
<li>There is <strong>no telemetry</strong> of any kind.</li>
</ul>
<p>For a tool that sits next to all of your agent activity, this matters. A cloud dashboard necessarily exfiltrates at least aggregate usage data; whale-meter keeps the entire ledger local. The raw-token-only design also means a later price change can be applied retroactively to historical usage without storing contradictory amounts.</p>
<h2 id="installation-and-configuration-dsh-plugin-zero-config-cordispatchyml-options">Installation and Configuration (dsh plugin, zero-config, cordis.patch.yml options)</h2>
<p>Installation is a single command. If you run DSH with a profile:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>dsh plugin --profile &lt;profile&gt; add dsh-whale-meter
</span></span></code></pre></div><p>There is a <strong>web panel</strong> for TUI or headless setups at <code>http://127.0.0.1:3080/whale-meter/api/summary</code>. Configuration options live in <code>cordis.patch.yml</code>, letting you tweak behavior without touching source code. The project&rsquo;s stated goal is zero-config for the common case: install, open the panel, and you immediately see your tiers and spend.</p>
<h2 id="limitations-and-honest-caveats-estimates-not-exact-unknown-models-marked-unpriced-community-plugin">Limitations and Honest Caveats (Estimates Not Exact, Unknown Models Marked Unpriced, Community Plugin)</h2>
<p>No cost tracker is perfect, and whale-meter is transparent about its boundaries:</p>
<ul>
<li><strong>Costs are estimates, not invoices.</strong> Prices are drawn from official pages, but actual billing can differ due to rounding, promotions, or regional rules. Treat the dashboard as a budgeting guide, not an accounting record.</li>
<li><strong>Unknown models are marked unpriced.</strong> If whale-meter hasn&rsquo;t been updated for a newly released model, it will not invent a price — you&rsquo;ll see it flagged instead.</li>
<li><strong>It&rsquo;s a community plugin.</strong> The repo is young (created August 16, 2026, roughly 3 stars at time of research) and MIT-licensed. You&rsquo;re relying on an actively maintained community project rather than an official DeepSeek product.</li>
<li><strong>Tiers are percentile estimates</strong>, not confirmed global rankings. They give you a feel for where you sit, but &ldquo;blue whale&rdquo; is descriptive, not audited.</li>
</ul>
<h2 id="dsh-whale-meter-vs-alternative-cost-tracking-tools-cachelens-agentledger-agentic-metric">dsh-whale-meter vs Alternative Cost-Tracking Tools (CacheLens, AgentLedger, Agentic Metric)</h2>
<p>How does the DSH-native plugin compare to the wider field of agent cost trackers?</p>
<table>
  <thead>
      <tr>
          <th>Tool</th>
          <th>Approach</th>
          <th>Best for</th>
          <th>Data locality</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>dsh-whale-meter</strong></td>
          <td>DSH-native plugin, zero-config, gamified tiers</td>
          <td>DeepSeek Harness users who want instant local visibility</td>
          <td>Fully on-device</td>
      </tr>
      <tr>
          <td><strong>CacheLens</strong></td>
          <td>Local-first proxy that tracks cache-hit savings</td>
          <td>Anyone focused on cache economics as an observability layer</td>
          <td>Local proxy</td>
      </tr>
      <tr>
          <td><strong>AgentLedger</strong></td>
          <td>SDK-based observability of real agent actions (SSE streaming)</td>
          <td>Teams tracking actions, not just LLM calls</td>
          <td>Cloud/streaming</td>
      </tr>
      <tr>
          <td><strong>Agentic Metric</strong></td>
          <td>Token/cost tracking for AI coding agents, broader than DSH</td>
          <td>Multi-tool agent environments</td>
          <td>Varies</td>
      </tr>
  </tbody>
</table>
<p>The trade-off is clear. Generic proxy and ledger tools (CacheLens, AgentLedger, Agentic Metric) are broader — AgentLedger, for instance, tracks every real-world agent action with sub-second SSE latency rather than just LLM calls. But they require integration, a proxy, or an SDK, and they don&rsquo;t understand DSH&rsquo;s internals. whale-meter&rsquo;s advantage is that it is a <strong>zero-config native plugin</strong>: no proxy to configure, no SDK to wire in, and it inherently knows the DSH data layout. If you&rsquo;re all-in on DSH, the plugin approach wins on speed and locality; if you span many tools, a broader tracker makes more sense.</p>
<h2 id="verdict-and-roadmap">Verdict and Roadmap</h2>
<p>For anyone running DeepSeek Harness seriously, dsh-whale-meter earns its place immediately. The 8-17 price hike means <strong>running blind on tokens now costs real money</strong> — and the peak/off-peak structure adds a scheduling decision you can only make with a meter. The gamified tiers make the abstract tangible, the before/after price comparison makes the hike measurable, and the fully-local, no-telemetry design makes it trustworthy.</p>
<p>The roadmap points in sensible directions: <strong>CSV/Markdown export</strong> for records and reporting, <strong>off-peak scheduling suggestions</strong> to help you shift work into the half-price window, and an enhanced <strong>TUI</strong>. Combined with the cache-ledger view — whose value <em>grows</em> after the hike, since the cache hit/miss price gap widened — these additions would round it into a complete cost-control tool.</p>
<p>If you use DSH and haven&rsquo;t looked at your token bill yet, now is the moment. Install whale-meter, read your tier, and schedule your heavy runs off-peak. Your wallet will thank you.</p>
<h2 id="faq">FAQ</h2>
<p><strong>What exactly does dsh-whale-meter track?</strong>
It tracks your DeepSeek Harness token usage across five gamified tiers (🐟 small fry through 🐳 blue whale) and estimates your cost over today, yesterday, the current month, and cumulative totals, in CNY or USD.</p>
<p><strong>How does the 8-17 DeepSeek price change work?</strong>
On August 17, 2026, DeepSeek raised v4-flash and v4-pro prices and introduced peak/off-peak billing. Peak hours are Beijing 9:00–12:00 and 14:00–18:00; off-peak costs exactly half the peak rate but is still more expensive than the old flat pre-8-17 price.</p>
<p><strong>Is whale-meter data private?</strong>
Yes. All data is stored locally in <code>~/.dsh/whale-meter/usage-YYYY-MM.jsonl</code>, only raw token counts are persisted, and there is no telemetry or network traffic except an optional balance query you enable manually.</p>
<p><strong>Does whale-meter support models beyond DeepSeek?</strong>
Yes. It covers 46 models across 6 vendors — DeepSeek, Anthropic, OpenAI, Google, Zhipu GLM, and Moonshot Kimi — including China vendors&rsquo; tiered pricing such as GLM-5.1&rsquo;s &lt;32K vs ≥32K input rates.</p>
<p><strong>Is whale-meter free and where do I get it?</strong>
It is an MIT-licensed open-source project at <code>Shiye-10Pages/dsh-whale-meter</code>. Install with <code>dsh plugin --profile &lt;profile&gt; add dsh-whale-meter</code>, then open the web panel at <code>http://127.0.0.1:3080/whale-meter/api/summary</code>.</p>
]]></content:encoded></item><item><title>OpenTelemetry Tracing for DeepSeek Harness: A Complete Setup Guide</title><link>https://baeseokjae.github.io/posts/opentelemetry-tracing-for-deepseek-harness/</link><pubDate>Sun, 16 Aug 2026 10:01:56 +0000</pubDate><guid>https://baeseokjae.github.io/posts/opentelemetry-tracing-for-deepseek-harness/</guid><description>Learn how to add OpenTelemetry tracing to DeepSeek Harness with community plugins, OTLP export, and GenAI semantic conventions.</description><content:encoded><![CDATA[<p>OpenTelemetry tracing for DeepSeek Harness lets you export every agent session, LLM call, and tool invocation as a standard OTLP trace tree to backends like Jaeger, Grafana Tempo, SigNoz, or Langfuse. You add it by installing a community plugin that implements the official <code>@deepseek-ai/dsh-session-telemetry</code> seam, configure an OTLP endpoint and a privacy mode, and then read the GenAI trace tree to debug agent loops, retries, and token usage.</p>
<h2 id="what-is-deepseek-harness-and-why-it-needs-tracing">What is DeepSeek Harness and why it needs tracing</h2>
<p>DeepSeek Harness is the official open-source agent framework from DeepSeek, written in TypeScript with the tagline &ldquo;Everything is a Plugin.&rdquo; Its official repository has roughly 123,000 GitHub stars, making it one of the most popular agent harnesses in the ecosystem. The framework orchestrates multi-step agent loops: it plans, calls LLMs, invokes tools, spawns subagents, and retries failed steps. Each of those steps is a potential failure point, and without tracing you are effectively debugging a black box.</p>
<p>Agent loops are non-deterministic. A single user request can trigger dozens of LLM calls, tool invocations, and retries, and the failure often lives in the interaction between them rather than in any single call. Traditional logging gives you a flat stream of text with no causal structure. OpenTelemetry tracing gives you a hierarchical span tree that shows exactly which step produced which LLM call, which tool ran under which step, and which retries happened along the way.</p>
<p>For DeepSeek Harness specifically, tracing matters because of its plugin architecture. Because &ldquo;everything is a plugin,&rdquo; the harness exposes a public telemetry seam that any plugin can implement. That means you are not locked into a single vendor&rsquo;s exporter. You can swap the official OTLP-logs exporter for a community OTLP-traces plugin without forking the harness, and you can point the output at whichever backend your team already runs.</p>
<h2 id="understanding-the-telemetry-seam-deepseek-aidsh-session-telemetry">Understanding the telemetry seam (@deepseek-ai/dsh-session-telemetry)</h2>
<p>The key architectural fact is that DeepSeek Harness ships a public telemetry seam called <code>@deepseek-ai/dsh-session-telemetry</code>. This is the contract that plugins implement to receive session, agent-loop, LLM-stream, and tool-lifecycle events. The official repository also ships an OTLP-logs exporter that implements this seam.</p>
<p>Community plugins implement the same seam as alternative backends. Instead of exporting logs, they convert the events into OpenTelemetry GenAI traces and metrics. Because they implement the same interface, you can drop them in without modifying the harness source code.</p>
<p>There is one critical gotcha: the telemetry seam accepts exactly one backend per context. If you load a duplicate backend — for example, the official OTLP-logs exporter and a tracing plugin at the same time — the load throws an error. You must choose one backend per context, not stack them.</p>
<h2 id="choosing-an-opentelemetry-backend-jaeger-grafana-tempo-signoz-langfuse">Choosing an OpenTelemetry backend (Jaeger, Grafana Tempo, SigNoz, Langfuse)</h2>
<p>Because the plugins export standard OTLP/HTTP protobuf, you can send traces to any compatible backend. The table below compares the most common choices.</p>
<table>
  <thead>
      <tr>
          <th>Backend</th>
          <th>Best for</th>
          <th>OTLP support</th>
          <th>GenAI semconv</th>
          <th>Notes</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Jaeger</td>
          <td>Lightweight local debugging</td>
          <td>Yes</td>
          <td>Partial</td>
          <td>Fast to spin up with Docker; great for single-node dev</td>
      </tr>
      <tr>
          <td>Grafana Tempo</td>
          <td>Grafana stack users</td>
          <td>Yes</td>
          <td>Yes</td>
          <td>Pairs with Grafana dashboards and Loki logs</td>
      </tr>
      <tr>
          <td>SigNoz</td>
          <td>Open-source APM alternative</td>
          <td>Yes</td>
          <td>Yes</td>
          <td>Full APM with metrics, traces, and logs in one</td>
      </tr>
      <tr>
          <td>Langfuse</td>
          <td>LLM product teams</td>
          <td>Yes</td>
          <td>Yes</td>
          <td>Native LLM features: feedback scores, sessions, prompts</td>
      </tr>
  </tbody>
</table>
<p>The GenAI semantic conventions (semconv) are what make these traces portable. They standardize LLM span attributes — model name, provider, token usage, prompt and completion — so the same trace renders meaningfully in Jaeger, Tempo, SigNoz, and Langfuse alike. If you already run one of these backends, you do not need to stand up a new one.</p>
<h2 id="installing-a-dsh-opentelemetry-tracing-plugin">Installing a dsh OpenTelemetry tracing plugin</h2>
<p>The most popular community options are <code>loongsuite/dsh-plugin</code>, <code>linyp/dsh-plugin-langfuse</code>, <code>CodePrometheus/dsh-observability</code>, and <code>TtTRz/dsh-langfuse</code>. All of them implement the telemetry seam and export OTLP traces. The table below summarizes their differences.</p>
<table>
  <thead>
      <tr>
          <th>Plugin</th>
          <th>Backend target</th>
          <th>Trace shape</th>
          <th>Metrics</th>
          <th>Notable config</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>loongsuite/dsh-plugin</td>
          <td>Any OTLP backend</td>
          <td>ENTRY -&gt; AGENT -&gt; STEP -&gt; LLM/TOOL</td>
          <td>gen_ai.client.operation.duration, gen_ai.client.token.usage</td>
          <td>Standalone, no sidecar or vendor dependency</td>
      </tr>
      <tr>
          <td>linyp/dsh-plugin-langfuse</td>
          <td>Langfuse</td>
          <td>One trace per turn, grouped by session</td>
          <td>No</td>
          <td>Reads LANGFUSE_HOST; feedback as Langfuse Scores</td>
      </tr>
      <tr>
          <td>CodePrometheus/dsh-observability</td>
          <td>Any OTLP backend</td>
          <td>Session span tree, model step to child span</td>
          <td>No</td>
          <td>DSH_OBSERVABILITY_MODE and DSH_OBSERVABILITY_OTLP_URL</td>
      </tr>
      <tr>
          <td>TtTRz/dsh-langfuse</td>
          <td>Langfuse</td>
          <td>One trace tree per session</td>
          <td>No</td>
          <td>Feedback scores and subagent lineage</td>
      </tr>
  </tbody>
</table>
<p>Before installing, verify your environment meets the requirements. The telemetry plugins require Node.js version 22.19.0 or higher and a DeepSeek Harness version of at least 0.1.0-rc.6 and below 0.2.0. If your harness is older or newer than that range, the plugin may not load.</p>
<p>Installation is typically done as a profile bundle. For example, the Langfuse plugin installs via a <code>cordis.patch.yml</code> profile bundle, and it reads the <code>LANGFUSE_HOST</code> environment variable rather than <code>LANGFUSE_BASE_URL</code>. Check each plugin&rsquo;s README for the exact install command, because the bundle mechanism differs slightly between plugins.</p>
<h2 id="configuring-otlp-export-and-privacy-modes-full--feedback_only--disabled">Configuring OTLP export and privacy modes (FULL / FEEDBACK_ONLY / DISABLED)</h2>
<p>Privacy is a first-class concern in these plugins. The design principle is that sharing stays off until a mode explicitly says otherwise, and configuring an endpoint is not consent to upload session content. You must opt in to each level of data sharing.</p>
<p>The <code>CodePrometheus/dsh-observability</code> plugin exposes three modes through the <code>DSH_OBSERVABILITY_MODE</code> environment variable:</p>
<ul>
<li><strong>FULL</strong> — exports the complete session content, including prompts, completions, and tool payloads. Use this only for backends you trust and for data you are allowed to share.</li>
<li><strong>FEEDBACK_ONLY</strong> — exports only feedback and scoring data, without the underlying session content. This is a middle ground for teams that want evaluation signals without shipping raw prompts.</li>
<li><strong>DISABLED</strong> — turns off sharing entirely. This is the safe default.</li>
</ul>
<p>You also configure the OTLP endpoint, typically through a variable such as <code>DSH_OBSERVABILITY_OTLP_URL</code> or the plugin&rsquo;s own endpoint setting. The endpoint points at your chosen backend&rsquo;s OTLP/HTTP receiver. Remember that setting the endpoint alone does not enable content sharing; the mode controls that.</p>
<h2 id="reading-the-genai-trace-tree-entry---agent---step---llmtool">Reading the GenAI trace tree (ENTRY -&gt; AGENT -&gt; STEP -&gt; LLM/TOOL)</h2>
<p>The trace shape is the most valuable part of the setup. The <code>loongsuite/dsh-plugin</code> exports a hierarchy of <code>ENTRY -&gt; AGENT -&gt; STEP -&gt; LLM/TOOL</code>. Here is what each level means:</p>
<ul>
<li><strong>ENTRY</strong> — the root span for a session or a top-level request.</li>
<li><strong>AGENT</strong> — the agent loop that orchestrates the work.</li>
<li><strong>STEP</strong> — a single planning or execution step within the loop.</li>
<li><strong>LLM/TOOL</strong> — the individual LLM call or tool invocation that ran under that step.</li>
</ul>
<p>The critical design detail is that each real LLM attempt gets its own LLM span. If the harness retries a failed LLM call, each retry appears as a separate span under the same step. This keeps retries and tool fallbacks visible under the same step, which is exactly what you need when debugging flaky agent loops. Instead of seeing one opaque &ldquo;LLM call failed&rdquo; message, you see the full sequence of attempts and their individual latencies and token usage.</p>
<p>Subagent sessions create their own trace and carry DeepSeek Harness parent-session and delegation attributes. This preserves fork and subagent lineage, so you can follow a request from the parent session down into each delegated subagent and back.</p>
<p>The plugins also export GenAI metrics. The <code>loongsuite/dsh-plugin</code> exports <code>gen_ai.client.operation.duration</code> and <code>gen_ai.client.token.usage</code>, giving you latency and token-cost telemetry alongside the traces.</p>
<h2 id="troubleshooting-common-issues-duplicate-backend-version-compatibility-restart-required">Troubleshooting common issues (duplicate backend, version compatibility, restart required)</h2>
<p>The most common problems fall into three buckets.</p>
<p><strong>Duplicate backend error.</strong> Because the telemetry seam accepts exactly one backend per context, loading the official OTLP-logs exporter and a tracing plugin together throws an error. Remove or disable the official exporter before loading a tracing plugin. If you need both logs and traces, choose one backend that handles both, or run them in separate contexts.</p>
<p><strong>Version incompatibility.</strong> The plugins require Node.js 22.19.0+ and DSH between 0.1.0-rc.6 and 0.2.0. If the plugin fails to load, check your Node and harness versions first. A harness outside the supported range will reject the plugin.</p>
<p><strong>Restart required.</strong> Telemetry backends are typically loaded at startup. After installing a plugin or changing a mode or endpoint variable, restart the harness so the new backend is picked up. A running session will not hot-reload the telemetry seam.</p>
<p><strong>No traces appearing.</strong> If your backend shows no traces, verify the OTLP endpoint is reachable, confirm the mode is not <code>DISABLED</code>, and check that the plugin actually loaded without a duplicate-backend error. Also confirm the backend&rsquo;s OTLP/HTTP receiver is enabled, since some backends disable it by default.</p>
<h2 id="faq">FAQ</h2>
<p><strong>What is OpenTelemetry tracing for DeepSeek Harness?</strong>
It is a way to export DeepSeek Harness agent sessions, LLM calls, and tool invocations as standard OTLP trace trees to backends like Jaeger, Grafana Tempo, SigNoz, or Langfuse, using community plugins that implement the official telemetry seam.</p>
<p><strong>Which DeepSeek Harness versions support OpenTelemetry tracing plugins?</strong>
The telemetry plugins require Node.js 22.19.0 or higher and a DeepSeek Harness version of at least 0.1.0-rc.6 and below 0.2.0.</p>
<p><strong>Can I use OpenTelemetry tracing with Langfuse?</strong>
Yes. Plugins like <code>linyp/dsh-plugin-langfuse</code> and <code>TtTRz/dsh-langfuse</code> export each session or turn as an OpenTelemetry trace to Langfuse&rsquo;s OTLP endpoint, including feedback scores and subagent lineage.</p>
<p><strong>Why do I get a duplicate backend error when installing a tracing plugin?</strong>
The <code>@deepseek-ai/dsh-session-telemetry</code> seam accepts exactly one backend per context. If you load the official OTLP-logs exporter and a tracing plugin together, the load throws an error. Remove the official exporter before loading a tracing plugin.</p>
<p><strong>How do privacy modes work in DeepSeek Harness tracing plugins?</strong>
Plugins like <code>CodePrometheus/dsh-observability</code> use modes such as FULL, FEEDBACK_ONLY, and DISABLED. Sharing stays off until a mode explicitly enables it, and configuring an endpoint is not consent to upload session content.</p>
]]></content:encoded></item><item><title>DeepSeek Harness Terminal UI: dsh-tianshu-tui Review (2026)</title><link>https://baeseokjae.github.io/posts/dsh-tianshu-tui-2026/</link><pubDate>Sat, 15 Aug 2026 16:01:21 +0000</pubDate><guid>https://baeseokjae.github.io/posts/dsh-tianshu-tui-2026/</guid><description>dsh-tianshu-tui turns DeepSeek Harness into a full terminal workspace. Review of features, install, prefix-cache savings, and how it compares to other dsh TUIs.</description><content:encoded><![CDATA[<p>The DeepSeek Harness terminal UI (dsh-tianshu-tui) is an official plugin that turns the DeepSeek Harness CLI into a full interactive terminal workspace, with live rendering, session restore, image support, and a TDD-driven evidence gate. It is a pure display layer that derives all agent state from the session event stream, so it adds no prompts, tools, or context of its own. This review covers what it does, how to install it, and how it compares to the other DeepSeek Harness TUIs.</p>
<h2 id="what-is-deepseek-harness-and-why-it-needs-a-tui">What is DeepSeek Harness and why it needs a TUI</h2>
<p>DeepSeek Harness (deepseek-ai/deepseek-harness) is the official open-source agent runtime from DeepSeek, and it is built around a simple but powerful philosophy: <strong>&ldquo;Everything is a Plugin.&rdquo;</strong> As of August 15, 2026, the repository holds 111,829 stars and 10,833 forks, making it one of the most-watched agent frameworks on GitHub. The harness is not a monolithic IDE; it is a modular runtime where prompts, tools, context providers, and even the user interface are all swappable plugins.</p>
<p>That modularity is exactly why a terminal UI matters. The stock <code>dsh</code> CLI is a capable but bare command-line interface. When you are running long agent sessions, reviewing tool calls, steering mid-turn, and inspecting reasoning traces, a plain prompt loop gets cramped. A TUI — a terminal user interface — gives you a full-screen workspace without leaving the terminal. It keeps the zero-chrome, scriptable, git-native workflow that terminal users prefer, while adding the visual density of an IDE.</p>
<p>The ecosystem has responded with at least five community TUI implementations. The most prominent is <strong>dsh-tianshu-tui</strong>, an official plugin by huiliyi37 that evolved from the Tianshu-Tui rendering core. It is the subject of this review.</p>
<h2 id="dsh-tianshu-tui-at-a-glance--the-plugin-that-turns-dsh-into-a-terminal-workspace">dsh-tianshu-tui at a glance — the plugin that turns dsh into a terminal workspace</h2>
<p>dsh-tianshu-tui is an npm package (<code>@huiliyi37/dsh-tianshu-tui</code>, Apache-2.0) that installs as a profile plugin for the official DeepSeek Harness CLI. It was created on August 13, 2026, and already has 158 stars and 6 forks, with the latest npm release at <code>0.1.2-rc.7</code> (August 15, 2026). The project co-evolved with the harness itself, accumulating 250+ commits between August 10 and August 13 on the August 9 baseline snapshot.</p>
<p>The key architectural decision is that the TUI is a <strong>pure display layer</strong>. It registers no prompts, no tools, and no context. Every piece of agent state — reasoning, tool calls, replies, subagent lifecycles — is derived from the session event stream. This means the TUI cannot interfere with the agent&rsquo;s behavior; it only renders what the harness already produces. That is a deliberate contrast to monolithic AI IDEs, where the interface and the agent logic are tightly coupled.</p>
<p>The result is a full in-terminal workspace with:</p>
<ul>
<li>Live rendering of the agent&rsquo;s activity</li>
<li>Session restore across restarts</li>
<li><code>/fork</code> and <code>/rewind</code> for branching and replaying sessions</li>
<li><code>/export</code> to Markdown</li>
<li><code>/steer</code> for mid-turn steering</li>
</ul>
<h2 id="installation-and-setup">Installation and setup</h2>
<p>Installing dsh-tianshu-tui requires three things: the official CLI, a recent Node.js, and pnpm.</p>
<p><strong>Requirements:</strong></p>
<table>
  <thead>
      <tr>
          <th>Requirement</th>
          <th>Version</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Official CLI</td>
          <td><code>@deepseek-ai/dsh</code> 0.1.0-rc.6</td>
      </tr>
      <tr>
          <td>Node.js</td>
          <td><code>^22.19</code> or <code>&gt;=24</code></td>
      </tr>
      <tr>
          <td>Package manager</td>
          <td>pnpm on PATH</td>
      </tr>
  </tbody>
</table>
<p>The install command is a single line:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>npx -y @deepseek-ai/dsh plugin --profile tui add @huiliyi37/dsh-tianshu-tui
</span></span></code></pre></div><p>This adds the plugin to the <code>tui</code> profile. You then launch the TUI through that profile.</p>
<p><strong>Common pitfalls.</strong> The review notes two recurring install failures. The first is <code>ERR_FS_EISDIR</code>, which typically appears when the plugin path is misconfigured or a stale directory is being treated as a file. The second is a &ldquo;stale dsh&rdquo; problem, where an older CLI version is still on PATH and the plugin refuses to load. Both are resolved by pinning the official CLI to exactly <code>0.1.0-rc.6</code> and ensuring pnpm is reachable. Because the plugin co-evolves rapidly with the harness, keeping the CLI version in sync matters more than with a stable tool.</p>
<h2 id="core-features--session-workspace-images-input-and-reasoning">Core features — session workspace, images, input, and reasoning</h2>
<p>Once running, dsh-tianshu-tui provides a dense but navigable interface. The core features fall into four groups.</p>
<p><strong>Session workspace.</strong> The TUI supports live rendering, session restore, <code>/fork</code>, <code>/rewind</code>, and <code>/export</code> to Markdown. You can branch a session to try a different approach, rewind to an earlier checkpoint, and export the full transcript for sharing or documentation. <code>/steer</code> lets you redirect the agent mid-turn without killing the run.</p>
<p><strong>End-to-end images.</strong> The plugin handles images from clipboard to inline render. You can paste an image from the clipboard, and it renders inline using the kitty or iTerm2 graphics protocol. The standout feature is the <strong>vision bridge</strong>: when the main model cannot see images, the TUI auto-detects an auxiliary vision model and routes image understanding through it, with graceful degradation if none is available. This is a practical solution to the common problem of a text-only main model being asked to reason about a screenshot.</p>
<p><strong>Complete input surface.</strong> The input layer is grok-style: a slash menu for commands, <code>@</code>-path tab completion, bracketed paste support, optional vim keys, an external editor via Ctrl+E, and history search via Ctrl+F. For heavy terminal users, the vim keybindings and external editor integration make long sessions far more comfortable.</p>
<p><strong>Reasoning visualization.</strong> The think channel streams live, then folds into compact rows to keep the screen readable. Ctrl+O expands a reasoning block inline when you want to inspect the model&rsquo;s chain of thought. This is a meaningful improvement over a plain chat UI, where reasoning either floods the screen or is hidden entirely.</p>
<h2 id="harness-engineering-differentiators--tdd-evidence-gate-memory-code-intelligence">Harness-engineering differentiators — TDD evidence gate, memory, code intelligence</h2>
<p>Beyond rendering, dsh-tianshu-tui exposes several harness-engineering features that set it apart from a plain chat interface.</p>
<p><strong>TDD-driven workflow and evidence gate.</strong> The plugin supports a RED-first verification workflow: write a failing test, watch it fail, then implement until it passes. The evidence gate is an obligation state machine that tracks what must be verified before a task is considered done. If verification fails, the run is routed to failure handling rather than silently continuing. This is a real differentiator from chat UIs, which have no notion of &ldquo;prove it works.&rdquo;</p>
<p><strong>Memory and cross-session recall.</strong> The <code>/memory</code> command opens a project memory browser, and the underlying Tianshu-Tui core uses a Stigmergy (pheromone) self-decaying memory model. This shifts the tool from a stateless chat to a persistent agent partner that remembers context across sessions.</p>
<p><strong>Code intelligence and git tools.</strong> The plugin integrates code intelligence retrieval and git tooling, so you can inspect repository context and manage version control from within the TUI.</p>
<p><strong>Personalized harness integration.</strong> A <code>/doctor</code> command runs diagnostics, <code>/btw</code> spawns a background agent, and <code>/model</code> plus <code>/effort</code> let you hot-switch models and effort levels mid-session.</p>
<h2 id="the-prefix-cache-advantage--95-99-hit-rate-and-what-it-saves-you">The prefix-cache advantage — 95-99% hit rate and what it saves you</h2>
<p>One of the most compelling technical details is the prefix-cache engineering in the Tianshu-Tui rendering core. In long sessions, the core reports a <strong>steady-state prefix-cache hit rate of 95-99%</strong> on DeepSeek V4.</p>
<p>What does that mean in practice? Prefix caching means the model provider does not recompute the shared prefix of a conversation on every request. When the hit rate is high, the cost and latency of each turn drop dramatically, because only the new tokens need to be processed. In a long agent session where the conversation history grows large, a 95-99% hit rate is the difference between a responsive, cheap workflow and one that degrades into slow, expensive recomputation.</p>
<p>This is a hidden cost lever that most TUI reviews miss. The interface itself does not save tokens, but by keeping sessions long-lived and well-structured, it maximizes the prefix-cache benefit. For teams running DeepSeek V4 at scale, this is a real operational advantage.</p>
<h2 id="how-it-compares-to-other-deepseek-harness-tuis">How it compares to other DeepSeek Harness TUIs</h2>
<p>dsh-tianshu-tui is not the only TUI in the ecosystem. Here is how it stacks up against the main alternatives.</p>
<table>
  <thead>
      <tr>
          <th>TUI</th>
          <th>Language / stack</th>
          <th>Stars</th>
          <th>Key strength</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>dsh-tianshu-tui</strong></td>
          <td>TypeScript (Tianshu-Tui core)</td>
          <td>158</td>
          <td>Pure display layer, vision bridge, TDD evidence gate, 95-99% prefix-cache</td>
      </tr>
      <tr>
          <td><strong>Tianshu-Tui</strong></td>
          <td>TypeScript, Apache-2.0</td>
          <td>229</td>
          <td>Full standalone runtime, CVM + Stigmergy memory, 13,000+ tests</td>
      </tr>
      <tr>
          <td><strong>openma-ai/deepseek-harness-tui</strong></td>
          <td>Rust / ratatui, MIT</td>
          <td>25</td>
          <td>Up to 8 images per prompt, JSON-RPC runtime, token/cache metrics</td>
      </tr>
      <tr>
          <td><strong>gxinxing/deepseek-harness-tui</strong></td>
          <td>JavaScript (Ink)</td>
          <td>7</td>
          <td>Thin ~800-line UI, zero-chrome, OSC 11 theme detection</td>
      </tr>
      <tr>
          <td><strong>oh-dsh</strong></td>
          <td>TypeScript, MIT</td>
          <td>188</td>
          <td>Desktop + Web + TUI unified, plugin marketplace, Git Review</td>
      </tr>
  </tbody>
</table>
<p><strong>Tianshu-Tui</strong> is the rendering core that dsh-tianshu-tui evolved from. It is a full standalone terminal coding agent runtime with 229 stars, 13,000+ passing tests, and the Stigmergy memory model. If you want the complete runtime rather than a plugin for the official harness, this is the base.</p>
<p><strong>openma-ai/deepseek-harness-tui</strong> is the Rust/ratatui option. It is lighter on features but strong on image handling (up to 8 images per prompt) and exposes token and cache metrics. It runs either as a dsh profile plugin or directly against the SDK JSON-RPC runtime.</p>
<p><strong>gxinxing/deepseek-harness-tui</strong> is deliberately minimal — about 800 lines of Ink (React for terminals). It is a thin, readable UI that folds tool calls into cells and derives its theme from your terminal via an OSC 11 probe. It is the choice for users who want the least chrome possible.</p>
<p><strong>oh-dsh</strong> takes a different approach: it packages the DSH runtime into Desktop, Web, and TUI distributions with a shared plugin marketplace and a Git Review sidebar. If you want the same sessions across a desktop app, a browser, and a terminal, oh-dsh is the unified option.</p>
<h2 id="who-should-use-it-and-who-should-wait">Who should use it and who should wait</h2>
<p>dsh-tianshu-tui is best for developers who already live in the terminal and run DeepSeek Harness for real agent work — especially those doing TDD, long multi-turn sessions, or image-heavy tasks where the vision bridge matters. The prefix-cache benefit and the evidence gate make it a strong fit for teams that care about cost and verifiability.</p>
<p>You might wait if you prefer a minimal UI (gxinxing&rsquo;s Ink plugin), need a full standalone runtime (Tianshu-Tui), want multi-form Desktop/Web/TUI access (oh-dsh), or need the Rust/ratatui stack with heavy image staging (openma). Because the plugin is young and co-evolves rapidly with the harness, you should also be comfortable with frequent updates and the CLI version pin.</p>
<h2 id="verdict-and-final-thoughts">Verdict and final thoughts</h2>
<p>dsh-tianshu-tui is a well-engineered, feature-complete terminal UI for DeepSeek Harness. Its decision to be a pure display layer is the right one: it stays out of the agent&rsquo;s way while giving you a dense, navigable workspace. The vision bridge, TDD evidence gate, memory browser, and 95-99% prefix-cache hit rate are genuine differentiators, not cosmetic additions.</p>
<p>The main caveats are the young age of the project and the install friction around the CLI version pin. But for terminal-native DeepSeek Harness users, dsh-tianshu-tui is currently the most complete and polished option in the ecosystem. If you run dsh for serious agent work, it is worth installing today.</p>
<h2 id="faq">FAQ</h2>
<p><strong>What is the DeepSeek Harness terminal UI?</strong>
It is a TUI plugin (dsh-tianshu-tui) that turns the DeepSeek Harness CLI into a full interactive terminal workspace with live rendering, session restore, image support, and a TDD evidence gate.</p>
<p><strong>How do I install dsh-tianshu-tui?</strong>
Run <code>npx -y @deepseek-ai/dsh plugin --profile tui add @huiliyi37/dsh-tianshu-tui</code>. You need the official CLI <code>@deepseek-ai/dsh</code> 0.1.0-rc.6, Node.js <code>^22.19</code> or <code>&gt;=24</code>, and pnpm on PATH.</p>
<p><strong>Does dsh-tianshu-tui change how the agent behaves?</strong>
No. It is a pure display layer that derives all state from the session event stream and registers no prompts, tools, or context, so it cannot alter agent behavior.</p>
<p><strong>What is the vision bridge?</strong>
When the main model cannot see images, the TUI auto-detects an auxiliary vision model and routes image understanding through it, with graceful degradation if none is available.</p>
<p><strong>What is the prefix-cache hit rate and why does it matter?</strong>
The Tianshu-Tui core reports a 95-99% steady-state prefix-cache hit rate on DeepSeek V4 in long sessions, which cuts token cost and latency by avoiding recomputation of the shared conversation prefix.</p>
]]></content:encoded></item></channel></rss>