hiw3c 日报精选
MarkTechPost RSS 全文

Vercel 开源了 durable-harness 工具,有助于实现无崩溃的代码编写环境。

原文标题 · Vercel Open-Sources durable-harness for Crash-Proof Coding Agents

Vercel 发布了 durable-harness 这个开源工具包,该工具可以记录所有模型和方法调用过程。因此,即使在 Vercel、Postgres 环境或笔记本电脑中出现崩溃、超时或重新部署的情况,使用 durable-harness 的编程工具仍然能够继续运行。关于 Vercel 将 durable-harness 开源的消息最初出现在 MarkTechPost 上。

来源:MarkTechPost · www.marktechpost.com

正文为英文,可一键机器翻译(仅首次需要等待)

Vercel has released durable-harness, an open-source package that keeps coding agent sessions alive through crashes and timeouts. Vercel durable-harness wraps existing harnesses, including Pi, OpenCode, Claude Code and Codex, without changing them. Each session lives in a durable log. A dead function no longer means lost work. For teams moving agents off laptops and into the cloud, that closes a real gap.

TL;DR

  • Size: npm package, version 0.0.x, Apache-2.0. Adapters cover 5 harnesses: Pi, OpenCode, fx, Claude Code, Codex.
  • Runs on: Vercel Functions plus Vercel Queues, Node.js 22+ with Postgres, or laptop files. Claude Code and Codex need a Vercel Sandbox.
  • Performance: No latency or throughput benchmarks published. All recovery claims are self-reported by Vercel.
  • Best: Finished model and tool calls are read back from the log, never re-run or billed twice.
  • Worst: Experimental 0.0.x API. Claude Code and Codex run only in a Vercel Sandbox, even self-hosted.

What is durable-harness?

durable-harness is a set of adapters from Vercel that store a harness session in a Workflow SDK World. A World bundles storage, a queue and a stream behind one interface. The package uses the same machinery that powers Vercel’s Workflow SDK.

Why do coding agents lose work in the cloud?

Harnesses like Pi and Claude Code were designed as long-lived local processes. They keep the session in memory. Locally, the workspace and history sit on the same disk, so resuming takes 1 prompt. In the cloud, a VM with persistent storage does not track which calls completed. Vercel team notes a failed turn or network error then means lost work.

How does durable-harness work?

It writes each step of a turn to a durable log. Before a model or tool call runs, it records an intent. When the call finishes, it records the outcome. Each turn is backed by a message on Vercel Queues. If the function dies, the queue hands the turn to a new function. That function reads the log and continues.

After a crash, the log shows what finished, what was running and what never started:

  • Completed calls are read from the log, so finished model tokens are not billed again.
  • replay: 'safe' tools, such as lookups, can run again.
  • replay: 'never' tools, such as refunds, never run twice. The model is told the call may have happened.

Harness session files are mirrored into the log as well. That covers Claude Code’s transcript, Codex’s rollout and OpenCode’s event store.

Where do files and shell commands run?

Model-chosen commands never run on the function’s own disk. The tools docs list 3 workspace options:

  • virtual() keeps files in the session log, with a bash-compatible shell and no network. It holds about 500 files.
  • virtual({ durable: false }) keeps scratch files in memory and clears them every turn.
  • sandbox() gives each session a Vercel Sandbox, with /workspace on a Drive.

Typed JSON documents, such as a to-do list, also live in the log. Each holds at most 64 KB.

Run turn</button> <button class="b red" id="kill" disabled>Kill function</button> <button class="b ghost" id="rst">Reset</button> </div> <div class="log" id="lg"><div>Press Run turn, then kill the function while CI is running.</div></div> <p class="note">Scenario from Vercel's post: an agent adds a pricing page, opens a PR, and waits for CI. Illustrative simulation, not a benchmark.</p> </div> <div class="pane" id="p2"> <p class="sub" style="margin-bottom:12px">Click a tool, then crash it mid-call.</p> <div class="rules"> <div class="box tool sel" data-r="safe"><h4><code>get_order</code><span class="pill">replay: 'safe'</span></h4><span class="note">A lookup. Safe to repeat after a crash.</span></div> <div class="box tool" data-r="never"><h4><code>refund_order</code><span class="pill">replay: 'never'</span></h4><span class="note">A refund. Must never run twice.</span></div> </div> <div class="btns"><button class="b red" id="crash">Crash mid-call</button></div> <div class="verdict" id="vd">Pick a tool and press Crash mid-call.</div> <pre id="code">{ name: 'get_order', replay: 'safe', ... }</pre> </div> <div class="pane" id="p3"> <div class="ws"> <div class="box sel" data-w="0"><h4><code>virtual()</code></h4><span class="note">Files in the session log. Bash-compatible shell, no network.</span></div> <div class="box" data-w="1"><h4><code>virtual({durable:false})</code></h4><span class="note">In-memory scratch. Cleared every turn.</span></div> <div class="box" data-w="2"><h4><code>sandbox()</code></h4><span class="note">Per-session Vercel Sandbox, <code>/workspace</code> on a Drive.</span></div> </div> <div class="box" style="margin-top:14px" id="wsd"></div> </div> <div class="pane" id="p4"> <div class="worlds"> <div class="box world sel" data-g="0"><h4>Vercel</h4><span class="note">Vercel World + Agent Runs traces</span></div> <div class="box world" data-g="1"><h4>Laptop</h4><span class="note">Local files, zero config</span></div> <div class="box world" data-g="2"><h4>Self-host</h4><span class="note">Postgres World, Node.js 22+</span></div> </div> <pre id="wc"></pre> <p class="note" id="wn"></p> </div> <div class="pane" id="p5"> <table> <tr><th>Harness</th><th>Package</th><th>Runs in</th><th>Status</th></tr> <tr><td>Pi</td><td><code>durable-harness/pi-durable</code></td><td>Your function + virtual workspace or Sandbox</td><td class="y">Supported</td></tr> <tr><td>OpenCode</td><td><code>durable-harness/opencode</code></td><td>Your function + virtual workspace or Sandbox</td><td class="y">Supported</td></tr> <tr><td>fx</td><td><code>libfx</code></td><td>Durable on its own</td><td class="y">Supported</td></tr> <tr><td>Claude Code</td><td><code>durable-harness/claude-code</code></td><td>Vercel Sandbox only</td><td class="n">Experimental</td></tr> <tr><td>Codex</td><td><code>durable-harness/codex</code></td><td>Vercel Sandbox only</td><td class="n">Experimental</td></tr> </table> <p class="note">Claude Code and Codex are single-user CLIs that keep state on disk, so each session gets its own Sandbox.</p> </div> <div class="ft"><span>Source: vercel.com/blog/making-every-harness-durable · Vercel docs · Oct 2026</span><b>© Marktechpost</b></div> </div> <script> (function(){ var R=document.getElementById('mtp-dh'); function $(s){return R.querySelector(s)}function $$(s){return R.querySelectorAll(s)} function rz(){try{parent.postMessage({mtpEmbedHeight:R.offsetHeight+40,id:'mtp-dh'},'*')}catch(e){}} $$('.tab').forEach(function(t){t.onclick=function(){$$('.tab').forEach(function(x){x.classList.remove('on')});$$('.pane').forEach(function(x){x.classList.remove('on')});t.classList.add('on');$('#'+t.dataset.t).classList.add('on');if(t.dataset.t==='p3')ws(cur);setTimeout(rz,60)}}); var S=[['model','Plan the change',1],['read','app/page.tsx',0],['write','app/pricing/page.tsx',0],['run','gh pr create',0],['wait','CI checks on the PR',0],['model','Reply with the result',1]]; function draw(id){var o=$(id);o.innerHTML='';S.forEach(function(s){var li=document.createElement('li');li.innerHTML='&