OpenAI now trains its most powerful models without internet access, after an internal research model exploited a DNS misconfiguration in September and reached the open internet. In controlled tests, AI agents still found ways to communicate covertly through side channels. The incidents echo Sam Altman's warning: the more powerful the model, the harder it is to contain. The article OpenAI's isolated AI agents found ways to talk to each other through CPU cache appeared first on The Decoder.
In this article, we will discuss newly trending open sourced Anthropic’s sandbox-runtime (srt), the OS-level sandbox behind Claude Code’s sandboxed bash tool. The Anthropic sandbox-runtime limits which files a process can touch and which hosts it can reach. It does this without spinning up a container. It is also not tied to Claude Code. Your own agents, local MCP servers and plain command-line programs can run inside it. TL;DR Size: npm package @anthropic-ai/sandbox-runtime v0.0.81, about 11.4 MB unpacked, Apache-2.0, Node.js 22.12+. Runs on: any macOS or Linux dev machine or CI box. macOS uses Seatbelt; Linux needs bubblewrap, socat and ripgrep. Windows is alpha. Performance: sandboxing cut Claude Code permission prompts by 84% in Anthropic’s internal usage (self-reported). Best: 84% fewer permission prompts, with file and network limits enforced on the whole process tree. Worst: still a beta research preview, Windows support is alpha. What is Anthropic sandbox-runtime? Anthropic sandbox-runtime is an open-source tool that wraps any process in filesystem and network restrictions. You install it with npm install -g @anthropic-ai/sandbox-runtime, then prefix a command with srt. It works as a CLI and as a TypeScript library. How does sandbox-runtime work on macOS, Linux and Windows? srt uses each operating system’s own isolation primitives. Its restrictions cover the entire process tree, including scripts and subprocesses. macOS: sandbox-exec with dynamically generated Seatbelt profiles. Only ripgrep is required. Linux: bubblewrap with the network namespace removed. It also needs socat and ripgrep. Windows (alpha): a dedicated srt-sandbox account, a Windows Filtering Platform egress fence and explicit file ACLs. Traffic leaves only through HTTP and SOCKS5 proxies running on the host. On Linux, those proxies sit behind Unix sockets bind-mounted into the sandbox. On macOS, the Seatbelt profile allows only one localhost port. The proxies then apply your domain allowlist and denylist. Why does it need both filesystem and network isolation? Anthropic team argues that 1 boundary without the other fails. Without network isolation, a prompt-injected agent could exfiltrate SSH keys. Without filesystem isolation, it could escape the sandbox and gain network access. srt’s defaults follow that logic. Reads are allowed everywhere unless denied. Writes are denied everywhere unless allowed. Network access is denied unless a domain is allowlisted. How do you sandbox an MCP server or your own agent? For an MCP server, change the command in .mcp.json from npx to srt. Pass the original command as arguments. Rules then live in ~/.srt-settings.json: Copy CodeCopiedUse a different Browser{ "network": { "allowedDomains": ["api.github.com", "*.npmjs.org"], "deniedDomains": [] }, "filesystem": { "denyRead": ["~/.ssh"], "allowWrite": ["."], "denyWrite": [".env"] } } For your own agent, the library exposes SandboxManager. Call initialize(config) to start the proxies. Then wrapWithSandbox() returns a wrapped command string you can spawn. What does the 84% figure mean? Anthropic reports that sandboxing reduced permission prompts by 84% in internal Claude Code usage. That is a self-reported number, not an external benchmark. The target is approval fatigue. Developers who click “approve” all day stop reading what they approve. A fixed boundary lets the agent work freely inside it and ask only at the edge. <iframe id="mtp-srt-frame" title="Anthropic sandbox-runtime interactive explainer" style="width:100%;height:600px;border:0;display:block;background:#141413;border-radius:16px;" loading="lazy" srcdoc="<!doctype html> <title>sandbox-runtime Explainer</title> :root{--bg:#141413;--panel:#1f1e1c;--panel2:#2a2926;--cream:#faf9f5;--muted:#b0aea5;--orange:#d97757;--blue:#6a9bcc;--green:#788c5d;--red:#d4504a;--mtp:#76B900;--line:#3a3935} *{box-sizing:border-box;margin:0;padding:0} html,body{background:var(--bg)!important} body{font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;color:var(--cream);line-height:1.5} #srt-x{max-width:880px;margin:0 auto;background:var(--bg)!important;border:1px solid var(--line)!important;border-radius:16px;overflow:hidden} #srt-x .hd{padding:22px 24px 14px;border-bottom:1px solid var(--line)} #srt-x .kicker{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--orange);font-weight:700} #srt-x h2{font-size:24px;font-weight:800;margin-top:4px;color:var(--cream)} #srt-x .sub{color:var(--muted);font-size:14px;margin-top:4px} #srt-x .tabs{display:flex;gap:4px;padding:10px 16px 0;border-bottom:1px solid var(--line);overflow-x:auto} #srt-x .tab{background:transparent;border:0;color:var(--muted);font:600 14px Inter,sans-serif;padding:10px 14px;cursor:pointer;border-bottom:2px solid transparent;white-space:nowrap} #srt-x .tab.on{color:var(--cream);border-bottom-color:var(--orange)} #srt-x .tab:hover{color:var(--cream)} #srt-x .pane{display:none;padding:22px 24px;animation:fade .35s ease} #srt-x .pane.on{display:block} @keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}} /* flow */ #srt-x .flow{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;align-items:stretch;position:relative} #srt-x .node{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:12px 10px;text-align:center;font-size:13px;transition:all .35s ease;position:relative} #srt-x .node b{display:block;font-size:14px;margin-bottom:2px} #srt-x .node small{color:var(--muted);font-size:12px} #srt-x .node.act{border-color:var(--orange);box-shadow:0 0 0 3px rgba(217,119,87,.25);transform:translateY(-3px)} #srt-x .node.ok{border-color:var(--green);box-shadow:0 0 0 3px rgba(120,140,93,.3)} #srt-x .node.bad{border-color:var(--red);box-shadow:0 0 0 3px rgba(212,80,74,.3)} #srt-x .track{height:6px;background:var(--panel2);border-radius:6px;margin:16px 0 6px;position:relative;overflow:hidden} #srt-x .pkt{position:absolute;top:0;left:0;height:6px;width:12%;border-radius:6px;background:var(--orange);transition:left .6s cubic-bezier(.4,0,.2,1),background .3s} #srt-x .desc{background:var(--panel);border-left:3px solid var(--orange);border-radius:8px;padding:14px 16px;margin-top:14px;min-height:92px;font-size:14px} #srt-x .desc h4{font-size:15px;margin-bottom:4px} #srt-x .ctrl{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap} #srt-x .btn{background:var(--panel2);color:var(--cream);border:1px solid var(--line);border-radius:999px;padding:8px 16px;font:600 13px Inter,sans-serif;cursor:pointer;transition:all .2s} #srt-x .btn:hover{border-color:var(--orange)} #srt-x .btn.pri{background:var(--orange);border-color:var(--orange);color:#141413} #srt-x .btn.sel{border-color:var(--orange);color:var(--orange)} /* sim */ #srt-x .sim{display:grid;grid-template-columns:1fr 1.25fr;gap:16px} #srt-x .card{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:14px} #srt-x .card h5{font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-bottom:8px} #srt-x label.chk{display:flex;align-items:center;gap:8px;font-size:13px;padding:5px 0;cursor:pointer} #srt-x label.chk input{accent-color:var(--orange);width:16px;height:16px} #srt-x code,#srt-x pre{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace!important;background:transparent!important;color:inherit!important;border:0!important} #srt-x .cmds{display:flex;flex-direction:column;gap:6px} #srt-x .cmd{text-align:left;background:var(--panel2);border:1px solid var(--line);color:var(--cream);border-radius:8px;padding:8px 10px;font:12.5px ui-monospace,Menlo,monospace;cursor:pointer;transition:all .2s} #srt-x .cmd:hover{border-color:var(--orange);transform:translateX(3px)} #srt-x .term{background:#0c0c0b!important;border:1px solid var(--line)!important;border-radius:10px;padding:12px 14px;font:12.5px/1.6 ui-monospace,Menlo,monospace;min-height:150px;color:var(--cream)!important;white-space:pre-wrap;word-break:break-word} #srt-x .term .p{color:var(--orange)} #srt-x .term .ok{color:#9fbf7a} #srt-x .term .no{color:#ef7a73} #srt-x .term .dim{color:var(--muted)} #srt-x .why{font-size:13px;color:var(--muted);margin-top:10px;min-height:40px} /* platforms */ #srt-x .plat{display:grid;grid-template-columns:repeat(3,1fr);gap:12px} #srt-x .pc{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:16px;cursor:pointer;transition:all .25s} #srt-x .pc:hover,#srt-x .pc.on{border-color:var(--orange);transform:translateY(-3px)} #srt-x .pc h4{font-size:16px} #srt-x .tag{display:inline-block;font-size:11px;font-weight:700;padding:2px 8px;border-radius:999px;margin-top:4px} #srt-x .t-g{background:rgba(120,140,93,.25);color:#b5cc94} #srt-x .t-o{background:rgba(217,119,87,.2);color:var(--orange)} #srt-x .pc ul{list-style:none;margin-top:10px;font-size:13px;color:var(--muted)} #srt-x .pc li{padding:3px 0} #srt-x .pc li::before{content:"→ ";color:var(--orange)} #srt-x .pdetail{margin-top:14px} /* defaults */ #srt-x .defs{display:grid;grid-template-columns:repeat(3,1fr);gap:12px} #srt-x .dc{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:16px;text-align:center} #srt-x .dc .big{font-size:22px;font-weight:800;margin:6px 0} #srt-x .dc p{font-size:13px;color:var(--muted)} #srt-x .bars{margin-top:18px} #srt-x .bar{margin:10px 0} #srt-x .bar .lb{display:flex;justify-content:space-between;font-size:13px;margin-bottom:4px} #srt-x .bar .bg{height:22px;background:var(--panel2);border-radius:6px;overflow:hidden} #srt-x .bar .fg{height:22px;width:0;border-radius:6px;transition:width 1.2s cubic-bezier(.2,.8,.2,1)} #srt-x .note{font-size:12px;color:var(--muted);margin-top:8px} /* compare */ #srt-x table{width:100%;border-collapse:collapse;font-size:13px} #srt-x th,#srt-x td{border:0!important;border-bottom:1px solid var(--line)!important;padding:9px 8px;text-align:left;vertical-align:top;background:transparent!important;color:var(--cream)!important} #srt-x th{color:var(--muted)!important;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.05em} #srt-x td.hl{color:var(--orange)!important;font-weight:600} #srt-x tr.row{opacity:0;transform:translateX(-6px);transition:all .4s ease} #srt-x tr.row.in{opacity:1;transform:none} #srt-x .ft{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;padding:12px 24px;border-top:1px solid var(--line);font-size:12px;color:var(--muted)} #srt-x .ft .mtp{color:var(--mtp);font-weight:700} #srt-x hr,#srt-x p:empty,#srt-x del,#srt-x s{display:none!important} #srt-x .tblwrap{overflow-x:auto} @media (max-width:640px){ #srt-x .hd{padding:18px 16px 12px} #srt-x h2{font-size:20px} #srt-x .pane{padding:18px 16px} #srt-x .flow{grid-template-columns:1fr 1fr} #srt-x .flow .node:last-child{grid-column:span 2} #srt-x .sim,#srt-x .plat,#srt-x .defs{grid-template-columns:1fr} #srt-x .ft{padding:12px 16px} } <div id="srt-x"> <div class="hd"> <div class="kicker">Anthropic · sandbox-runtime (srt)</div> <h2>How an OS-level agent sandbox works</h2> <div class="sub">Filesystem and network limits for any process, without a container.</div> </div> <div class="tabs" role="tablist"> <button class="tab on" data-t="flow">How it works</button> <button class="tab" data-t="sim">Try a command</button> <button class="tab" data-t="plat">Platforms</button> <button class="tab" data-t="defs">Defaults & 84%</button> <button class="tab" data-t="cmp">Compare</button> </div> <div class="pane on" id="p-flow"> <div class="flow"> <div class="node" data-n="0"><b>Agent / process</b><small>Claude Code, MCP server, any CLI</small></div> <div class="node" data-n="1"><b>srt wrapper</b><small>reads ~/.srt-settings.json</small></div> <div class="node" data-n="2"><b>OS boundary</b><small>Seatbelt · bubblewrap · WFP</small></div> <div class="node" data-n="3"><b>Host proxy</b><small>HTTP + SOCKS5</small></div> <div class="node" data-n="4"><b>Allowlist check</b><small>allow · deny · ask</small></div> </div> <div class="track"><div class="pkt" id="pkt"></div></div> <div class="desc" id="fdesc"></div> <div class="ctrl"> <button class="btn" id="fprev"> Back</button> <button class="btn pri" id="fnext">Next step </button> <button class="btn" id="fplay">Auto-play</button> </div> </div> <div class="pane" id="p-sim"> <div class="sim"> <div> <div class="card"> <h5>network.allowedDomains</h5> <label class="chk"> anthropic.com</label> <label class="chk"> *.npmjs.org</label> <label class="chk"> github.com</label> <h5 style="margin-top:12px">filesystem</h5> <label class="chk"> denyRead: ~/.ssh</label> <label class="chk"> denyWrite: .env</label> </div> </div> <div> <div class="cmds" id="cmds"> <button class="cmd" data-c="0">srt "cat README.md"</button> <button class="cmd" data-c="1">srt "cat ~/.ssh/id_rsa"</button> <button class="cmd" data-c="2">srt "curl anthropic.com"</button> <button class="cmd" data-c="3">srt "curl example.com"</button> <button class="cmd" data-c="4">srt "npm install"</button> <button class="cmd" data-c="5">srt "echo KEY=1 >> .env"</button> </div> <div class="term" id="term" style="margin-top:10px"><span class="dim">Pick a command. Toggle the config to see what changes.</span></div> <div class="why" id="why"></div> </div> </div> </div> <div class="pane" id="p-plat"> <div class="plat"> <div class="pc on" data-p="0"><h4>macOS</h4><span class="tag t-g">Supported</span><ul><li>sandbox-exec</li><li>Seatbelt profiles</li><li>Needs ripgrep</li></ul></div> <div class="pc" data-p="1"><h4>Linux</h4><span class="tag t-g">Supported</span><ul><li>bubblewrap</li><li>No network namespace</li><li>socat + ripgrep</li></ul></div> <div class="pc" data-p="2"><h4>Windows</h4><span class="tag t-o">Alpha</span><ul><li>srt-sandbox account</li><li>WFP egress fence</li><li>One-time install</li></ul></div> </div> <div class="desc pdetail" id="pdesc"></div> </div> <div class="pane" id="p-defs"> <div class="defs"> <div class="dc"><div class="kicker">Read</div><div class="big" style="color:#b5cc94">Allow</div><p>Allowed everywhere by default. Deny regions like ~/.ssh, re-allow with allowRead.</p></div> <div class="dc"><div class="kicker">Write</div><div class="big" style="color:#ef7a73">Deny</div><p>Denied everywhere by default. Open paths like "." and /tmp with allowWrite.</p></div> <div class="dc"><div class="kicker">Network</div><div class="big" style="color:#ef7a73">Deny</div><p>No access by default. Every host must match allowedDomains.</p></div> </div> <div class="bars" id="bars"> <div class="kicker" style="margin-bottom:4px">Claude Code permission prompts (indexed)</div> <div class="bar"><div class="lb"><span>Without sandboxing</span><span>100</span></div><div class="bg"><div class="fg" data-w="100" style="background:var(--muted)"></div></div></div> <div class="bar"><div class="lb"><span>With sandboxing</span><span>16</span></div><div class="bg"><div class="fg" data-w="16" style="background:var(--orange)"></div></div></div> <div class="note">84% fewer prompts in Anthropic's internal usage (self-reported, Oct 2025 engineering post). Indexed to 100.</div> </div> </div> <div class="pane" id="p-cmp"> <div class="tblwrap"> <table> <thead><tr><th></th><th>srt</th><th>Codex CLI</th><th>Docker Sandboxes</th><th>E2B</th></tr></thead> <tbody> <tr class="row"><td>Isolation</td><td class="hl">OS primitives</td><td>OS primitives</td><td>microVM</td><td>Firecracker microVM</td></tr> <tr class="row"><td>Runs</td><td class="hl">Local</td><td>Local</td><td>Local</td><td>Cloud / BYOC</td></tr> <tr class="row"><td>Container or VM</td><td class="hl">No</td><td>No</td><td>Yes</td><td>Yes</td></tr> <tr class="row"><td>Network default</td><td class="hl">Deny all</td><td>Off (toggle)</td><td>Chosen policy</td><td>On</td></tr> <tr class="row"><td>Domain allowlist</td><td class="hl">Wildcards + ports</td><td>Not disclosed</td><td>Wildcards + ports</td><td>allowOut, wildcards</td></tr> <tr class="row"><td>License</td><td class="hl">Apache-2.0</td><td>Apache-2.0</td><td>Not disclosed</td><td>Apache-2.0 (SDK)</td></tr> </tbody> </table> </div> </div> <div class="ft"><span>Sources: github.com/anthropics/sandbox-runtime · anthropic.com/engineering · v0.0.81</span><span class="mtp">Built by Marktechpost</span></div> </div> (function(){ var R=document.getElementById('srt-x'); function post(){try{parent.postMessage({srtH:R.offsetHeight+40},'*')}catch(e){}} var tabs=R.querySelectorAll('.tab'); tabs.forEach(function(b){b.addEventListener('click',function(){ tabs.forEach(function(x){x.classList.remove('on')});b.classList.add('on'); R.querySelectorAll('.pane').forEach(function(p){p.classList.remove('on')}); var t=b.getAttribute('data-t');document.getElementById('p-'+t).classList.add('on'); if(t==='defs')bars();if(t==='cmp')rows();setTimeout(post,60); })}); // flow var steps=[ ['Your agent runs a command','The agent, MCP server or CLI tool issues a command. It is unchanged; srt simply wraps it.',0,'act'], ['srt builds the policy','srt loads ~/.srt-settings.json (or built-in defaults) and starts HTTP and SOCKS5 proxies on the host.',1,'act'], ['The OS enforces the boundary','Seatbelt (macOS), bubblewrap (Linux) or a WFP fence (Windows alpha) applies file rules to the whole process tree.',2,'act'], ['All traffic goes through the proxy','The sandbox has no direct route out. On Linux, the network namespace is removed; proxies are reached via Unix sockets.',3,'act'], ['Allowed host: connection proceeds','A host in allowedDomains passes, after a check that it does not resolve to loopback or cloud metadata IPs.',4,'ok'], ['Unknown host: blocked or asked','A denied or unlisted host is refused, or an ask callback decides. The violation is logged for the agent to read.',4,'bad'] ]; var fi=0,timer=null; function draw(){ var s=steps[fi];var ns=R.querySelectorAll('.node'); ns.forEach(function(n,i){n.classList.remove('act','ok','bad');if(i<s[2])n.classList.add('act')}); ns[s[2]].classList.add(s[3]); var pk=document.getElementById('pkt');pk.style.left=(s[2]*22)+'%'; pk.style.background=s[3]==='ok'?'#788c5d':s[3]==='bad'?'#d4504a':'#d97757'; document.getElementById('fdesc').innerHTML='<h4>Step '+(fi+1)+' of '+steps.length+': '+s[0]+'</h4>'+s[1]; } document.getElementById('fnext').onclick=function(){fi=(fi+1)%steps.length;draw()}; document.getElementById('fprev').onclick=function(){fi=(fi-1+steps.length)%steps.length;draw()}; document.getElementById('fplay').onclick=function(){ if(timer){clearInterval(timer);timer=null;this.textContent='Auto-play';return} this.textContent='Pause';timer=setInterval(function(){fi=(fi+1)%steps.length;draw()},1800); }; draw(); // sim function on(id){return document.getElementById(id).checked} var C=[ function(){return [1,'# Anthropic Sandbox Runtime (srt) ...','Reads are allowed by default, and the current directory is readable.']}, function(){return on('f-ssh')?[0,'cat: ~/.ssh/id_rsa: Operation not permitted','~/.ssh is in denyRead, so the key cannot be read.']:[1,'-----BEGIN OPENSSH PRIVATE KEY----- ...','Without a denyRead rule, reads are open everywhere. Deny secrets explicitly.']}, function(){return on('d-anth')?[1,'...','anthropic.com is in allowedDomains, so the proxy forwards it.']:[0,'Connection blocked by network allowlist','No allowlist match: network is deny-by-default.']}, function(){return [0,'Connection blocked by network allowlist','example.com is not allowlisted.']}, function(){return on('d-npm')?[1,'packages installed (illustrative output)','*.npmjs.org is allowlisted, so the registry is reachable.']:[0,'npm ERR! network request to registry.npmjs.org failednConnection blocked by network allowlist','The classic trade-off: too strict, and installs fail.']}, function(){return on('f-env')?[0,'bash: .env: Operation not permitted','denyWrite beats allowWrite, so .env stays protected inside the project.']:[1,'(written)','"." is in allowWrite, so the write succeeds.']} ]; var busy=false; R.querySelectorAll('.cmd').forEach(function(b){b.addEventListener('click',function(){ if(busy)return;busy=true;var r=C[+b.getAttribute('data-c')]();var t=document.getElementById('term'); t.innerHTML='<span class="p">$</span> '+b.textContent.replace(/</g,'<')+'n<span class="dim">Running inside sandbox...</span>'; document.getElementById('why').textContent=''; setTimeout(function(){ t.innerHTML='<span class="p">$</span> '+b.textContent.replace(/</g,'<')+'n<span class="'+(r[0]?'ok':'no')+'">'+(r[0]?'✓ ':'✗ ')+r[1].replace(/</g,'<')+'</span>'; document.getElementById('why').textContent=r[2];busy=false;post(); },650); })}); // platforms var P=['macOS uses the built-in sandbox-exec tool with Seatbelt profiles generated per run. The profile allows only 1 localhost port, where the srt proxies listen. Violations can be read from the system log in real time.', 'Linux uses bubblewrap and removes the network namespace entirely. Proxies are reached through Unix sockets bind-mounted into the sandbox. Ubuntu 24.04+ needs an AppArmor change for user namespaces.', 'Windows (alpha) runs commands as a dedicated srt-sandbox account. A machine-wide WFP filter blocks its outbound traffic except to the proxy ports. Setup needs 1 elevated install.']; var pcs=R.querySelectorAll('.pc'); function pd(i){pcs.forEach(function(x){x.classList.remove('on')});pcs[i].classList.add('on');document.getElementById('pdesc').innerHTML='<h4>'+pcs[i].querySelector('h4').textContent+'</h4>'+P[i];post()} pcs.forEach(function(c,i){c.addEventListener('click',function(){pd(i)})});pd(0); function bars(){R.querySelectorAll('.fg').forEach(function(f){f.style.width='0';setTimeout(function(){f.style.width=f.getAttribute('data-w')+'%'},80)})} function rows(){R.querySelectorAll('tr.row').forEach(function(r,i){r.classList.remove('in');setTimeout(function(){r.classList.add('in')},90*i+60)})} window.addEventListener('load',post);window.addEventListener('resize',post);setTimeout(post,300); })(); "> (function(){var f=document.getElementById('mtp-srt-frame');window.addEventListener('message',function(e){if(e.source===f.contentWindow&&e.data&&e.data.srtH){f.style.height=e.data.srtH+'px';}});})(); The real trade-off: strict allowlists vs working agents Coding agents do more than edit files. They install dependencies, pull docs and call APIs. Make the allowlist too strict and npm install fails. Make it too loose and the sandbox protects little. srt ships several knobs for that middle ground: Wildcards and ports: entries like *.npmjs.org or api.example.com:443. Ask callback: decides hosts no rule covers, and can return a reason the model reads. Per-command allow lists: open a registry for 1 invocation only. Live updates: --control-fd swaps network lists while a command runs. Resolved-address check: blocks allowed names that resolve to loopback or cloud metadata IPs. Denied-domain reasons: tell the agent the sanctioned alternative, such as an HTTPS git remote.. How does it compare with other agent sandboxes? Key Takeaways srt sandboxes any process at the OS level, no container needed. Seatbelt on macOS, bubblewrap on Linux, Windows in alpha. Network is deny-by-default; every connection passes a host-side allowlist proxy. Anthropic reports 84% fewer Claude Code permission prompts (internal). Allowlist breadth is the real security dial; broad domains can leak data. Check out the GitHub repo, the Anthropic engineering post and the Claude Code sandboxing docs. 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. Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.? Connect with us The post Meet Anthropic’s sandbox-runtime: OS-Level Sandboxing for AI Agents, No Containers appeared first on MarkTechPost.
In this tutorial, we build a stateful engineering copilot with Letta that demonstrates how agentic memory extends beyond conventional prompt-based conversations. We begin by creating inspectable core memory blocks that the agent can autonomously update, then expose those blocks for programmatic state synchronization and shared access across multiple agents. We further extend the architecture with archival vector memory for semantic retrieval, a custom server-side tool for deterministic risk estimation, streaming for observing agent execution, server-side message history for persistent conversations, and .af export for portability. Together, these components demonstrate a practical memory architecture in which persistent state, retrieval, tools, multi-agent collaboration, and execution traces work as an integrated agentic system. Copy CodeCopiedUse a different Browserimport subprocess, sys subprocess.run([sys.executable, "-m", "pip", "install", "-q", "-U", "letta-client"], check=True) import os, json, time, textwrap from getpass import getpass from letta_client import Letta def flex(*attempts, label=""): err = None for fn in attempts: try: return fn() except Exception as e: err = e raise RuntimeError(f"All call variants failed for {label or 'call'}: {err}") from err API_KEY = os.environ.get("LETTA_API_KEY") or getpass("Letta API key (platform.letta.com/api-keys): ") BASE_URL = os.environ.get("LETTA_BASE_URL", "").strip() client = flex( lambda: Letta(base_url=BASE_URL, api_key=API_KEY) if BASE_URL else Letta(api_key=API_KEY), lambda: Letta(base_url=BASE_URL, token=API_KEY) if BASE_URL else Letta(token=API_KEY), label="client init", ) def hr(title): print("n" + "=" * 92 + f"n {title}n" + "=" * 92) def as_text(content): if isinstance(content, str): return content if isinstance(content, list): return "".join(getattr(p, "text", "") or "" for p in content) return str(content or "") def show(response, hide_reasoning=False): for m in getattr(response, "messages", response) or []: kind = getattr(m, "message_type", None) or getattr(m, "type", "?") if kind == "reasoning_message" and not hide_reasoning: print(" reasoning :", textwrap.shorten(getattr(m, "reasoning", "") or "", 220)) elif kind == "tool_call_message": tc = getattr(m, "tool_call", None) print(" tool call :", getattr(tc, "name", "?"), textwrap.shorten(str(getattr(tc, "arguments", "")), 200)) elif kind == "tool_return_message": print(" tool ret :", textwrap.shorten(str(getattr(m, "tool_return", "")), 260)) elif kind == "assistant_message": print(" assistant :", as_text(getattr(m, "content", ""))) elif kind == "approval_request_message": print(" approval : agent is waiting for you to approve a tool call") u = getattr(response, "usage", None) if u: print(f" ↳ steps={getattr(u, 'step_count', '?')} tokens={getattr(u, 'total_tokens', '?')}") def chat(agent_id, text, max_steps=12, quiet=False): r = flex( lambda: client.agents.messages.create(agent_id=agent_id, input=text, max_steps=max_steps), lambda: client.agents.messages.create(agent_id=agent_id, input=text), lambda: client.agents.messages.create(agent_id=agent_id, messages=[{"role": "user", "content": text}]), label="messages.create", ) if not quiet: print(f"n user : {text}") show(r) return r PREFERRED = ["openai/gpt-4.1", "openai/gpt-4o-mini", "anthropic/claude-sonnet-4-20250514"] try: handles = [getattr(m, "handle", None) for m in client.models.list()] MODEL = next((h for h in PREFERRED if h in handles), None) or handles[0] except Exception: MODEL = PREFERRED[0] print(f" connected · model handle = {MODEL}") hr("1. Create a stateful agent with custom memory blocks") def make_agent(**kw): return flex( lambda: client.agents.create(model=MODEL, embedding="openai/text-embedding-3-small", **kw), lambda: client.agents.create(model=MODEL, **kw), label="agents.create", ) copilot = make_agent( name=f"copilot-{int(time.time())}", description="Engineering copilot with inspectable long-term memory", tags=["tutorial", "copilot"], memory_blocks=[ {"label": "persona", "value": "I am Mnemo, an engineering copilot. I am terse, concrete, and I never " "invent facts — if I don't know something I say so and then go look it up.", "limit": 3000}, {"label": "human", "description": "Durable facts about the engineer I work with: name, role, stack, " "preferences, working style. Update this whenever I learn something stable.", "value": "Unknown so far.", "limit": 3000}, {"label": "project_state", "description": "Live state of the project we are shipping: milestones, blockers, " "decisions and their rationale. Keep it dense and current; delete stale lines.", "value": "(empty)", "limit": 5000}, {"label": "lessons", "description": "Hard-won lessons and mistakes to never repeat. Append-only, one line each.", "value": "(empty)", "limit": 2000}, ], ) print("agent id:", copilot.id) def get_block(agent_id, label): return flex( lambda: client.agents.blocks.retrieve(agent_id=agent_id, block_label=label), lambda: client.agents.blocks.retrieve(agent_id, label), label="agents.blocks.retrieve", ) def set_block(agent_id, label, value): return flex( lambda: client.agents.blocks.update(agent_id=agent_id, block_label=label, value=value), lambda: client.agents.blocks.modify(agent_id=agent_id, block_label=label, value=value), lambda: client.agents.blocks.update(agent_id, label, value=value), label="agents.blocks.update", ) def dump_memory(agent_id, title="core memory"): blocks = flex(lambda: client.agents.blocks.list(agent_id=agent_id), lambda: client.agents.blocks.list(agent_id), label="agents.blocks.list") print(f"n──── {title} ────") for b in blocks: ro = " [read-only]" if getattr(b, "read_only", False) else "" print(f"▸ {b.label}{ro} ({len(b.value or '')}/{getattr(b, 'limit', '?')} chars)") print(textwrap.indent(textwrap.fill(b.value or "", 100), " ")) return blocks dump_memory(copilot.id, "core memory at birth") We set up the Letta client, install the SDK, and add compatibility helpers that handle API variations across Letta versions. We dynamically select an available model and create a stateful engineering copilot with structured core memory blocks. We then inspect the initial memory state to establish the agent’s persistent context. Copy CodeCopiedUse a different Browserhr("2. Self-editing memory — talk once, then read the block back") chat(copilot.id, "Hi, I'm Priya, staff engineer at Northwind. We're shipping 'Halo', a Rust ingestion " "service, on Nov 14. I hate long explanations — give me bullets or code, never essays. " "Current blocker: the Kafka consumer rebalances every ~4 minutes under load.") chat(copilot.id, "Update: we traced the rebalance to a 5s max.poll.interval.ms with slow batch commits. " "Decision: move commits off the poll loop. Also remember we already tried bumping " "session.timeout.ms and it did nothing — don't suggest that again.") dump_memory(copilot.id, "core memory after 2 turns (note what moved where)") hr("3. Your code writes into the context window") live = get_block(copilot.id, "project_state") set_block(copilot.id, "project_state", (live.value or "") + "n[CI 09:41Z] main is RED: integration/kafka_rebalance_test failing (flaky x3).") chat(copilot.id, "Anything I should know before I start the day?") hr("4. Shared memory between two agents") policies = client.blocks.create( label="policies", description="Non-negotiable engineering policies. Read-only: obey, never edit.", value="1. No direct pushes to main.n2. Every fix ships with a regression test.n" "3. Customer data never leaves EU regions.", limit=2000, read_only=True, ) scratchpad = client.blocks.create( label="team_scratchpad", description="Shared working notes between the copilot and the reviewer agent. " "Both agents read and write here; keep entries prefixed with your name.", value="(empty)", limit=4000, ) for bid in (policies.id, scratchpad.id): flex(lambda: client.agents.blocks.attach(agent_id=copilot.id, block_id=bid), lambda: client.agents.blocks.attach(copilot.id, bid), label="agents.blocks.attach") reviewer = make_agent( name=f"reviewer-{int(time.time())}", description="Strict code reviewer sharing memory with the copilot", tags=["tutorial", "reviewer"], block_ids=[policies.id, scratchpad.id], memory_blocks=[{"label": "persona", "value": "I am Argus, a paranoid staff reviewer. I look for the failure mode " "everyone else skipped, and I cite the team policies by number."}], ) print("reviewer id:", reviewer.id) chat(copilot.id, "Write your proposed fix for the rebalance issue into the team_scratchpad " "block so the reviewer can see it. Keep it to 4 lines.") print("n what the REVIEWER sees in the shared block (written by the other agent):") print(textwrap.indent(client.blocks.retrieve(scratchpad.id).value, " ")) chat(reviewer.id, "Read team_scratchpad and review the proposed fix. Cite any policy it violates, " "then append your verdict to the same block.") print("n shared block after the reviewer replied:") print(textwrap.indent(client.blocks.retrieve(scratchpad.id).value, " ")) print("nagents attached to this block:", [a.name for a in flex(lambda: client.blocks.agents.list(block_id=scratchpad.id), lambda: client.blocks.agents.list(scratchpad.id), label="blocks.agents.list")]) We demonstrate self-editing memory by providing the copilot with durable information about the engineer, project, decisions, and known failure modes. We also update project state directly from application code and create shared read-only and writable blocks for multi-agent collaboration. We then connect a reviewer agent to the shared memory and observe how both agents exchange persistent working context. Copy CodeCopiedUse a different Browserhr("5. Archival memory: bulk-load knowledge, then let the agent retrieve it") KNOWLEDGE = [ ("Postmortem 2024-08-02: Halo dropped 1.2M events when the consumer group rebalanced during a " "deploy. Root cause: commits inside the poll loop blocked past max.poll.interval.ms.", ["postmortem", "kafka", "halo"]), ("ADR-017: Halo uses at-least-once delivery with idempotent writes keyed on (tenant_id, event_id). " "Exactly-once via Kafka transactions was rejected for throughput reasons.", ["adr", "architecture", "halo"]), ("Runbook: to drain a Halo node, set DRAIN=1, wait for lag str: """Estimate the risk of shipping a release on time. Args: open_bugs (int): Number of open P0/P1 bugs. days_to_deadline (int): Calendar days left before the ship date. test_coverage (float): Line coverage as a fraction between 0.0 and 1.0. Returns: str: A risk score from 0-100 and a verdict. """ import math pressure = open_bugs / max(days_to_deadline, 1) score = max(0.0, min(100.0, 100 * (1 - math.exp(-1.4 * pressure)) * (1.3 - test_coverage))) verdict = "SHIP" if score < 35 else ("SLIP ONE WEEK" if score < 70 else "DO NOT SHIP") return f"risk_score={score:.1f} verdict={verdict}" tool = flex( lambda: client.tools.upsert_from_function(func=estimate_release_risk), lambda: client.tools.create_from_function(func=estimate_release_risk), label="tools.upsert_from_function", ) flex(lambda: client.agents.tools.attach(agent_id=copilot.id, tool_id=tool.id), lambda: client.agents.tools.attach(copilot.id, tool.id), label="agents.tools.attach") print("attached tool:", tool.name, "| agent tools:", [t.name for t in flex(lambda: client.agents.tools.list(agent_id=copilot.id), lambda: client.agents.tools.list(copilot.id), label="agents.tools.list")]) chat(copilot.id, "We have 9 open P0/P1 bugs, 12 days to the Nov 14 date, coverage is 0.61. " "Score the risk with the tool, then record the verdict in project_state.") We populate archival memory with tagged engineering knowledge and use semantic search to retrieve relevant information without relying on exact keyword matches. We then allow the agent to query this archival knowledge autonomously when answering an operational question. Finally, we create and attach a custom server-side release-risk tool so the agent can perform deterministic calculations and record the resulting decision in memory. Copy CodeCopiedUse a different Browserhr("7. Streaming the agent's steps") def stream_chat(agent_id, text): print(f" user : {text}") s = flex( lambda: client.agents.messages.stream(agent_id=agent_id, input=text), lambda: client.agents.messages.stream(agent_id=agent_id, messages=[{"role": "user", "content": text}]), lambda: client.agents.messages.create_stream(agent_id=agent_id, messages=[{"role": "user", "content": text}]), label="messages.stream", ) for chunk in s: kind = getattr(chunk, "message_type", None) or getattr(chunk, "type", "") if kind == "reasoning_message": print("", textwrap.shorten(getattr(chunk, "reasoning", "") or "", 160)) elif kind == "tool_call_message": print("", getattr(getattr(chunk, "tool_call", None), "name", "?")) elif kind == "assistant_message": print("", as_text(getattr(chunk, "content", ""))) try: stream_chat(copilot.id, "One-line status of Halo, from memory only. No tools.") except Exception as e: print("streaming unavailable on this SDK version:", e) hr("8. Server-side conversation history") hist = flex(lambda: client.agents.messages.list(agent_id=copilot.id, limit=8), lambda: client.agents.messages.list(copilot.id, limit=8), label="agents.messages.list") for m in hist: kind = getattr(m, "message_type", "?") body = as_text(getattr(m, "content", "")) or getattr(m, "reasoning", "") or "" print(f" [{kind:<24}] {textwrap.shorten(str(body), 110)}") print("n reconnect from a fresh process with just the id:") print(" client.agents.messages.create(agent_id='%s', input='...')" % copilot.id) We use Letta’s streaming interface to observe reasoning, tool calls, and assistant responses as the agent executes a task. We then inspect server-side conversation history to verify that the interaction state persists independently of the local Python process. We also demonstrate how the agent can be reconnected from a fresh process using only its persistent identifier. Copy CodeCopiedUse a different Browserhr("9. Export / import the agent") try: dump = flex(lambda: client.agents.export_file(agent_id=copilot.id), lambda: client.agents.export_file(copilot.id), label="agents.export_file") blob = dump if isinstance(dump, (str, bytes)) else json.dumps(dump, default=str) path = "/content/copilot.af" if os.path.isdir("/content") else "copilot.af" with open(path, "wb" if isinstance(blob, bytes) else "w") as f: f.write(blob) print(f"exported → {path} ({len(blob)} bytes) — memory, tools and history travel with it.") print("re-import later with: client.agents.import_file(file=open(path,'rb'))") except Exception as e: print("export not available on this SDK/deployment:", e) CLEANUP = False if CLEANUP: for aid in (copilot.id, reviewer.id): try: client.agents.delete(aid) except Exception as e: print("agent delete:", e) for bid in (policies.id, scratchpad.id): try: client.blocks.delete(bid) except Exception as e: print("block delete:", e) print("deleted.") else: hr("Done") print(f"copilot : {copilot.id}nreviewer : {reviewer.id}") print("Inspect them visually in the ADE at ") We export the complete agent state to an .af file, providing a portable representation of the agent’s memory, tools, and conversation state. We then include optional cleanup logic that removes the agents and shared blocks created during the tutorial. We finish by displaying the persistent agent identifiers and the Letta ADE location for further inspection. In conclusion, we now have a complete view of how Letta supports persistent, inspectable agent workflows rather than treating every interaction as an isolated prompt. We saw how core memory maintains high-value state in context, archival memory provides scalable retrieval, shared and read-only blocks coordinate multiple agents, and application code can directly synchronize external state. We also used custom tools and streaming to extend and observe agent behavior while server-side history and agent export provide persistence and portability. Through this workflow, we established a practical foundation for building engineering copilots that continuously retain context, reason over accumulated knowledge, collaborate across agents, and operate with explicit, controllable memory. Check out the FULL CODES here. 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. Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.? Connect with us The post Stateful Agentic Engineering Copilots with Letta: Core Memory, Shared State, Semantic Retrieval, Custom Tools, Streaming, and Portable Agent Workflows appeared first on MarkTechPost.
A controlled study shows that switching between coding-agent harnesses like Claude Code, OpenCode, or mini-SWE-agent barely moves pass rates more than rerunning the same setup. Cost per task, however, can triple, driven mainly by the system prompt that gets resent with every step. The article Fancy harnesses make coding agents more expensive but not better, study finds appeared first on The Decoder.
Kyutai has released CADRE, open causal diffusion representation autoencoders for interactive world models. The Kyutai CADRE video autoencoder targets one problem: action lag. Many world models borrow autoencoders from text-to-video generators. Those autoencoders pack many frames into one latent, so every action waits. Per the research paper, CADRE world models run at 20 fps on 1 H100 and react within 230 ms. TL;DR Size: 7 autoencoders, each about 476M trained parameters plus a frozen 86M DINOv3 ViT-B/16. The world model is 1.2B parameters. Video runs at 288×512, 20 fps. Runs on: 1 H100 (bf16, batch 1). Quantized variants: Not disclosed. Performance: CADRE forms most of the latency-quality frontier. It is as fast and better in 42 of 48 comparisons with MIRA, Wan 2.2, Cosmos and LTX-2. Best: Driving FVD of 162.6 (CADRE-2×16×16, 1 step) against 599.7 for Wan 2.2. Worst: Robot manipulation action following (ARR) of 0.45 for CADRE-2×32×32, against 0.85 for Wan 2.2. What is CADRE? CADRE is a family of video autoencoders from Kyutai built for action-conditioned world models. A world model generates in the autoencoder’s latent space. So the autoencoder’s compression sets both cost per frame and action delay. Compression is written τ×s×s. τ is frames per latent, and s is the spatial factor. The research gives the latency as τ/f plus generation and decode time. At τ = 8 and 20 fps, the chunk alone adds 400 ms. Humans notice their own movement lagging beyond about 230 ms. How does CADRE work? The encoder reuses the MIRA recipe. A frozen DINOv3 extracts per-patch features from each frame. One trained 3D convolution then compresses them into a 64-channel latent. Only this bottleneck changes between the 7 members. The decoder is a causal diffusion transformer with 24 blocks. It streams chunk by chunk. Progressive self-distillation teaches it to decode in 1 or 2 steps. This happens in a single training stage, without an adversarial loss. The autoencoders train on 23 public video sources, about 76k hours. The mix spans web, robot, driving and game video. How was CADRE evaluated? Kyutai trained the same 1.2B causal diffusion transformer on each autoencoder. It used 4 environments: robot manipulation (ABC), human manipulation (EgoDex), driving (PhysicalAI AV) and indoor navigation (RealEstate10K). Each model sees 2 s of real video, then generates 4.8 s. Scores cover image quality (FID), motion quality (FVD) and action following (ARR). ARR uses a frozen inverse dynamics probe. An ARR of 1 matches real video. (function(){var f=document.getElementById('mtp-cadre-frame');window.addEventListener('message',function(e){if(e.data&&e.data.mtpEmbed==='cadre'&&e.data.height){f.style.height=e.data.height+'px';}});})(); What do the benchmarks show? On one H100, CADRE-2×32×32 reacts in 185 ms and sustains 23.4 fps with 1 decoding step. The Wan 2.2 autoencoder needs 317 ms, LTX-2 492 ms and Cosmos 605 ms. DC-AE is faster at 118 ms but frame-by-frame. The gap is widest with a moving camera. In driving, Wan 2.2 FVD reaches 599.7 and LTX-2 913.3. In indoor navigation, LTX-2 ARR falls to 0.04. Against the retrained MIRA decoder, the 1-step diffusion decoder lowers FVD by 1.4 to 2.5×. What are the 4 findings? Decode by diffusion: at strong compression, perceptual regression blurs, while diffusion samples 1 sharp video. Compress time in the autoencoder: patching inside the world model loses detail. At 8 frames, ARR drops from 0.72 to 0.56. Camera motion decides compression: still cameras tolerate temporal compression. Moving cameras favor fewer frames and coarser spatial tokens. Coarse tokens hurt motion first: in robot manipulation, 32× spatial compression multiplies FVD by 2.4 over 16×. FID barely moves. Comparison: CADRE vs other video autoencoders Latency, fpsA, FVD, ARR and PSNR: CADRE paper, Tables 4, 6 and 7. CADRE uses 1 decoding step. All figures are self-reported by Kyutai. Where does CADRE fall short? CADRE does not win everywhere. In robot manipulation, Cosmos posts an FVD of 39.5 against 47.6 for the best 1-step CADRE. At the fast end, DC-AE beats CADRE-1×48×48 in manipulation. Wan 2.2 also reconstructs held-out video far better, at 35.02 dB PSNR. Kyutai team argues reconstruction does not predict rollouts. Wan 2.2 ranks last on indoor rollout FVD. Long latents leave visible seams between chunks. At τ = 8, boundary excess reaches 1.6 to 1.8 across environments. CADRE-4×24×24 is an outlier in navigation, with FVD 403 in driving. Each world model covers one environment at 288×512. Whether findings transfer to generalist models remains open. How can developers use CADRE? The code is MIT licensed. Weights on Hugging Face are CC BY-NC 4.0, so commercial use is excluded. The release covers 7 autoencoders, 4 longer-trained multi-resolution versions and 4 world models on CADRE-2×16×16. A live demo lets you drive them by keyboard. Key Takeaways 7 open autoencoders, one bottleneck apart, isolate compression as the only variable. World models on CADRE run at 20 fps on 1 H100, under 230 ms lag. Driving FVD drops to 162.6, against 599.7 for Wan 2.2. Still cameras favor temporal compression; moving cameras favor spatial compression. Weights are non-commercial (CC BY-NC 4.0); code is MIT. Check out the paper, the Kyutai blog, the GitHub repo and the model collection. 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. Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.? Connect with us The post Kyutai CADRE: Video Autoencoders That Cut World Model Lag Below 230 ms appeared first on MarkTechPost.
Moonshot AI has just released Kimi K3.1 Pro, the first model in its K3.1 series. Kimi K3.1 Pro is a 3T-class open-weight* model with a 1-million-token context window. Moonshot team positions it against the strongest proprietary models on coding, agentic and knowledge benchmarks. For developers, it is cheaper API pricing than K3 and open weights yet not available. *open weights are expected to release in November 2026. TL;DR Size: 2.8T total, 104B active parameters (MoE), 1M-token context. Runs on: Kimi API today. For K3, Moonshot recommends supernodes of 64+ accelerators, with MXFP4 weights and MXFP8 activations. Not a single-GPU model. Performance: Near the proprietary frontier on terminal coding; behind it on scientific terminal tasks. Best: SWE-Marathon 51.7, ahead of every model in Kimi’s chart (self-reported). Worst: Terminal-Bench Science 0.1 at 38.1, versus 68.1 for GPT-6 Astra in Kimi’s chart. What is Kimi K3.1 Pro? Kimi K3.1 Pro is a post-trained version of Kimi K3 with much larger post-training compute. Moonshot team ran joint reinforcement learning across hundreds of downstream domains. To support this, the Moonshot team optimized the RL framework, long-context inference, sandbox infrastructure and rollout scheduling. The base K3 architecture uses Kimi Delta Attention (KDA) and Attention Residuals (AttnRes). It activates 16 of 896 experts through a Stable LatentMoE framework. The model accepts text, images and video through the API, per the quickstart docs. Moonshot team also shipped Kimi K3.1 Pro Highspeed. According to the official Moonshot blog, it runs 2 to 3x faster. How does Kimi K3.1 Pro perform on benchmarks? All numbers below are self-reported by Moonshot at max reasoning effort, mostly with the Claude Code harness. Coding: On Terminal-Bench 4.0, K3.1 Pro scores 65.7%. That is just behind Claude Opus 5.5 at 66.4% in Kimi’s chart. On SWE-Marathon it leads at 51.7, ahead of Opus 5.5 at 46.3. On Kimi Code Bench 3.0 Long-horizon, an internal benchmark, it scores 61.2, up from K3’s 55.95. Science: Terminal-Bench Science 0.1 is the clear gap. K3.1 Pro scores 38.1, versus 68.1 for GPT-6 Astra and 63.3 for Opus 5.5 in Kimi’s chart. 3D and CAD: On BenchCAD with tools, K3.1 Pro scores 92.7. Opus 5.5 scores 96.2 and GPT-6 Astra 95.9. Without tools, K3.1 Pro scores 72.8, close to Opus 5.5 at 73.0. Finance: K3.1 Pro reports a state-of-the-art 64.4 on OfficeQA Pro v2. It scores 58.6 on Frontier Finance. On internal finance tests, it gains 7.2 points in modeling and 11.6 in research over K3. Hallucination: On Kimi Hallu Bench Hard, an internal stress test, claim-level hallucinations fell from 23.4% (K3) to 8.3%. That is roughly the 65% drop Moonshot cites. GPT-6 Astra still posts a lower 5.5% on the same test. window.addEventListener('message',function(e){if(e.data&&e.data.id==='mtp-k31'&&e.data.mtpH){var f=document.getElementById('mtp-k31-frame');if(f)f.style.height=e.data.mtpH+'px';}}); How does Kimi K3.1 Pro handle cyber risk? Moonshot removed cyber-related data from mid-training and RL for the open-weight release. On its internal xdev-bench-hard, an unfiltered checkpoint solved 90.5% at pass@3. The shipped K3.1 Pro solves 81.0%. Moonshot says it stays behind frontier proprietary models on offensive cyber tasks. How can developers access Kimi K3.1 Pro? The model is live on Kimi.ai, Kimi Work, Kimi Code and the Kimi API. The API IDs are kimi-k3.1-pro and kimi-k3.1-pro-highspeed. The endpoint is OpenAI-compatible. Pricing for K3.1 Pro is $2.00 input and $10.00 output per million tokens. Cache hits cost $0.20. Highspeed costs $4.00 input and $20.00 output. K3 itself was priced at $3.00 and $15.00. Practical limits from the quickstart: Thinking mode is always on. Reasoning effort is low, high or max (default max). Temperature 1.0 and top-p 0.95 are fixed. Output defaults to 131,072 tokens and can go up to 1,048,576. Access unlocks after a minimum $1 top-up. Vision input does not accept public image URLs. Use base64 or uploaded file IDs. How does it compare with competing models? window.addEventListener('message',function(e){if(e.data&&e.data.id==='mtp-k31c'&&e.data.mtpH){var f=document.getElementById('mtp-k31c-frame');if(f)f.style.height=e.data.mtpH+'px';}}); *Figure taken from Kimi’s comparison chart; not confirmed on the competitor’s own page. What are the limitations? Weights are not public yet, so self-hosting is not possible today. The 2.8T size points to multi-node, supernode-class serving. Science-heavy terminal work trails GPT-6 Astra and Opus 5.5 by 25+ points. Several claimed wins come from internal benchmarks. For K3, Moonshot warned that dropping reasoning history in a harness destabilizes output. The K3.1 Pro docs also say to return the full assistant message. Key Takeaways Kimi K3.1 Pro: 2.8T total, 104B active, 1M context. Terminal-Bench 4.0 at 65.7%, 0.7 points behind Opus 5.5. Leads SWE-Marathon at 51.7; trails badly on Terminal-Bench Science (38.1). API costs $2/$10 per million tokens, cheaper than K3. Open weights are expected in November 2026. Check out the official tech blog, the API quickstart and the launch post on X. 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. Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.? Connect with us The post Moonshot AI Releases Kimi K3.1 Pro: A 2.8T Total/104B Active Params (MoE) Model with 1M Context appeared first on MarkTechPost.
Moonshot AI's Kimi K3.1 Pro scores 55 points on the Artificial Analysis Intelligence Index, an 11-point jump over its predecessor that puts it in fourth place. Only three Anthropic and Meta models rank higher. If Moonshot releases the weights as planned, the gap between open and proprietary models shrinks to just three points. The article Chinese AI model Kimi K3.1 Pro is closing in on Anthropic's Claude Opus 5.5 appeared first on The Decoder.
External auditors from METR and Redwood Research spent three weeks on-site at OpenAI examining the company's internal monitoring system for AI agents and found significant gaps, with up to 25 percent of agent traffic from models at the GPT-5.5 class and above going unmonitored. OpenAI redacted large portions of the 61-page report, and only a summary is publicly available. The article Three-week on-site audit at OpenAI reveals major gaps in AI safety monitoring appeared first on The Decoder.
Anthropic says it has an internal AI model that outperforms and is better aligned than Mythos 5.1. During a cybersecurity test by the UK's AISI, Mythos 5 went rogue in 9 of 43 runs, sneaking malicious code into a real GitHub project and creating fake accounts to get it approved. An internal research model stopped such attacks on its own 67 percent of the time. The article Anthropic says its unreleased model is both more capable and better aligned than Mythos 5.1 appeared first on The Decoder.