@alvin0/ai-agent-sdk-core 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +12 -1
  2. package/dist/agent/define/session.d.ts +5 -2
  3. package/dist/agent/define/session.d.ts.map +1 -1
  4. package/dist/agent/define/session.js +1 -1
  5. package/dist/agent/define/session.js.map +1 -1
  6. package/dist/agent/history/input-work.js +2 -0
  7. package/dist/agent/history/input-work.js.map +1 -0
  8. package/dist/agent/loop/control-text.d.ts +6 -0
  9. package/dist/agent/loop/control-text.d.ts.map +1 -0
  10. package/dist/agent/loop/control-text.js +2 -0
  11. package/dist/agent/loop/control-text.js.map +1 -0
  12. package/dist/agent/loop/run-turn.d.ts.map +1 -1
  13. package/dist/agent/loop/run-turn.js +1 -1
  14. package/dist/agent/loop/run-turn.js.map +1 -1
  15. package/dist/agent/loop/schedule.d.ts +5 -0
  16. package/dist/agent/loop/schedule.d.ts.map +1 -1
  17. package/dist/agent/loop/schedule.js +1 -1
  18. package/dist/agent/loop/schedule.js.map +1 -1
  19. package/dist/agent/loop/turn/model-round.js +1 -1
  20. package/dist/agent/loop/turn/model-round.js.map +1 -1
  21. package/dist/agent/mode/run-agent.d.ts +8 -15
  22. package/dist/agent/mode/run-agent.d.ts.map +1 -1
  23. package/dist/agent/mode/run-agent.js +2 -2
  24. package/dist/agent/mode/run-agent.js.map +1 -1
  25. package/dist/agent/team/contracts.d.ts +3 -1
  26. package/dist/agent/team/contracts.d.ts.map +1 -1
  27. package/dist/agent/team/managed.d.ts.map +1 -1
  28. package/dist/agent/team/managed.js +5 -5
  29. package/dist/agent/team/managed.js.map +1 -1
  30. package/dist/agent/team/team.d.ts.map +1 -1
  31. package/dist/agent/team/team.js +1 -1
  32. package/dist/agent/team/team.js.map +1 -1
  33. package/dist/agent/tool/pipeline.js +1 -1
  34. package/dist/agent/tool/pipeline.js.map +1 -1
  35. package/dist/agent.d.ts +2 -1
  36. package/dist/agent.js +1 -1
  37. package/dist/composition/agent/session.js +1 -1
  38. package/dist/composition/agent/session.js.map +1 -1
  39. package/dist/composition/agent/types.d.ts +3 -1
  40. package/dist/composition/agent/types.d.ts.map +1 -1
  41. package/dist/composition/embedding/retry.js +1 -1
  42. package/dist/composition/embedding/retry.js.map +1 -1
  43. package/dist/embedding/errors.d.ts +5 -1
  44. package/dist/embedding/errors.d.ts.map +1 -1
  45. package/dist/embedding/errors.js +1 -1
  46. package/dist/embedding/errors.js.map +1 -1
  47. package/dist/observability/bus.js +1 -1
  48. package/dist/primitives/version.d.ts +1 -1
  49. package/dist/primitives/version.js +1 -1
  50. package/dist/primitives/version.js.map +1 -1
  51. package/dist/runtime/registry.js +1 -1
  52. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- import{createSpanId as e}from"../../../observation/context.js";import{MODEL_ERROR_CODES as t}from"../../../errors/model-error.js";import{BlockAssembler as n}from"../../../stream/assembler.js";import{normalizeToolPairing as r}from"../../history/normalize.js";import{observeModelRequestBoundary as i}from"./model-request-boundary.js";import{stepProjectionSources as a}from"./step-projection.js";import{positiveFinite as o,positiveSafeInteger as s}from"./config.js";import{messageOf as c,modelAbortedFinish as ee,modelFailureFinish as l,now as u,serializedBytes as d}from"./common.js";import{StreamAbortError as te,closeIterator as ne,nextWithAbort as re}from"./cancellation.js";import{runOptionalHook as f}from"./hooks.js";import{classifyTextPhases as p,contentTiming as m,createAssistant as ie,dropDuplicateToolCalls as ae,invalidHostToolCall as oe,recentToolResultIds as se,systemText as ce,textOf as h}from"./content.js";import{validateStreamChunk as le}from"./validation.js";import{accountingUsageStop as ue}from"./usage-stop.js";function g(e){let t=e.replace(/\s+/gu,` `).trim();return t.length>600?`${t.slice(0,600)}…`:t}function _(e){let t=[],n=[];for(let r of e.content)r.type===`text`||r.type===`reasoning`?t.push(r.text):r.type===`tool-call`?n.push(`${r.name}(${g(r.arguments)})`):r.type===`tool-result`?t.push(h(r.content)):t.push(`[${r.type}]`);return{role:e.role,producer:e.source.kind,...t.length===0?{}:{text:g(t.join(` `))},...n.length===0?{}:{toolCalls:n}}}function de(e){let t=e.messages??[],n=Math.max(0,t.length-8);return{messageCount:t.length,...t.at(-1)===void 0?{}:{lastMessageId:t.at(-1)?.id},...e.system===void 0?{}:{system:g(e.system)},...e.tools===void 0||e.tools.length===0?{}:{tools:e.tools.map(e=>e.name)},...e.toolChoice===void 0?{}:{toolChoice:e.toolChoice},...n===0?{}:{earlierMessagesOmitted:n},messages:t.slice(-8).map(_)}}async function v(g,_,v,pe,me,y,b,x){let S=x===`forced-final`,C=x===`final`||S,w={traceId:me.traceId,spanId:e(),parentSpanId:me.spanId},T=r(g.history.messages()),he=T,E=se(g.history),ge=g.history.generation(),_e=g.history.entries().length,D=()=>{let e=ue(g.accounting);if(!(e===void 0&&!_.aborted))return{trace:w,finish:_.aborted?{kind:`aborted`,failure:{code:`ABORTED`,message:c(_.reason)}}:{kind:`stop`},calls:[],afterToolCallIds:E,timing:m(!1,E.length>0),...e?.kind===`error`?{usageRequired:!0}:{},...e?.kind===`usage-unavailable`?{usageUnavailable:!0}:{}}},O=D();if(O!==void 0)return O;let k=await f(g.hooks?.beforeStep,[{turn:y,step:b,messages:T,snapshot:g.history.snapshot(),signal:_,...g.logger===void 0?{}:{logger:g.logger},emit:pe}],g,_,`beforeStep`),A=D();if(A!==void 0)return A;if(k?.kind===`reject`)return{trace:w,finish:{kind:`error`,failure:{message:k.reason,code:`STEP_REJECTED`}},calls:[],afterToolCallIds:E,timing:m(!1,E.length>0)};if((g.history.generation()!==ge||g.history.entries().length!==_e)&&(T=r(g.history.messages())),k?.messages!==void 0){let e=a(k)??new Set(he.map(e=>e.id)),t=new Set(k.messages.map(e=>e.id)),n=T.filter(n=>!e.has(n.id)&&!t.has(n.id)),i=new Set(T.map(e=>e.id)),o=[...e].some(e=>!i.has(e)),s=new Map(k.messages.map(e=>[e.id,e]));T=r(o?[...k.messages.filter(t=>!e.has(t.id)&&!i.has(t.id)&&t.source.kind===`app`),...T.flatMap(t=>{let n=s.get(t.id);return n===void 0?e.has(t.id)?[]:[t]:[n]})]:[...k.messages,...n])}k?.prepend!==void 0&&(T=Object.freeze([...k.prepend,...T]));let j=ce(g,S),M=[...g.tools?.schemas()??[],...g.nativeTools??[]],N=!C&&g.outputFormat?.type===`json_schema`?{type:`text`}:g.outputFormat,P={...g.config,messages:T,...j.length===0?{}:{system:j},...M.length===0?{}:{tools:M},...C&&M.length>0?{toolChoice:`none`}:g.toolChoice===void 0?{}:{toolChoice:g.toolChoice},...g.imagePolicy===void 0?{}:{imagePolicy:g.imagePolicy},...g.documentPolicy===void 0?{}:{documentPolicy:g.documentPolicy},...N===void 0?{}:{outputFormat:N}},ve={...P,signal:_};i(g.history,!0);try{await f(g.hooks?.checkpoint,[{kind:`before-model-request`,request:ve,snapshot:g.history.snapshot(),signal:_,...g.logger===void 0?{}:{logger:g.logger}}],g,_,`checkpoint`)}catch(e){return i(g.history,!1),{trace:w,finish:{kind:`error`,failure:{message:`history checkpoint failed: ${c(e)}`,code:`CHECKPOINT_FAILED`}},calls:[],afterToolCallIds:E,timing:m(!1,E.length>0)}}let F=D();if(F!==void 0)return i(g.history,!1),F;await v({type:`span-start`,trace:w,at:u(),name:`chat ${g.config.model}`,kind:`chat`,attributes:{"gen_ai.operation.name":`chat`,"gen_ai.request.model":g.config.model,...g.config.reasoningEffort===void 0?{}:{"gen_ai.request.reasoning_effort":g.config.reasoningEffort},turn:y,step:b,forcedFinal:S,phase:x},input:de(P)}),await v({type:`step-start`,turn:y,step:b,trace:w,...S?{forcedFinal:!0}:{}});let I=new n,L=new Set,R=o(g.modelTimeoutMs??6e5,`modelTimeoutMs`),z=s(g.maxModelRequestBytes??33554432,`maxModelRequestBytes`),B=s(g.maxModelResponseBytes??33554432,`maxModelResponseBytes`),V=s(g.maxModelStreamEvents??1e5,`maxModelStreamEvents`),ye=o(g.teardownTimeoutMs??3e4,`teardownTimeoutMs`),H,be=!1,xe=!1,U;try{U=d(P)}catch(e){U=-1,I.push(l(`model request is not serializable: ${c(e)}`,`INVALID_MODEL_REQUEST`))}if(U>z)I.push(l(`model request exceeds the ${z}-byte limit`,`MODEL_REQUEST_TOO_LARGE`));else if(U>=0){let e=new AbortController,t=AbortSignal.any([_,e.signal]),n=!1,r=setTimeout(()=>{n=!0,e.abort(Error(`model stream exceeded ${R}ms`))},R),i=g.registry.stream({...P,signal:t},g.accounting?.modelInvocation),a=i[Symbol.asyncIterator](),o=!1,s=0,u=0,f=!1;try{for(;;){let n=await re(a.next(),t);if(n.done===!0){o=!0;break}let r=n.value;try{le(r,V)}catch(t){I.push(l(`model adapter emitted an invalid stream chunk: ${c(t)}`,`INVALID_MODEL_STREAM`)),e.abort(Error(`invalid model stream chunk`));break}s++;try{u+=d(r)}catch(t){I.push(l(`model adapter emitted a non-serializable stream chunk: ${c(t)}`,`INVALID_MODEL_STREAM`)),e.abort(Error(`non-serializable model stream chunk`));break}if(s>V||u>B){let t=s>V?`${V}-event`:`${B}-byte`;I.push(l(`model response exceeds the ${t} limit`,`MODEL_RESPONSE_TOO_LARGE`)),e.abort(Error(`model response resource limit exceeded`));break}if(f){I.push(l(`model adapter emitted data after its terminal finish chunk`,`INVALID_MODEL_STREAM`)),e.abort(Error(`invalid model stream`));break}I.push(r),!((r.type===`text-delta`||r.type===`reasoning-delta`||r.type===`tool-call-delta`)&&L.has(r.index))&&(r.type===`block-end`&&L.add(r.index),r.type===`finish`&&(f=!0),r.type===`text-delta`?await v({type:`text-delta`,index:r.index,text:r.text,phase:x===`process`?`commentary`:r.phase??`unknown`,trace:w}):r.type===`reasoning-delta`?await v({type:`reasoning-delta`,index:r.index,text:r.text,trace:w}):r.type===`image-delta`?await v({type:`image-delta`,itemId:r.itemId,data:r.data,mediaType:r.mediaType,...r.partialIndex===void 0?{}:{partialIndex:r.partialIndex},trace:w}):r.type===`usage`?await v({type:`usage`,usage:r.usage,trace:w}):r.type===`usage-progress`&&await v({...r,trace:w}))}}catch(e){if(!(e instanceof te))throw e;I.push(_.aborted?ee(c(_.reason??e)):n?l(`model stream exceeded ${R}ms`,`MODEL_TIMEOUT`):l(c(e.cause??e),`MODEL_STREAM_ABORTED`))}finally{clearTimeout(r),o||(e.abort(Error(`model stream closed before exhaustion`)),await ne(a,ye)||I.push(l(`model stream ignored cancellation for more than ${ye}ms; the adapter operation may still be running`,`MODEL_TEARDOWN_TIMEOUT`)))}let p=await i.report,m=g.accounting===void 0?void 0:await g.accounting.recordModelCall(p,{...P,signal:_});H=m?.report??p,be=m?.usageRequired??!1,xe=m?.usageUnavailable??!1}let W=I.finish,G=W.kind===`aborted`,K;try{K=W.kind===`aborted`?I.interruptedBlocks():I.blocks()}catch(e){W={kind:`error`,failure:{message:`model adapter emitted an invalid block sequence: ${c(e)}`,code:`INVALID_MODEL_STREAM`}},G=!0,K=I.interruptedBlocks()}let Se=I.textBlocks().filter(({block:e})=>!G||e.text.trim()!==``),Ce=0,we=p(K.map(e=>{if(e.type!==`text`)return e;let t=Se[Ce++];return e.phase===void 0&&t?.beforeNativeCall?{...e,phase:`commentary`}:e}),x===`process`,I.hasToolCalls),q=ae(we,g.history),J=q.blocks,Te=C&&g.outputFormat?.type===`json_schema`&&W.kind===`stop`&&!fe(h(J),g.validateOutput)?{message:`model returned invalid JSON or failed the structured output validator`,code:t.MALFORMED_RESPONSE}:void 0,Y=(C&&J.some(e=>e.type===`tool-call`)?{message:`model emitted a host tool call during the final output phase`,code:`INVALID_TOOL_CALL`}:void 0)??Te??oe(J,g.history),X=Y===void 0?J:J.filter(e=>e.type!==`tool-call`),Z=Y===void 0?W:{kind:`error`,failure:Y},Q=X.length===0&&(Z.kind===`error`||Z.kind===`aborted`)?void 0:ie(g,X,G?void 0:I.replayState),$=Q?.content.filter(e=>e.type===`tool-call`).map(e=>({callId:e.id,toolName:e.name,rawArguments:e.arguments}))??[],Ee=m($.length>0,E.length>0);if(X.some(e=>e.type===`text`)){let e=Se.map(({index:e})=>e),t=Z.kind===`error`||Z.kind===`aborted`||Z.kind===`max-tokens`,n=0;for(let r of X){if(r.type!==`text`)continue;let i=e[n++];i!==void 0&&await v({type:`text-end`,index:i,text:r.text,phase:r.phase??`final-answer`,trace:w,...t?{incomplete:!0}:{}})}}return await v({type:`span-end`,trace:w,at:u(),status:Z.kind===`error`?`error`:Z.kind===`aborted`?`aborted`:`success`,output:Q===void 0?void 0:{text:h(Q.content),commentary:Q.content.flatMap(e=>e.type===`text`&&e.phase===`commentary`?[e.text]:[]),reasoning:Q.content.flatMap(e=>e.type===`reasoning`?[e.text]:[]),toolCalls:$.length},...I.usage===void 0?{}:{usage:I.usage},...Z.kind===`error`||Z.kind===`aborted`?{error:{type:`ModelError`,message:Z.failure.message,code:Z.failure.code}}:{}}),($.length===0||C)&&await v({type:`step-end`,turn:y,step:b,trace:w}),{trace:w,...Q===void 0?{}:{message:Q},finish:Z,...I.usage===void 0?{}:{usage:I.usage},...H===void 0?{}:{report:H},...be?{usageRequired:!0}:{},...xe?{usageUnavailable:!0}:{},calls:$,afterToolCallIds:E,timing:Ee,...q.dropped.length===0?{}:{droppedDuplicateCalls:q.dropped}}}function fe(e,t){try{let n=JSON.parse(e);return t?.(n),!0}catch{return!1}}export{v as modelRound};
1
+ import{createSpanId as e}from"../../../observation/context.js";import{MODEL_ERROR_CODES as t}from"../../../errors/model-error.js";import{BlockAssembler as n}from"../../../stream/assembler.js";import{normalizeToolPairing as r}from"../../history/normalize.js";import{observeModelRequestBoundary as i}from"./model-request-boundary.js";import{stepProjectionSources as a}from"./step-projection.js";import{positiveFinite as o,positiveSafeInteger as s}from"./config.js";import{messageOf as c,modelAbortedFinish as ee,modelFailureFinish as l,now as u,serializedBytes as te}from"./common.js";import{StreamAbortError as ne,closeIterator as re,nextWithAbort as ie}from"./cancellation.js";import{runOptionalHook as d}from"./hooks.js";import{classifyTextPhases as f,contentTiming as p,createAssistant as ae,dropDuplicateToolCalls as oe,invalidHostToolCall as se,recentToolResultIds as ce,systemText as le,textOf as m}from"./content.js";import{UNCHANGED_ANSWER_MARKER as ue}from"../control-text.js";import{validateStreamChunk as de}from"./validation.js";import{accountingUsageStop as fe}from"./usage-stop.js";function h(e){let t=e.replace(/\s+/gu,` `).trim();return t.length>600?`${t.slice(0,600)}…`:t}function g(e){let t=[],n=[];for(let r of e.content)r.type===`text`||r.type===`reasoning`?t.push(r.text):r.type===`tool-call`?n.push(`${r.name}(${h(r.arguments)})`):r.type===`tool-result`?t.push(m(r.content)):t.push(`[${r.type}]`);return{role:e.role,producer:e.source.kind,...t.length===0?{}:{text:h(t.join(` `))},...n.length===0?{}:{toolCalls:n}}}function pe(e){let t=e.messages??[],n=Math.max(0,t.length-8);return{messageCount:t.length,...t.at(-1)===void 0?{}:{lastMessageId:t.at(-1)?.id},...e.system===void 0?{}:{system:h(e.system)},...e.tools===void 0||e.tools.length===0?{}:{tools:e.tools.map(e=>e.name)},...e.toolChoice===void 0?{}:{toolChoice:e.toolChoice},...n===0?{}:{earlierMessagesOmitted:n},messages:t.slice(-8).map(g)}}async function _(h,g,_,he,ge,v,y,b){let x=b===`forced-final`,S=b===`final`||x,C={traceId:ge.traceId,spanId:e(),parentSpanId:ge.spanId},w=r(h.history.messages()),_e=w,T=ce(h.history),ve=h.history.generation(),ye=h.history.entries().length,E=()=>{let e=fe(h.accounting);if(!(e===void 0&&!g.aborted))return{trace:C,finish:g.aborted?{kind:`aborted`,failure:{code:`ABORTED`,message:c(g.reason)}}:{kind:`stop`},calls:[],afterToolCallIds:T,timing:p(!1,T.length>0),...e?.kind===`error`?{usageRequired:!0}:{},...e?.kind===`usage-unavailable`?{usageUnavailable:!0}:{}}},D=E();if(D!==void 0)return D;let O=await d(h.hooks?.beforeStep,[{turn:v,step:y,messages:w,snapshot:h.history.snapshot(),signal:g,...h.logger===void 0?{}:{logger:h.logger},emit:he}],h,g,`beforeStep`),k=E();if(k!==void 0)return k;if(O?.kind===`reject`)return{trace:C,finish:{kind:`error`,failure:{message:O.reason,code:`STEP_REJECTED`}},calls:[],afterToolCallIds:T,timing:p(!1,T.length>0)};if((h.history.generation()!==ve||h.history.entries().length!==ye)&&(w=r(h.history.messages())),O?.messages!==void 0){let e=a(O)??new Set(_e.map(e=>e.id)),t=new Set(O.messages.map(e=>e.id)),n=w.filter(n=>!e.has(n.id)&&!t.has(n.id)),i=new Set(w.map(e=>e.id)),o=[...e].some(e=>!i.has(e)),s=new Map(O.messages.map(e=>[e.id,e]));w=r(o?[...O.messages.filter(t=>!e.has(t.id)&&!i.has(t.id)&&t.source.kind===`app`),...w.flatMap(t=>{let n=s.get(t.id);return n===void 0?e.has(t.id)?[]:[t]:[n]})]:[...O.messages,...n])}O?.prepend!==void 0&&(w=Object.freeze([...O.prepend,...w]));let A=le(h,x),j=[...h.tools?.schemas()??[],...h.nativeTools??[]],M=!S&&h.outputFormat?.type===`json_schema`?{type:`text`}:h.outputFormat,N={...h.config,messages:w,...A.length===0?{}:{system:A},...j.length===0?{}:{tools:j},...S&&j.length>0?{toolChoice:`none`}:h.toolChoice===void 0?{}:{toolChoice:h.toolChoice},...h.imagePolicy===void 0?{}:{imagePolicy:h.imagePolicy},...h.documentPolicy===void 0?{}:{documentPolicy:h.documentPolicy},...M===void 0?{}:{outputFormat:M}},be={...N,signal:g};i(h.history,!0);try{await d(h.hooks?.checkpoint,[{kind:`before-model-request`,request:be,snapshot:h.history.snapshot(),signal:g,...h.logger===void 0?{}:{logger:h.logger}}],h,g,`checkpoint`)}catch(e){return i(h.history,!1),{trace:C,finish:{kind:`error`,failure:{message:`history checkpoint failed: ${c(e)}`,code:`CHECKPOINT_FAILED`}},calls:[],afterToolCallIds:T,timing:p(!1,T.length>0)}}let P=E();if(P!==void 0)return i(h.history,!1),P;await _({type:`span-start`,trace:C,at:u(),name:`chat ${h.config.model}`,kind:`chat`,attributes:{"gen_ai.operation.name":`chat`,"gen_ai.request.model":h.config.model,...h.config.reasoningEffort===void 0?{}:{"gen_ai.request.reasoning_effort":h.config.reasoningEffort},turn:v,step:y,forcedFinal:x,phase:b},input:pe(N)}),await _({type:`step-start`,turn:v,step:y,trace:C,...x?{forcedFinal:!0}:{}});let F=new n,I=new Set,L=o(h.modelTimeoutMs??6e5,`modelTimeoutMs`),R=s(h.maxModelRequestBytes??33554432,`maxModelRequestBytes`),z=s(h.maxModelResponseBytes??33554432,`maxModelResponseBytes`),B=s(h.maxModelStreamEvents??1e5,`maxModelStreamEvents`),xe=o(h.teardownTimeoutMs??3e4,`teardownTimeoutMs`),V,Se=!1,Ce=!1,H;try{H=te(N)}catch(e){H=-1,F.push(l(`model request is not serializable: ${c(e)}`,`INVALID_MODEL_REQUEST`))}if(H>R)F.push(l(`model request exceeds the ${R}-byte limit`,`MODEL_REQUEST_TOO_LARGE`));else if(H>=0){let e=new AbortController,t=AbortSignal.any([g,e.signal]),n=!1,r=setTimeout(()=>{n=!0,e.abort(Error(`model stream exceeded ${L}ms`))},L),i=h.registry.stream({...N,signal:t},h.accounting?.modelInvocation),a=i[Symbol.asyncIterator](),o=!1,s=0,u=0,d=!1;try{for(;;){let n=await ie(a.next(),t);if(n.done===!0){o=!0;break}let r=n.value;try{de(r,B)}catch(t){F.push(l(`model adapter emitted an invalid stream chunk: ${c(t)}`,`INVALID_MODEL_STREAM`)),e.abort(Error(`invalid model stream chunk`));break}s++;try{u+=te(r)}catch(t){F.push(l(`model adapter emitted a non-serializable stream chunk: ${c(t)}`,`INVALID_MODEL_STREAM`)),e.abort(Error(`non-serializable model stream chunk`));break}if(s>B||u>z){let t=s>B?`${B}-event`:`${z}-byte`;F.push(l(`model response exceeds the ${t} limit`,`MODEL_RESPONSE_TOO_LARGE`)),e.abort(Error(`model response resource limit exceeded`));break}if(d){F.push(l(`model adapter emitted data after its terminal finish chunk`,`INVALID_MODEL_STREAM`)),e.abort(Error(`invalid model stream`));break}F.push(r),!((r.type===`text-delta`||r.type===`reasoning-delta`||r.type===`tool-call-delta`)&&I.has(r.index))&&(r.type===`block-end`&&I.add(r.index),r.type===`finish`&&(d=!0),r.type===`text-delta`?await _({type:`text-delta`,index:r.index,text:r.text,phase:b===`process`?`commentary`:r.phase??`unknown`,trace:C}):r.type===`reasoning-delta`?await _({type:`reasoning-delta`,index:r.index,text:r.text,trace:C}):r.type===`image-delta`?await _({type:`image-delta`,itemId:r.itemId,data:r.data,mediaType:r.mediaType,...r.partialIndex===void 0?{}:{partialIndex:r.partialIndex},trace:C}):r.type===`usage`?await _({type:`usage`,usage:r.usage,trace:C}):r.type===`usage-progress`&&await _({...r,trace:C}))}}catch(e){if(!(e instanceof ne))throw e;F.push(g.aborted?ee(c(g.reason??e)):n?l(`model stream exceeded ${L}ms`,`MODEL_TIMEOUT`):l(c(e.cause??e),`MODEL_STREAM_ABORTED`))}finally{clearTimeout(r),o||(e.abort(Error(`model stream closed before exhaustion`)),await re(a,xe)||F.push(l(`model stream ignored cancellation for more than ${xe}ms; the adapter operation may still be running`,`MODEL_TEARDOWN_TIMEOUT`)))}let f=await i.report,p=h.accounting===void 0?void 0:await h.accounting.recordModelCall(f,{...N,signal:g});V=p?.report??f,Se=p?.usageRequired??!1,Ce=p?.usageUnavailable??!1}let U=F.finish,W=U.kind===`aborted`,G;try{G=U.kind===`aborted`?F.interruptedBlocks():F.blocks()}catch(e){U={kind:`error`,failure:{message:`model adapter emitted an invalid block sequence: ${c(e)}`,code:`INVALID_MODEL_STREAM`}},W=!0,G=F.interruptedBlocks()}let we=F.textBlocks().filter(({block:e})=>!W||e.text.trim()!==``),Te=0,Ee=f(G.map(e=>{if(e.type!==`text`)return e;let t=we[Te++];return e.phase===void 0&&t?.beforeNativeCall?{...e,phase:`commentary`}:e}),b===`process`,F.hasToolCalls),K=oe(Ee,h.history),q=K.blocks,De=S&&h.outputFormat?.type===`json_schema`&&U.kind===`stop`&&!me(m(q),h.validateOutput)?{message:`model returned invalid JSON or failed the structured output validator`,code:t.MALFORMED_RESPONSE}:void 0,J=(S&&q.some(e=>e.type===`tool-call`)?{message:`model emitted a host tool call during the final output phase`,code:`INVALID_TOOL_CALL`}:void 0)??De??se(q,h.history),Y=J===void 0?q:q.filter(e=>e.type!==`tool-call`),X=Y.some(e=>e.type===`tool-call`)?Y.map(e=>e.type===`text`?{...e,text:e.text.replaceAll(ue,``)}:e):Y,Z=J===void 0?U:{kind:`error`,failure:J},Q=X.length===0?void 0:ae(h,X,W?void 0:F.replayState),$=Q?.content.filter(e=>e.type===`tool-call`).map(e=>({callId:e.id,toolName:e.name,rawArguments:e.arguments}))??[],Oe=p($.length>0,T.length>0);if(X.some(e=>e.type===`text`)){let e=we.map(({index:e})=>e),t=Z.kind===`error`||Z.kind===`aborted`||Z.kind===`max-tokens`,n=0;for(let r of X){if(r.type!==`text`)continue;let i=e[n++];i!==void 0&&await _({type:`text-end`,index:i,text:r.text,phase:r.phase??`final-answer`,trace:C,...t?{incomplete:!0}:{}})}}return await _({type:`span-end`,trace:C,at:u(),status:Z.kind===`error`?`error`:Z.kind===`aborted`?`aborted`:`success`,output:Q===void 0?void 0:{text:m(Q.content),commentary:Q.content.flatMap(e=>e.type===`text`&&e.phase===`commentary`?[e.text]:[]),reasoning:Q.content.flatMap(e=>e.type===`reasoning`?[e.text]:[]),toolCalls:$.length},...F.usage===void 0?{}:{usage:F.usage},...Z.kind===`error`||Z.kind===`aborted`?{error:{type:`ModelError`,message:Z.failure.message,code:Z.failure.code}}:{}}),($.length===0||S)&&await _({type:`step-end`,turn:v,step:y,trace:C}),{trace:C,...Q===void 0?{}:{message:Q},finish:Z,...F.usage===void 0?{}:{usage:F.usage},...V===void 0?{}:{report:V},...Se?{usageRequired:!0}:{},...Ce?{usageUnavailable:!0}:{},calls:$,afterToolCallIds:T,timing:Oe,...K.dropped.length===0?{}:{droppedDuplicateCalls:K.dropped}}}function me(e,t){try{let n=JSON.parse(e);return t?.(n),!0}catch{return!1}}export{_ as modelRound};
2
2
  //# sourceMappingURL=model-round.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-round.js","names":[],"sources":["../../../../src/agent/loop/turn/model-round.ts"],"sourcesContent":["import type { GenerateOptions } from '../../../contract/index.ts'\nimport { MODEL_ERROR_CODES, type ModelFailure } from '../../../errors/index.ts'\nimport type { ContentBlock, Message, ToolCallBlock } from '../../../message/index.ts'\nimport { BlockAssembler } from '../../../stream/index.ts'\nimport type { FinishReason } from '../../../stream/index.ts'\nimport type { ModelCallReport } from '../../../observation/index.ts'\nimport { normalizeToolPairing } from '../../history/normalize.ts'\nimport { createSpanId, type TraceRef } from '../../trace/trace.ts'\nimport type { AgentEvent, AgentMaintenanceEvent } from '../types.ts'\nimport { type ModelRoundPhase, type RunTurnOptions, type RoundResult } from './types.ts'\nimport { positiveFinite, positiveSafeInteger } from './config.ts'\nimport { serializedBytes, modelFailureFinish, modelAbortedFinish, messageOf, now } from './common.ts'\nimport { validateStreamChunk } from './validation.ts'\nimport { StreamAbortError, nextWithAbort, closeIterator } from './cancellation.ts'\nimport { runOptionalHook } from './hooks.ts'\nimport { stepProjectionSources } from './step-projection.ts'\nimport { observeModelRequestBoundary } from './model-request-boundary.ts'\nimport { accountingUsageStop } from './usage-stop.ts'\nimport {\n classifyTextPhases, dropDuplicateToolCalls, invalidHostToolCall, contentTiming,\n recentToolResultIds, systemText,\n createAssistant, textOf,\n} from './content.ts'\n\n/** How much of one message the trace keeps. */\nconst PREVIEW_CHARS = 600\n\n/** How many trailing messages the trace keeps. */\nconst PREVIEW_MESSAGES = 8\n\nfunction clip(text: string): string {\n const flattened = text.replace(/\\s+/gu, ' ').trim()\n return flattened.length > PREVIEW_CHARS ? `${flattened.slice(0, PREVIEW_CHARS)}…` : flattened\n}\n\n/** One message as a line: who spoke, and what the model could read of it. */\nfunction previewMessage(message: Message): Record<string, unknown> {\n const parts: string[] = []\n const calls: string[] = []\n for (const block of message.content) {\n if (block.type === 'text' || block.type === 'reasoning') parts.push(block.text)\n else if (block.type === 'tool-call') calls.push(`${block.name}(${clip(block.arguments)})`)\n else if (block.type === 'tool-result') parts.push(textOf(block.content))\n else parts.push(`[${block.type}]`)\n }\n return {\n role: message.role,\n producer: message.source.kind,\n ...parts.length === 0 ? {} : { text: clip(parts.join(' ')) },\n ...calls.length === 0 ? {} : { toolCalls: calls },\n }\n}\n\n/**\n * What this round sent the model, in a form a person can read.\n *\n * A summary, not a copy: the request can be the whole conversation plus every\n * tool schema, and a trace that stored it verbatim would be larger than the\n * work it describes. What survives is the part that explains the round — which\n * tools were on offer, how long the context was, and the tail of the\n * conversation the model was actually answering, each message clipped.\n * @param request - The request about to be dispatched.\n * @returns The summary for the span.\n */\nfunction requestSummary(request: GenerateOptions): Record<string, unknown> {\n const messages = request.messages ?? []\n const dropped = Math.max(0, messages.length - PREVIEW_MESSAGES)\n return {\n messageCount: messages.length,\n // The identity of the request, for a host that records the provider call\n // separately and has to say WHICH round each recording belongs to. Message\n // ids are stable across every representation boundary, so the last one plus\n // the count names one round of one agent without ambiguity.\n ...messages.at(-1) === undefined ? {} : { lastMessageId: messages.at(-1)?.id },\n ...request.system === undefined ? {} : { system: clip(request.system) },\n ...request.tools === undefined || request.tools.length === 0\n ? {}\n : { tools: request.tools.map(tool => tool.name) },\n ...request.toolChoice === undefined ? {} : { toolChoice: request.toolChoice },\n ...dropped === 0 ? {} : { earlierMessagesOmitted: dropped },\n messages: messages.slice(-PREVIEW_MESSAGES).map(previewMessage),\n }\n}\n\nexport async function modelRound(\n options: RunTurnOptions,\n signal: AbortSignal,\n emit: (event: AgentEvent) => Promise<void>,\n emitMaintenance: (event: AgentMaintenanceEvent) => Promise<void>,\n root: TraceRef,\n turn: number,\n step: number,\n phase: ModelRoundPhase,\n): Promise<RoundResult> {\n const forcedFinal = phase === 'forced-final'\n const finalOutput = phase === 'final' || forcedFinal\n const trace: TraceRef = { traceId: root.traceId, spanId: createSpanId(), parentSpanId: root.spanId }\n let messages = normalizeToolPairing(options.history.messages())\n const initialMessages = messages\n const afterToolCallIds = recentToolResultIds(options.history)\n const generation = options.history.generation()\n const entries = options.history.entries().length\n const stopped = (): RoundResult | undefined => {\n const stop = accountingUsageStop(options.accounting)\n if (stop === undefined && !signal.aborted) return undefined\n return {\n trace, finish: signal.aborted\n ? { kind: 'aborted', failure: { code: 'ABORTED', message: messageOf(signal.reason) } }\n : { kind: 'stop' },\n calls: [], afterToolCallIds, timing: contentTiming(false, afterToolCallIds.length > 0),\n ...(stop?.kind === 'error' ? { usageRequired: true } : {}),\n ...(stop?.kind === 'usage-unavailable' ? { usageUnavailable: true } : {}),\n }\n }\n const beforeMaintenance = stopped()\n if (beforeMaintenance !== undefined) return beforeMaintenance\n const decision = await runOptionalHook(options.hooks?.beforeStep, [{\n turn, step, messages, snapshot: options.history.snapshot(), signal,\n ...(options.logger === undefined ? {} : { logger: options.logger }),\n emit: emitMaintenance,\n }], options, signal, 'beforeStep')\n const afterMaintenance = stopped()\n if (afterMaintenance !== undefined) return afterMaintenance\n if (decision?.kind === 'reject') {\n const failure: ModelFailure = { message: decision.reason, code: 'STEP_REJECTED' }\n return {\n trace, finish: { kind: 'error', failure }, calls: [], afterToolCallIds,\n timing: contentTiming(false, afterToolCallIds.length > 0),\n }\n }\n // Hooks may append live steering as well as replacing compacted history.\n // Refresh for either mutation so new user input stays at the chronological\n // tail instead of needing to be prepended ahead of older history.\n if (options.history.generation() !== generation\n || options.history.entries().length !== entries) {\n messages = normalizeToolPairing(options.history.messages())\n }\n if (decision?.messages !== undefined) {\n const originalIds = stepProjectionSources(decision) ?? new Set(initialMessages.map(message => message.id))\n const projectedIds = new Set(decision.messages.map(message => message.id))\n const introduced = messages.filter(message => !originalIds.has(message.id) && !projectedIds.has(message.id))\n const currentIds = new Set(messages.map(message => message.id))\n const replaced = [...originalIds].some(id => !currentIds.has(id))\n // A hook can await external I/O while live steering or replacement arrives.\n // Replacements invalidate a stale projection; append-only steering stays at the tail.\n const projectedById = new Map(decision.messages.map(message => [message.id, message]))\n messages = normalizeToolPairing(replaced\n ? [...decision.messages.filter(message => !originalIds.has(message.id) && !currentIds.has(message.id) && message.source.kind === 'app'),\n ...messages.flatMap(message => {\n const projected = projectedById.get(message.id)\n return projected === undefined ? originalIds.has(message.id) ? [] : [message] : [projected]\n })]\n : [...decision.messages, ...introduced])\n }\n if (decision?.prepend !== undefined) messages = Object.freeze([...decision.prepend, ...messages])\n const system = systemText(options, forcedFinal)\n const availableTools = [\n ...options.tools?.schemas() ?? [],\n ...options.nativeTools ?? [],\n ]\n const tools = availableTools\n const outputFormat = !finalOutput && options.outputFormat?.type === 'json_schema'\n ? { type: 'text' as const }\n : options.outputFormat\n const requestBase: GenerateOptions = {\n ...options.config,\n messages,\n ...system.length === 0 ? {} : { system },\n ...tools.length === 0 ? {} : { tools },\n ...finalOutput && tools.length > 0\n ? { toolChoice: 'none' as const }\n : options.toolChoice === undefined ? {} : { toolChoice: options.toolChoice },\n ...options.imagePolicy === undefined ? {} : { imagePolicy: options.imagePolicy },\n ...options.documentPolicy === undefined ? {} : { documentPolicy: options.documentPolicy },\n ...outputFormat === undefined ? {} : { outputFormat },\n }\n const checkpointRequest: GenerateOptions = { ...requestBase, signal }\n observeModelRequestBoundary(options.history, true)\n try {\n await runOptionalHook(options.hooks?.checkpoint, [{\n kind: 'before-model-request', request: checkpointRequest,\n snapshot: options.history.snapshot(), signal,\n ...(options.logger === undefined ? {} : { logger: options.logger }),\n }], options, signal, 'checkpoint')\n } catch (error: unknown) {\n // No output will be recorded for this request. Release queued input before\n // recovery hooks or the retry's beforeStep can read or inject into history.\n observeModelRequestBoundary(options.history, false)\n const failure: ModelFailure = { message: `history checkpoint failed: ${messageOf(error)}`, code: 'CHECKPOINT_FAILED' }\n return {\n trace, finish: { kind: 'error', failure }, calls: [], afterToolCallIds,\n timing: contentTiming(false, afterToolCallIds.length > 0),\n }\n }\n const beforeDispatch = stopped()\n if (beforeDispatch !== undefined) {\n observeModelRequestBoundary(options.history, false)\n return beforeDispatch\n }\n await emit({ type: 'span-start', trace, at: now(), name: `chat ${options.config.model}`, kind: 'chat', attributes: {\n 'gen_ai.operation.name': 'chat', 'gen_ai.request.model': options.config.model,\n // The effort is part of WHICH call this was: the same model at minimal and\n // at high is two different requests, priced and paced differently, and a\n // trace that omits it cannot explain either. Absent when the route has no\n // effort ladder, rather than reported as a default nobody chose.\n ...options.config.reasoningEffort === undefined\n ? {}\n : { 'gen_ai.request.reasoning_effort': options.config.reasoningEffort },\n turn, step, forcedFinal, phase,\n }, input: requestSummary(requestBase) })\n await emit({ type: 'step-start', turn, step, trace, ...forcedFinal ? { forcedFinal: true as const } : {} })\n const assembler = new BlockAssembler()\n const closedBlockIndexes = new Set<number>()\n const modelTimeoutMs = positiveFinite(options.modelTimeoutMs ?? 10 * 60_000, 'modelTimeoutMs')\n const maxRequestBytes = positiveSafeInteger(options.maxModelRequestBytes ?? 32 * 1024 * 1024, 'maxModelRequestBytes')\n const maxResponseBytes = positiveSafeInteger(options.maxModelResponseBytes ?? 32 * 1024 * 1024, 'maxModelResponseBytes')\n const maxStreamEvents = positiveSafeInteger(options.maxModelStreamEvents ?? 100_000, 'maxModelStreamEvents')\n const teardownTimeoutMs = positiveFinite(options.teardownTimeoutMs ?? 30_000, 'teardownTimeoutMs')\n let modelCallReport: ModelCallReport | undefined\n let usageRequired = false\n let usageUnavailable = false\n let requestBytes: number\n try {\n requestBytes = serializedBytes(requestBase)\n } catch (error: unknown) {\n requestBytes = -1\n assembler.push(modelFailureFinish(`model request is not serializable: ${messageOf(error)}`, 'INVALID_MODEL_REQUEST'))\n }\n if (requestBytes > maxRequestBytes) {\n assembler.push(modelFailureFinish(\n `model request exceeds the ${maxRequestBytes}-byte limit`,\n 'MODEL_REQUEST_TOO_LARGE',\n ))\n } else if (requestBytes >= 0) {\n const owned = new AbortController()\n const roundSignal = AbortSignal.any([signal, owned.signal])\n let timedOut = false\n const timeout = setTimeout(() => {\n timedOut = true\n owned.abort(new Error(`model stream exceeded ${modelTimeoutMs}ms`))\n }, modelTimeoutMs)\n const handle = options.registry.stream(\n { ...requestBase, signal: roundSignal },\n options.accounting?.modelInvocation,\n )\n const iterator = handle[Symbol.asyncIterator]()\n let exhausted = false\n let events = 0\n let responseBytes = 0\n let sawFinish = false\n try {\n while (true) {\n const next = await nextWithAbort(iterator.next(), roundSignal)\n if (next.done === true) {\n exhausted = true\n break\n }\n const chunk = next.value\n try {\n validateStreamChunk(chunk, maxStreamEvents)\n } catch (error: unknown) {\n assembler.push(modelFailureFinish(\n `model adapter emitted an invalid stream chunk: ${messageOf(error)}`,\n 'INVALID_MODEL_STREAM',\n ))\n owned.abort(new Error('invalid model stream chunk'))\n break\n }\n events++\n try {\n responseBytes += serializedBytes(chunk)\n } catch (error: unknown) {\n assembler.push(modelFailureFinish(\n `model adapter emitted a non-serializable stream chunk: ${messageOf(error)}`,\n 'INVALID_MODEL_STREAM',\n ))\n owned.abort(new Error('non-serializable model stream chunk'))\n break\n }\n if (events > maxStreamEvents || responseBytes > maxResponseBytes) {\n const dimension = events > maxStreamEvents\n ? `${maxStreamEvents}-event`\n : `${maxResponseBytes}-byte`\n assembler.push(modelFailureFinish(\n `model response exceeds the ${dimension} limit`,\n 'MODEL_RESPONSE_TOO_LARGE',\n ))\n owned.abort(new Error('model response resource limit exceeded'))\n break\n }\n if (sawFinish) {\n assembler.push(modelFailureFinish(\n 'model adapter emitted data after its terminal finish chunk',\n 'INVALID_MODEL_STREAM',\n ))\n owned.abort(new Error('invalid model stream'))\n break\n }\n assembler.push(chunk)\n // The assembler ignores deltas after the first close. The visible\n // stream must do the same or UI text can disagree with stored history.\n if ((chunk.type === 'text-delta' || chunk.type === 'reasoning-delta' || chunk.type === 'tool-call-delta')\n && closedBlockIndexes.has(chunk.index)) continue\n if (chunk.type === 'block-end') closedBlockIndexes.add(chunk.index)\n if (chunk.type === 'finish') sawFinish = true\n if (chunk.type === 'text-delta') await emit({\n type: 'text-delta', index: chunk.index, text: chunk.text,\n phase: phase === 'process' ? 'commentary' : chunk.phase ?? 'unknown', trace,\n })\n else if (chunk.type === 'reasoning-delta') await emit({\n type: 'reasoning-delta', index: chunk.index, text: chunk.text, trace,\n })\n else if (chunk.type === 'image-delta') await emit({\n type: 'image-delta', itemId: chunk.itemId, data: chunk.data,\n mediaType: chunk.mediaType, ...chunk.partialIndex === undefined ? {} : { partialIndex: chunk.partialIndex }, trace,\n })\n else if (chunk.type === 'usage') await emit({ type: 'usage', usage: chunk.usage, trace })\n else if (chunk.type === 'usage-progress') await emit({ ...chunk, trace })\n }\n } catch (error: unknown) {\n if (!(error instanceof StreamAbortError)) throw error\n assembler.push(signal.aborted\n ? modelAbortedFinish(messageOf(signal.reason ?? error))\n : timedOut\n ? modelFailureFinish(`model stream exceeded ${modelTimeoutMs}ms`, 'MODEL_TIMEOUT')\n : modelFailureFinish(messageOf(error.cause ?? error), 'MODEL_STREAM_ABORTED'))\n } finally {\n clearTimeout(timeout)\n if (!exhausted) {\n owned.abort(new Error('model stream closed before exhaustion'))\n const settled = await closeIterator(iterator, teardownTimeoutMs)\n if (!settled) {\n assembler.push(modelFailureFinish(\n `model stream ignored cancellation for more than ${teardownTimeoutMs}ms; the adapter operation may still be running`,\n 'MODEL_TEARDOWN_TIMEOUT',\n ))\n }\n }\n }\n const report = await handle.report\n const decision = options.accounting === undefined\n ? undefined\n : await options.accounting.recordModelCall(report, { ...requestBase, signal })\n modelCallReport = decision?.report ?? report\n usageRequired = decision?.usageRequired ?? false\n usageUnavailable = decision?.usageUnavailable ?? false\n }\n let providerFinish = assembler.finish\n let retainedPrefix = providerFinish.kind === 'aborted'\n let rawBlocks: ContentBlock[]\n try {\n rawBlocks = providerFinish.kind === 'aborted' ? assembler.interruptedBlocks() : assembler.blocks()\n } catch (error: unknown) {\n providerFinish = {\n kind: 'error',\n failure: {\n message: `model adapter emitted an invalid block sequence: ${messageOf(error)}`,\n code: 'INVALID_MODEL_STREAM',\n },\n }\n // A broken extension must not discard text already delivered to the user.\n // This prefix deliberately excludes tools and unassembled extension data.\n retainedPrefix = true\n rawBlocks = assembler.interruptedBlocks()\n }\n // Interrupted/truncated assembly drops unfinished calls, but the text that\n // introduced those calls is still process narration, not a final answer.\n const canonicalTexts = assembler.textBlocks()\n .filter(({ block }) => !retainedPrefix || block.text.trim() !== '')\n let textPosition = 0\n const classifiedRaw = classifyTextPhases(rawBlocks.map(block => {\n if (block.type !== 'text') return block\n const canonical = canonicalTexts[textPosition++]\n // Safe-prefix recovery removes native calls too. Retain their position so\n // search narration cannot become an answer merely because a call was removed.\n return block.phase === undefined && canonical?.beforeNativeCall\n ? { ...block, phase: 'commentary' as const } : block\n }), phase === 'process', assembler.hasToolCalls)\n // A repeated id costs the model that one call, not its whole turn.\n const deduped = dropDuplicateToolCalls(classifiedRaw, options.history)\n const classified = deduped.blocks\n const structuredOutputFailure = finalOutput\n && options.outputFormat?.type === 'json_schema'\n && providerFinish.kind === 'stop'\n && !isJsonText(textOf(classified), options.validateOutput)\n ? {\n message: 'model returned invalid JSON or failed the structured output validator',\n code: MODEL_ERROR_CODES.MALFORMED_RESPONSE,\n }\n : undefined\n const disabledCall = finalOutput && classified.some(block => block.type === 'tool-call')\n ? { message: 'model emitted a host tool call during the final output phase', code: 'INVALID_TOOL_CALL' }\n : undefined\n const invalidCall = disabledCall\n ?? structuredOutputFailure\n ?? invalidHostToolCall(classified, options.history)\n const blocks = invalidCall === undefined\n ? classified\n : classified.filter(block => block.type !== 'tool-call')\n const finish: FinishReason = invalidCall === undefined\n ? providerFinish\n : { kind: 'error', failure: invalidCall }\n const message = blocks.length === 0 && (finish.kind === 'error' || finish.kind === 'aborted')\n ? undefined\n : createAssistant(options, blocks, retainedPrefix ? undefined : assembler.replayState)\n const calls = message?.content\n .filter((block): block is ToolCallBlock => block.type === 'tool-call')\n .map(block => ({ callId: block.id, toolName: block.name, rawArguments: block.arguments })) ?? []\n const timing = contentTiming(calls.length > 0, afterToolCallIds.length > 0)\n // Deltas may have no phase, or block-end may correct it. Publish the\n // canonical snapshot before consumers close this step, including providers\n // that only emit block-end. Keep provider indexes (which may be sparse).\n if (blocks.some(block => block.type === 'text')) {\n const indexes = canonicalTexts.map(({ index }) => index)\n const incomplete = finish.kind === 'error' || finish.kind === 'aborted' || finish.kind === 'max-tokens'\n let position = 0\n for (const block of blocks) {\n if (block.type !== 'text') continue\n const index = indexes[position++]\n if (index !== undefined) await emit({\n type: 'text-end', index, text: block.text,\n phase: block.phase ?? 'final-answer', trace,\n ...incomplete ? { incomplete: true as const } : {},\n })\n }\n }\n await emit({\n type: 'span-end', trace, at: now(),\n status: finish.kind === 'error' ? 'error' : finish.kind === 'aborted' ? 'aborted' : 'success',\n output: message === undefined ? undefined : {\n text: textOf(message.content),\n commentary: message.content.flatMap(block => block.type === 'text' && block.phase === 'commentary' ? [block.text] : []),\n reasoning: message.content.flatMap(block => block.type === 'reasoning' ? [block.text] : []),\n toolCalls: calls.length,\n },\n ...assembler.usage === undefined ? {} : { usage: assembler.usage },\n ...finish.kind === 'error' || finish.kind === 'aborted'\n ? { error: { type: 'ModelError', message: finish.failure.message, code: finish.failure.code } }\n : {},\n })\n if (calls.length === 0 || finalOutput) await emit({ type: 'step-end', turn, step, trace })\n return {\n trace, ...message === undefined ? {} : { message }, finish,\n ...assembler.usage === undefined ? {} : { usage: assembler.usage },\n ...modelCallReport === undefined ? {} : { report: modelCallReport },\n ...usageRequired ? { usageRequired: true as const } : {},\n ...usageUnavailable ? { usageUnavailable: true as const } : {},\n calls, afterToolCallIds, timing,\n ...deduped.dropped.length === 0 ? {} : { droppedDuplicateCalls: deduped.dropped },\n }\n}\n\nfunction isJsonText(value: string, validate?: (value: unknown) => void): boolean {\n try {\n const parsed: unknown = JSON.parse(value)\n validate?.(parsed)\n return true\n } catch {\n return false\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"model-round.js","names":[],"sources":["../../../../src/agent/loop/turn/model-round.ts"],"sourcesContent":["import type { GenerateOptions } from '../../../contract/index.ts'\nimport { UNCHANGED_ANSWER_MARKER } from '../control-text.ts'\nimport { MODEL_ERROR_CODES, type ModelFailure } from '../../../errors/index.ts'\nimport type { ContentBlock, Message, ToolCallBlock } from '../../../message/index.ts'\nimport { BlockAssembler } from '../../../stream/index.ts'\nimport type { FinishReason } from '../../../stream/index.ts'\nimport type { ModelCallReport } from '../../../observation/index.ts'\nimport { normalizeToolPairing } from '../../history/normalize.ts'\nimport { createSpanId, type TraceRef } from '../../trace/trace.ts'\nimport type { AgentEvent, AgentMaintenanceEvent } from '../types.ts'\nimport { type ModelRoundPhase, type RunTurnOptions, type RoundResult } from './types.ts'\nimport { positiveFinite, positiveSafeInteger } from './config.ts'\nimport { serializedBytes, modelFailureFinish, modelAbortedFinish, messageOf, now } from './common.ts'\nimport { validateStreamChunk } from './validation.ts'\nimport { StreamAbortError, nextWithAbort, closeIterator } from './cancellation.ts'\nimport { runOptionalHook } from './hooks.ts'\nimport { stepProjectionSources } from './step-projection.ts'\nimport { observeModelRequestBoundary } from './model-request-boundary.ts'\nimport { accountingUsageStop } from './usage-stop.ts'\nimport {\n classifyTextPhases, dropDuplicateToolCalls, invalidHostToolCall, contentTiming,\n recentToolResultIds, systemText,\n createAssistant, textOf,\n} from './content.ts'\n\n/** How much of one message the trace keeps. */\nconst PREVIEW_CHARS = 600\n\n/** How many trailing messages the trace keeps. */\nconst PREVIEW_MESSAGES = 8\n\nfunction clip(text: string): string {\n const flattened = text.replace(/\\s+/gu, ' ').trim()\n return flattened.length > PREVIEW_CHARS ? `${flattened.slice(0, PREVIEW_CHARS)}…` : flattened\n}\n\n/** One message as a line: who spoke, and what the model could read of it. */\nfunction previewMessage(message: Message): Record<string, unknown> {\n const parts: string[] = []\n const calls: string[] = []\n for (const block of message.content) {\n if (block.type === 'text' || block.type === 'reasoning') parts.push(block.text)\n else if (block.type === 'tool-call') calls.push(`${block.name}(${clip(block.arguments)})`)\n else if (block.type === 'tool-result') parts.push(textOf(block.content))\n else parts.push(`[${block.type}]`)\n }\n return {\n role: message.role,\n producer: message.source.kind,\n ...parts.length === 0 ? {} : { text: clip(parts.join(' ')) },\n ...calls.length === 0 ? {} : { toolCalls: calls },\n }\n}\n\n/**\n * What this round sent the model, in a form a person can read.\n *\n * A summary, not a copy: the request can be the whole conversation plus every\n * tool schema, and a trace that stored it verbatim would be larger than the\n * work it describes. What survives is the part that explains the round — which\n * tools were on offer, how long the context was, and the tail of the\n * conversation the model was actually answering, each message clipped.\n * @param request - The request about to be dispatched.\n * @returns The summary for the span.\n */\nfunction requestSummary(request: GenerateOptions): Record<string, unknown> {\n const messages = request.messages ?? []\n const dropped = Math.max(0, messages.length - PREVIEW_MESSAGES)\n return {\n messageCount: messages.length,\n // The identity of the request, for a host that records the provider call\n // separately and has to say WHICH round each recording belongs to. Message\n // ids are stable across every representation boundary, so the last one plus\n // the count names one round of one agent without ambiguity.\n ...messages.at(-1) === undefined ? {} : { lastMessageId: messages.at(-1)?.id },\n ...request.system === undefined ? {} : { system: clip(request.system) },\n ...request.tools === undefined || request.tools.length === 0\n ? {}\n : { tools: request.tools.map(tool => tool.name) },\n ...request.toolChoice === undefined ? {} : { toolChoice: request.toolChoice },\n ...dropped === 0 ? {} : { earlierMessagesOmitted: dropped },\n messages: messages.slice(-PREVIEW_MESSAGES).map(previewMessage),\n }\n}\n\nexport async function modelRound(\n options: RunTurnOptions,\n signal: AbortSignal,\n emit: (event: AgentEvent) => Promise<void>,\n emitMaintenance: (event: AgentMaintenanceEvent) => Promise<void>,\n root: TraceRef,\n turn: number,\n step: number,\n phase: ModelRoundPhase,\n): Promise<RoundResult> {\n const forcedFinal = phase === 'forced-final'\n const finalOutput = phase === 'final' || forcedFinal\n const trace: TraceRef = { traceId: root.traceId, spanId: createSpanId(), parentSpanId: root.spanId }\n let messages = normalizeToolPairing(options.history.messages())\n const initialMessages = messages\n const afterToolCallIds = recentToolResultIds(options.history)\n const generation = options.history.generation()\n const entries = options.history.entries().length\n const stopped = (): RoundResult | undefined => {\n const stop = accountingUsageStop(options.accounting)\n if (stop === undefined && !signal.aborted) return undefined\n return {\n trace, finish: signal.aborted\n ? { kind: 'aborted', failure: { code: 'ABORTED', message: messageOf(signal.reason) } }\n : { kind: 'stop' },\n calls: [], afterToolCallIds, timing: contentTiming(false, afterToolCallIds.length > 0),\n ...(stop?.kind === 'error' ? { usageRequired: true } : {}),\n ...(stop?.kind === 'usage-unavailable' ? { usageUnavailable: true } : {}),\n }\n }\n const beforeMaintenance = stopped()\n if (beforeMaintenance !== undefined) return beforeMaintenance\n const decision = await runOptionalHook(options.hooks?.beforeStep, [{\n turn, step, messages, snapshot: options.history.snapshot(), signal,\n ...(options.logger === undefined ? {} : { logger: options.logger }),\n emit: emitMaintenance,\n }], options, signal, 'beforeStep')\n const afterMaintenance = stopped()\n if (afterMaintenance !== undefined) return afterMaintenance\n if (decision?.kind === 'reject') {\n const failure: ModelFailure = { message: decision.reason, code: 'STEP_REJECTED' }\n return {\n trace, finish: { kind: 'error', failure }, calls: [], afterToolCallIds,\n timing: contentTiming(false, afterToolCallIds.length > 0),\n }\n }\n // Hooks may append live steering as well as replacing compacted history.\n // Refresh for either mutation so new user input stays at the chronological\n // tail instead of needing to be prepended ahead of older history.\n if (options.history.generation() !== generation\n || options.history.entries().length !== entries) {\n messages = normalizeToolPairing(options.history.messages())\n }\n if (decision?.messages !== undefined) {\n const originalIds = stepProjectionSources(decision) ?? new Set(initialMessages.map(message => message.id))\n const projectedIds = new Set(decision.messages.map(message => message.id))\n const introduced = messages.filter(message => !originalIds.has(message.id) && !projectedIds.has(message.id))\n const currentIds = new Set(messages.map(message => message.id))\n const replaced = [...originalIds].some(id => !currentIds.has(id))\n // A hook can await external I/O while live steering or replacement arrives.\n // Replacements invalidate a stale projection; append-only steering stays at the tail.\n const projectedById = new Map(decision.messages.map(message => [message.id, message]))\n messages = normalizeToolPairing(replaced\n ? [...decision.messages.filter(message => !originalIds.has(message.id) && !currentIds.has(message.id) && message.source.kind === 'app'),\n ...messages.flatMap(message => {\n const projected = projectedById.get(message.id)\n return projected === undefined ? originalIds.has(message.id) ? [] : [message] : [projected]\n })]\n : [...decision.messages, ...introduced])\n }\n if (decision?.prepend !== undefined) messages = Object.freeze([...decision.prepend, ...messages])\n const system = systemText(options, forcedFinal)\n const availableTools = [\n ...options.tools?.schemas() ?? [],\n ...options.nativeTools ?? [],\n ]\n const tools = availableTools\n const outputFormat = !finalOutput && options.outputFormat?.type === 'json_schema'\n ? { type: 'text' as const }\n : options.outputFormat\n const requestBase: GenerateOptions = {\n ...options.config,\n messages,\n ...system.length === 0 ? {} : { system },\n ...tools.length === 0 ? {} : { tools },\n ...finalOutput && tools.length > 0\n ? { toolChoice: 'none' as const }\n : options.toolChoice === undefined ? {} : { toolChoice: options.toolChoice },\n ...options.imagePolicy === undefined ? {} : { imagePolicy: options.imagePolicy },\n ...options.documentPolicy === undefined ? {} : { documentPolicy: options.documentPolicy },\n ...outputFormat === undefined ? {} : { outputFormat },\n }\n const checkpointRequest: GenerateOptions = { ...requestBase, signal }\n observeModelRequestBoundary(options.history, true)\n try {\n await runOptionalHook(options.hooks?.checkpoint, [{\n kind: 'before-model-request', request: checkpointRequest,\n snapshot: options.history.snapshot(), signal,\n ...(options.logger === undefined ? {} : { logger: options.logger }),\n }], options, signal, 'checkpoint')\n } catch (error: unknown) {\n // No output will be recorded for this request. Release queued input before\n // recovery hooks or the retry's beforeStep can read or inject into history.\n observeModelRequestBoundary(options.history, false)\n const failure: ModelFailure = { message: `history checkpoint failed: ${messageOf(error)}`, code: 'CHECKPOINT_FAILED' }\n return {\n trace, finish: { kind: 'error', failure }, calls: [], afterToolCallIds,\n timing: contentTiming(false, afterToolCallIds.length > 0),\n }\n }\n const beforeDispatch = stopped()\n if (beforeDispatch !== undefined) {\n observeModelRequestBoundary(options.history, false)\n return beforeDispatch\n }\n await emit({ type: 'span-start', trace, at: now(), name: `chat ${options.config.model}`, kind: 'chat', attributes: {\n 'gen_ai.operation.name': 'chat', 'gen_ai.request.model': options.config.model,\n // The effort is part of WHICH call this was: the same model at minimal and\n // at high is two different requests, priced and paced differently, and a\n // trace that omits it cannot explain either. Absent when the route has no\n // effort ladder, rather than reported as a default nobody chose.\n ...options.config.reasoningEffort === undefined\n ? {}\n : { 'gen_ai.request.reasoning_effort': options.config.reasoningEffort },\n turn, step, forcedFinal, phase,\n }, input: requestSummary(requestBase) })\n await emit({ type: 'step-start', turn, step, trace, ...forcedFinal ? { forcedFinal: true as const } : {} })\n const assembler = new BlockAssembler()\n const closedBlockIndexes = new Set<number>()\n const modelTimeoutMs = positiveFinite(options.modelTimeoutMs ?? 10 * 60_000, 'modelTimeoutMs')\n const maxRequestBytes = positiveSafeInteger(options.maxModelRequestBytes ?? 32 * 1024 * 1024, 'maxModelRequestBytes')\n const maxResponseBytes = positiveSafeInteger(options.maxModelResponseBytes ?? 32 * 1024 * 1024, 'maxModelResponseBytes')\n const maxStreamEvents = positiveSafeInteger(options.maxModelStreamEvents ?? 100_000, 'maxModelStreamEvents')\n const teardownTimeoutMs = positiveFinite(options.teardownTimeoutMs ?? 30_000, 'teardownTimeoutMs')\n let modelCallReport: ModelCallReport | undefined\n let usageRequired = false\n let usageUnavailable = false\n let requestBytes: number\n try {\n requestBytes = serializedBytes(requestBase)\n } catch (error: unknown) {\n requestBytes = -1\n assembler.push(modelFailureFinish(`model request is not serializable: ${messageOf(error)}`, 'INVALID_MODEL_REQUEST'))\n }\n if (requestBytes > maxRequestBytes) {\n assembler.push(modelFailureFinish(\n `model request exceeds the ${maxRequestBytes}-byte limit`,\n 'MODEL_REQUEST_TOO_LARGE',\n ))\n } else if (requestBytes >= 0) {\n const owned = new AbortController()\n const roundSignal = AbortSignal.any([signal, owned.signal])\n let timedOut = false\n const timeout = setTimeout(() => {\n timedOut = true\n owned.abort(new Error(`model stream exceeded ${modelTimeoutMs}ms`))\n }, modelTimeoutMs)\n const handle = options.registry.stream(\n { ...requestBase, signal: roundSignal },\n options.accounting?.modelInvocation,\n )\n const iterator = handle[Symbol.asyncIterator]()\n let exhausted = false\n let events = 0\n let responseBytes = 0\n let sawFinish = false\n try {\n while (true) {\n const next = await nextWithAbort(iterator.next(), roundSignal)\n if (next.done === true) {\n exhausted = true\n break\n }\n const chunk = next.value\n try {\n validateStreamChunk(chunk, maxStreamEvents)\n } catch (error: unknown) {\n assembler.push(modelFailureFinish(\n `model adapter emitted an invalid stream chunk: ${messageOf(error)}`,\n 'INVALID_MODEL_STREAM',\n ))\n owned.abort(new Error('invalid model stream chunk'))\n break\n }\n events++\n try {\n responseBytes += serializedBytes(chunk)\n } catch (error: unknown) {\n assembler.push(modelFailureFinish(\n `model adapter emitted a non-serializable stream chunk: ${messageOf(error)}`,\n 'INVALID_MODEL_STREAM',\n ))\n owned.abort(new Error('non-serializable model stream chunk'))\n break\n }\n if (events > maxStreamEvents || responseBytes > maxResponseBytes) {\n const dimension = events > maxStreamEvents\n ? `${maxStreamEvents}-event`\n : `${maxResponseBytes}-byte`\n assembler.push(modelFailureFinish(\n `model response exceeds the ${dimension} limit`,\n 'MODEL_RESPONSE_TOO_LARGE',\n ))\n owned.abort(new Error('model response resource limit exceeded'))\n break\n }\n if (sawFinish) {\n assembler.push(modelFailureFinish(\n 'model adapter emitted data after its terminal finish chunk',\n 'INVALID_MODEL_STREAM',\n ))\n owned.abort(new Error('invalid model stream'))\n break\n }\n assembler.push(chunk)\n // The assembler ignores deltas after the first close. The visible\n // stream must do the same or UI text can disagree with stored history.\n if ((chunk.type === 'text-delta' || chunk.type === 'reasoning-delta' || chunk.type === 'tool-call-delta')\n && closedBlockIndexes.has(chunk.index)) continue\n if (chunk.type === 'block-end') closedBlockIndexes.add(chunk.index)\n if (chunk.type === 'finish') sawFinish = true\n if (chunk.type === 'text-delta') await emit({\n type: 'text-delta', index: chunk.index, text: chunk.text,\n phase: phase === 'process' ? 'commentary' : chunk.phase ?? 'unknown', trace,\n })\n else if (chunk.type === 'reasoning-delta') await emit({\n type: 'reasoning-delta', index: chunk.index, text: chunk.text, trace,\n })\n else if (chunk.type === 'image-delta') await emit({\n type: 'image-delta', itemId: chunk.itemId, data: chunk.data,\n mediaType: chunk.mediaType, ...chunk.partialIndex === undefined ? {} : { partialIndex: chunk.partialIndex }, trace,\n })\n else if (chunk.type === 'usage') await emit({ type: 'usage', usage: chunk.usage, trace })\n else if (chunk.type === 'usage-progress') await emit({ ...chunk, trace })\n }\n } catch (error: unknown) {\n if (!(error instanceof StreamAbortError)) throw error\n assembler.push(signal.aborted\n ? modelAbortedFinish(messageOf(signal.reason ?? error))\n : timedOut\n ? modelFailureFinish(`model stream exceeded ${modelTimeoutMs}ms`, 'MODEL_TIMEOUT')\n : modelFailureFinish(messageOf(error.cause ?? error), 'MODEL_STREAM_ABORTED'))\n } finally {\n clearTimeout(timeout)\n if (!exhausted) {\n owned.abort(new Error('model stream closed before exhaustion'))\n const settled = await closeIterator(iterator, teardownTimeoutMs)\n if (!settled) {\n assembler.push(modelFailureFinish(\n `model stream ignored cancellation for more than ${teardownTimeoutMs}ms; the adapter operation may still be running`,\n 'MODEL_TEARDOWN_TIMEOUT',\n ))\n }\n }\n }\n const report = await handle.report\n const decision = options.accounting === undefined\n ? undefined\n : await options.accounting.recordModelCall(report, { ...requestBase, signal })\n modelCallReport = decision?.report ?? report\n usageRequired = decision?.usageRequired ?? false\n usageUnavailable = decision?.usageUnavailable ?? false\n }\n let providerFinish = assembler.finish\n let retainedPrefix = providerFinish.kind === 'aborted'\n let rawBlocks: ContentBlock[]\n try {\n rawBlocks = providerFinish.kind === 'aborted' ? assembler.interruptedBlocks() : assembler.blocks()\n } catch (error: unknown) {\n providerFinish = {\n kind: 'error',\n failure: {\n message: `model adapter emitted an invalid block sequence: ${messageOf(error)}`,\n code: 'INVALID_MODEL_STREAM',\n },\n }\n // A broken extension must not discard text already delivered to the user.\n // This prefix deliberately excludes tools and unassembled extension data.\n retainedPrefix = true\n rawBlocks = assembler.interruptedBlocks()\n }\n // Interrupted/truncated assembly drops unfinished calls, but the text that\n // introduced those calls is still process narration, not a final answer.\n const canonicalTexts = assembler.textBlocks()\n .filter(({ block }) => !retainedPrefix || block.text.trim() !== '')\n let textPosition = 0\n const classifiedRaw = classifyTextPhases(rawBlocks.map(block => {\n if (block.type !== 'text') return block\n const canonical = canonicalTexts[textPosition++]\n // Safe-prefix recovery removes native calls too. Retain their position so\n // search narration cannot become an answer merely because a call was removed.\n return block.phase === undefined && canonical?.beforeNativeCall\n ? { ...block, phase: 'commentary' as const } : block\n }), phase === 'process', assembler.hasToolCalls)\n // A repeated id costs the model that one call, not its whole turn.\n const deduped = dropDuplicateToolCalls(classifiedRaw, options.history)\n const classified = deduped.blocks\n const structuredOutputFailure = finalOutput\n && options.outputFormat?.type === 'json_schema'\n && providerFinish.kind === 'stop'\n && !isJsonText(textOf(classified), options.validateOutput)\n ? {\n message: 'model returned invalid JSON or failed the structured output validator',\n code: MODEL_ERROR_CODES.MALFORMED_RESPONSE,\n }\n : undefined\n const disabledCall = finalOutput && classified.some(block => block.type === 'tool-call')\n ? { message: 'model emitted a host tool call during the final output phase', code: 'INVALID_TOOL_CALL' }\n : undefined\n const invalidCall = disabledCall\n ?? structuredOutputFailure\n ?? invalidHostToolCall(classified, options.history)\n const rawContent = invalidCall === undefined\n ? classified\n : classified.filter(block => block.type !== 'tool-call')\n // A control reply cannot confirm an answer while dispatching more work.\n // Strip it before persistence so tool-call identities are recorded only once.\n const blocks = rawContent.some(block => block.type === 'tool-call')\n ? rawContent.map(block => block.type === 'text'\n ? { ...block, text: block.text.replaceAll(UNCHANGED_ANSWER_MARKER, '') } : block)\n : rawContent\n const finish: FinishReason = invalidCall === undefined\n ? providerFinish\n : { kind: 'error', failure: invalidCall }\n const message = blocks.length === 0\n ? undefined\n : createAssistant(options, blocks, retainedPrefix ? undefined : assembler.replayState)\n const calls = message?.content\n .filter((block): block is ToolCallBlock => block.type === 'tool-call')\n .map(block => ({ callId: block.id, toolName: block.name, rawArguments: block.arguments })) ?? []\n const timing = contentTiming(calls.length > 0, afterToolCallIds.length > 0)\n // Deltas may have no phase, or block-end may correct it. Publish the\n // canonical snapshot before consumers close this step, including providers\n // that only emit block-end. Keep provider indexes (which may be sparse).\n if (blocks.some(block => block.type === 'text')) {\n const indexes = canonicalTexts.map(({ index }) => index)\n const incomplete = finish.kind === 'error' || finish.kind === 'aborted' || finish.kind === 'max-tokens'\n let position = 0\n for (const block of blocks) {\n if (block.type !== 'text') continue\n const index = indexes[position++]\n if (index !== undefined) await emit({\n type: 'text-end', index, text: block.text,\n phase: block.phase ?? 'final-answer', trace,\n ...incomplete ? { incomplete: true as const } : {},\n })\n }\n }\n await emit({\n type: 'span-end', trace, at: now(),\n status: finish.kind === 'error' ? 'error' : finish.kind === 'aborted' ? 'aborted' : 'success',\n output: message === undefined ? undefined : {\n text: textOf(message.content),\n commentary: message.content.flatMap(block => block.type === 'text' && block.phase === 'commentary' ? [block.text] : []),\n reasoning: message.content.flatMap(block => block.type === 'reasoning' ? [block.text] : []),\n toolCalls: calls.length,\n },\n ...assembler.usage === undefined ? {} : { usage: assembler.usage },\n ...finish.kind === 'error' || finish.kind === 'aborted'\n ? { error: { type: 'ModelError', message: finish.failure.message, code: finish.failure.code } }\n : {},\n })\n if (calls.length === 0 || finalOutput) await emit({ type: 'step-end', turn, step, trace })\n return {\n trace, ...message === undefined ? {} : { message }, finish,\n ...assembler.usage === undefined ? {} : { usage: assembler.usage },\n ...modelCallReport === undefined ? {} : { report: modelCallReport },\n ...usageRequired ? { usageRequired: true as const } : {},\n ...usageUnavailable ? { usageUnavailable: true as const } : {},\n calls, afterToolCallIds, timing,\n ...deduped.dropped.length === 0 ? {} : { droppedDuplicateCalls: deduped.dropped },\n }\n}\n\nfunction isJsonText(value: string, validate?: (value: unknown) => void): boolean {\n try {\n const parsed: unknown = JSON.parse(value)\n validate?.(parsed)\n return true\n } catch {\n return false\n }\n}\n"],"mappings":"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"}
@@ -1,28 +1,16 @@
1
+ import { Message } from "../../message/message.js";
1
2
  import { CallConfig } from "../../contract/call-config.js";
2
3
  import { ToolCatalog } from "../tool/registry.js";
3
4
  import { AgentEvent, TurnHooks, TurnOutcome } from "../loop/events.js";
4
5
  import { TurnBounds } from "../loop/types.js";
5
6
  import { RunTurnOptions } from "../loop/turn/types.js";
7
+ import { UNCHANGED_ANSWER_MARKER } from "../loop/control-text.js";
6
8
  import { UserInputBroker, UserInputRequest, UserInputResponse } from "./user-input.js";
7
9
  //#region src/agent/mode/run-agent.d.ts
8
10
  declare const AGENT_CONTROL_TOOLS: Readonly<{
9
11
  readonly complete: 'submit_result';
10
12
  readonly requestUserInput: 'request_user_input';
11
13
  }>;
12
- /**
13
- * What the model replies with, after an accepted self-check, when the answer
14
- * it already gave the user earlier in the run still stands.
15
- *
16
- * Deep modes gate on an accepted `submit_result`, so a model that answered
17
- * before checking is asked to check, then told to "deliver the answer"
18
- * again — even when the check found nothing to add. Without this marker that
19
- * second pass either pads an already-adequate answer or, worse, quietly
20
- * changes it while claiming to only be confirming it. `driveAgent` treats a
21
- * reply that is exactly this marker as "no change": the run's `text` (and,
22
- * where the earlier answer is still the history's current surface, the
23
- * transcript) keep the answer already given instead of this marker.
24
- */
25
- declare const UNCHANGED_ANSWER_MARKER = "<<deep-mode:answer-unchanged>>";
26
14
  /** Default high-level runtime requested by this SDK; `runTurn` remains provider-neutral. */
27
15
  type AgentMode = 'basic' | 'deep' | 'deep-human-in-loop';
28
16
  interface AgentRunCommon extends Omit<RunTurnOptions, 'bounds' | 'commentary' | 'config' | 'hooks' | 'system' | 'tools'> {
@@ -79,7 +67,12 @@ interface AgentModeEndEvent {
79
67
  readonly type: 'agent-end';
80
68
  readonly outcome: AgentRunOutcome;
81
69
  }
82
- type AgentRunEvent = AgentEvent | AgentModeStartEvent | UserInputRequestEvent | UserInputResponseEvent | AgentModeEndEvent;
70
+ interface AssistantReplacementEvent {
71
+ readonly type: 'assistant-replacement';
72
+ readonly fromMessageId: Message['id'];
73
+ readonly message: Message;
74
+ }
75
+ type AgentRunEvent = AgentEvent | AssistantReplacementEvent | AgentModeStartEvent | UserInputRequestEvent | UserInputResponseEvent | AgentModeEndEvent;
83
76
  /**
84
77
  * Run an agent in basic, self-checking deep, or deep human-in-loop mode.
85
78
  *
@@ -1 +1 @@
1
- {"version":3,"file":"run-agent.d.ts","names":[],"sources":["../../../src/agent/mode/run-agent.ts"],"mappings":";;;;;;;cAkBa,qBAAmB;WACpB;WACQ;;;;;;;;;;;;;;;cAgBP;;KAGD;UAEF,uBAAuB,KAAK;;WAE3B,QAAQ;WACR,QAAQ;WACR;;;WAGA;WACA,SAAS,KAAK,QAAQ;WACtB,aAAa;WACb,QAAQ;;UAGF,0BAA0B;WAChC;;UAGM,yBAAyB;WAC/B;;WAEA,YAAY;;UAGN,gCAAgC;WACtC;;WAEA,WAAW;;KAGV,kBAAkB,oBAAoB,mBAAmB;UAEpD;WACN;WACA;;UAGM,wBAAwB;WAC9B,MAAM;;WAEN;WACA,aAAa;;UAGd;WACC;WACA,MAAM;WACN;;UAED;WACC;WACA,SAAS;;UAEV;WACC;WACA,SAAS;WACT,UAAU;;UAEX;WACC;WACA,SAAS;;KAGR,gBAAgB,aACxB,sBACA,wBACA,yBACA;;;;;;;;iBA4CY,SAAS,SAAS,kBAAkB,cAAc"}
1
+ {"version":3,"file":"run-agent.d.ts","names":[],"sources":["../../../src/agent/mode/run-agent.ts"],"mappings":";;;;;;;;;cAmBa,qBAAmB;WACpB;WACQ;;;KAmBR;UAEF,uBAAuB,KAAK;;WAE3B,QAAQ;WACR,QAAQ;WACR;;;WAGA;WACA,SAAS,KAAK,QAAQ;WACtB,aAAa;WACb,QAAQ;;UAGF,0BAA0B;WAChC;;UAGM,yBAAyB;WAC/B;;WAEA,YAAY;;UAGN,gCAAgC;WACtC;;WAEA,WAAW;;KAGV,kBAAkB,oBAAoB,mBAAmB;UAEpD;WACN;WACA;;UAGM,wBAAwB;WAC9B,MAAM;;WAEN;WACA,aAAa;;UAGd;WACC;WACA,MAAM;WACN;;UAED;WACC;WACA,SAAS;;UAEV;WACC;WACA,SAAS;WACT,UAAU;;UAEX;WACC;WACA,SAAS;;UAGV;WACC;WACA,eAAe;WACf,SAAS;;KAGR,gBAAgB,aAAa,4BACrC,sBACA,wBACA,yBACA;;;;;;;;iBAqDY,SAAS,SAAS,kBAAkB,cAAc"}
@@ -1,4 +1,4 @@
1
- import{detachedFrozen as e}from"../../primitives/snapshot.js";import{waitForSettlement as t}from"../../async/settlement.js";import{createMessage as n,createUserMessage as r}from"../../message/message.js";import{defineTool as i}from"../tool/definition.js";import{readSpillTool as a}from"../tool/output-budget.js";import{AwaitedEventQueue as o}from"../loop/queue.js";import{runTurn as s}from"../loop/run-turn.js";const c=Object.freeze({complete:`submit_result`,requestUserInput:`request_user_input`}),l=`<<deep-mode:answer-unchanged>>`;function u(n){return{async*[Symbol.asyncIterator](){let r=new o,i=new AbortController,a=M(n.teardownTimeoutMs??3e4,`teardownTimeoutMs`),s=n.signal===void 0?i.signal:AbortSignal.any([n.signal,i.signal]),c=Promise.resolve(),l=d(n,s,t=>{let n=c.then(()=>r.push(e(t)));return c=n.catch(()=>void 0),n}).then(async()=>{await c,r.close()},async e=>{await c,r.fail(e)});try{for(;;){let e=await r.take();if(e.done)break;yield e.value}await l}finally{if(i.abort(Error(`agent event consumer stopped`)),r.close(),!await t(l,a)){let e=Error(`agent producer ignored cancellation for more than ${a}ms`,{cause:i.signal.reason});throw e.code=`AGENT_TEARDOWN_TIMEOUT`,e}}}}}async function d(e,t,n){let r=e.mode??`basic`;if(![`basic`,`deep`,`deep-human-in-loop`].includes(r))throw RangeError(`unsupported agent mode "${String(r)}"`);let i=`userInput`in e?e.userInput:void 0;if(r===`deep-human-in-loop`&&(i===void 0||typeof i.request!=`function`))throw TypeError(`deep-human-in-loop mode requires a UserInputBroker`);let o=e.maxTurns??16;if(o!==`auto`&&(!Number.isSafeInteger(o)||o<1))throw RangeError(`maxTurns must be a positive safe integer or 'auto'`);await n({type:`agent-start`,mode:r,maxTurns:o});let l={completion:void 0,userAborted:!1,unverifiedAnswers:0,completionInvalidated:!1,draftAnswer:void 0,orphanMarkerNudged:!1,markerCut:!1,markerReply:!1},u=r!==`basic`,d=e.mode===`deep`||e.mode===`deep-human-in-loop`?i:void 0,b=[];e.spillStore!==void 0&&b.push(a(e.spillStore)),u&&b.push(_(l)),d!==void 0&&r!==`basic`&&b.push(v(r,d,l,n,e.accounting));let w=b.length===0?e.tools:x(e.tools,b),T=u?y(e.hooks,e.history,l,o):e.hooks,E={registry:e.registry,config:e.config,history:e.history,...w===void 0?{}:{tools:w},...e.nativeTools===void 0?{}:{nativeTools:e.nativeTools},...e.toolChoice===void 0?{}:{toolChoice:e.toolChoice},...e.imagePolicy===void 0?{}:{imagePolicy:e.imagePolicy},...e.documentPolicy===void 0?{}:{documentPolicy:e.documentPolicy},...e.validateOutput===void 0?{}:{validateOutput:e.validateOutput},...e.outputFormat===void 0?{}:{outputFormat:e.outputFormat},system:k(e.system,O(r,d!==void 0)),...e.interceptors===void 0?{}:{interceptors:S(e.interceptors)},...e.approvals===void 0?{}:{approvals:e.approvals},bounds:{...e.bounds,maxSteps:o},...T===void 0?{}:{hooks:T},signal:t,...e.logger===void 0?{}:{logger:e.logger},commentary:e.commentary??`auto`,teardownTimeoutMs:e.teardownTimeoutMs??3e4,...e.modelTimeoutMs===void 0?{}:{modelTimeoutMs:e.modelTimeoutMs},...e.maxModelRequestBytes===void 0?{}:{maxModelRequestBytes:e.maxModelRequestBytes},...e.maxModelResponseBytes===void 0?{}:{maxModelResponseBytes:e.maxModelResponseBytes},...e.maxModelStreamEvents===void 0?{}:{maxModelStreamEvents:e.maxModelStreamEvents},...e.hookTimeoutMs===void 0?{}:{hookTimeoutMs:e.hookTimeoutMs},...e.hookTeardownTimeoutMs===void 0?{}:{hookTeardownTimeoutMs:e.hookTeardownTimeoutMs},...e.trace===void 0?{}:{trace:e.trace},...e.accounting===void 0?{}:{accounting:e.accounting},...e.spillStore===void 0?{}:{spillStore:e.spillStore},...e.experimentalPrograms===void 0?{}:{experimentalPrograms:e.experimentalPrograms},...e.contextSections===void 0?{}:{contextSections:e.contextSections}},D,A=[],j,M=!1,N=``,P=[],F,I,L=!1,R=async()=>{let e=P;P=[];for(let t of e)await n(t)},z=async()=>{let e=P;P=[];for(let t of e)t.type!==`text-delta`&&t.type!==`text-end`&&await n(t)},B=async t=>{if(I===void 0||t.type!==`assistant-text`||t.messageId!==I){if(F!==void 0&&t.type===`assistant-reasoning`&&t.messageId===F.from){await n({...t,messageId:F.message.id});return}if(F!==void 0&&t.type===`assistant-text`&&t.messageId===F.from){let e=F.message.content.find(e=>e.type===`text`);await n({...t,messageId:F.message.id,text:e?.type===`text`?e.text:t.text});return}if(t.type===`step-start`&&(F=void 0,I=void 0,L=!1,l.markerCut=!1,l.markerReply=!1,await R(),M=l.completion!==void 0,N=``),M&&(t.type===`text-delta`||t.type===`text-end`)){N=t.type===`text-end`?t.text:N+t.text,P.push(t),p(N)?t.type===`text-end`&&t.incomplete&&(l.markerCut=!0):(M=!1,await R());return}if(M&&t.type===`assistant-message`){let r=t.message.content,i=l.draftAnswer,a=f(r),o=a!==void 0&&(a.trim()===`<<deep-mode:answer-unchanged>>`||l.markerCut&&p(a));if(M=!1,o){l.markerReply=!0,F={from:t.message.id,message:h(i??``,r)},g(e.history,F.message,l.markerCut),L=!0,i===void 0&&(I=t.message.id),await z(),await n({...t,message:F.message});return}l.markerCut=!1,await R()}else if(P.length>0){if(t.type===`turn-end`&&M&&p(N))M=!1,l.markerCut=!0,await z();else if(t.type===`turn-end`||t.type===`tool-call`)M=!1,await R();else{P.push(t);return}}await n(t)}};for await(let t of s(E)){if(t.type===`step-start`?(A=[],j=void 0):t.type===`tool-call`?(A.push(t.call.toolName),t.call.toolName!==c.complete&&w?.get(t.call.toolName)?.completionExempt!==!0&&(l.completion!==void 0&&(l.completionInvalidated=!0),l.completion=void 0,l.unverifiedAnswers=0)):t.type===`tool-result`&&t.call.toolName===c.complete&&!t.result.isError?j=C(t.result.value):t.type===`step-end`&&j!==void 0&&A.filter(e=>e===c.complete).length===1&&A.every(e=>e===c.complete||w?.get(e)?.completionExempt===!0)&&(l.completion=j,l.completionInvalidated=!1),t.type===`turn-end`){M&&P.length>0&&p(N)&&(l.markerCut=!0),D=m(t.outcome,l),D!==t.outcome&&l.draftAnswer!==void 0&&!L&&g(e.history,F?.message??h(D.text),l.markerCut),await B({...t,outcome:D});continue}await B(t)}if(D===void 0)throw Error(`runTurn ended without a turn-end event`);let V=r===`basic`?D.reason.kind===`completed`||D.reason.kind===`concluded-by-tool`:l.completion!==void 0&&!l.userAborted&&(D.reason.kind===`completed`||D.reason.kind===`concluded-by-tool`||D.reason.kind===`budget-exhausted`&&D.reason.forcedFinalAnswer)&&D.text.trim()!==``;await n({type:`agent-end`,outcome:{...D,mode:r,completed:V,...l.completion===void 0?{}:{completion:l.completion}}})}function f(e){let t=e.filter(e=>e.type!==`reasoning`);return t.length===1&&t[0]?.type===`text`?t[0].text:void 0}function p(e){let t=e.trim();return t.length===0||l.startsWith(t)}function m(e,t){return t.completion===void 0||!t.markerReply&&!t.markerCut||!(t.markerCut&&e.text.trim()!==``&&p(e.text))&&e.text.trim()!==`<<deep-mode:answer-unchanged>>`?e:{...e,text:t.draftAnswer??``}}function h(e,t){return n({role:`assistant`,content:t===void 0?[{type:`text`,text:e,phase:`final-answer`}]:t.flatMap(t=>t.type===`reasoning`?[t]:e===``?[]:[{type:`text`,text:e,phase:`final-answer`}]),source:{kind:`app`,producer:`deep-mode-kept-answer`}})}function g(e,t,n=!1){let r=e.entries(),i;for(let e=r.length-1;e>=0;e--){let t=r[e];if(t?.event.kind===`assistant`){i=t;break}}let a=i?.event.kind===`assistant`?f(i.event.message.content):void 0;i!==void 0&&a!==void 0&&(a.trim()!==`<<deep-mode:answer-unchanged>>`&&!(n&&a.trim()!==``&&p(a))||e.append({kind:`assistant`,message:t},{op:`replace`,from:i.seq,to:i.seq}))}function _(e){return i({name:c.complete,description:`Submit the self-check only when the user objective and constraints are fully satisfied. After acceptance, give the user the final answer.`,budgetExempt:!0,parameters:{type:`object`,properties:{summary:{type:`string`,description:`Concise statement of what was completed.`},evidence:{type:`array`,items:{type:`string`},description:`Concrete checks or tool results showing the objective is satisfied.`}},required:[`summary`,`evidence`],additionalProperties:!1},parse:T,execute:t=>({accepted:!0,summary:t.summary,evidence:[...t.evidence],instruction:e.draftAnswer===void 0?`This self-check is accepted for the current run. Now deliver the answer or artifact requested by the current user or assigned task, preserving its requested content and format. For exact text, only JSON, only a number, or another constrained format, return only the requested output. The summary and evidence in this tool result are verification metadata; keep them out of the final answer unless the task requests them. If the task requests a report, provide the substantive findings or changes, supporting evidence or sources, and relevant limitations. Do not merely say the self-check passed or refer to an earlier message. Do not call submit_result again in this run unless you perform new substantive tool work that invalidates this submission. A later user request or worker follow-up starts a new run and needs its own self-check.`:`This self-check is accepted for the current run. You already gave the user a complete answer earlier in this run, before this check. If that answer is still correct and complete, reply with exactly ${l} and nothing else — no summary, no reference to it, no repeating it; the earlier answer is kept as the final answer. Only if this check found something to correct or add, give the complete corrected answer in full, as if the earlier one did not exist: never summarize it, point back to it, or say the self-check passed. Do not call submit_result again in this run unless you perform new substantive tool work that invalidates this submission. A later user request or worker follow-up starts a new run and needs its own self-check.`})})}function v(e,t,n,r,a){return i({name:c.requestUserInput,budgetExempt:!0,description:e===`deep-human-in-loop`?`Ask the user one to three short questions when a material choice or missing fact requires human input, then wait for the response. Provide 2-3 mutually exclusive suggestions; free-form input is added by the client.`:`Ask the user one to three short clarification questions only when blocked, then wait for the response. Provide suggested choices; free-form input is added by the client.`,parameters:D(),parse:E,execute:async({questions:e},i)=>{let o=a?.startOperation(`user-input`,{toolCallId:i.callId,data:{questionCount:e.length}}),s={requestId:i.callId,callId:i.callId,turn:i.turn,step:i.step,questions:e,isBlocking:!0};try{let c=t.request(s,i.signal);await r({type:`user-input-request`,request:s});let l=await c;return await r({type:`user-input-response`,request:s,response:l}),l===`abort`?(n.userAborted=!0,i.concludeTurn(),o!==void 0&&a?.endOperation(o,`aborted`),{aborted:!0}):(o!==void 0&&a?.endOperation(o,`success`),w(l,e))}catch(e){throw o!==void 0&&a?.endOperation(o,i.signal.aborted?`aborted`:`error`,{error:e}),e}}})}function y(e,t,n,i){return{...e,onTurnEnd:async a=>{let o=m(a.outcome,n);if(await e?.onTurnEnd?.(o===a.outcome?a:{...a,outcome:o}),a.outcome.reason.kind===`completed`&&a.canContinue&&n.completion!==void 0&&n.draftAnswer===void 0&&!n.orphanMarkerNudged&&n.markerReply&&a.outcome.text.trim()===`<<deep-mode:answer-unchanged>>`){n.orphanMarkerNudged=!0,t.append({kind:`user`,message:r({source:{kind:`app`,producer:`deep-mode-self-check`},content:[{type:`text`,text:`There is no earlier answer in this run for ${l} to keep: that reply applies only after an answer was given before the check in the same run. Reply with the answer itself now, in the requested format.`}]})});return}a.outcome.reason.kind!==`completed`||i!==`auto`&&a.outcome.steps>=i||n.completion!==void 0||n.userAborted||(n.unverifiedAnswers++,!(n.unverifiedAnswers>=3)&&(a.outcome.text.trim()!==``&&a.outcome.text.trim()!==`<<deep-mode:answer-unchanged>>`&&(n.draftAnswer=a.outcome.text),t.append({kind:`user`,message:r({source:{kind:`app`,producer:`deep-mode-self-check`},content:[{type:`text`,text:(n.completionInvalidated?`Your previously accepted submission is no longer current because you called another substantive tool afterwards. Review the later tool results and call ${c.complete} again when complete; the old instruction not to resubmit no longer applies. `:``)+`Self-check required: this run has no accepted current self-check. Acceptance recorded in an earlier run does not complete this request or follow-up; an earlier instruction not to resubmit applied only to that earlier run. Compare the current result against the user's objective and every constraint. If anything is missing, continue with tools. If blocked and request_user_input is available, ask the user. Only when the work is actually complete, call ${c.complete}. Keep verification in that tool call and then deliver the current user or assigned task's requested output in its original format. This reminder does not change the task or request a process report. Rephrasing a completion claim without submitting does not satisfy this gate.`}]})})))}}}var b=class{definitions;constructor(e,t){let n=new Map;for(let t of e?.names()??[]){let r=e?.get(t);r!==void 0&&n.set(t,r)}for(let e of t){if(n.has(e.name))throw Error(`tool name "${e.name}" is reserved by the selected agent mode`);n.set(e.name,e)}this.definitions=n}get(e){return this.definitions.get(e)}has(e){return this.definitions.has(e)}names(){return[...this.definitions.keys()]}schemas(){return[...this.definitions.values()].map(({name:e,description:t,parameters:n})=>({name:e,description:t,parameters:structuredClone(n)}))}executionMode(e,t){let n=this.definitions.get(e);if(n===void 0)return`exclusive`;try{return n.isConcurrencySafe?.(t)===!0?`parallel`:`exclusive`}catch{return`exclusive`}}};function x(e,t){return new b(e,t)}function S(e){let t=new Set(Object.values(c));return e.map(e=>({name:e.name,...e.before===void 0?{}:{before:(n,r)=>t.has(n.toolName)?r():e.before(n,r)},...e.around===void 0?{}:{around:(n,r)=>t.has(n.toolName)?r():e.around(n,r)},...e.after===void 0?{}:{after:(n,r,i)=>t.has(n.toolName)?i():e.after(n,r,i)}}))}function C(e){let t=A(e,`submit_result result`);return T({summary:t.summary,evidence:t.evidence})}function w(e,t){let n=new Set(t.map(e=>e.id));for(let t of n){let n=e.answers[t];if(n===void 0||!Array.isArray(n.answers)||n.answers.length===0||n.answers.some(e=>typeof e!=`string`||e.trim().length===0))throw Error(`the user-input broker returned no valid answer for "${t}"`)}for(let t of Object.keys(e.answers))if(!n.has(t))throw Error(`the user-input broker returned an answer for unknown question "${t}"`);return e}function T(e){let t=A(e,`submit_result arguments`);if(typeof t.summary!=`string`||t.summary.trim().length===0)throw Error(`summary must be a non-empty string`);if(!Array.isArray(t.evidence)||t.evidence.some(e=>typeof e!=`string`||e.trim().length===0))throw Error(`evidence must be an array of non-empty strings`);return{summary:t.summary,evidence:t.evidence}}function E(e){let t=A(e,`request_user_input arguments`);if(!Array.isArray(t.questions)||t.questions.length<1||t.questions.length>3)throw Error(`questions must contain one to three items`);let n=new Set,r=t.questions.map((e,t)=>{let r=A(e,`questions[${t}]`),i=j(r.id,`questions[${t}].id`);if(!/^[a-z][a-z0-9_]*$/.test(i))throw Error(`questions[${t}].id must be snake_case`);if(n.has(i))throw Error(`question id "${i}" is duplicated`);n.add(i);let a=j(r.header,`questions[${t}].header`),o=j(r.question,`questions[${t}].question`);if(!Array.isArray(r.options)||r.options.length<2||r.options.length>3)throw Error(`questions[${t}].options must contain two or three choices`);let s=r.options.map((e,n)=>{let r=A(e,`questions[${t}].options[${n}]`);return{label:j(r.label,`questions[${t}].options[${n}].label`),description:j(r.description,`questions[${t}].options[${n}].description`)}});return Object.freeze({id:i,header:a,question:o,options:Object.freeze(s),allowFreeForm:!0})});return{questions:Object.freeze(r)}}function D(){return{type:`object`,properties:{questions:{type:`array`,minItems:1,maxItems:3,description:`Questions to show the user. Prefer one and do not exceed three.`,items:{type:`object`,additionalProperties:!1,properties:{id:{type:`string`,description:`Stable snake_case answer key.`},header:{type:`string`,description:`Short UI label, ideally 12 characters or fewer.`},question:{type:`string`,description:`Single-sentence question.`},options:{type:`array`,minItems:2,maxItems:3,description:`Mutually exclusive choices. Put the recommended choice first and suffix its label with "(Recommended)". Do not add Other; the client supplies free-form input.`,items:{type:`object`,additionalProperties:!1,properties:{label:{type:`string`,description:`User-facing label, one to five words.`},description:{type:`string`,description:`One sentence explaining impact or trade-off.`}},required:[`label`,`description`]}}},required:[`id`,`header`,`question`,`options`]}}},required:[`questions`],additionalProperties:!1}}function O(e,t){if(e===`basic`)return[`Work as a bounded tool-using agent. Use available tools proactively when they materially improve correctness.`,`Stay within the configured iteration budget, then give the best final answer supported by the gathered results.`].join(` `);let n=t?`If a missing fact or material user choice blocks correct progress, call ${c.requestUserInput} and continue after the answer.`:`If blocked by missing user input, state that limitation plainly in the final response.`,r=e===`deep-human-in-loop`?`For material choices, surface 2-3 concise options with the recommended option first; the UI also permits free-form feedback.`:``;return[`Work autonomously in deep mode. After every tool result, compare the evidence against the user objective and all constraints; continue until gaps are closed.`,`Do not treat a plausible draft as completion. When the work is actually complete, call ${c.complete} with a summary and concrete evidence, then provide the final answer.`,`Put verification summaries and evidence in the self-check tool call. Deliver the current user or assigned task's requested answer or artifact in its requested format, including exact text or JSON. Add verification commentary only when that format permits it.`,n,r,`Never reveal private chain-of-thought. Use concise user-visible commentary for intent, progress, observations, and decisions.`].filter(Boolean).join(` `)}function k(...e){return e.filter(e=>e!==void 0&&e.length>0).join(`
1
+ import{detachedFrozen as e}from"../../primitives/snapshot.js";import{waitForSettlement as t}from"../../async/settlement.js";import{createMessage as n,createUserMessage as r}from"../../message/message.js";import{defineTool as i}from"../tool/definition.js";import{readSpillTool as a}from"../tool/output-budget.js";import{AwaitedEventQueue as o}from"../loop/queue.js";import{UNCHANGED_ANSWER_MARKER as s}from"../loop/control-text.js";import{runTurn as c}from"../loop/run-turn.js";const l=Object.freeze({complete:`submit_result`,requestUserInput:`request_user_input`});function u(n){return{async*[Symbol.asyncIterator](){let r=new o,i=new AbortController,a=P(n.teardownTimeoutMs??3e4,`teardownTimeoutMs`),s=n.signal===void 0?i.signal:AbortSignal.any([n.signal,i.signal]),c=Promise.resolve(),l=d(n,s,t=>{let n=c.then(()=>r.push(e(t)));return c=n.catch(()=>void 0),n}).then(async()=>{await c,r.close()},async e=>{await c,r.fail(e)});try{for(;;){let e=await r.take();if(e.done)break;yield e.value}await l}finally{if(i.abort(Error(`agent event consumer stopped`)),r.close(),!await t(l,a)){let e=Error(`agent producer ignored cancellation for more than ${a}ms`,{cause:i.signal.reason});throw e.code=`AGENT_TEARDOWN_TIMEOUT`,e}}}}}async function d(e,t,r){let i=new Map,o=async e=>{if(e.type===`step-start`&&i.clear(),e.type===`text-delta`){let t=((i.get(e.index)??``)+e.text).replaceAll(s,``),n=Math.min(t.length,s.length-1);for(;n>0&&!`<<deep-mode:answer-unchanged>>`.startsWith(t.slice(-n));)n--;i.set(e.index,n===0?``:t.slice(-n));let a=n===0?t:t.slice(0,-n);a!==``&&await r({...e,text:a});return}if(e.type===`text-end`){let t=i.get(e.index)??``;i.delete(e.index),t!==``&&!e.incomplete&&await r({...e,type:`text-delta`,text:t}),await r({...e,text:e.text.replaceAll(s,``)});return}await r(e)},u=e.mode??`basic`;if(![`basic`,`deep`,`deep-human-in-loop`].includes(u))throw RangeError(`unsupported agent mode "${String(u)}"`);let d=`userInput`in e?e.userInput:void 0;if(u===`deep-human-in-loop`&&(d===void 0||typeof d.request!=`function`))throw TypeError(`deep-human-in-loop mode requires a UserInputBroker`);let S=e.maxTurns??16;if(S!==`auto`&&(!Number.isSafeInteger(S)||S<1))throw RangeError(`maxTurns must be a positive safe integer or 'auto'`);await o({type:`agent-start`,mode:u,maxTurns:S});let E={completion:void 0,userAborted:!1,unverifiedAnswers:0,completionInvalidated:void 0,draftAnswer:void 0,draftSeq:void 0,orphanMarkerNudged:!1,markerCut:!1,markerReply:!1},D=u!==`basic`,O=e.mode===`deep`||e.mode===`deep-human-in-loop`?d:void 0,k=[];e.spillStore!==void 0&&k.push(a(e.spillStore)),D&&k.push(y(E,e.history,e.tools)),O!==void 0&&u!==`basic`&&k.push(b(u,O,E,o,e.accounting));let M=k.length===0?e.tools:C(e.tools,k),N=D?x(e.hooks,e.history,E,S):e.hooks,P={registry:e.registry,config:e.config,history:e.history,...M===void 0?{}:{tools:M},...e.nativeTools===void 0?{}:{nativeTools:e.nativeTools},...e.toolChoice===void 0?{}:{toolChoice:e.toolChoice},...e.imagePolicy===void 0?{}:{imagePolicy:e.imagePolicy},...e.documentPolicy===void 0?{}:{documentPolicy:e.documentPolicy},...e.validateOutput===void 0?{}:{validateOutput:e.validateOutput},...e.outputFormat===void 0?{}:{outputFormat:e.outputFormat},system:j(e.system,A(u,O!==void 0)),...e.interceptors===void 0?{}:{interceptors:w(e.interceptors)},...e.approvals===void 0?{}:{approvals:e.approvals},bounds:{...e.bounds,maxSteps:S},...N===void 0?{}:{hooks:N},signal:t,...e.logger===void 0?{}:{logger:e.logger},commentary:e.commentary??`auto`,teardownTimeoutMs:e.teardownTimeoutMs??3e4,...e.modelTimeoutMs===void 0?{}:{modelTimeoutMs:e.modelTimeoutMs},...e.maxModelRequestBytes===void 0?{}:{maxModelRequestBytes:e.maxModelRequestBytes},...e.maxModelResponseBytes===void 0?{}:{maxModelResponseBytes:e.maxModelResponseBytes},...e.maxModelStreamEvents===void 0?{}:{maxModelStreamEvents:e.maxModelStreamEvents},...e.hookTimeoutMs===void 0?{}:{hookTimeoutMs:e.hookTimeoutMs},...e.hookTeardownTimeoutMs===void 0?{}:{hookTeardownTimeoutMs:e.hookTeardownTimeoutMs},...e.trace===void 0?{}:{trace:e.trace},...e.accounting===void 0?{}:{accounting:e.accounting},...e.spillStore===void 0?{}:{spillStore:e.spillStore},...e.experimentalPrograms===void 0?{}:{experimentalPrograms:e.experimentalPrograms},...e.contextSections===void 0?{}:{contextSections:e.contextSections}},F,I=[],L,R=!1,z=``,B=new Map,V=[],H,U,W,G=!1,K=e.history.entries().length,q,J=!1,Y=async()=>{let e=V;V=[];for(let t of e)await o(t)},X=async()=>{let e=V;V=[];for(let t of e)t.type!==`text-delta`&&t.type!==`text-end`&&await o(t)},Z=async t=>{if(U!==void 0&&(t.type===`assistant-text`||t.type===`assistant-reasoning`)&&t.messageId===U.from){await o({...t,messageId:U.message.id,...t.type===`assistant-text`?{text:t.text.replaceAll(s,``)}:{}});return}if(W===void 0||t.type!==`assistant-text`||t.messageId!==W){if(H!==void 0&&t.type===`assistant-reasoning`&&t.messageId===H.from){await o({...t,messageId:H.message.id});return}if(H!==void 0&&t.type===`assistant-text`&&t.messageId===H.from){if(J)return;J=!0;let e=H.message.content.find(e=>e.type===`text`);await o({...t,messageId:H.message.id,text:e?.type===`text`?e.text:t.text});return}if(t.type===`step-start`&&(K=e.history.entries().length,H=void 0,U=void 0,W=void 0,G=!1,J=!1,E.markerCut=!1,E.markerReply=!1,await Y(),v(E,e.history),R=!0,z=``,B.clear()),R&&(t.type===`text-delta`||t.type===`text-end`)){B.set(t.index,t.type===`text-end`?t.text:(B.get(t.index)??``)+t.text),z=[...B.values()].join(``),V.push(t),!p(z)&&!z.trimStart().startsWith(`<<deep-mode:answer-unchanged>>`)?(R=!1,await Y()):t.type===`text-end`&&t.incomplete&&(E.markerCut=!0);return}if(R&&t.type===`assistant-message`){let n=t.message.content,r=E.draftAnswer,i=f(n),a=i!==void 0&&(i.trim()===`<<deep-mode:answer-unchanged>>`||E.markerCut&&p(i));if(R=!1,a){E.markerReply=!0,E.resolvedMarkerAnswer=r??``,H={from:t.message.id,message:h(r??``,n)},g(e.history,H.message,E.markerCut),G=!0,r===void 0&&(W=t.message.id),await X(),q!==void 0&&await o({type:`assistant-replacement`,fromMessageId:q,message:H.message}),await o({...t,message:H.message});return}if(i?.includes(`<<deep-mode:answer-unchanged>>`)){E.resolvedMarkerAnswer=i.replaceAll(s,``).trim();let r=h(i.replaceAll(s,``).trim(),n);g(e.history,r),H={from:t.message.id,message:r};let a=V.find(e=>e.type===`text-end`)??V.find(e=>e.type===`text-delta`);await X(),(a?.type===`text-end`||a?.type===`text-delta`)&&(await o({type:`text-delta`,trace:a.trace,index:a.index,phase:`final-answer`,text:E.resolvedMarkerAnswer}),await o({type:`text-end`,trace:a.trace,index:a.index,phase:`final-answer`,text:E.resolvedMarkerAnswer})),await o({...t,message:r});return}E.markerCut=!1,await Y()}else if(V.length>0){if(t.type===`turn-end`&&R&&p(z))R=!1,E.markerCut=!0,await X();else if(t.type===`turn-end`||t.type===`tool-call`)R=!1,await Y();else{V.push(t);return}}if(t.type===`assistant-message`&&H===void 0){let r=t.message,i=r.content.flatMap(e=>e.type===`text`?[e.text]:[]).join(``);if(delete E.resolvedMarkerAnswer,i.includes(`<<deep-mode:answer-unchanged>>`)){let i=n({role:`assistant`,source:r.source,content:r.content.map(e=>e.type===`text`?{...e,text:e.text.replaceAll(s,``)}:e)});g(e.history,i),U={from:r.id,message:i},await o({...t,message:i});return}D&&!r.content.some(e=>e.type===`tool-call`)&&i.trim()!==``&&(E.completion!==void 0&&q!==void 0&&await o({type:`assistant-replacement`,fromMessageId:q,message:r}),q=r.id)}if(t.type===`assistant-text`){await o({...t,text:t.text.replaceAll(s,``)});return}await o(t)}};for await(let t of c(P)){if(t.type===`step-start`?(I=[],L=void 0):t.type===`tool-call`?(I.push(t.call.toolName),t.call.toolName!==l.complete&&M?.get(t.call.toolName)?.completionExempt!==!0&&(E.completion!==void 0&&(E.completionInvalidated=`tool`),E.completion=void 0,E.unverifiedAnswers=0)):t.type===`tool-result`&&t.call.toolName===l.complete&&!t.result.isError?t.result.value?.accepted===!0&&(L=T(t.result.value)):t.type===`step-end`&&L!==void 0&&I.filter(e=>e===l.complete).length===1&&I.every(e=>e===l.complete||M?.get(e)?.completionExempt===!0)&&(E.completion=L,E.completionSeq=e.history.entries().length,E.completionInvalidated=void 0),t.type===`turn-end`){R&&V.length>0&&p(z)&&(E.markerCut=!0),F=m(t.outcome,E),F!==t.outcome&&E.draftAnswer!==void 0&&!G&&g(e.history,H?.message??h(F.text),E.markerCut),await Z({...t,outcome:F});continue}await Z(t)}if(F===void 0)throw Error(`runTurn ended without a turn-end event`);v(E,e.history);let Q=(u===`basic`?F.reason.kind===`completed`&&F.text.trim()!==``||F.reason.kind===`concluded-by-tool`:E.completion!==void 0&&!E.userAborted&&(F.reason.kind===`completed`||F.reason.kind===`concluded-by-tool`||F.reason.kind===`budget-exhausted`&&F.reason.forcedFinalAnswer)&&F.text.trim()!==``)&&!_(e.history,K);await o({type:`agent-end`,outcome:{...F,mode:u,completed:Q,...E.completion===void 0?{}:{completion:E.completion}}})}function f(e){let t=e.filter(e=>e.type!==`reasoning`);return t.length>0&&t.every(e=>e.type===`text`)?t.map(e=>e.type===`text`?e.text:``).join(``):void 0}function p(e){let t=e.trim();return t.length===0||s.startsWith(t)}function m(e,t){return e.text.trim()===`<<deep-mode:answer-unchanged>>`&&t.resolvedMarkerAnswer!==void 0?{...e,text:t.resolvedMarkerAnswer}:e.text.trim()===`<<deep-mode:answer-unchanged>>`?{...e,text:t.completion!==void 0&&(t.markerReply||t.markerCut)?t.draftAnswer??``:``}:e.text.includes(`<<deep-mode:answer-unchanged>>`)?{...e,text:e.text.replaceAll(s,``).trim()}:!t.markerReply&&!t.markerCut||!(t.markerCut&&e.text.trim()!==``&&p(e.text))&&e.text.trim()!==`<<deep-mode:answer-unchanged>>`?e:{...e,text:t.draftAnswer??``}}function h(e,t){return n({role:`assistant`,content:t===void 0?[{type:`text`,text:e,phase:`final-answer`}]:[...t.filter(e=>e.type===`reasoning`),{type:`text`,text:e,phase:`final-answer`}],source:{kind:`app`,producer:e===``?`deep-mode-invalid-marker`:`deep-mode-kept-answer`}})}function g(e,t,n=!1){let r=e.entries(),i;for(let e=r.length-1;e>=0;e--){let t=r[e];if(t?.event.kind===`assistant`){i=t;break}}let a=i?.event.kind===`assistant`?i.event.message.content.flatMap(e=>e.type===`text`?[e.text]:[]).join(``):void 0;i!==void 0&&a!==void 0&&(!a.includes(`<<deep-mode:answer-unchanged>>`)&&!(n&&a.trim()!==``&&p(a))||e.append({kind:`assistant`,message:t},{op:`replace`,from:i.seq,to:i.seq}))}function _(e,t){return e.entries().slice(t??0).some(e=>e.event.kind===`user`&&[`user`,`agent-message`,`a2a-message`].includes(e.event.message.source.kind))}function v(e,t){e.completion!==void 0&&_(t,e.completionSeq)&&(e.completion=void 0,e.completionInvalidated=`input`),!(e.draftAnswer===void 0||!_(t,e.draftSeq))&&(e.draftAnswer=void 0,e.draftSeq=void 0)}function y(e,t,n){return i({name:l.complete,description:`Submit the self-check only when the user objective and constraints are fully satisfied. After acceptance, give the user the final answer.`,budgetExempt:!0,parameters:{type:`object`,properties:{summary:{type:`string`,description:`Concise statement of what was completed.`},evidence:{type:`array`,items:{type:`string`},description:`Concrete checks or tool results showing the objective is satisfied.`}},required:[`summary`,`evidence`],additionalProperties:!1},parse:D,execute:r=>{v(e,t);let i=t.messages().findLast(e=>e.role===`assistant`)?.content.filter(e=>e.type===`tool-call`)??[];return i.filter(e=>e.name===l.complete).length!==1||i.some(e=>e.name!==l.complete&&n?.get(e.name)?.completionExempt!==!0)?{accepted:!1,instruction:`Review the tool results, then call submit_result exactly once without substantive sibling tools. This batch has no accepted self-check.`}:{accepted:!0,summary:r.summary,evidence:[...r.evidence],instruction:e.draftAnswer===void 0?`This self-check is accepted for the current run. Now deliver the answer or artifact requested by the current user or assigned task, preserving its requested content and format. For exact text, only JSON, only a number, or another constrained format, return only the requested output. The summary and evidence in this tool result are verification metadata; keep them out of the final answer unless the task requests them. If the task requests a report, provide the substantive findings or changes, supporting evidence or sources, and relevant limitations. Do not merely say the self-check passed or refer to an earlier message. Do not call submit_result again in this run unless you perform new substantive tool work that invalidates this submission. A later user request or worker follow-up starts a new run and needs its own self-check.`:`This self-check is accepted for the current run. You already gave the user a complete answer earlier in this run, before this check. If no user message or delegated task arrived after that answer and it still satisfies every current requirement, reply with exactly ${s} and nothing else. If a user message or delegated task arrived after that answer, give the complete answer to the latest request in full, even if the earlier answer seems correct. If this check found something to correct or add, also give the complete corrected answer in full, as if the earlier one did not exist: never summarize it, point back to it, or say the self-check passed. Do not call submit_result again in this run unless you perform new substantive tool work that invalidates this submission. A later user request or worker follow-up starts a new run and needs its own self-check.`}}})}function b(e,t,n,r,a){return i({name:l.requestUserInput,budgetExempt:!0,description:e===`deep-human-in-loop`?`Ask the user one to three short questions when a material choice or missing fact requires human input, then wait for the response. Provide 2-3 mutually exclusive suggestions; free-form input is added by the client.`:`Ask the user one to three short clarification questions only when blocked, then wait for the response. Provide suggested choices; free-form input is added by the client.`,parameters:k(),parse:O,execute:async({questions:e},i)=>{let o=a?.startOperation(`user-input`,{toolCallId:i.callId,data:{questionCount:e.length}}),s={requestId:i.callId,callId:i.callId,turn:i.turn,step:i.step,questions:e,isBlocking:!0};try{let c=t.request(s,i.signal);await r({type:`user-input-request`,request:s});let l=await c;return await r({type:`user-input-response`,request:s,response:l}),l===`abort`?(n.userAborted=!0,i.concludeTurn(),o!==void 0&&a?.endOperation(o,`aborted`),{aborted:!0}):(n.draftAnswer=void 0,n.draftSeq=void 0,n.completion=void 0,o!==void 0&&a?.endOperation(o,`success`),E(l,e))}catch(e){throw i.signal.aborted&&await r({type:`user-input-response`,request:s,response:`abort`}),o!==void 0&&a?.endOperation(o,i.signal.aborted?`aborted`:`error`,{error:e}),e}}})}function x(e,t,n,i){return{...e,onTurnEnd:async a=>{let o=t.entries().length,c=m(a.outcome,n);if(await e?.onTurnEnd?.(c===a.outcome?a:{...a,outcome:c}),a.outcome.reason.kind===`completed`&&a.canContinue&&n.completion!==void 0&&n.draftAnswer===void 0&&!n.orphanMarkerNudged&&n.markerReply&&a.outcome.text.trim()===`<<deep-mode:answer-unchanged>>`){n.orphanMarkerNudged=!0,t.append({kind:`user`,message:r({source:{kind:`app`,producer:`deep-mode-self-check`},content:[{type:`text`,text:`There is no earlier answer in this run eligible for ${s} to keep. A new user or delegated task after the earlier answer makes it ineligible too. Reply with the answer itself now, in the requested format.`}]})});return}a.outcome.reason.kind!==`completed`||!a.canContinue||i!==`auto`&&a.outcome.steps>=i||n.completion!==void 0||n.userAborted||(n.unverifiedAnswers++,!(n.unverifiedAnswers>=3)&&(a.outcome.text.trim()!==``&&a.outcome.text.trim()!==`<<deep-mode:answer-unchanged>>`&&(n.draftAnswer=a.outcome.text,n.draftSeq=o),t.append({kind:`user`,message:r({source:{kind:`app`,producer:`deep-mode-self-check`},content:[{type:`text`,text:(n.completionInvalidated===void 0?``:n.completionInvalidated===`input`?`Your previously accepted submission is no longer current because a new user request or delegated task arrived afterwards. Review the latest input and call ${l.complete} again when complete; the old instruction not to resubmit no longer applies. `:`Your previously accepted submission is no longer current because you called another substantive tool afterwards. Review the later tool results and call ${l.complete} again when complete; the old instruction not to resubmit no longer applies. `)+`Self-check required: this run has no accepted current self-check. Acceptance recorded in an earlier run does not complete this request or follow-up; an earlier instruction not to resubmit applied only to that earlier run. Compare the current result against the user's objective and every constraint. If anything is missing, continue with tools. If blocked and request_user_input is available, ask the user. Only when the work is actually complete, call ${l.complete}. Keep verification in that tool call and then deliver the current user or assigned task's requested output in its original format. This reminder does not change the task or request a process report. Rephrasing a completion claim without submitting does not satisfy this gate.`}]})})))}}}var S=class{definitions;constructor(e,t){let n=new Map;for(let t of e?.names()??[]){let r=e?.get(t);r!==void 0&&n.set(t,r)}for(let e of t){if(n.has(e.name))throw Error(`tool name "${e.name}" is reserved by the selected agent mode`);n.set(e.name,e)}this.definitions=n}get(e){return this.definitions.get(e)}has(e){return this.definitions.has(e)}names(){return[...this.definitions.keys()]}schemas(){return[...this.definitions.values()].map(({name:e,description:t,parameters:n})=>({name:e,description:t,parameters:structuredClone(n)}))}executionMode(e,t){let n=this.definitions.get(e);if(n===void 0)return`exclusive`;try{return n.isConcurrencySafe?.(t)===!0?`parallel`:`exclusive`}catch{return`exclusive`}}};function C(e,t){return new S(e,t)}function w(e){let t=new Set(Object.values(l));return e.map(e=>({name:e.name,...e.before===void 0?{}:{before:(n,r)=>t.has(n.toolName)?r():e.before(n,r)},...e.around===void 0?{}:{around:(n,r)=>t.has(n.toolName)?r():e.around(n,r)},...e.after===void 0?{}:{after:(n,r,i)=>t.has(n.toolName)?i():e.after(n,r,i)}}))}function T(e){let t=M(e,`submit_result result`);return D({summary:t.summary,evidence:t.evidence})}function E(e,t){let n=new Set(t.map(e=>e.id));for(let t of n){let n=e.answers[t];if(n===void 0||!Array.isArray(n.answers)||n.answers.length===0||n.answers.some(e=>typeof e!=`string`||e.trim().length===0))throw Error(`the user-input broker returned no valid answer for "${t}"`)}for(let t of Object.keys(e.answers))if(!n.has(t))throw Error(`the user-input broker returned an answer for unknown question "${t}"`);return e}function D(e){let t=M(e,`submit_result arguments`);if(typeof t.summary!=`string`||t.summary.trim().length===0)throw Error(`summary must be a non-empty string`);if(!Array.isArray(t.evidence)||t.evidence.some(e=>typeof e!=`string`||e.trim().length===0))throw Error(`evidence must be an array of non-empty strings`);return{summary:t.summary,evidence:t.evidence}}function O(e){let t=M(e,`request_user_input arguments`);if(!Array.isArray(t.questions)||t.questions.length<1||t.questions.length>3)throw Error(`questions must contain one to three items`);let n=new Set,r=t.questions.map((e,t)=>{let r=M(e,`questions[${t}]`),i=N(r.id,`questions[${t}].id`);if(!/^[a-z][a-z0-9_]*$/.test(i))throw Error(`questions[${t}].id must be snake_case`);if(n.has(i))throw Error(`question id "${i}" is duplicated`);n.add(i);let a=N(r.header,`questions[${t}].header`),o=N(r.question,`questions[${t}].question`);if(!Array.isArray(r.options)||r.options.length<2||r.options.length>3)throw Error(`questions[${t}].options must contain two or three choices`);let s=r.options.map((e,n)=>{let r=M(e,`questions[${t}].options[${n}]`);return{label:N(r.label,`questions[${t}].options[${n}].label`),description:N(r.description,`questions[${t}].options[${n}].description`)}});return Object.freeze({id:i,header:a,question:o,options:Object.freeze(s),allowFreeForm:!0})});return{questions:Object.freeze(r)}}function k(){return{type:`object`,properties:{questions:{type:`array`,minItems:1,maxItems:3,description:`Questions to show the user. Prefer one and do not exceed three.`,items:{type:`object`,additionalProperties:!1,properties:{id:{type:`string`,description:`Stable snake_case answer key.`},header:{type:`string`,description:`Short UI label, ideally 12 characters or fewer.`},question:{type:`string`,description:`Single-sentence question.`},options:{type:`array`,minItems:2,maxItems:3,description:`Mutually exclusive choices. Put the recommended choice first and suffix its label with "(Recommended)". Do not add Other; the client supplies free-form input.`,items:{type:`object`,additionalProperties:!1,properties:{label:{type:`string`,description:`User-facing label, one to five words.`},description:{type:`string`,description:`One sentence explaining impact or trade-off.`}},required:[`label`,`description`]}}},required:[`id`,`header`,`question`,`options`]}}},required:[`questions`],additionalProperties:!1}}function A(e,t){if(e===`basic`)return[`Work as a bounded tool-using agent. Use available tools proactively when they materially improve correctness.`,`Stay within the configured iteration budget, then give the best final answer supported by the gathered results.`].join(` `);let n=t?`If a missing fact or material user choice blocks correct progress, call ${l.requestUserInput} and continue after the answer.`:`If blocked by missing user input, state that limitation plainly in the final response.`,r=e===`deep-human-in-loop`?`For material choices, surface 2-3 concise options with the recommended option first; the UI also permits free-form feedback.`:``;return[`Work autonomously in deep mode. After every tool result, compare the evidence against the user objective and all constraints; continue until gaps are closed.`,`Do not treat a plausible draft as completion. When the work is actually complete, call ${l.complete} with a summary and concrete evidence, then provide the final answer.`,`Put verification summaries and evidence in the self-check tool call. Deliver the current user or assigned task's requested answer or artifact in its requested format, including exact text or JSON. Add verification commentary only when that format permits it.`,n,r,`Never reveal private chain-of-thought. Use concise user-visible commentary for intent, progress, observations, and decisions.`].filter(Boolean).join(` `)}function j(...e){return e.filter(e=>e!==void 0&&e.length>0).join(`
2
2
 
3
- `)}function A(e,t){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} must be an object`);return e}function j(e,t){if(typeof e!=`string`||e.trim().length===0)throw Error(`${t} must be a non-empty string`);return e}function M(e,t){if(!Number.isFinite(e)||e<=0)throw RangeError(`${t} must be a positive finite number`);return e}export{c as AGENT_CONTROL_TOOLS,l as UNCHANGED_ANSWER_MARKER,u as runAgent};
3
+ `)}function M(e,t){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} must be an object`);return e}function N(e,t){if(typeof e!=`string`||e.trim().length===0)throw Error(`${t} must be a non-empty string`);return e}function P(e,t){if(!Number.isFinite(e)||e<=0)throw RangeError(`${t} must be a positive finite number`);return e}export{l as AGENT_CONTROL_TOOLS,s as UNCHANGED_ANSWER_MARKER,u as runAgent};
4
4
  //# sourceMappingURL=run-agent.js.map