1import{j as e}from"./index-CThNTRDP.js";import{c as _}from"./vendor-i18n-5wc_S7sb.js";import{L as f,T as t,D}from"./diagramKit-DuL1M-qB.js";import{M as N,b as l,a as z,S as X,K,H as I,l as ae,p as me,e as xe}from"./mechanismKit-BdUjG51p.js";import"./vendor-react-H8Xurm4u.js";const le=(g,a=3)=>{const w=[];for(let r=1;r<g.length;r+=1){const[k,c]=g[r-1],[h,M]=g[r],d=Math.max(1,Math.ceil(Math.hypot(h-k,M-c)/a));for(let i=0;i<=d;i+=1){const p=k+(h-k)*i/d,y=c+(M-c)*i/d;w.push({x0:p-1,x1:p+1,y0:y-1,y1:y+1})}}return w},ye=[[9,15],[-9,15],[0,19],[9,25],[-9,25],[24,16],[-24,16],[9,35],[-9,35],[40,20],[-40,20],[9,45],[-9,45],[9,-7],[-9,-7]],ue=(g,a,w,r=!1)=>w.map(([k,c])=>{const h=r?-k:k;return{x:g+h,y:a+c,anchor:h>0?"start":h<0?"end":"middle"}}),U=(g,a,w,r,k,c)=>{const h=[];if(c){for(let d=k.y0+w;d<=k.y1;d+=5)for(let i=k.x0;i<=k.x1;i+=10)h.push({x:i,y:d,anchor:i>=c.x?"start":"end",d:Math.hypot(i-c.x,d-c.y)});h.sort((d,i)=>d.d-i.d)}const M=[...g,...h].filter(d=>{const i=ae(d.x,d.y,a,w,d.anchor);return i.x0>=k.x0&&i.x1<=k.x1&&i.y0>=k.y0&&i.y1<=k.y1});return me(M.length?M:g,a,w,r)},ge=(g,a,w)=>({x0:g-1,x1:g+1,y0:Math.min(a,w),y1:Math.max(a,w)}),pe=(g,a,w)=>({x0:Math.min(a,w),x1:Math.max(a,w),y0:g-1,y1:g+1}),L=(g,a=0)=>`${(g*100).toFixed(a)}%`;function fe(g,a){const w=xe(g),r=[];for(;r.length<a;){const k=Math.max(1e-9,w()),c=w();r.push(Math.sqrt(-2*Math.log(k))*Math.cos(2*Math.PI*c))}return r}
1const Q=[1,4,10],se=16,we=(()=>{const g=xe(6007);return Array.from({length:se},()=>Array.from({length:10},()=>g()))})();function ke({color:g}){const[a,w]=_.useState(1),[r,k]=_.useState(90),c=r/100,h=Q[a],M=we.map(b=>b.slice(0,h).map(R=>R<c)),d=M.filter(b=>b.every(Boolean)).length,i=c**h,p=44,y=50,S=24,j=9.2,m=372,v=190,n=56,o=120,$=b=>m+(b-1)/9*v,x=b=>n+o-b*o,s=b=>Array.from({length:10},(R,E)=>[$(E+1),x(b(E+1))]),u=b=>s(b).map(([R,E],B)=>`${B?"L":"M"} ${R.toFixed(1)} ${E.toFixed(1)}`).join(" "),A=b=>c**b,C=b=>1-(1-c)**b,T=$(h),W=h===Q[Q.length-1],G=!W&&T>m+v/2,F=[...le(s(A)),...le(s(C)),{x0:m,x1:m+v,y0:x(c)-1,y1:x(c)+1},pe(n+o,m,m+v),ge(m,n,n+o),ae(m,n+o+13,"one try",l.caption,"start"),ae(m+v,n+o+13,"more tries",l.caption,"end")],P={x0:m-6,x1:598,y0:30,y1:n+o-2},oe=L(i),O=U([...W?[{x:T+8,y:x(i)+4,anchor:"start"}]:[],...ue(T,x(i),ye,G)],oe,l.part,F,P,{x:T,y:x(i)}),Z=(b,R)=>[m+v,m+v-50].flatMap(E=>R.map(B=>({x:E,y:b+B,anchor:"end"}))),ne="works every time",Y=U(Z(x(A(10)),[12,22,-5,-15,-25,32]),ne,l.caption,[...F,O.box],P,{x:m+v,y:x(A(10))}),re="benchmark",J=U(Z(x(c),[-5,12,-15,22]),re,l.caption,[...F,O.box,Y.box],P,{x:m+v,y:x(c)}),ie="works at least once",ce=U(Z(x(C(10)),[11,-5,21,-15,31]),ie,l.caption,[...F,O.box,Y.box,J.box],P,{x:m+v,y:x(C(10))});return e.jsx(N,{maxWidth:600*D,controls:e.jsxs(e.Fragment,{children:[e.jsx(X,{label:"Attempts per task",value:a,onChange:w,stages:["One run each","Four runs each","Ten runs each"]}),e.jsx(K,{label:"Chance one attempt works",value:r,onChange:k,min:50,max:99,display:`${r} in 100`,hint:"Chance one attempt at a task succeeds"}),e.jsx(I,{children:"Leave the chance alone and add runs: green tiles barely change, but fewer rows stay green all the way across."})]}),summary:"A grid of tasks, one row per task and one tile per attempt, red where the attempt failed. A benchmark that runs each task once reports the share of good tiles. A user who relies on the agent for the same kind of task session after session needs the whole row to work, which happens with probability equal to the single-attempt rate raised to the number of attempts. The chart beside the grid traces both, along with the chance that at least one attempt works, which is what a retry-until-success harness measures and which rises instead. The line under the figure puts the single-run score next to the every-time rate. The same agent can therefore post a strong single-run score while users find it flaky. Run each evaluation task several times, report the every-time rate against a reliability target, and separate model sampling from flaky tools and correlated infrastructure failures before attributing the variance to the model.",children:e.jsxs("svg",{viewBox:"0 0 600 300",width:"100%",style:{maxWidth:600*D},role:"img",children:[e.jsx("title",{children:"Task attempts as a grid, against the rate of working every time"}),e.jsx("desc",{children:"A grid of tasks by attempts coloured by success, with rows marked where every attempt succeeded, beside curves for single-run, every-time and at-least-once success."}),e.jsx(z,{x:300,y:22,size:12,weight:700,color:t.text,text:h===1?"Each task tried once: what a benchmark sees":`Each task tried ${h} times: does it work every time?`}),M.map((b,R)=>e.jsxs("g",{children:[b.map((E,B)=>e.jsx("rect",{className:"iv-mech-bar",x:p+B*S+1,y:y+R*j+1,width:S-2,height:j-2,rx:1.5,fill:E?g:t.error,opacity:E?.55:.9},`t${R}-${B}`)),e.jsx("circle",{cx:p+10*S+12,cy:y+R*j+j/2,r:3,fill:b.every(Boolean)?t.success:"none",stroke:b.every(Boolean)?t.success:t.border,strokeWidth:"1"})]},`r${R}`)),e.jsx(f,{x:p,y:y-7,anchor:"start",size:l.caption,color:t.textSec,text:"row = a task, tile = a try, red = failed"}),e.jsx(f,{x:p+10*S+12,y:y-7,size:l.caption,color:t.textSec,text:"every time"}),e.jsx(z,{x:p,y:y+se*j+16,anchor:"start",size:l.note,weight:700,color:t.text,text:`${d} of ${se} tasks worked every time`}),e.jsx("line",{x1:m,y1:n+o,x2:m+v,y2:n+o,stroke:t.border,strokeWidth:"0.75"}),e.jsx("line",{x1:m,y1:n,x2:m,y2:n+o,stroke:t.border,strokeWidth:"0.75"}),e.jsx("line",{x1:m,y1:x(c),x2:m+v,y2:x(c),stroke:t.textMuted,strokeWidth:"1",strokeDasharray:"4 3"}),e.jsx("path",{d:u(A),fill:"none",stroke:t.error,strokeWidth:"1.6"}),e.jsx("path",{d:u(C),fill:"none",stroke:t.success,strokeWidth:"1.3",opacity:"0.8"}),e.jsx("circle",{className:"iv-mech-dot",r:4.2,fill:t.error,transform:`translate(${T.toFixed(1)} ${x(i).toFixed(1)})`}),e.jsx(z,{x:O.x,y:O.y,anchor:O.anchor,size:l.part,weight:700,color:t.text,text:oe}),e.jsx(f,{x:J.x,y:J.y,anchor:"end",size:l.caption,color:t.textSec,text:re}),e.jsx(f,{x:Y.x,y:Y.y,anchor:"end",size:l.caption,color:t.error,text:ne}),e.jsx(f,{x:ce.x,y:ce.y,anchor:"end",size:l.caption,color:t.success,text:ie}),e.jsx(f,{x:m,y:n+o+13,anchor:"start",size:l.caption,color:t.textMuted,text:"one try"}),e.jsx(f,{x:m+v,y:n+o+13,anchor:"end",size:l.caption,color:t.textMuted,text:"more tries"}),e.jsx(z,{x:16,y:246,anchor:"start",size:l.part,weight:600,color:i<.9?t.error:t.text,text:h===1?`One run each: the benchmark and the user both see ${L(c)}`:`The benchmark says ${L(c)}, but only ${L(i)} of tasks work all ${h} times`}),e.jsx(f,{x:16,y:272,anchor:"start",size:l.caption,color:t.textMuted,text:"Run each task several times and report how often it works every time, not once."})]})})}const je=["Retry without a key","Retry with an idempotency key","No auto-retry, reconcile"],ee=fe(4403,400).map(g=>800*Math.exp(.6*g));function ve({color:g}){const[a,w]=_.useState(0),[r,k]=_.useState(1500),h=ee.filter(T=>T>r).length/ee.length,M=Math.round(h*1e3),d=a===0?M:0,i=48,p=504,y=Math.log10(100),S=Math.log10(1e4),j=T=>i+(Math.log10(Math.max(100,Math.min(1e4,T)))-y)/(S-y)*p,m=42,v=new Array(m).fill(0);ee.forEach(T=>{const W=Math.min(m-1,Math.max(0,Math.floor((Math.log10(Math.max(100,T))-y)/(S-y)*m)));v[W]+=1});const n=Math.max(...v),o=180,$=104,x=p/m,s=a===0?t.error:a===1?t.warning:t.info,u=j(r),A=u<400,C=a===0?`Charged twice: ${d} customers in every thousand`:a===1?"Charged twice: nobody. The key makes the retry return the first result":`Charged twice: nobody, but ${M} in every thousand need checking`;return e.jsx(N,{maxWidth:600*D,controls:e.jsxs(e.Fragment,{children:[e.jsx(X,{label:"What happens after a timeout",value:a,onChange:w,stages:je}),e.jsx(K,{label:"Caller gives up after",value:r,onChange:k,min:300,max:4e3,step:100,display:`${(r/1e3).toFixed(1)} s`,hint:"How long the caller waits before treating a call as failed"}),e.jsx(I,{children:"Shorten the timeout and watch the late calls grow, then add the key: the same calls time out, none charge twice."})]}),summary:"How long a state-changing call such as a payment actually takes at the server, as a histogram, with the client timeout as a vertical line. Every call to the right of the line looked like a failure to the caller and in fact succeeded, and the share of them is printed beside the line. Retried without an idempotency key, each of those becomes a second charge, so the duplicate rate is exactly the share of calls slower than the timeout, and tightening the timeout to feel more responsive raises it. With a caller-generated idempotency key derived from the task and intent rather than the attempt, the server recognises the retry and returns the original result, so the same calls time out and none charges twice. For actions that cannot be repeated safely at all, the right response to an unknown outcome is to stop and reconcile: ask the downstream system whether the action with that key landed, and escalate to a person when it cannot say.",children:e.jsxs("svg",{viewBox:"0 0 600 300",width:"100%",style:{maxWidth:600*D},role:"img",children:[e.jsx("title",{children:"Server latency of a payment call against the client timeout"}),e.jsx("desc",{children:"A latency histogram for a state-changing call with the client timeout marked, and the calls slower than the timeout highlighted as ones that succeeded but looked failed."}),e.jsx(f,{x:300,y:24,text:"The payment call timed out. Did it go through?",color:t.text,size:12,weight:700}),e.jsx("rect",{className:"iv-mech-bar",x:u,y:52,width:Math.max(0,i+p-u),height:o-52,fill:s,opacity:"0.07"}),v.map((T,W)=>{const G=T/n*$,P=10**(y+(W+.5)/m*(S-y))>r;return e.jsx("rect",{className:"iv-mech-bar",x:i+W*x+.5,y:o-G,width:Math.max(1,x-1),height:G,fill:P?s:g,opacity:P?.85:.5},`b${W}`)}),e.jsx("line",{x1:i,y1:o,x2:i+p,y2:o,stroke:t.border,strokeWidth:"0.75"}),e.jsx("line",{className:"iv-mech-leash",x1:u,y1:52,x2:u,y2:o,stroke:t.text,strokeWidth:"1.4",strokeDasharray:"4 3"}),e.jsx(f,{x:u-6,y:60,anchor:"end",size:l.caption,color:t.textSec,text:"answered in time"}),e.jsx(f,{x:A?u+6:u-6,y:A?60:74,anchor:A?"start":"end",size:l.caption,color:s,text:a===0?"caller retries: charged twice":a===1?"retry: same key, same result":"caller asks: did it land?"}),e.jsx(z,{x:A?u+6:u-6,y:A?75:89,anchor:A?"start":"end",size:l.part,weight:700,color:t.text,text:`${L(h,1)} went through late`}),e.jsx(f,{x:i,y:o+14,anchor:"start",size:l.caption,color:t.textMuted,text:"fast"}),e.jsx(f,{x:i+p,y:o+14,anchor:"end",size:l.caption,color:t.textMuted,text:"slow, and still successful"}),e.jsx(z,{x:16,y:228,anchor:"start",size:l.part,weight:600,color:d?t.error:t.text,text:C}),e.jsx(f,{x:16,y:254,anchor:"start",size:l.caption,color:t.textMuted,text:"A timeout means unknown, not failed: the idempotency key belongs in the tool contract."})]})})}const be=["Retry at every layer","One budget per request","Circuit breaker"],Me=5;function Se({color:g}){const[a,w]=_.useState(0),[r,k]=_.useState(3),c=r;let h;a===0?h=[c,c*c,c*c*c]:a===1?h=[1,1,1+Me]:h=[1,1,0];const M=h.reduce((n,o)=>n+o,0),d=n=>`${n} ${n===1?"call":"calls"}`,i=a===0?`${c} Ã ${c} Ã ${c} = ${d(h[2])} on an agent that is already down, and the user still gets an error`:a===1?`One budget caps it at ${d(h[2])}: the user gets an error, quickly`:"Breaker open: no calls reach it, and the user gets a degraded answer",p=[{x:60,name:"agent A"},{x:230,name:"agent B"}
1,{x:400,name:"agent C, failing"}],y=150,S=86,j=n=>Math.max(1,Math.min(15,Math.ceil(Math.sqrt(n*1.8)))),m=(n,o)=>{const $=j(n),x=Math.min(9,y/$);return Array.from({length:n},(s,u)=>({x:o.x+u%$*x+x/2,y:S+Math.floor(u/$)*9}))},v=h.map((n,o)=>m(Math.min(n,150),p[o]));return e.jsx(N,{maxWidth:600*D,controls:e.jsxs(e.Fragment,{children:[e.jsx(X,{label:"How failures are retried",value:a,onChange:w,stages:be}),e.jsx(K,{label:"Attempts at every layer",value:r,onChange:k,min:1,max:5,dimmed:a!==0,display:`${r}`,hint:"How many times each layer tries a failing call"}),e.jsx(I,{children:"Add one attempt per layer and count the red dots: a small retry setting everywhere turns one failure into a storm."})]}),summary:"One user request flowing through three agents, the last of which is failing, with a dot for every call each agent receives and the count printed under each name. When every layer retries on failure, each retry at one layer re-runs every attempt beneath it, so the failing agent receives the product of all the layers attempts, and the request takes longest exactly when the system is least able to serve it. That multiplication, repeated across concurrent requests, is the retry storm: the failing dependency is hit hardest at the moment it is weakest. A single retry budget per request caps the total attempts wherever they happen, so the request fails quickly and predictably. A circuit breaker on the failing agent stops calling it altogether after repeated failures and returns a fallback, so upstream agents receive a degraded flag and the user gets a degraded answer instead of an error. Identify the root failure from the earliest error timestamp in the trace, not the loudest agent.",children:e.jsxs("svg",{viewBox:"0 0 600 300",width:"100%",style:{maxWidth:600*D},role:"img",children:[e.jsx("title",{children:"Calls received by each agent in a chain when the last one fails"}),e.jsx("desc",{children:"Three columns of dots, one per agent, counting the calls each receives for a single request when the last agent fails, under per-layer retries, a retry budget and a circuit breaker."}),e.jsx(f,{x:300,y:24,text:"How many calls does one failing agent cause?",color:t.text,size:12,weight:700}),p.map((n,o)=>e.jsxs("g",{children:[e.jsx(f,{x:n.x,y:56,anchor:"start",size:l.part,weight:700,color:o===2?t.error:t.textSec,text:n.name}),e.jsx(z,{x:n.x,y:72,anchor:"start",size:l.note,color:t.text,text:d(h[o])}),v[o].map(($,x)=>e.jsx("circle",{className:"iv-mech-dot",r:3,fill:o===2?t.error:g,opacity:o===2?.85:.7,transform:`translate(${$.x.toFixed(1)} ${$.y.toFixed(1)})`},`d${o}-${x}`)),o<2&&e.jsxs("g",{children:[e.jsx("line",{x1:n.x+y-16,y1:52,x2:p[o+1].x-14,y2:52,stroke:t.textMuted,strokeWidth:"1"}),e.jsx("path",{d:`M ${p[o+1].x-8} 52 L ${p[o+1].x-15} 48.5 L ${p[o+1].x-15} 55.5 Z`,fill:t.textMuted})]})]},n.name)),a===2&&e.jsxs(e.Fragment,{children:[e.jsx("rect",{x:p[2].x-4,y:84,width:y,height:34,rx:6,fill:"none",stroke:t.success,strokeWidth:"1",strokeDasharray:"4 3"}),e.jsx(f,{x:p[2].x+y/2-4,y:105,size:l.note,color:t.text,text:"breaker open: fallback returned"})]}),e.jsx(z,{x:p[0].x,y:186,anchor:"start",size:l.note,weight:600,color:t.textSec,text:`${d(M)} in all, for one request`}),e.jsx(z,{x:16,y:220,anchor:"start",size:l.part,weight:600,color:a===0?t.error:t.text,text:i}),e.jsx(f,{x:16,y:246,anchor:"start",size:l.caption,color:t.textMuted,text:"Retry at one layer only, inside a per-request budget, and put a breaker on the failing agent."})]})})}const $e=["Carry everything","Compact tool results","Also cache the prefix"],q=20,he=4,Te=24,te=40,Ae=.1;function Ce({color:g}){const[a,w]=_.useState(0),[r,k]=_.useState(20),c=s=>{const u=he*(s-1);return a===0?u:Math.min(u,Te)},h=a===2?q*Ae:q;let M=0;for(let s=1;s<=r;s+=1)M+=h+c(s);const d=r*q,i=q+c(r),p=M/d,y=52,S=440,j=190,m=132,v=q+he*(te-1),n=S/te,o=s=>s/v*m,$=j-o(q),x=y+(r-.5)*n;return e.jsx(N,{maxWidth:600*D,controls:e.jsxs(e.Fragment,{children:[e.jsx(X,{label:"How the context is managed",value:a,onChange:w,stages:$e}),e.jsx(K,{label:"Steps in the task",value:r,onChange:k,min:1,max:te,display:`${r}`,hint:"Number of model calls the agent makes to finish one task"}),e.jsx(I,{children:"Make the task longer and watch the bars climb above the dashed forecast, then compact and cache to see what each removes."})]}),summary:"One bar per model call in a single agent task. The lower part of each bar is the fixed prefix every call resends: system prompt, tool definitions and task framing. The upper part is everything the agent has appended so far, tool calls and their results, which grows by a similar amount each step. The dashed line is a capacity forecast made by measuring the first call and multiplying by the number of steps. Because each call resends everything before it, the real total is a triangle rather than a rectangle and grows with the square of the step count, so the forecast error widens on exactly the long tasks, while no single call looks unusual and the window never overflows. The line under the chart gives the whole task in tokens against that forecast. Compacting old tool results into a running summary caps the staircase. Caching the stable prefix leaves the tokens in place and bills them at a fraction of the price. Measure cumulative tokens per
1completed task, not per call.",children:e.jsxs("svg",{viewBox:"0 0 600 300",width:"100%",style:{maxWidth:600*D},role:"img",children:[e.jsx("title",{children:"Tokens sent on each call of an agent task, against a first-call forecast"}),e.jsx("desc",{children:"A staircase of bars, one per model call, split into a fixed prefix and accumulated history, against a flat forecast line taken from the first call."}),e.jsx(f,{x:300,y:24,text:"What does a long agent task really cost?",color:t.text,size:12,weight:700}),Array.from({length:r},(s,u)=>{const A=u+1,C=o(q),T=o(c(A)),W=y+u*n+.6;return e.jsxs("g",{children:[e.jsx("rect",{className:"iv-mech-bar",x:W,y:j-C,width:Math.max(1,n-1.2),height:C,fill:t.textMuted,opacity:a===2?.18:.5}),T>0&&e.jsx("rect",{className:"iv-mech-bar",x:W,y:j-C-T,width:Math.max(1,n-1.2),height:T,fill:g,opacity:"0.8"})]},`s${A}`)}),e.jsx("line",{x1:y,y1:j,x2:y+S,y2:j,stroke:t.border,strokeWidth:"0.75"}),e.jsx("line",{x1:y,y1:$,x2:y+S,y2:$,stroke:t.warning,strokeWidth:"1.3",strokeDasharray:"5 4"}),e.jsx(f,{x:y-5,y:j-4,anchor:"end",size:l.caption,color:t.textSec,text:a===2?"cached":"prefix"}),e.jsx(f,{x:y-5,y:$-10,anchor:"end",size:l.caption,color:t.textSec,text:"history"}),e.jsx(f,{x:y+S+6,y:$-2,anchor:"start",size:l.caption,color:t.textSec,text:"forecast:"}),e.jsx(f,{x:y+S+6,y:$+9,anchor:"start",size:l.caption,color:t.textSec,text:"first call à steps"}),e.jsx(z,{x:r>20?x+n/2:x-n/2,y:j-o(i)-7,anchor:r>20?"end":"start",size:l.note,weight:700,color:t.text,text:`call ${r} sends ${Math.round(i)}K tokens`}),e.jsx(f,{x:y,y:j+14,anchor:"start",size:l.caption,color:t.textMuted,text:"first call"}),e.jsx(f,{x:y+S,y:j+14,anchor:"end",size:l.caption,color:t.textMuted,text:"later calls"}),e.jsx(z,{x:16,y:236,anchor:"start",size:l.part,weight:600,color:p>1.2?t.error:t.text,text:`Whole task: ${Math.round(M).toLocaleString("en-GB")}K tokens billed, ${p.toFixed(1)}x the forecast`}),e.jsx(f,{x:16,y:262,anchor:"start",size:l.caption,color:t.textMuted,text:"Cost grows with the square of the steps: compact old tool results and cache the fixed prefix."})]})})}const ze=["In sequence","Independent calls together","Together, one hangs"],H=8,de=2,V=5,We=9;function Re({color:g}){const[a,w]=_.useState(1),[r,k]=_.useState(1),c=s=>a===2&&s===V?We:de,h=[];let M=0;for(let s=0;s<H;s+=1){let u;a===0?(u=M,M+=c(s)):s<=r?u=s===0?0:h[s-1].end:u=0,h.push({i:s,start:u,end:u+c(s),chained:a!==0&&s<=r&&s>0})}const d=Math.max(...h.map(s=>s.end)),i=Array.from({length:H},(s,u)=>c(u)).reduce((s,u)=>s+u,0),p=h.filter(s=>s.end===d),y=a===0?H:p.some(s=>s.i<=r)?r+1:1,S=a===2&&h[V].end===d&&V>r;let j;a===0?j=`In sequence the wait is every call added up: ${d} s`:S?j=`One hanging call is now the whole wait: ${d} s`:y===1?j=`Every call runs at once: the wait is one call, ${d} s instead of ${i} s`:j=`The wait is the chain of ${y} linked calls: ${d} s instead of ${i} s`;const m=60,v=490,n=50,o=17,$=Math.max(i,H*de),x=s=>m+s/$*v;return e.jsx(N,{maxWidth:600*D,controls:e.jsxs(e.Fragment,{children:[e.jsx(X,{label:"How the calls are scheduled",value:a,onChange:w,stages:ze}),e.jsx(K,{label:"Calls that need an earlier result",value:r,onChange:k,min:0,max:H-1,dimmed:a===0,display:`${r}`,hint:"How many of the calls genuinely depend on the call before them"}),e.jsx(I,{children:"Switch from sequence to together and watch the turn shrink to the linked chain, then let one call hang."})]}),summary:"Eight tool calls drawn on a timeline, one row each. Run strictly one after another, the turn takes the sum of all their durations, and most of that time is spent waiting rather than computing. Most calls in a turn do not depend on each other, such as fetching a profile, an order history and inventory, so they can be issued together and executed in parallel. The turn then takes only as long as the longest chain of calls that genuinely need an earlier result, which is the critical path, drawn in orange with a link from each call to the one it waits for, and the control sets how long that chain is. Parallelism cannot shorten the critical path itself, so once calls overlap, the next lever is the longest dependent chain, and a single slow or hanging call becomes the whole wait unless it has its own timeout and a fallback. Measure the trace per call before optimising anything.",children:e.jsxs("svg",{viewBox:"0 0 600 300",width:"100%",style:{maxWidth:600*D},role:"img",children:[e.jsx("title",{children:"Tool calls on a timeline, in sequence and as dependencies allow"}),e.jsx("desc",{children:"A timeline with one row per tool call, laid out end to end in sequence or overlapped where calls do not depend on each other, with the longest chain marked."}),e.jsx(f,{x:300,y:22,text:"How long does one agent turn take?",color:t.text,size:12,weight:700}),e.jsx(f,{x:m,y:n-12,anchor:"start",size:l.caption,color:t.textSec,text:"one bar per tool call, orange = the chain that sets the wait"}),e.jsx("rect",{x:m,y:n-6,width:x(i)-m,height:H*o+8,rx:4,fill:"none",stroke:t.border,strokeWidth:"1",strokeDasharray:"3 3"}),h.map(s=>{const u=s.end===d||a!==0&&s.i<=r&&p.some(T=>T.i<=r),A=a===2&&s.i===V,C=n+s.i*o;return e.jsxs("g",{children:[s.chained&&e.jsx("line",{x1:x(s.start),y1:C-4,x2:x(s.start),y2:C+2,stroke:t.textSec,strokeWidth:"1.4"}),e.jsx("rect",{className:"iv-mech-bar",x:x(s.start),y:C,width:Math.max(2,x(s.end)-x(s.start)-1),height:o-4,rx:3,fill:A?t.error:u?t.warning:g,opacity:u||A?.9:.6})]},`b${s.i}`)}),e.jsx("line",{className:"iv-mech-leash",x1:x(d),y1:n-6,x2:x(d),y2:n+H*o+4,stroke:t.text,strokeWidth:"1.3"}),e.jsx(z,{x:Math.max(110,Math.min(x(d),520)),y:n+H*o+18,size:l.note,weight:700,color:t.text,text:`turn ends at ${d} s`}),x(i)-x(d)>150&&e.jsx(z,{x:x(i),y:n+H*o+18,anchor:"end",size:l.caption,color:t.textSec,text:`one after another: ${i} s`}),e.jsx(z,{x:16,y:236,anchor:"start",size:l.part,weight:600,color:S?t.error:t.text,text:j}),e.jsx(f,{x:16,y:262,anchor:"start",size:l.caption,color:t.textMuted,text:"Run independent calls together, and g
1ive every tool its own timeout."})]})})}const qe={"ag-pass-k":ke,"ag-idempotent-retry":ve,"ag-retry-storm":Se,"ag-context-growth":Ce,"ag-critical-path":Re};export{qe as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.