• bitcoinBitcoin(BTC)$83,477.000.59%
  • ethereumEthereum(ETH)$2,451.08-0.22%
  • tetherTether(USDT)$1.000.01%
  • binancecoinBNB(BNB)$744.530.26%
  • rippleXRP(XRP)$1.350.75%
  • usd-coinUSDC(USDC)$1.000.00%
  • solanaSolana(SOL)$106.14-0.57%
  • tronTRON(TRX)$0.330261-0.18%
  • Figure HelocFigure Heloc(FIGR_HELOC)$1.030.43%
  • zcashZcash(ZEC)$1,305.583.08%
  • HyperliquidHyperliquid(HYPE)$80.10-2.36%
  • dogecoinDogecoin(DOGE)$0.081085-1.25%
  • moneroMonero(XMR)$608.184.87%
  • USDSUSDS(USDS)$1.00-0.13%
  • whitebitWhiteBIT Coin(WBT)$81.00-0.20%
  • chainlinkChainlink(LINK)$12.40-0.13%
  • cardanoCardano(ADA)$0.223028-1.03%
  • leo-tokenLEO Token(LEO)$9.04-0.05%
  • nearNEAR Protocol(NEAR)$5.203.59%
  • stellarStellar(XLM)$0.181888-0.77%
  • RainRain(RAIN)$0.008994-5.36%
  • bitcoin-cashBitcoin Cash(BCH)$283.35-1.37%
  • litecoinLitecoin(LTC)$61.17-1.27%
  • Ethena USDeEthena USDe(USDE)$1.00-0.02%
  • uniswapUniswap(UNI)$7.42-3.16%
  • daiDai(DAI)$1.00-0.03%
  • CantonCanton(CC)$0.1088542.88%
  • avalanche-2Avalanche(AVAX)$9.53-2.49%
  • suiSui(SUI)$1.02-1.85%
  • USD1USD1(USD1)$1.000.01%
  • the-open-networkGram (prev. Toncoin)(GRAM)$1.34-0.53%
  • hedera-hashgraphHedera(HBAR)$0.083682-0.55%
  • tether-goldTether Gold(XAUT)$4,112.08-0.17%
  • Global DollarGlobal Dollar(USDG)$1.00-0.02%
  • BittensorBittensor(TAO)$267.94-2.65%
  • shiba-inuShiba Inu(SHIB)$0.000005-0.64%
  • quant-networkQuant(QNT)$204.343.96%
  • paypal-usdPayPal USD(PYUSD)$1.00-0.12%
  • crypto-com-chainCronos(CRO)$0.057531-1.03%
  • EthenaEthena(ENA)$0.2099975.03%
  • BitwayBitway(BTW)$1.68-16.80%
  • okbOKB(OKB)$115.37-0.57%
  • Circle USYCCircle USYC(USYC)$1.140.01%
  • Ondo US Dollar YieldOndo US Dollar Yield(USDY)$1.15-0.09%
  • aaveAave(AAVE)$152.69-2.47%
  • Ripple USDRipple USD(RLUSD)$1.00-0.02%
  • Pump.funPump.fun(PUMP)$0.0050804.99%
  • OndoOndo(ONDO)$0.453717-0.49%
  • worldcoin-wldWorldcoin(WLD)$0.57-2.07%
  • BlackRock USD Institutional Digital Liquidity FundBlackRock USD Institutional Digital Liquidity Fund(BUIDL)$1.000.00%
TradePoint.io
  • Main
  • AI & Technology
  • Stock Charts
  • Market & News
  • Business
  • Finance Tips
  • Trade Tube
  • Blog
  • Shop
No Result
View All Result
TradePoint.io
No Result
View All Result

Vercel Open-Sources durable-harness for Crash-Proof Coding Agents

October 21, 2026
in AI & Technology
Reading Time: 17 mins read
A A
Vercel Open-Sources durable-harness for Crash-Proof Coding Agents
ShareShareShareShareShare

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.

<iframe id="mtp-dh-frame" title="Vercel durable-harness interactive explainer" style="width:100%;height:600px;border:0;display:block;background:transparent;" scrolling="no" loading="lazy" srcdoc="<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>durable-harness explainer</title>
<style>
html,body{margin:0!important;padding:0!important;background:transparent!important;}
#mtp-dh{–bg:#000;–card:#0a0a0a;–line:#262626;–mute:#a1a1a1;–txt:#ededed;–blue:#0070f3;–ok:#50e3c2;–warn:#f5a623;–err:#ee0000;–mtp:#76B900;
max-width:880px;margin:0 auto;background:var(–bg)!important;color:var(–txt)!important;border:1px solid var(–line)!important;border-radius:14px;
font-family:Inter,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:15px;line-height:1.5;overflow:hidden;box-sizing:border-box}
#mtp-dh *{box-sizing:border-box}
#mtp-dh hr,#mtp-dh p:empty,#mtp-dh del,#mtp-dh s{display:none!important}
#mtp-dh .hd{padding:20px 24px 14px;border-bottom:1px solid var(–line)!important;background:radial-gradient(600px 160px at 0% 0%,rgba(0,112,243,.18),transparent)!important}
#mtp-dh .tag{display:inline-flex;gap:6px;align-items:center;font-size:12px;color:var(–mute)!important;letter-spacing:.04em;text-transform:uppercase}
#mtp-dh .tri{width:8px;height:8px;border-radius:50%;background:#0070f3!important;box-shadow:0 0 8px #0070f3}
#mtp-dh h3{margin:6px 0 4px!important;font-size:22px!important;color:#fff!important;font-weight:700;letter-spacing:-.02em}
#mtp-dh .sub{color:var(–mute)!important;font-size:14px;margin:0}
#mtp-dh .tabs{display:flex;gap:4px;padding:10px 16px 0;border-bottom:1px solid var(–line)!important;overflow-x:auto}
#mtp-dh .tab{background:transparent!important;color:var(–mute)!important;border:0!important;border-bottom:2px solid transparent!important;padding:9px 12px;font:600 13px Inter,sans-serif;cursor:pointer;white-space:nowrap}
#mtp-dh .tab.on{color:#fff!important;border-bottom-color:#fff!important}
#mtp-dh .pane{display:none;padding:20px 24px 22px;animation:dhfade .35s ease}
#mtp-dh .pane.on{display:block}
@keyframes dhfade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
#mtp-dh .cols{display:grid;grid-template-columns:1fr 1fr;gap:14px}
#mtp-dh .box{background:var(–card)!important;border:1px solid var(–line)!important;border-radius:10px;padding:14px}
#mtp-dh .box h4{margin:0 0 10px!important;font-size:13px!important;color:#fff!important;display:flex;justify-content:space-between;align-items:center}
#mtp-dh .pill{font-size:11px;padding:2px 8px;border-radius:99px;border:1px solid var(–line)!important;color:var(–mute)!important;font-weight:600}
#mtp-dh ol.steps{list-style:none;margin:0;padding:0}
#mtp-dh ol.steps li{display:flex;gap:8px;align-items:center;padding:6px 8px;border-radius:6px;font-size:13px;color:var(–mute)!important;transition:all .3s}
#mtp-dh ol.steps li .k{font:600 11px ui-monospace,Menlo,monospace;width:46px;color:#888!important}
#mtp-dh ol.steps li.run{background:rgba(0,112,243,.15)!important;color:#fff!important}
#mtp-dh ol.steps li.done{color:#fff!important}
#mtp-dh ol.steps li.done::after{content:"\2713";margin-left:auto;color:var(–ok)!important}
#mtp-dh ol.steps li.rerun::after{content:"ran twice";margin-left:auto;color:var(–err)!important;font-size:11px;font-weight:600}
#mtp-dh ol.steps li.fromlog::after{content:"from log";margin-left:auto;color:var(–ok)!important;font-size:11px;font-weight:600}
#mtp-dh ol.steps li.dead{background:rgba(238,0,0,.12)!important;color:#ff6b6b!important}
#mtp-dh .stat{display:flex;justify-content:space-between;font-size:12px;color:var(–mute)!important;margin-top:10px;border-top:1px dashed var(–line)!important;padding-top:8px}
#mtp-dh .stat b{color:#fff!important}
#mtp-dh .btns{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0 4px}
#mtp-dh button.b{background:#fff!important;color:#000!important;border:0!important;border-radius:8px;padding:8px 14px;font:600 13px Inter,sans-serif;cursor:pointer}
#mtp-dh button.b.ghost{background:transparent!important;color:#fff!important;border:1px solid var(–line)!important}
#mtp-dh button.b.red{background:var(–err)!important;color:#fff!important}
#mtp-dh button.b:disabled{opacity:.4;cursor:not-allowed}
#mtp-dh .note{font-size:12.5px;color:var(–mute)!important;margin-top:10px}
#mtp-dh .log{font:12px/1.6 ui-monospace,Menlo,monospace;background:#050505!important;border:1px solid var(–line)!important;border-radius:8px;padding:10px;height:150px;overflow:hidden;margin-top:12px}
#mtp-dh .log div{animation:dhfade .3s ease;color:#bbb!important}
#mtp-dh .log .i{color:var(–warn)!important}#mtp-dh .log .o{color:var(–ok)!important}#mtp-dh .log .x{color:#ff6b6b!important}
#mtp-dh .rules{display:grid;grid-template-columns:1fr 1fr;gap:14px}
#mtp-dh .tool{cursor:pointer;transition:border-color .2s}
#mtp-dh .tool:hover,#mtp-dh .tool.sel{border-color:#fff!important}
#mtp-dh code,#mtp-dh pre{font-family:ui-monospace,Menlo,monospace!important;background:#111!important;color:#ededed!important;border:1px solid var(–line)!important;border-radius:5px;padding:1px 5px;font-size:12px}
#mtp-dh pre{padding:10px 12px;white-space:pre-wrap;margin:10px 0 0;line-height:1.55}
#mtp-dh .verdict{margin-top:14px;padding:12px;border-radius:8px;border:1px solid var(–line)!important;background:var(–card)!important;font-size:13.5px;min-height:60px}
#mtp-dh .ws{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
#mtp-dh .ws .box{cursor:pointer}
#mtp-dh .ws .box.sel{border-color:var(–blue)!important;box-shadow:0 0 0 1px var(–blue)}
#mtp-dh .meter{height:8px;background:#1a1a1a!important;border-radius:99px;overflow:hidden;margin:6px 0 2px}
#mtp-dh .meter i{display:block;height:100%;width:0;background:var(–blue)!important;transition:width .9s cubic-bezier(.2,.8,.2,1)}
#mtp-dh .ml{font-size:11px;color:var(–mute)!important;display:flex;justify-content:space-between}
#mtp-dh table{width:100%;border-collapse:collapse;font-size:12.5px}
#mtp-dh th,#mtp-dh td{border-bottom:1px solid var(–line)!important;padding:8px 6px;text-align:left;vertical-align:top;color:var(–txt)!important;background:transparent!important}
#mtp-dh th{color:var(–mute)!important;font-weight:600}
#mtp-dh td.y{color:var(–ok)!important}#mtp-dh td.n{color:#888!important}
#mtp-dh .worlds{display:flex;gap:10px;flex-wrap:wrap}
#mtp-dh .world{flex:1;min-width:150px;cursor:pointer}
#mtp-dh .world.sel{border-color:#fff!important}
#mtp-dh .ft{display:flex;justify-content:space-between;align-items:center;padding:10px 24px;border-top:1px solid var(–line)!important;font-size:11.5px;color:#777!important}
#mtp-dh .ft b{color:var(–mtp)!important;font-weight:700}
#mtp-dh a{color:#fff!important;text-decoration:underline}
@media (max-width:640px){
#mtp-dh .cols,#mtp-dh .rules,#mtp-dh .ws{grid-template-columns:1fr}
#mtp-dh .hd,#mtp-dh .pane{padding-left:16px;padding-right:16px}
#mtp-dh h3{font-size:19px!important}
#mtp-dh .ft{flex-direction:column;gap:4px;align-items:flex-start;padding:10px 16px}
#mtp-dh table{font-size:11.5px}
}
</style></head><body>
<div id="mtp-dh">
<div class="hd">
<div class="tag"><span class="tri"></span> Vercel · durable-harness · v0.0.x</div>
<h3>How durable-harness keeps agent turns alive</h3>
<p class="sub">Every model and tool call goes into a durable log. A crashed turn resumes on a new function.</p>
</div>
<div class="tabs" role="tablist">
<button class="tab on" data-t="p1">Crash demo</button>
<button class="tab" data-t="p2">Replay rules</button>
<button class="tab" data-t="p3">Workspaces</button>
<button class="tab" data-t="p4">Where it runs</button>
<button class="tab" data-t="p5">Harnesses</button>
</div>

<div class="pane on" id="p1">
<div class="cols">
<div class="box"><h4>Without durability <span class="pill">state in memory</span></h4>
<ol class="steps" id="sA"></ol>
<div class="stat"><span>Steps run twice <b id="aRe">0</b></span><span>Model calls <b id="aMc">0</b></span></div>
</div>
<div class="box"><h4>With durable-harness <span class="pill">state in log</span></h4>
<ol class="steps" id="sB"></ol>
<div class="stat"><span>Steps run twice <b id="bRe">0</b></span><span>Model calls <b id="bMc">0</b></span></div>
</div>
</div>
<div class="btns">
<button class="b" id="go"> 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='<span class="k">’+s[0]+'</span>’+s[1];o.appendChild(li)})}
var i=0,tm=null,killed=false,ma=0,mb=0;
function log(t,c){var l=$(‘#lg’),d=document.createElement(‘div’);d.className=c||”;d.textContent=t;l.appendChild(d);while(l.children.length>6)l.removeChild(l.firstChild)}
function reset(){clearTimeout(tm);i=0;killed=false;ma=mb=0;draw(‘#sA’);draw(‘#sB’);$(‘#aRe’).textContent=0;$(‘#bRe’).textContent=0;$(‘#aMc’).textContent=0;$(‘#bMc’).textContent=0;$(‘#go’).disabled=false;$(‘#kill’).disabled=true;$(‘#lg’).innerHTML='<div>Press Run turn, then kill the function while CI is running.</div>’}
function li(id,n){return $(id).children[n]}
function step(){if(i>=S.length){$(‘#kill’).disabled=true;log(‘turn complete’,’o’);return}
[‘#sA’,’#sB’].forEach(function(id){var e=li(id,i);e.className=”run”});
log(‘intent ‘+S[i][0]+’ ‘+S[i][1],’i’);
tm=setTimeout(function(){[‘#sA’,’#sB’].forEach(function(id){li(id,i).className=”done”});if(S[i][2]){ma++;mb++;$(‘#aMc’).textContent=ma;$(‘#bMc’).textContent=mb}log(‘outcome ‘+S[i][0]+’ ok’,’o’);i++;step()},i===4?1800:700)}
$(‘#go’).onclick=function(){reset();$(‘#go’).disabled=true;$(‘#kill’).disabled=false;$(‘#lg’).innerHTML=”;step()};
$(‘#rst’).onclick=reset;
$(‘#kill’).onclick=function(){if(i>=S.length)return;clearTimeout(tm);killed=true;$(‘#kill’).disabled=true;var k=i;
li(‘#sA’,k).className=”dead”;li(‘#sB’,k).className=”dead”;log(‘function 1 died at step ‘+(k+1),’x’);
setTimeout(function(){log(‘without durability: manual restart, turn starts over’,’x’);
draw(‘#sA’);var re=0,j=0;(function a(){if(j>=S.length){$(‘#aRe’).textContent=re;return}var e=li(‘#sA’,j);e.className=”run”;setTimeout(function(){e.className=j<k?’rerun’:’done’;if(j<k){re++;$(‘#aRe’).textContent=re}if(S[j][2]){ma++;$(‘#aMc’).textContent=ma}j++;a()},260)})();
log(‘with durable-harness: queue hands turn to function 2′,’o’);
for(var q=0;q<k;q++)li(‘#sB’,q).className=”fromlog”;
i=k;(function b(){if(i>=S.length){log(‘turn complete, 0 steps repeated’,’o’);return}var e=li(‘#sB’,i);e.className=”run”;setTimeout(function(){e.className=”done”;if(S[i][2]){mb++;$(‘#bMc’).textContent=mb}i++;b()},450)})();
},600)};
reset();
var rule=”safe”;
$$(‘.tool’).forEach(function(t){t.onclick=function(){$$(‘.tool’).forEach(function(x){x.classList.remove(‘sel’)});t.classList.add(‘sel’);rule=t.dataset.r;$(‘#vd’).textContent=”Pick a tool and press Crash mid-call.”;$(‘#code’).textContent=rule===’safe’?"{ name: ‘get_order’, replay: ‘safe’, … }":"{ name: ‘refund_order’, replay: ‘never’, … }"}});
$(‘#crash’).onclick=function(){var v=$(‘#vd’);v.style.opacity=0;setTimeout(function(){v.innerHTML=rule===’safe’?'<b style="color:#50e3c2">Resumed:</b> the interrupted lookup can run again. Pi reruns it; Claude Code, Codex and OpenCode tell the model it is safe to repeat.’:'<b style="color:#f5a623">Never re-run:</b> the model is told the refund may or may not have happened, so it can check first. Every harness waits for the log to record a \’never\’ call before it starts.’;v.style.transition=’opacity .3s’;v.style.opacity=1;rz()},150)};
var W=[{t:’Short tasks and small workspaces’,f:[‘Files kept’,’In the session log’],m:[[‘Workspace size’,’about 500 files’,55]],x:’A crash mid-call leaves nothing behind, and the call runs again. Cost: function CPU plus log events and storage.’},
{t:’Scratch work within a turn’,f:[‘Files kept’,’Cleared every turn’],m:[[‘Persistence’,’none across turns’,8]],x:’Nothing goes to the log. The model is told files are cleared. Cost: function CPU only.’},
{t:’Real projects and long-running work’,f:[‘Files kept’,’On a Drive that outlives every Sandbox’],m:[[‘Isolation’,’1 Sandbox per session’,100]],x:’A command a crash interrupts may have partly run, and the model is told. Cost: Sandbox and Drive usage, plus a start on first use.’}];
var cur=0;function ws(n){cur=n;var w=W[n];$(‘#wsd’).innerHTML='<h4>Best for: ‘+w.t+'</h4><div class="note">’+w.f[0]+’: <b style="color:#fff">’+w.f[1]+'</b></div>’+w.m.map(function(m){return ‘<div class="meter"><i></i></div><div class="ml"><span>’+m[0]+'</span><span>’+m[1]+'</span></div>’}).join(”)+'<p class="note">’+w.x+’ Typed JSON documents live in the log too, up to 64 KB each.</p>’;setTimeout(function(){$$(‘#wsd .meter i’).forEach(function(e){e.style.width=w.m[0][2]+’%’});rz()},40)}
$$(‘.ws .box’).forEach(function(b){b.onclick=function(){$$(‘.ws .box’).forEach(function(x){x.classList.remove(‘sel’)});b.classList.add(‘sel’);ws(+b.dataset.w)}});ws(0);
var G=[["// On Vercel: @workflow/world-vercel is picked automatically\nimport { claudeCode } from ‘durable-harness/claude-code’\nexport const agent = claudeCode({ model: ‘anthropic/claude-sonnet-5.5′ })",’Sessions show up in Agent Runs with each model and tool call. Resumed turns appear in the same trace.’],
["# Local dev: @workflow/world-local, no configuration\n# sessions live in .workflow-data by default\nnpm install durable-harness",’The local World suits development and a single server with a persistent disk.’],
["# Self-host: 2 variables move every agent to Postgres\nWORKFLOW_TARGET_WORLD=\"@workflow/world-postgres\"\nWORKFLOW_POSTGRES_URL=\"postgres://user:password@host:5432/database\"",’Needs @workflow/world-postgres 5.0.4+ and Node.js 22+. It is a reference implementation: no route auth, no encryption, not tuned for scale.’]];
function wd(n){$(‘#wc’).textContent=G[n][0];$(‘#wn’).textContent=G[n][1];rz()}
$$(‘.world’).forEach(function(b){b.onclick=function(){$$(‘.world’).forEach(function(x){x.classList.remove(‘sel’)});b.classList.add(‘sel’);wd(+b.dataset.g)}});wd(0);
window.addEventListener(‘load’,rz);window.addEventListener(‘resize’,rz);setTimeout(rz,300);
})();
</script>
</body></html>
“>

window.addEventListener(‘message’,function(e){if(e.data&&e.data.id===’mtp-dh’&&e.data.mtpEmbedHeight){var f=document.getElementById(‘mtp-dh-frame’);if(f){f.style.height=e.data.mtpEmbedHeight+’px’;}}});

Where can you run durable-harness?

The agent code stays the same across Worlds:

  • Vercel: the Vercel World, with every session traced in Agent Runs.
  • Local: files on your machine, with no configuration.
  • Self-hosted: the Postgres World, version 5.0.4 or later, on Node.js 22+. Vercel’s blog also lists MongoDB, Redis and Turso.

2 environment variables, WORKFLOW_TARGET_WORLD and WORKFLOW_POSTGRES_URL, move an agent to Postgres.

How does durable-harness compare?

Feature durable-harness Temporal + OpenAI Agents SDK Inngest AgentKit Cloudflare Agents SDK
What it is Durability adapters for existing coding harnesses Durable execution wrapper for OpenAI Agents SDK TypeScript multi-agent framework Stateful agents on Durable Objects
Wraps Claude Code / Codex Yes, experimental, Sandbox-only Not disclosed Not disclosed Not disclosed
Durability backend Workflow SDK World (Vercel, local, Postgres) Temporal server or Temporal Cloud Inngest orchestration engine Durable Objects, Cloudflare Workflows
Language TypeScript Python TypeScript TypeScript
License Apache-2.0 MIT (server) Apache-2.0 MIT
Status 0.0.x, experimental GA since Mar 23, 2026 Not disclosed Not disclosed

Key Takeaways

  • durable-harness logs every model and tool call, then resumes crashed turns on a new function.
  • Finished calls are never repeated, so tokens are not billed twice.
  • Pi and OpenCode run in your function; Claude Code and Codex need a Vercel Sandbox.
  • Self-hosting works with 2 env vars and a Postgres World.
  • It is 0.0.x and experimental, with no published benchmarks.


Check out the GitHub repo, docs and Vercel’s announcement. All credit goes to the researcher of this project. Also, feel free to follow us on Twitter and don’t forget to join our 150k+ML SubReddit and Subscribe to our Newsletter. Wait! are you on telegram? now you can join us on telegram as well.

The post Vercel Open-Sources durable-harness for Crash-Proof Coding Agents appeared first on MarkTechPost.

YOU MAY ALSO LIKE

Mark Zuckerberg Says Meta Is ‘Entering A New Phase’ With Muse

Bose Buys Audio Rival Skullcandy

Credit: Source link

ShareTweetSendSharePin

Related Posts

Mark Zuckerberg Says Meta Is ‘Entering A New Phase’ With Muse
AI & Technology

Mark Zuckerberg Says Meta Is ‘Entering A New Phase’ With Muse

October 21, 2026
Bose Buys Audio Rival Skullcandy
AI & Technology

Bose Buys Audio Rival Skullcandy

October 21, 2026
Tesla Posts Roughly Flat Quarterly Revenue as Operating Costs Rise – Unite.AI
AI & Technology

Tesla Posts Roughly Flat Quarterly Revenue as Operating Costs Rise – Unite.AI

October 21, 2026
Xbox Is Previewing Paid Cloud Gaming For Players Without Game Pass
AI & Technology

Xbox Is Previewing Paid Cloud Gaming For Players Without Game Pass

October 21, 2026
Next Post
Bose Buys Audio Rival Skullcandy

Bose Buys Audio Rival Skullcandy

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Search

No Result
View All Result
What Do All The Lights On Your Netgear Router Mean, And Which Ones Actually Matter?

What Do All The Lights On Your Netgear Router Mean, And Which Ones Actually Matter?

October 19, 2026
How To Use Google’s SynthID AI Detection Website

How To Use Google’s SynthID AI Detection Website

October 18, 2026
Kathy Hochul pushing to announce chipmaking plant in Utica, NY — despite AI data center ban: sources

Kathy Hochul pushing to announce chipmaking plant in Utica, NY — despite AI data center ban: sources

October 20, 2026

About

Learn more

Our Services

Legal

Privacy Policy

Terms of Use

Bloggers

Learn more

Article Links

Contact

Advertise

Ask us anything

©2020- TradePoint.io - All rights reserved!

Tradepoint.io, being just a publishing and technology platform, is not a registered broker-dealer or investment adviser. So we do not provide investment advice. Rather, brokerage services are provided to clients of Tradepoint.io by independent SEC-registered broker-dealers and members of FINRA/SIPC. Every form of investing carries some risk and past performance is not a guarantee of future results. “Tradepoint.io“, “Instant Investing” and “My Trading Tools” are registered trademarks of Apperbuild, LLC.

This website is operated by Apperbuild, LLC. We have no link to any brokerage firm and we do not provide investment advice. Every information and resource we provide is solely for the education of our readers. © 2020 Apperbuild, LLC. All rights reserved.

No Result
View All Result
  • Main
  • AI & Technology
  • Stock Charts
  • Market & News
  • Business
  • Finance Tips
  • Trade Tube
  • Blog
  • Shop

© 2023 - TradePoint.io - All Rights Reserved!