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

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 (107) hide show
  1. package/README.md +13 -1
  2. package/dist/agent/define/definition.d.ts +1 -1
  3. package/dist/agent/define/definition.js +1 -1
  4. package/dist/agent/define/definition.js.map +1 -1
  5. package/dist/agent/define/session/types.d.ts +6 -0
  6. package/dist/agent/define/session/types.d.ts.map +1 -1
  7. package/dist/agent/define/session.d.ts +39 -2
  8. package/dist/agent/define/session.d.ts.map +1 -1
  9. package/dist/agent/define/session.js +1 -1
  10. package/dist/agent/define/session.js.map +1 -1
  11. package/dist/agent/loop/admission.js +2 -0
  12. package/dist/agent/loop/admission.js.map +1 -0
  13. package/dist/agent/loop/events.d.ts +4 -0
  14. package/dist/agent/loop/events.d.ts.map +1 -1
  15. package/dist/agent/loop/program.js +2 -0
  16. package/dist/agent/loop/program.js.map +1 -0
  17. package/dist/agent/loop/run-turn.d.ts.map +1 -1
  18. package/dist/agent/loop/run-turn.js +1 -1
  19. package/dist/agent/loop/run-turn.js.map +1 -1
  20. package/dist/agent/loop/schedule.d.ts.map +1 -1
  21. package/dist/agent/loop/schedule.js +2 -2
  22. package/dist/agent/loop/schedule.js.map +1 -1
  23. package/dist/agent/loop/tool-call-support.js +2 -0
  24. package/dist/agent/loop/tool-call-support.js.map +1 -0
  25. package/dist/agent/loop/turn/hooks.js +1 -1
  26. package/dist/agent/loop/turn/hooks.js.map +1 -1
  27. package/dist/agent/loop/turn/model-request-boundary.js +2 -0
  28. package/dist/agent/loop/turn/model-request-boundary.js.map +1 -0
  29. package/dist/agent/loop/turn/model-round.js +1 -1
  30. package/dist/agent/loop/turn/model-round.js.map +1 -1
  31. package/dist/agent/loop/turn/step-projection.js +2 -0
  32. package/dist/agent/loop/turn/step-projection.js.map +1 -0
  33. package/dist/agent/loop/turn/types.d.ts +6 -0
  34. package/dist/agent/loop/turn/types.d.ts.map +1 -1
  35. package/dist/agent/memory/context-optimizer.d.ts +61 -0
  36. package/dist/agent/memory/context-optimizer.d.ts.map +1 -0
  37. package/dist/agent/memory/context-optimizer.js +4 -0
  38. package/dist/agent/memory/context-optimizer.js.map +1 -0
  39. package/dist/agent/memory/memory.js +1 -1
  40. package/dist/agent/memory/memory.js.map +1 -1
  41. package/dist/agent/mode/run-agent.d.ts +15 -1
  42. package/dist/agent/mode/run-agent.d.ts.map +1 -1
  43. package/dist/agent/mode/run-agent.js +2 -2
  44. package/dist/agent/mode/run-agent.js.map +1 -1
  45. package/dist/agent/skill/provider/snapshot.js +1 -1
  46. package/dist/agent/team/contracts.d.ts +5 -0
  47. package/dist/agent/team/contracts.d.ts.map +1 -1
  48. package/dist/agent/team/managed.d.ts +33 -64
  49. package/dist/agent/team/managed.d.ts.map +1 -1
  50. package/dist/agent/team/managed.js +6 -3
  51. package/dist/agent/team/managed.js.map +1 -1
  52. package/dist/agent/team/team.d.ts +2 -0
  53. package/dist/agent/team/team.d.ts.map +1 -1
  54. package/dist/agent/team/team.js +1 -1
  55. package/dist/agent/team/team.js.map +1 -1
  56. package/dist/agent/team/types.d.ts +1 -0
  57. package/dist/agent/team/types.d.ts.map +1 -1
  58. package/dist/agent/tool/action-fusion.d.ts +30 -0
  59. package/dist/agent/tool/action-fusion.d.ts.map +1 -0
  60. package/dist/agent/tool/action-fusion.js +2 -0
  61. package/dist/agent/tool/action-fusion.js.map +1 -0
  62. package/dist/agent/tool/capture.js +1 -1
  63. package/dist/agent/tool/capture.js.map +1 -1
  64. package/dist/agent/tool/definition.d.ts +8 -0
  65. package/dist/agent/tool/definition.d.ts.map +1 -1
  66. package/dist/agent/tool/definition.js.map +1 -1
  67. package/dist/agent/tool/evidence-reducer.d.ts +41 -0
  68. package/dist/agent/tool/evidence-reducer.d.ts.map +1 -0
  69. package/dist/agent/tool/evidence-reducer.js +7 -0
  70. package/dist/agent/tool/evidence-reducer.js.map +1 -0
  71. package/dist/agent/tool/nested.d.ts +117 -0
  72. package/dist/agent/tool/nested.d.ts.map +1 -0
  73. package/dist/agent/tool/nested.js +2 -0
  74. package/dist/agent/tool/nested.js.map +1 -0
  75. package/dist/agent/tool/output-budget.d.ts.map +1 -1
  76. package/dist/agent/tool/output-budget.js +2 -2
  77. package/dist/agent/tool/output-budget.js.map +1 -1
  78. package/dist/agent/tool/output-schema.js +2 -0
  79. package/dist/agent/tool/output-schema.js.map +1 -0
  80. package/dist/agent/tool/pipeline.d.ts +7 -0
  81. package/dist/agent/tool/pipeline.d.ts.map +1 -1
  82. package/dist/agent/tool/pipeline.js +2 -2
  83. package/dist/agent/tool/pipeline.js.map +1 -1
  84. package/dist/agent/tool/program-results.js +2 -0
  85. package/dist/agent/tool/program-results.js.map +1 -0
  86. package/dist/agent.d.ts +6 -2
  87. package/dist/agent.js +1 -1
  88. package/dist/composition/agent/definition.js +1 -1
  89. package/dist/composition/agent/options.js +1 -1
  90. package/dist/composition/agent/options.js.map +1 -1
  91. package/dist/composition/agent/session.js +1 -1
  92. package/dist/composition/agent/session.js.map +1 -1
  93. package/dist/composition/agent/types.d.ts +6 -0
  94. package/dist/composition/agent/types.d.ts.map +1 -1
  95. package/dist/composition/tool-source/snapshot.js +1 -1
  96. package/dist/index.d.ts +2 -1
  97. package/dist/index.js +1 -1
  98. package/dist/memory.d.ts +2 -1
  99. package/dist/memory.js +1 -1
  100. package/dist/observability/bus.js +1 -1
  101. package/dist/primitives/version.d.ts +1 -1
  102. package/dist/primitives/version.js +1 -1
  103. package/dist/primitives/version.js.map +1 -1
  104. package/dist/runtime/registry.js +1 -1
  105. package/dist/tools.d.ts +4 -1
  106. package/dist/tools.js +1 -1
  107. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import{detachedFrozen as e}from"../../primitives/snapshot.js";import{waitForSettlement as t}from"../../async/settlement.js";import{createUserMessage as n}from"../../message/message.js";import{defineTool as r}from"../tool/definition.js";import{AwaitedEventQueue as i}from"../loop/queue.js";import{readSpillTool as a}from"../tool/output-budget.js";import{runTurn as o}from"../loop/run-turn.js";const s=Object.freeze({complete:`submit_result`,requestUserInput:`request_user_input`});function c(n){return{async*[Symbol.asyncIterator](){let r=new i,a=new AbortController,o=T(n.teardownTimeoutMs??3e4,`teardownTimeoutMs`),s=n.signal===void 0?a.signal:AbortSignal.any([n.signal,a.signal]),c=Promise.resolve(),u=l(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 u}finally{if(a.abort(Error(`agent event consumer stopped`)),r.close(),!await t(u,o)){let e=Error(`agent producer ignored cancellation for more than ${o}ms`,{cause:a.signal.reason});throw e.code=`AGENT_TEARDOWN_TIMEOUT`,e}}}}}async function l(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 c=e.maxTurns??16;if(c!==`auto`&&(!Number.isSafeInteger(c)||c<1))throw RangeError(`maxTurns must be a positive safe integer or 'auto'`);await n({type:`agent-start`,mode:r,maxTurns:c});let l={completion:void 0,userAborted:!1,unverifiedAnswers:0,completionInvalidated:!1},p=r!==`basic`,_=e.mode===`deep`||e.mode===`deep-human-in-loop`?i:void 0,v=[];e.spillStore!==void 0&&v.push(a(e.spillStore)),p&&v.push(u()),_!==void 0&&r!==`basic`&&v.push(d(r,_,l,n,e.accounting));let y=v.length===0?e.tools:m(e.tools,v),b=p?f(e.hooks,e.history,l,c):e.hooks,C={registry:e.registry,config:e.config,history:e.history,...y===void 0?{}:{tools:y},...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:S(e.system,x(r,_!==void 0)),...e.interceptors===void 0?{}:{interceptors:h(e.interceptors)},...e.approvals===void 0?{}:{approvals:e.approvals},bounds:{...e.bounds,maxSteps:c},...b===void 0?{}:{hooks:b},signal:t,...e.logger===void 0?{}:{logger:e.logger},commentary:e.commentary??`concise`,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.contextSections===void 0?{}:{contextSections:e.contextSections}},w,T=[],E;for await(let e of o(C))e.type===`step-start`?(T=[],E=void 0):e.type===`tool-call`?(T.push(e.call.toolName),e.call.toolName!==s.complete&&y?.get(e.call.toolName)?.completionExempt!==!0&&(l.completion!==void 0&&(l.completionInvalidated=!0),l.completion=void 0,l.unverifiedAnswers=0)):e.type===`tool-result`&&e.call.toolName===s.complete&&!e.result.isError?E=g(e.result.value):e.type===`step-end`&&E!==void 0&&T.filter(e=>e===s.complete).length===1&&T.every(e=>e===s.complete||y?.get(e)?.completionExempt===!0)&&(l.completion=E,l.completionInvalidated=!1),e.type===`turn-end`&&(w=e.outcome),await n(e);if(w===void 0)throw Error(`runTurn ended without a turn-end event`);let D=r===`basic`?w.reason.kind===`completed`||w.reason.kind===`concluded-by-tool`:l.completion!==void 0&&!l.userAborted&&(w.reason.kind===`completed`||w.reason.kind===`concluded-by-tool`||w.reason.kind===`budget-exhausted`&&w.reason.forcedFinalAnswer)&&w.text.trim()!==``;await n({type:`agent-end`,outcome:{...w,mode:r,completed:D,...l.completion===void 0?{}:{completion:l.completion}}})}function u(){return r({name:s.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:v,execute:e=>({accepted:!0,summary:e.summary,evidence:[...e.evidence],instruction:`This self-check is accepted for the current run. Now provide the substantive final report itself: findings or changes, evidence or sources, checks performed, and remaining 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.`})})}function d(e,t,n,i,a){return r({name:s.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:b(),parse:y,execute:async({questions:e},r)=>{let o=a?.startOperation(`user-input`,{toolCallId:r.callId,data:{questionCount:e.length}}),s={requestId:r.callId,callId:r.callId,turn:r.turn,step:r.step,questions:e,isBlocking:!0};try{let c=t.request(s,r.signal);await i({type:`user-input-request`,request:s});let l=await c;return await i({type:`user-input-response`,request:s,response:l}),l===`abort`?(n.userAborted=!0,r.concludeTurn(),o!==void 0&&a?.endOperation(o,`aborted`),{aborted:!0}):(o!==void 0&&a?.endOperation(o,`success`),_(l,e))}catch(e){throw o!==void 0&&a?.endOperation(o,r.signal.aborted?`aborted`:`error`,{error:e}),e}}})}function f(e,t,r,i){return{...e,onTurnEnd:async a=>{await e?.onTurnEnd?.(a),!(a.outcome.reason.kind!==`completed`||i!==`auto`&&a.outcome.steps>=i||r.completion!==void 0||r.userAborted)&&(r.unverifiedAnswers++,!(r.unverifiedAnswers>=3)&&t.append({kind:`user`,message:n({source:{kind:`app`,producer:`deep-mode-self-check`},content:[{type:`text`,text:(r.completionInvalidated?`Your previously accepted submission is no longer current because you called another substantive tool afterwards. Review the later tool results and call ${s.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 ${s.complete}. Rephrasing a completion claim without submitting does not satisfy this gate.`}]})}))}}}var p=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 m(e,t){return new p(e,t)}function h(e){let t=new Set(Object.values(s));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 g(e){let t=C(e,`submit_result result`);return v({summary:t.summary,evidence:t.evidence})}function _(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 v(e){let t=C(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 y(e){let t=C(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=C(e,`questions[${t}]`),i=w(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=w(r.header,`questions[${t}].header`),o=w(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=C(e,`questions[${t}].options[${n}]`);return{label:w(r.label,`questions[${t}].options[${n}].label`),description:w(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 b(){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 x(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 ${s.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 ${s.complete} with a summary and concrete evidence, then provide the final answer.`,n,r,`Never reveal private chain-of-thought. Use concise user-visible commentary for intent, progress, observations, and decisions.`].filter(Boolean).join(` `)}function S(...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{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(`
2
2
 
3
- `)}function C(e,t){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} must be an object`);return e}function w(e,t){if(typeof e!=`string`||e.trim().length===0)throw Error(`${t} must be a non-empty string`);return e}function T(e,t){if(!Number.isFinite(e)||e<=0)throw RangeError(`${t} must be a positive finite number`);return e}export{s as AGENT_CONTROL_TOOLS,c as runAgent};
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};
4
4
  //# sourceMappingURL=run-agent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-agent.js","names":[],"sources":["../../../src/agent/mode/run-agent.ts"],"sourcesContent":["/** High-level agent modes built on the provider-neutral bounded tool loop. */\n\nimport { createUserMessage } from '../../message/index.ts'\nimport type { CallConfig } from '../../contract/index.ts'\nimport type { JsonObject } from '../../primitives/index.ts'\nimport { detachedFrozen } from '../../primitives/index.ts'\nimport { runTurn, type RunTurnOptions } from '../loop/run-turn.ts'\nimport { AwaitedEventQueue } from '../loop/queue.ts'\nimport type { AgentEvent, TurnBounds, TurnHooks, TurnOutcome } from '../loop/types.ts'\nimport { defineTool, type ToolDefinition, type ToolExecutionMode } from '../tool/definition.ts'\nimport { readSpillTool } from '../tool/output-budget.ts'\nimport type { ToolInterceptor } from '../tool/pipeline.ts'\nimport type { ToolCatalog } from '../tool/registry.ts'\nimport { waitForSettlement } from '../../async/index.ts'\nimport type {\n UserInputBroker, UserInputQuestion, UserInputRequest, UserInputResponse,\n} from './user-input.ts'\n\nexport const AGENT_CONTROL_TOOLS = Object.freeze({\n complete: 'submit_result',\n requestUserInput: 'request_user_input',\n} as const)\n\n/** Default high-level runtime requested by this SDK; `runTurn` remains provider-neutral. */\nexport type AgentMode = 'basic' | 'deep' | 'deep-human-in-loop'\n\ninterface AgentRunCommon extends Omit<RunTurnOptions, 'bounds' | 'commentary' | 'config' | 'hooks' | 'system' | 'tools'> {\n /** Explicit low-level model binding; composition users can select a configured provider default instead. */\n readonly config: CallConfig\n readonly tools?: ToolCatalog\n readonly system?: string\n /** Maximum normal model iterations. A forced final answer may use one extra request. */\n /** Model steps per prompt; 'auto' keeps completion and resource guards only. */\n readonly maxTurns?: number | 'auto'\n readonly bounds?: Omit<Partial<TurnBounds>, 'maxSteps'>\n readonly commentary?: RunTurnOptions['commentary']\n readonly hooks?: TurnHooks\n}\n\nexport interface BasicAgentOptions extends AgentRunCommon {\n readonly mode?: 'basic'\n}\n\nexport interface DeepAgentOptions extends AgentRunCommon {\n readonly mode: 'deep'\n /** Optional in deep mode: expose a blocking clarification tool when configured. */\n readonly userInput?: UserInputBroker\n}\n\nexport interface HumanInLoopAgentOptions extends AgentRunCommon {\n readonly mode: 'deep-human-in-loop'\n /** Required in HIL mode: the tool call remains parked until this broker answers. */\n readonly userInput: UserInputBroker\n}\n\nexport type RunAgentOptions = BasicAgentOptions | DeepAgentOptions | HumanInLoopAgentOptions\n\nexport interface CompletionSubmission {\n readonly summary: string\n readonly evidence: readonly string[]\n}\n\nexport interface AgentRunOutcome extends TurnOutcome {\n readonly mode: AgentMode\n /** Deep modes are complete only after the model explicitly submits its self-check. */\n readonly completed: boolean\n readonly completion?: CompletionSubmission\n}\n\ninterface AgentModeStartEvent {\n readonly type: 'agent-start'\n readonly mode: AgentMode\n readonly maxTurns: number | 'auto'\n}\ninterface UserInputRequestEvent {\n readonly type: 'user-input-request'\n readonly request: UserInputRequest\n}\ninterface UserInputResponseEvent {\n readonly type: 'user-input-response'\n readonly request: UserInputRequest\n readonly response: UserInputResponse | 'abort'\n}\ninterface AgentModeEndEvent {\n readonly type: 'agent-end'\n readonly outcome: AgentRunOutcome\n}\n\nexport type AgentRunEvent = AgentEvent\n | AgentModeStartEvent\n | UserInputRequestEvent\n | UserInputResponseEvent\n | AgentModeEndEvent\n\ninterface DeepState {\n completion: CompletionSubmission | undefined\n userAborted: boolean\n /** Answers without intervening substantive tool work or an accepted check. */\n unverifiedAnswers: number\n completionInvalidated: boolean\n}\n\nconst DEFAULT_MAX_TURNS = 16\n\n/** Changing the wording of an unsubmitted conclusion is not execution progress. */\nconst UNVERIFIED_ANSWER_LIMIT = 3\n\n/**\n * Run an agent in basic, self-checking deep, or deep human-in-loop mode.\n *\n * The low-level `turn-*`, trace, commentary, reasoning-summary, and tool events are\n * forwarded unchanged. High-level `agent-*` and `user-input-*` events make GUI\n * orchestration possible without parsing assistant prose.\n */\nexport function runAgent(options: RunAgentOptions): AsyncIterable<AgentRunEvent> {\n return {\n async * [Symbol.asyncIterator]() {\n const queue = new AwaitedEventQueue<AgentRunEvent>()\n const consumer = new AbortController()\n const teardownTimeoutMs = positiveFinite(options.teardownTimeoutMs ?? 30_000, 'teardownTimeoutMs')\n const signal = options.signal === undefined\n ? consumer.signal\n : AbortSignal.any([options.signal, consumer.signal])\n let tail = Promise.resolve()\n const emit = (event: AgentRunEvent): Promise<void> => {\n const next = tail.then(() => queue.push(detachedFrozen(event)))\n tail = next.catch(() => undefined)\n return next\n }\n const task = driveAgent(options, signal, emit)\n .then(async () => { await tail; queue.close() }, async error => { await tail; queue.fail(error) })\n\n try {\n while (true) {\n const item = await queue.take()\n if (item.done) break\n yield item.value\n }\n await task\n } finally {\n consumer.abort(new Error('agent event consumer stopped'))\n queue.close()\n if (!await waitForSettlement(task, teardownTimeoutMs)) {\n const error = new Error(\n `agent producer ignored cancellation for more than ${teardownTimeoutMs}ms`,\n { cause: consumer.signal.reason },\n ) as Error & { code: string }\n error.code = 'AGENT_TEARDOWN_TIMEOUT'\n throw error\n }\n }\n },\n }\n}\n\nasync function driveAgent(\n options: RunAgentOptions,\n signal: AbortSignal,\n emit: (event: AgentRunEvent) => Promise<void>,\n): Promise<void> {\n const mode: AgentMode = options.mode ?? 'basic'\n if (!['basic', 'deep', 'deep-human-in-loop'].includes(mode)) {\n throw new RangeError(`unsupported agent mode \"${String(mode)}\"`)\n }\n const configuredUserInput = 'userInput' in options ? options.userInput : undefined\n if (mode === 'deep-human-in-loop'\n && (configuredUserInput === undefined || typeof configuredUserInput.request !== 'function')) {\n throw new TypeError('deep-human-in-loop mode requires a UserInputBroker')\n }\n const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS\n if (maxTurns !== 'auto' && (!Number.isSafeInteger(maxTurns) || maxTurns < 1)) {\n throw new RangeError(\"maxTurns must be a positive safe integer or 'auto'\")\n }\n await emit({ type: 'agent-start', mode, maxTurns })\n\n const state: DeepState = {\n completion: undefined, userAborted: false, unverifiedAnswers: 0, completionInvalidated: false,\n }\n const deep = mode !== 'basic'\n const broker = options.mode === 'deep' || options.mode === 'deep-human-in-loop'\n ? configuredUserInput\n : undefined\n const internalTools: ToolDefinition[] = []\n // Spilling without a way to read the spill back would be worse than cutting\n // the output: the model would be told the rest exists and given no way in.\n if (options.spillStore !== undefined) {\n internalTools.push(readSpillTool(options.spillStore) as ToolDefinition)\n }\n if (deep) internalTools.push(completionTool())\n if (broker !== undefined && mode !== 'basic') {\n internalTools.push(userInputTool(mode, broker, state, emit, options.accounting))\n }\n const tools = internalTools.length === 0 ? options.tools : combineTools(options.tools, internalTools)\n const hooks = deep ? deepHooks(options.hooks, options.history, state, maxTurns) : options.hooks\n const turnOptions: RunTurnOptions = {\n registry: options.registry,\n config: options.config,\n history: options.history,\n ...tools === undefined ? {} : { tools },\n ...options.nativeTools === undefined ? {} : { nativeTools: options.nativeTools },\n ...options.toolChoice === undefined ? {} : { toolChoice: options.toolChoice },\n ...options.imagePolicy === undefined ? {} : { imagePolicy: options.imagePolicy },\n ...options.documentPolicy === undefined ? {} : { documentPolicy: options.documentPolicy },\n ...(options.validateOutput === undefined ? {} : { validateOutput: options.validateOutput }),\n ...options.outputFormat === undefined ? {} : { outputFormat: options.outputFormat },\n system: joinSystem(options.system, modeSystem(mode, broker !== undefined)),\n ...options.interceptors === undefined ? {} : { interceptors: shieldControlTools(options.interceptors) },\n ...options.approvals === undefined ? {} : { approvals: options.approvals },\n bounds: { ...options.bounds, maxSteps: maxTurns },\n ...hooks === undefined ? {} : { hooks },\n signal,\n ...options.logger === undefined ? {} : { logger: options.logger },\n commentary: options.commentary ?? 'concise',\n teardownTimeoutMs: options.teardownTimeoutMs ?? 30_000,\n ...options.modelTimeoutMs === undefined ? {} : { modelTimeoutMs: options.modelTimeoutMs },\n ...options.maxModelRequestBytes === undefined ? {} : { maxModelRequestBytes: options.maxModelRequestBytes },\n ...options.maxModelResponseBytes === undefined ? {} : { maxModelResponseBytes: options.maxModelResponseBytes },\n ...options.maxModelStreamEvents === undefined ? {} : { maxModelStreamEvents: options.maxModelStreamEvents },\n ...options.hookTimeoutMs === undefined ? {} : { hookTimeoutMs: options.hookTimeoutMs },\n ...options.hookTeardownTimeoutMs === undefined ? {} : { hookTeardownTimeoutMs: options.hookTeardownTimeoutMs },\n ...options.trace === undefined ? {} : { trace: options.trace },\n ...options.accounting === undefined ? {} : { accounting: options.accounting },\n ...options.spillStore === undefined ? {} : { spillStore: options.spillStore },\n ...options.contextSections === undefined ? {} : { contextSections: options.contextSections },\n }\n\n let terminal: TurnOutcome | undefined\n let stepCalls: string[] = []\n let completionCandidate: CompletionSubmission | undefined\n for await (const event of runTurn(turnOptions)) {\n if (event.type === 'step-start') {\n stepCalls = []\n completionCandidate = undefined\n } else if (event.type === 'tool-call') {\n stepCalls.push(event.call.toolName)\n // Work performed after an accepted submission invalidates that submission;\n // the new result has not yet passed the completion gate.\n if (event.call.toolName !== AGENT_CONTROL_TOOLS.complete\n && tools?.get(event.call.toolName)?.completionExempt !== true) {\n if (state.completion !== undefined) state.completionInvalidated = true\n state.completion = undefined\n state.unverifiedAnswers = 0\n }\n } else if (event.type === 'tool-result'\n && event.call.toolName === AGENT_CONTROL_TOOLS.complete\n && !event.result.isError) {\n completionCandidate = completionFromResult(event.result.value)\n } else if (event.type === 'step-end'\n && completionCandidate !== undefined\n && stepCalls.filter(name => name === AGENT_CONTROL_TOOLS.complete).length === 1\n && stepCalls.every(name => name === AGENT_CONTROL_TOOLS.complete || tools?.get(name)?.completionExempt === true)) {\n // A completion submission cannot share a batch with work whose results the\n // model had not seen when it claimed success.\n state.completion = completionCandidate\n state.completionInvalidated = false\n }\n if (event.type === 'turn-end') terminal = event.outcome\n await emit(event)\n }\n if (terminal === undefined) throw new Error('runTurn ended without a turn-end event')\n const completed = mode === 'basic'\n ? terminal.reason.kind === 'completed' || terminal.reason.kind === 'concluded-by-tool'\n : state.completion !== undefined && !state.userAborted\n && (terminal.reason.kind === 'completed'\n || terminal.reason.kind === 'concluded-by-tool'\n || (terminal.reason.kind === 'budget-exhausted' && terminal.reason.forcedFinalAnswer))\n && terminal.text.trim() !== ''\n const outcome: AgentRunOutcome = {\n ...terminal,\n mode,\n completed,\n ...state.completion === undefined ? {} : { completion: state.completion },\n }\n await emit({ type: 'agent-end', outcome })\n}\n\nfunction completionTool(): ToolDefinition<CompletionSubmission> {\n return defineTool({\n name: AGENT_CONTROL_TOOLS.complete,\n description: 'Submit the self-check only when the user objective and constraints are fully satisfied. After acceptance, give the user the final answer.',\n // The one call that ENDS a deep run. A budget that can block it can leave\n // the run with no way to complete at all.\n budgetExempt: true,\n parameters: {\n type: 'object',\n properties: {\n summary: { type: 'string', description: 'Concise statement of what was completed.' },\n evidence: {\n type: 'array', items: { type: 'string' },\n description: 'Concrete checks or tool results showing the objective is satisfied.',\n },\n },\n required: ['summary', 'evidence'],\n additionalProperties: false,\n },\n parse: parseCompletion,\n execute: submission => ({\n accepted: true,\n summary: submission.summary,\n evidence: [...submission.evidence],\n instruction: 'This self-check is accepted for the current run. Now provide the substantive final report itself: findings or changes, evidence or sources, checks performed, and remaining 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.',\n }),\n })\n}\n\nfunction userInputTool(\n mode: Exclude<AgentMode, 'basic'>,\n broker: UserInputBroker,\n state: DeepState,\n emit: (event: AgentRunEvent) => Promise<void>,\n accounting?: RunTurnOptions['accounting'],\n): ToolDefinition<{ readonly questions: readonly UserInputQuestion[] }> {\n return defineTool({\n name: AGENT_CONTROL_TOOLS.requestUserInput,\n // Asking the user is how a blocked run gets unblocked; a spent budget must\n // not be the reason the question is never asked.\n budgetExempt: true,\n description: mode === 'deep-human-in-loop'\n ? '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.'\n : '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.',\n parameters: requestUserInputSchema(),\n parse: parseUserInput,\n execute: async ({ questions }, ctx) => {\n const operation = accounting?.startOperation('user-input', {\n toolCallId: ctx.callId,\n data: { questionCount: questions.length },\n })\n const request: UserInputRequest = {\n requestId: ctx.callId, callId: ctx.callId, turn: ctx.turn, step: ctx.step,\n questions, isBlocking: true,\n }\n // Start the broker first: an event consumer may resolve synchronously, and\n // the waiter must already exist when the request event becomes visible.\n try {\n const pending = broker.request(request, ctx.signal)\n await emit({ type: 'user-input-request', request })\n const response = await pending\n await emit({ type: 'user-input-response', request, response })\n if (response === 'abort') {\n state.userAborted = true\n ctx.concludeTurn()\n if (operation !== undefined) accounting?.endOperation(operation, 'aborted')\n return { aborted: true }\n }\n if (operation !== undefined) accounting?.endOperation(operation, 'success')\n return validateUserResponse(response, questions) as unknown as JsonObject\n } catch (error) {\n if (operation !== undefined) accounting?.endOperation(\n operation,\n ctx.signal.aborted ? 'aborted' : 'error',\n { error },\n )\n throw error\n }\n },\n })\n}\n\nfunction deepHooks(\n userHooks: TurnHooks | undefined,\n history: RunAgentOptions['history'],\n state: DeepState,\n maxTurns: number | 'auto',\n): TurnHooks {\n return {\n ...userHooks,\n onTurnEnd: async context => {\n await userHooks?.onTurnEnd?.(context)\n if (context.outcome.reason.kind !== 'completed'\n || (maxTurns !== 'auto' && context.outcome.steps >= maxTurns)\n || state.completion !== undefined\n || state.userAborted) return\n // Auto must not pay indefinitely for paraphrases of \"already checked\".\n // Substantive tool work resets this allowance; progress-only updates do not.\n state.unverifiedAnswers++\n if (state.unverifiedAnswers >= UNVERIFIED_ANSWER_LIMIT) return\n history.append({ kind: 'user', message: createUserMessage({\n source: { kind: 'app', producer: 'deep-mode-self-check' },\n content: [{\n type: 'text',\n text: (state.completionInvalidated\n ? `Your previously accepted submission is no longer current because you called another substantive tool afterwards. Review the later tool results and call ${AGENT_CONTROL_TOOLS.complete} again when complete; the old instruction not to resubmit no longer applies. `\n : '')\n + `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 ${AGENT_CONTROL_TOOLS.complete}. Rephrasing a completion claim without submitting does not satisfy this gate.`,\n }],\n }) })\n },\n }\n}\n\nclass CombinedToolCatalog implements ToolCatalog {\n private readonly definitions: ReadonlyMap<string, ToolDefinition>\n constructor(base: ToolCatalog | undefined, additions: readonly ToolDefinition[]) {\n const definitions = new Map<string, ToolDefinition>()\n for (const name of base?.names() ?? []) {\n const definition = base?.get(name)\n if (definition !== undefined) definitions.set(name, definition)\n }\n for (const definition of additions) {\n if (definitions.has(definition.name)) {\n throw new Error(`tool name \"${definition.name}\" is reserved by the selected agent mode`)\n }\n definitions.set(definition.name, definition)\n }\n this.definitions = definitions\n }\n get(name: string): ToolDefinition | undefined { return this.definitions.get(name) }\n has(name: string): boolean { return this.definitions.has(name) }\n names(): readonly string[] { return [...this.definitions.keys()] }\n schemas() {\n return [...this.definitions.values()].map(({ name, description, parameters }) => ({\n name, description, parameters: structuredClone(parameters),\n }))\n }\n executionMode(name: string, args: unknown): ToolExecutionMode {\n const definition = this.definitions.get(name)\n if (definition === undefined) return 'exclusive'\n try { return definition.isConcurrencySafe?.(args) === true ? 'parallel' : 'exclusive' }\n catch { return 'exclusive' }\n }\n}\n\nfunction combineTools(base: ToolCatalog | undefined, additions: readonly ToolDefinition[]): ToolCatalog {\n return new CombinedToolCatalog(base, additions)\n}\n\n/** Control tools are host protocol, not application capabilities subject to tool policy. */\nfunction shieldControlTools(interceptors: readonly ToolInterceptor[]): readonly ToolInterceptor[] {\n const reserved = new Set<string>(Object.values(AGENT_CONTROL_TOOLS))\n return interceptors.map(interceptor => ({\n name: interceptor.name,\n ...interceptor.before === undefined ? {} : {\n before: (call, next) => reserved.has(call.toolName) ? next() : interceptor.before!(call, next),\n },\n ...interceptor.around === undefined ? {} : {\n around: (call, next) => reserved.has(call.toolName) ? next() : interceptor.around!(call, next),\n },\n ...interceptor.after === undefined ? {} : {\n after: (call, result, next) => reserved.has(call.toolName) ? next() : interceptor.after!(call, result, next),\n },\n }))\n}\n\nfunction completionFromResult(value: unknown): CompletionSubmission {\n const result = record(value, 'submit_result result')\n return parseCompletion({ summary: result.summary, evidence: result.evidence })\n}\n\nfunction validateUserResponse(\n response: UserInputResponse,\n questions: readonly UserInputQuestion[],\n): UserInputResponse {\n const expected = new Set(questions.map(question => question.id))\n for (const id of expected) {\n const answer = response.answers[id]\n if (answer === undefined || !Array.isArray(answer.answers) || answer.answers.length === 0\n || answer.answers.some(value => typeof value !== 'string' || value.trim().length === 0)) {\n throw new Error(`the user-input broker returned no valid answer for \"${id}\"`)\n }\n }\n for (const id of Object.keys(response.answers)) {\n if (!expected.has(id)) throw new Error(`the user-input broker returned an answer for unknown question \"${id}\"`)\n }\n return response\n}\n\nfunction parseCompletion(raw: unknown): CompletionSubmission {\n const value = record(raw, 'submit_result arguments')\n if (typeof value.summary !== 'string' || value.summary.trim().length === 0) {\n throw new Error('summary must be a non-empty string')\n }\n if (!Array.isArray(value.evidence) || value.evidence.some(item => typeof item !== 'string' || item.trim().length === 0)) {\n throw new Error('evidence must be an array of non-empty strings')\n }\n return { summary: value.summary, evidence: value.evidence as string[] }\n}\n\nfunction parseUserInput(raw: unknown): { readonly questions: readonly UserInputQuestion[] } {\n const value = record(raw, 'request_user_input arguments')\n if (!Array.isArray(value.questions) || value.questions.length < 1 || value.questions.length > 3) {\n throw new Error('questions must contain one to three items')\n }\n const ids = new Set<string>()\n const questions = value.questions.map((rawQuestion, index) => {\n const question = record(rawQuestion, `questions[${index}]`)\n const id = requiredString(question.id, `questions[${index}].id`)\n if (!/^[a-z][a-z0-9_]*$/.test(id)) throw new Error(`questions[${index}].id must be snake_case`)\n if (ids.has(id)) throw new Error(`question id \"${id}\" is duplicated`)\n ids.add(id)\n const header = requiredString(question.header, `questions[${index}].header`)\n const prompt = requiredString(question.question, `questions[${index}].question`)\n if (!Array.isArray(question.options) || question.options.length < 2 || question.options.length > 3) {\n throw new Error(`questions[${index}].options must contain two or three choices`)\n }\n const options = question.options.map((rawOption, optionIndex) => {\n const option = record(rawOption, `questions[${index}].options[${optionIndex}]`)\n return {\n label: requiredString(option.label, `questions[${index}].options[${optionIndex}].label`),\n description: requiredString(option.description, `questions[${index}].options[${optionIndex}].description`),\n }\n })\n return Object.freeze({ id, header, question: prompt, options: Object.freeze(options), allowFreeForm: true as const })\n })\n return { questions: Object.freeze(questions) }\n}\n\nfunction requestUserInputSchema(): Record<string, unknown> {\n return {\n type: 'object',\n properties: {\n questions: {\n type: 'array', minItems: 1, maxItems: 3,\n description: 'Questions to show the user. Prefer one and do not exceed three.',\n items: {\n type: 'object', additionalProperties: false,\n properties: {\n id: { type: 'string', description: 'Stable snake_case answer key.' },\n header: { type: 'string', description: 'Short UI label, ideally 12 characters or fewer.' },\n question: { type: 'string', description: 'Single-sentence question.' },\n options: {\n type: 'array', minItems: 2, maxItems: 3,\n 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.',\n items: {\n type: 'object', additionalProperties: false,\n properties: {\n label: { type: 'string', description: 'User-facing label, one to five words.' },\n description: { type: 'string', description: 'One sentence explaining impact or trade-off.' },\n },\n required: ['label', 'description'],\n },\n },\n },\n required: ['id', 'header', 'question', 'options'],\n },\n },\n },\n required: ['questions'],\n additionalProperties: false,\n }\n}\n\nfunction modeSystem(mode: AgentMode, canAskUser: boolean): string {\n if (mode === 'basic') return [\n 'Work as a bounded tool-using agent. Use available tools proactively when they materially improve correctness.',\n 'Stay within the configured iteration budget, then give the best final answer supported by the gathered results.',\n ].join(' ')\n const ask = canAskUser\n ? `If a missing fact or material user choice blocks correct progress, call ${AGENT_CONTROL_TOOLS.requestUserInput} and continue after the answer.`\n : 'If blocked by missing user input, state that limitation plainly in the final response.'\n const hil = mode === 'deep-human-in-loop'\n ? 'For material choices, surface 2-3 concise options with the recommended option first; the UI also permits free-form feedback.'\n : ''\n return [\n 'Work autonomously in deep mode. After every tool result, compare the evidence against the user objective and all constraints; continue until gaps are closed.',\n `Do not treat a plausible draft as completion. When the work is actually complete, call ${AGENT_CONTROL_TOOLS.complete} with a summary and concrete evidence, then provide the final answer.`,\n ask, hil,\n 'Never reveal private chain-of-thought. Use concise user-visible commentary for intent, progress, observations, and decisions.',\n ].filter(Boolean).join(' ')\n}\n\nfunction joinSystem(...parts: readonly (string | undefined)[]): string {\n return parts.filter((part): part is string => part !== undefined && part.length > 0).join('\\n\\n')\n}\n\nfunction record(value: unknown, label: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new Error(`${label} must be an object`)\n return value as Record<string, unknown>\n}\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.trim().length === 0) throw new Error(`${label} must be a non-empty string`)\n return value\n}\nfunction positiveFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${name} must be a positive finite number`)\n return value\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"run-agent.js","names":[],"sources":["../../../src/agent/mode/run-agent.ts"],"sourcesContent":["/** High-level agent modes built on the provider-neutral bounded tool loop. */\n\nimport { createMessage, createUserMessage, type Message } from '../../message/index.ts'\nimport type { CallConfig } from '../../contract/index.ts'\nimport type { JsonObject } from '../../primitives/index.ts'\nimport { detachedFrozen } from '../../primitives/index.ts'\nimport { runTurn, type RunTurnOptions } from '../loop/run-turn.ts'\nimport { AwaitedEventQueue } from '../loop/queue.ts'\nimport type { AgentEvent, TurnBounds, TurnHooks, TurnOutcome } from '../loop/types.ts'\nimport { defineTool, type ToolDefinition, type ToolExecutionMode } from '../tool/definition.ts'\nimport { readSpillTool } from '../tool/output-budget.ts'\nimport type { ToolInterceptor } from '../tool/pipeline.ts'\nimport type { ToolCatalog } from '../tool/registry.ts'\nimport { waitForSettlement } from '../../async/index.ts'\nimport type {\n UserInputBroker, UserInputQuestion, UserInputRequest, UserInputResponse,\n} from './user-input.ts'\n\nexport const AGENT_CONTROL_TOOLS = Object.freeze({\n complete: 'submit_result',\n requestUserInput: 'request_user_input',\n} as const)\n\n/**\n * What the model replies with, after an accepted self-check, when the answer\n * it already gave the user earlier in the run still stands.\n *\n * Deep modes gate on an accepted `submit_result`, so a model that answered\n * before checking is asked to check, then told to \"deliver the answer\"\n * again — even when the check found nothing to add. Without this marker that\n * second pass either pads an already-adequate answer or, worse, quietly\n * changes it while claiming to only be confirming it. `driveAgent` treats a\n * reply that is exactly this marker as \"no change\": the run's `text` (and,\n * where the earlier answer is still the history's current surface, the\n * transcript) keep the answer already given instead of this marker.\n */\nexport const UNCHANGED_ANSWER_MARKER = '<<deep-mode:answer-unchanged>>'\n\n/** Default high-level runtime requested by this SDK; `runTurn` remains provider-neutral. */\nexport type AgentMode = 'basic' | 'deep' | 'deep-human-in-loop'\n\ninterface AgentRunCommon extends Omit<RunTurnOptions, 'bounds' | 'commentary' | 'config' | 'hooks' | 'system' | 'tools'> {\n /** Explicit low-level model binding; composition users can select a configured provider default instead. */\n readonly config: CallConfig\n readonly tools?: ToolCatalog\n readonly system?: string\n /** Maximum normal model iterations. A forced final answer may use one extra request. */\n /** Model steps per prompt; 'auto' keeps completion and resource guards only. */\n readonly maxTurns?: number | 'auto'\n readonly bounds?: Omit<Partial<TurnBounds>, 'maxSteps'>\n readonly commentary?: RunTurnOptions['commentary']\n readonly hooks?: TurnHooks\n}\n\nexport interface BasicAgentOptions extends AgentRunCommon {\n readonly mode?: 'basic'\n}\n\nexport interface DeepAgentOptions extends AgentRunCommon {\n readonly mode: 'deep'\n /** Optional in deep mode: expose a blocking clarification tool when configured. */\n readonly userInput?: UserInputBroker\n}\n\nexport interface HumanInLoopAgentOptions extends AgentRunCommon {\n readonly mode: 'deep-human-in-loop'\n /** Required in HIL mode: the tool call remains parked until this broker answers. */\n readonly userInput: UserInputBroker\n}\n\nexport type RunAgentOptions = BasicAgentOptions | DeepAgentOptions | HumanInLoopAgentOptions\n\nexport interface CompletionSubmission {\n readonly summary: string\n readonly evidence: readonly string[]\n}\n\nexport interface AgentRunOutcome extends TurnOutcome {\n readonly mode: AgentMode\n /** Deep modes are complete only after the model explicitly submits its self-check. */\n readonly completed: boolean\n readonly completion?: CompletionSubmission\n}\n\ninterface AgentModeStartEvent {\n readonly type: 'agent-start'\n readonly mode: AgentMode\n readonly maxTurns: number | 'auto'\n}\ninterface UserInputRequestEvent {\n readonly type: 'user-input-request'\n readonly request: UserInputRequest\n}\ninterface UserInputResponseEvent {\n readonly type: 'user-input-response'\n readonly request: UserInputRequest\n readonly response: UserInputResponse | 'abort'\n}\ninterface AgentModeEndEvent {\n readonly type: 'agent-end'\n readonly outcome: AgentRunOutcome\n}\n\nexport type AgentRunEvent = AgentEvent\n | AgentModeStartEvent\n | UserInputRequestEvent\n | UserInputResponseEvent\n | AgentModeEndEvent\n\ninterface DeepState {\n completion: CompletionSubmission | undefined\n userAborted: boolean\n /** Answers without intervening substantive tool work or an accepted check. */\n unverifiedAnswers: number\n completionInvalidated: boolean\n /**\n * The text of the last answer the self-check gate held back, so an accept\n * that finds nothing to change can point back to it instead of asking the\n * model to retype it. Tool work between that answer and the accept does not\n * clear it: nothing has been shown to the user since, so it is still the\n * right thing to compare against.\n */\n draftAnswer: string | undefined\n /**\n * A bare marker with no draft to keep has been answered with a request for\n * the answer itself. Once is enough: a model that repeats it gets an empty,\n * incomplete result rather than another paid round.\n */\n orphanMarkerNudged: boolean\n /**\n * The confirming round was cut off (aborted, errored, out of tokens) while\n * its text was still only the start of the marker. That text can only be\n * the marker arriving; it is dropped rather than shown in place of the draft.\n */\n markerCut: boolean\n /** The current reply was confirmed to contain only the control marker. */\n markerReply: boolean\n}\n\nconst DEFAULT_MAX_TURNS = 16\n\n/** Changing the wording of an unsubmitted conclusion is not execution progress. */\nconst UNVERIFIED_ANSWER_LIMIT = 3\n\n/**\n * Run an agent in basic, self-checking deep, or deep human-in-loop mode.\n *\n * The low-level `turn-*`, trace, commentary, reasoning-summary, and tool events are\n * forwarded unchanged. High-level `agent-*` and `user-input-*` events make GUI\n * orchestration possible without parsing assistant prose.\n */\nexport function runAgent(options: RunAgentOptions): AsyncIterable<AgentRunEvent> {\n return {\n async * [Symbol.asyncIterator]() {\n const queue = new AwaitedEventQueue<AgentRunEvent>()\n const consumer = new AbortController()\n const teardownTimeoutMs = positiveFinite(options.teardownTimeoutMs ?? 30_000, 'teardownTimeoutMs')\n const signal = options.signal === undefined\n ? consumer.signal\n : AbortSignal.any([options.signal, consumer.signal])\n let tail = Promise.resolve()\n const emit = (event: AgentRunEvent): Promise<void> => {\n const next = tail.then(() => queue.push(detachedFrozen(event)))\n tail = next.catch(() => undefined)\n return next\n }\n const task = driveAgent(options, signal, emit)\n .then(async () => { await tail; queue.close() }, async error => { await tail; queue.fail(error) })\n\n try {\n while (true) {\n const item = await queue.take()\n if (item.done) break\n yield item.value\n }\n await task\n } finally {\n consumer.abort(new Error('agent event consumer stopped'))\n queue.close()\n if (!await waitForSettlement(task, teardownTimeoutMs)) {\n const error = new Error(\n `agent producer ignored cancellation for more than ${teardownTimeoutMs}ms`,\n { cause: consumer.signal.reason },\n ) as Error & { code: string }\n error.code = 'AGENT_TEARDOWN_TIMEOUT'\n throw error\n }\n }\n },\n }\n}\n\nasync function driveAgent(\n options: RunAgentOptions,\n signal: AbortSignal,\n emit: (event: AgentRunEvent) => Promise<void>,\n): Promise<void> {\n const mode: AgentMode = options.mode ?? 'basic'\n if (!['basic', 'deep', 'deep-human-in-loop'].includes(mode)) {\n throw new RangeError(`unsupported agent mode \"${String(mode)}\"`)\n }\n const configuredUserInput = 'userInput' in options ? options.userInput : undefined\n if (mode === 'deep-human-in-loop'\n && (configuredUserInput === undefined || typeof configuredUserInput.request !== 'function')) {\n throw new TypeError('deep-human-in-loop mode requires a UserInputBroker')\n }\n const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS\n if (maxTurns !== 'auto' && (!Number.isSafeInteger(maxTurns) || maxTurns < 1)) {\n throw new RangeError(\"maxTurns must be a positive safe integer or 'auto'\")\n }\n await emit({ type: 'agent-start', mode, maxTurns })\n\n const state: DeepState = {\n completion: undefined, userAborted: false, unverifiedAnswers: 0, completionInvalidated: false,\n draftAnswer: undefined, orphanMarkerNudged: false, markerCut: false, markerReply: false,\n }\n const deep = mode !== 'basic'\n const broker = options.mode === 'deep' || options.mode === 'deep-human-in-loop'\n ? configuredUserInput\n : undefined\n const internalTools: ToolDefinition[] = []\n // Spilling without a way to read the spill back would be worse than cutting\n // the output: the model would be told the rest exists and given no way in.\n if (options.spillStore !== undefined) {\n internalTools.push(readSpillTool(options.spillStore) as ToolDefinition)\n }\n if (deep) internalTools.push(completionTool(state))\n if (broker !== undefined && mode !== 'basic') {\n internalTools.push(userInputTool(mode, broker, state, emit, options.accounting))\n }\n const tools = internalTools.length === 0 ? options.tools : combineTools(options.tools, internalTools)\n const hooks = deep ? deepHooks(options.hooks, options.history, state, maxTurns) : options.hooks\n const turnOptions: RunTurnOptions = {\n registry: options.registry,\n config: options.config,\n history: options.history,\n ...tools === undefined ? {} : { tools },\n ...options.nativeTools === undefined ? {} : { nativeTools: options.nativeTools },\n ...options.toolChoice === undefined ? {} : { toolChoice: options.toolChoice },\n ...options.imagePolicy === undefined ? {} : { imagePolicy: options.imagePolicy },\n ...options.documentPolicy === undefined ? {} : { documentPolicy: options.documentPolicy },\n ...(options.validateOutput === undefined ? {} : { validateOutput: options.validateOutput }),\n ...options.outputFormat === undefined ? {} : { outputFormat: options.outputFormat },\n system: joinSystem(options.system, modeSystem(mode, broker !== undefined)),\n ...options.interceptors === undefined ? {} : { interceptors: shieldControlTools(options.interceptors) },\n ...options.approvals === undefined ? {} : { approvals: options.approvals },\n bounds: { ...options.bounds, maxSteps: maxTurns },\n ...hooks === undefined ? {} : { hooks },\n signal,\n ...options.logger === undefined ? {} : { logger: options.logger },\n commentary: options.commentary ?? 'auto',\n teardownTimeoutMs: options.teardownTimeoutMs ?? 30_000,\n ...options.modelTimeoutMs === undefined ? {} : { modelTimeoutMs: options.modelTimeoutMs },\n ...options.maxModelRequestBytes === undefined ? {} : { maxModelRequestBytes: options.maxModelRequestBytes },\n ...options.maxModelResponseBytes === undefined ? {} : { maxModelResponseBytes: options.maxModelResponseBytes },\n ...options.maxModelStreamEvents === undefined ? {} : { maxModelStreamEvents: options.maxModelStreamEvents },\n ...options.hookTimeoutMs === undefined ? {} : { hookTimeoutMs: options.hookTimeoutMs },\n ...options.hookTeardownTimeoutMs === undefined ? {} : { hookTeardownTimeoutMs: options.hookTeardownTimeoutMs },\n ...options.trace === undefined ? {} : { trace: options.trace },\n ...options.accounting === undefined ? {} : { accounting: options.accounting },\n ...options.spillStore === undefined ? {} : { spillStore: options.spillStore },\n ...options.experimentalPrograms === undefined ? {} : { experimentalPrograms: options.experimentalPrograms },\n ...options.contextSections === undefined ? {} : { contextSections: options.contextSections },\n }\n\n let terminal: TurnOutcome | undefined\n let stepCalls: string[] = []\n let completionCandidate: CompletionSubmission | undefined\n let markerCandidate = false\n let candidateText = ''\n let heldEvents: AgentRunEvent[] = []\n // The one message that stands in for a kept marker reply: live events, the\n // terminal outcome and the history surface all carry this same identity.\n let kept: { readonly from: Message['id']; readonly message: Message } | undefined\n // A bare marker with nothing to keep: its text is not shown at all.\n let orphan: Message['id'] | undefined\n // The history surface already carries the stand-in for this round.\n let keptRestored = false\n const flushHeld = async (): Promise<void> => {\n const pending = heldEvents\n heldEvents = []\n for (const event of pending) await emit(event)\n }\n /** Release everything held except the text itself. */\n const dropHeldText = async (): Promise<void> => {\n const pending = heldEvents\n heldEvents = []\n for (const held of pending) if (held.type !== 'text-delta' && held.type !== 'text-end') await emit(held)\n }\n const emitAnswerEvent = async (event: AgentRunEvent): Promise<void> => {\n // The loop describes each block of the message it just built. For a kept\n // reply that message is the marker: describe the stand-in instead.\n if (orphan !== undefined && event.type === 'assistant-text' && event.messageId === orphan) return\n if (kept !== undefined && event.type === 'assistant-reasoning' && event.messageId === kept.from) {\n await emit({ ...event, messageId: kept.message.id })\n return\n }\n if (kept !== undefined && event.type === 'assistant-text' && event.messageId === kept.from) {\n const block = kept.message.content.find(block => block.type === 'text')\n await emit({ ...event, messageId: kept.message.id, text: block?.type === 'text' ? block.text : event.text })\n return\n }\n if (event.type === 'step-start') {\n kept = undefined\n orphan = undefined\n keptRestored = false\n state.markerCut = false\n state.markerReply = false\n await flushHeld()\n // Held after any accepted check, with or without a draft: a later run can\n // imitate an earlier accept, and the marker must not stream either way.\n markerCandidate = state.completion !== undefined\n candidateText = ''\n }\n if (markerCandidate && (event.type === 'text-delta' || event.type === 'text-end')) {\n candidateText = event.type === 'text-end' ? event.text : candidateText + event.text\n heldEvents.push(event)\n // Ordinary answers resume streaming as soon as their prefix differs.\n // Hold the control reply until its complete assistant message confirms\n // it contains no additional text or tool calls.\n if (!isMarkerPrefix(candidateText)) {\n markerCandidate = false\n await flushHeld()\n } else if (event.type === 'text-end' && event.incomplete) {\n // Cut off mid-marker: stay a candidate so the message that follows is\n // resolved as the marker it was becoming, not shown as an answer.\n state.markerCut = true\n }\n return\n }\n if (markerCandidate && event.type === 'assistant-message') {\n const content = event.message.content\n const draft = state.draftAnswer\n const only = soleText(content)\n const bare = only !== undefined\n && (only.trim() === UNCHANGED_ANSWER_MARKER || (state.markerCut && isMarkerPrefix(only)))\n markerCandidate = false\n if (bare) {\n state.markerReply = true\n kept = { from: event.message.id, message: keptAnswerMessage(draft ?? '', content) }\n // Correct the persisted surface before exposing the replacement, even\n // when there is no draft: a reload must not present the control marker.\n restoreKeptAnswer(options.history, kept.message, state.markerCut)\n keptRestored = true\n if (draft === undefined) orphan = event.message.id\n await dropHeldText()\n await emit({ ...event, message: kept.message })\n return\n }\n // Text alone cannot identify a control reply if other content accompanies it.\n state.markerCut = false\n await flushHeld()\n } else if (heldEvents.length > 0) {\n if (event.type === 'turn-end' && markerCandidate && isMarkerPrefix(candidateText)) {\n // The round ended (abort, error) before a message could confirm it.\n markerCandidate = false\n state.markerCut = true\n await dropHeldText()\n } else if (event.type === 'turn-end' || event.type === 'tool-call') {\n markerCandidate = false\n await flushHeld()\n } else {\n heldEvents.push(event)\n return\n }\n }\n await emit(event)\n }\n for await (const event of runTurn(turnOptions)) {\n if (event.type === 'step-start') {\n stepCalls = []\n completionCandidate = undefined\n } else if (event.type === 'tool-call') {\n stepCalls.push(event.call.toolName)\n // Work performed after an accepted submission invalidates that submission;\n // the new result has not yet passed the completion gate.\n if (event.call.toolName !== AGENT_CONTROL_TOOLS.complete\n && tools?.get(event.call.toolName)?.completionExempt !== true) {\n if (state.completion !== undefined) state.completionInvalidated = true\n state.completion = undefined\n state.unverifiedAnswers = 0\n }\n } else if (event.type === 'tool-result'\n && event.call.toolName === AGENT_CONTROL_TOOLS.complete\n && !event.result.isError) {\n completionCandidate = completionFromResult(event.result.value)\n } else if (event.type === 'step-end'\n && completionCandidate !== undefined\n && stepCalls.filter(name => name === AGENT_CONTROL_TOOLS.complete).length === 1\n && stepCalls.every(name => name === AGENT_CONTROL_TOOLS.complete || tools?.get(name)?.completionExempt === true)) {\n // A completion submission cannot share a batch with work whose results the\n // model had not seen when it claimed success.\n state.completion = completionCandidate\n state.completionInvalidated = false\n }\n if (event.type === 'turn-end') {\n // A round that ends while its held text is only the start of the marker was\n // cut off mid-marker; resolve that before the outcome is decided.\n if (markerCandidate && heldEvents.length > 0 && isMarkerPrefix(candidateText)) state.markerCut = true\n terminal = keptAnswerOutcome(event.outcome, state)\n // Resolve the control reply before exposing the terminal turn outcome,\n // so consumers of turn-end and agent-end receive the same answer.\n if (terminal !== event.outcome && state.draftAnswer !== undefined && !keptRestored) {\n restoreKeptAnswer(options.history, kept?.message ?? keptAnswerMessage(terminal.text), state.markerCut)\n }\n await emitAnswerEvent({ ...event, outcome: terminal })\n continue\n }\n await emitAnswerEvent(event)\n }\n if (terminal === undefined) throw new Error('runTurn ended without a turn-end event')\n const completed = mode === 'basic'\n ? terminal.reason.kind === 'completed' || terminal.reason.kind === 'concluded-by-tool'\n : state.completion !== undefined && !state.userAborted\n && (terminal.reason.kind === 'completed'\n || terminal.reason.kind === 'concluded-by-tool'\n || (terminal.reason.kind === 'budget-exhausted' && terminal.reason.forcedFinalAnswer))\n && terminal.text.trim() !== ''\n const outcome: AgentRunOutcome = {\n ...terminal,\n mode,\n completed,\n ...state.completion === undefined ? {} : { completion: state.completion },\n }\n await emit({ type: 'agent-end', outcome })\n}\n\n/**\n * The message's one text block, when text is all it says. Reasoning is not\n * something it says to the user: reasoning models attach it to a reply that is\n * otherwise only the marker, and that reply must still count as the marker.\n */\nfunction soleText(content: readonly Message['content'][number][]): string | undefined {\n const said = content.filter(block => block.type !== 'reasoning')\n return said.length === 1 && said[0]?.type === 'text' ? said[0].text : undefined\n}\n\n/** Text that is, so far, only the beginning (or the whole) of the marker. */\nfunction isMarkerPrefix(text: string): boolean {\n const trimmed = text.trim()\n return trimmed.length === 0 ? true : UNCHANGED_ANSWER_MARKER.startsWith(trimmed)\n}\n\nfunction keptAnswerOutcome(outcome: TurnOutcome, state: DeepState): TurnOutcome {\n if (state.completion === undefined || (!state.markerReply && !state.markerCut)) return outcome\n const cut = state.markerCut && outcome.text.trim() !== '' && isMarkerPrefix(outcome.text)\n if (!cut && outcome.text.trim() !== UNCHANGED_ANSWER_MARKER) return outcome\n // With no draft there is nothing the marker could mean: an empty answer, so\n // the run reports incomplete instead of presenting the marker as its answer.\n return { ...outcome, text: state.draftAnswer ?? '' }\n}\n\n/** Replace the control text while preserving the confirming round's reasoning. */\nfunction keptAnswerMessage(draftAnswer: string, content?: Message['content']): Message {\n return createMessage({\n role: 'assistant',\n content: content === undefined\n ? [{ type: 'text', text: draftAnswer, phase: 'final-answer' }]\n : content.flatMap<Message['content'][number]>(block => block.type === 'reasoning' ? [block]\n : draftAnswer === '' ? [] : [{ type: 'text' as const, text: draftAnswer, phase: 'final-answer' as const }]),\n source: { kind: 'app', producer: 'deep-mode-kept-answer' },\n })\n}\n\n/** Supersede a bare marker on the history surface without changing the raw log. */\nfunction restoreKeptAnswer(history: RunAgentOptions['history'], replacement: Message, cut = false): void {\n const entries = history.entries()\n let target: (typeof entries)[number] | undefined\n for (let index = entries.length - 1; index >= 0; index--) {\n const entry = entries[index]\n if (entry?.event.kind !== 'assistant') continue\n target = entry\n break\n }\n const only = target?.event.kind === 'assistant' ? soleText(target.event.message.content) : undefined\n if (target === undefined || only === undefined) return\n if (only.trim() !== UNCHANGED_ANSWER_MARKER && !(cut && only.trim() !== '' && isMarkerPrefix(only))) return\n // Persist before emitting the replacement. Capacity and validation failures\n // must fail the run; claiming success would leave its result and replay in\n // disagreement and expose the raw marker through the session response.\n history.append(\n { kind: 'assistant', message: replacement },\n { op: 'replace', from: target.seq, to: target.seq },\n )\n}\n\nfunction completionTool(state: DeepState): ToolDefinition<CompletionSubmission> {\n return defineTool({\n name: AGENT_CONTROL_TOOLS.complete,\n description: 'Submit the self-check only when the user objective and constraints are fully satisfied. After acceptance, give the user the final answer.',\n // The one call that ENDS a deep run. A budget that can block it can leave\n // the run with no way to complete at all.\n budgetExempt: true,\n parameters: {\n type: 'object',\n properties: {\n summary: { type: 'string', description: 'Concise statement of what was completed.' },\n evidence: {\n type: 'array', items: { type: 'string' },\n description: 'Concrete checks or tool results showing the objective is satisfied.',\n },\n },\n required: ['summary', 'evidence'],\n additionalProperties: false,\n },\n parse: parseCompletion,\n execute: submission => ({\n accepted: true,\n summary: submission.summary,\n evidence: [...submission.evidence],\n // A draft recorded means the model already gave the user a complete\n // answer before this check, so confirming it is a legitimate outcome,\n // not just a shorter way to restate it.\n instruction: state.draftAnswer === undefined\n ? '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.'\n : `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 ${UNCHANGED_ANSWER_MARKER} 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.`,\n }),\n })\n}\n\nfunction userInputTool(\n mode: Exclude<AgentMode, 'basic'>,\n broker: UserInputBroker,\n state: DeepState,\n emit: (event: AgentRunEvent) => Promise<void>,\n accounting?: RunTurnOptions['accounting'],\n): ToolDefinition<{ readonly questions: readonly UserInputQuestion[] }> {\n return defineTool({\n name: AGENT_CONTROL_TOOLS.requestUserInput,\n // Asking the user is how a blocked run gets unblocked; a spent budget must\n // not be the reason the question is never asked.\n budgetExempt: true,\n description: mode === 'deep-human-in-loop'\n ? '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.'\n : '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.',\n parameters: requestUserInputSchema(),\n parse: parseUserInput,\n execute: async ({ questions }, ctx) => {\n const operation = accounting?.startOperation('user-input', {\n toolCallId: ctx.callId,\n data: { questionCount: questions.length },\n })\n const request: UserInputRequest = {\n requestId: ctx.callId, callId: ctx.callId, turn: ctx.turn, step: ctx.step,\n questions, isBlocking: true,\n }\n // Start the broker first: an event consumer may resolve synchronously, and\n // the waiter must already exist when the request event becomes visible.\n try {\n const pending = broker.request(request, ctx.signal)\n await emit({ type: 'user-input-request', request })\n const response = await pending\n await emit({ type: 'user-input-response', request, response })\n if (response === 'abort') {\n state.userAborted = true\n ctx.concludeTurn()\n if (operation !== undefined) accounting?.endOperation(operation, 'aborted')\n return { aborted: true }\n }\n if (operation !== undefined) accounting?.endOperation(operation, 'success')\n return validateUserResponse(response, questions) as unknown as JsonObject\n } catch (error) {\n if (operation !== undefined) accounting?.endOperation(\n operation,\n ctx.signal.aborted ? 'aborted' : 'error',\n { error },\n )\n throw error\n }\n },\n })\n}\n\nfunction deepHooks(\n userHooks: TurnHooks | undefined,\n history: RunAgentOptions['history'],\n state: DeepState,\n maxTurns: number | 'auto',\n): TurnHooks {\n return {\n ...userHooks,\n onTurnEnd: async context => {\n const outcome = keptAnswerOutcome(context.outcome, state)\n await userHooks?.onTurnEnd?.(outcome === context.outcome ? context : { ...context, outcome })\n if (context.outcome.reason.kind === 'completed' && context.canContinue\n && state.completion !== undefined && state.draftAnswer === undefined && !state.orphanMarkerNudged\n && state.markerReply\n && context.outcome.text.trim() === UNCHANGED_ANSWER_MARKER) {\n state.orphanMarkerNudged = true\n history.append({ kind: 'user', message: createUserMessage({\n source: { kind: 'app', producer: 'deep-mode-self-check' },\n content: [{ type: 'text', text: `There is no earlier answer in this run for ${UNCHANGED_ANSWER_MARKER} 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.` }],\n }) })\n return\n }\n if (context.outcome.reason.kind !== 'completed'\n || (maxTurns !== 'auto' && context.outcome.steps >= maxTurns)\n || state.completion !== undefined\n || state.userAborted) return\n // Auto must not pay indefinitely for paraphrases of \"already checked\".\n // Substantive tool work resets this allowance; progress-only updates do not.\n state.unverifiedAnswers++\n if (state.unverifiedAnswers >= UNVERIFIED_ANSWER_LIMIT) return\n // What the gate is about to ask the model to justify or repeat. Kept\n // even though tool work may follow: nothing new has been shown to the\n // user since, so this is still what an eventual accept is confirming.\n if (context.outcome.text.trim() !== '' && context.outcome.text.trim() !== UNCHANGED_ANSWER_MARKER) {\n state.draftAnswer = context.outcome.text\n }\n history.append({ kind: 'user', message: createUserMessage({\n source: { kind: 'app', producer: 'deep-mode-self-check' },\n content: [{\n type: 'text',\n text: (state.completionInvalidated\n ? `Your previously accepted submission is no longer current because you called another substantive tool afterwards. Review the later tool results and call ${AGENT_CONTROL_TOOLS.complete} again when complete; the old instruction not to resubmit no longer applies. `\n : '')\n + `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 ${AGENT_CONTROL_TOOLS.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.`,\n }],\n }) })\n },\n }\n}\n\nclass CombinedToolCatalog implements ToolCatalog {\n private readonly definitions: ReadonlyMap<string, ToolDefinition>\n constructor(base: ToolCatalog | undefined, additions: readonly ToolDefinition[]) {\n const definitions = new Map<string, ToolDefinition>()\n for (const name of base?.names() ?? []) {\n const definition = base?.get(name)\n if (definition !== undefined) definitions.set(name, definition)\n }\n for (const definition of additions) {\n if (definitions.has(definition.name)) {\n throw new Error(`tool name \"${definition.name}\" is reserved by the selected agent mode`)\n }\n definitions.set(definition.name, definition)\n }\n this.definitions = definitions\n }\n get(name: string): ToolDefinition | undefined { return this.definitions.get(name) }\n has(name: string): boolean { return this.definitions.has(name) }\n names(): readonly string[] { return [...this.definitions.keys()] }\n schemas() {\n return [...this.definitions.values()].map(({ name, description, parameters }) => ({\n name, description, parameters: structuredClone(parameters),\n }))\n }\n executionMode(name: string, args: unknown): ToolExecutionMode {\n const definition = this.definitions.get(name)\n if (definition === undefined) return 'exclusive'\n try { return definition.isConcurrencySafe?.(args) === true ? 'parallel' : 'exclusive' }\n catch { return 'exclusive' }\n }\n}\n\nfunction combineTools(base: ToolCatalog | undefined, additions: readonly ToolDefinition[]): ToolCatalog {\n return new CombinedToolCatalog(base, additions)\n}\n\n/** Control tools are host protocol, not application capabilities subject to tool policy. */\nfunction shieldControlTools(interceptors: readonly ToolInterceptor[]): readonly ToolInterceptor[] {\n const reserved = new Set<string>(Object.values(AGENT_CONTROL_TOOLS))\n return interceptors.map(interceptor => ({\n name: interceptor.name,\n ...interceptor.before === undefined ? {} : {\n before: (call, next) => reserved.has(call.toolName) ? next() : interceptor.before!(call, next),\n },\n ...interceptor.around === undefined ? {} : {\n around: (call, next) => reserved.has(call.toolName) ? next() : interceptor.around!(call, next),\n },\n ...interceptor.after === undefined ? {} : {\n after: (call, result, next) => reserved.has(call.toolName) ? next() : interceptor.after!(call, result, next),\n },\n }))\n}\n\nfunction completionFromResult(value: unknown): CompletionSubmission {\n const result = record(value, 'submit_result result')\n return parseCompletion({ summary: result.summary, evidence: result.evidence })\n}\n\nfunction validateUserResponse(\n response: UserInputResponse,\n questions: readonly UserInputQuestion[],\n): UserInputResponse {\n const expected = new Set(questions.map(question => question.id))\n for (const id of expected) {\n const answer = response.answers[id]\n if (answer === undefined || !Array.isArray(answer.answers) || answer.answers.length === 0\n || answer.answers.some(value => typeof value !== 'string' || value.trim().length === 0)) {\n throw new Error(`the user-input broker returned no valid answer for \"${id}\"`)\n }\n }\n for (const id of Object.keys(response.answers)) {\n if (!expected.has(id)) throw new Error(`the user-input broker returned an answer for unknown question \"${id}\"`)\n }\n return response\n}\n\nfunction parseCompletion(raw: unknown): CompletionSubmission {\n const value = record(raw, 'submit_result arguments')\n if (typeof value.summary !== 'string' || value.summary.trim().length === 0) {\n throw new Error('summary must be a non-empty string')\n }\n if (!Array.isArray(value.evidence) || value.evidence.some(item => typeof item !== 'string' || item.trim().length === 0)) {\n throw new Error('evidence must be an array of non-empty strings')\n }\n return { summary: value.summary, evidence: value.evidence as string[] }\n}\n\nfunction parseUserInput(raw: unknown): { readonly questions: readonly UserInputQuestion[] } {\n const value = record(raw, 'request_user_input arguments')\n if (!Array.isArray(value.questions) || value.questions.length < 1 || value.questions.length > 3) {\n throw new Error('questions must contain one to three items')\n }\n const ids = new Set<string>()\n const questions = value.questions.map((rawQuestion, index) => {\n const question = record(rawQuestion, `questions[${index}]`)\n const id = requiredString(question.id, `questions[${index}].id`)\n if (!/^[a-z][a-z0-9_]*$/.test(id)) throw new Error(`questions[${index}].id must be snake_case`)\n if (ids.has(id)) throw new Error(`question id \"${id}\" is duplicated`)\n ids.add(id)\n const header = requiredString(question.header, `questions[${index}].header`)\n const prompt = requiredString(question.question, `questions[${index}].question`)\n if (!Array.isArray(question.options) || question.options.length < 2 || question.options.length > 3) {\n throw new Error(`questions[${index}].options must contain two or three choices`)\n }\n const options = question.options.map((rawOption, optionIndex) => {\n const option = record(rawOption, `questions[${index}].options[${optionIndex}]`)\n return {\n label: requiredString(option.label, `questions[${index}].options[${optionIndex}].label`),\n description: requiredString(option.description, `questions[${index}].options[${optionIndex}].description`),\n }\n })\n return Object.freeze({ id, header, question: prompt, options: Object.freeze(options), allowFreeForm: true as const })\n })\n return { questions: Object.freeze(questions) }\n}\n\nfunction requestUserInputSchema(): Record<string, unknown> {\n return {\n type: 'object',\n properties: {\n questions: {\n type: 'array', minItems: 1, maxItems: 3,\n description: 'Questions to show the user. Prefer one and do not exceed three.',\n items: {\n type: 'object', additionalProperties: false,\n properties: {\n id: { type: 'string', description: 'Stable snake_case answer key.' },\n header: { type: 'string', description: 'Short UI label, ideally 12 characters or fewer.' },\n question: { type: 'string', description: 'Single-sentence question.' },\n options: {\n type: 'array', minItems: 2, maxItems: 3,\n 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.',\n items: {\n type: 'object', additionalProperties: false,\n properties: {\n label: { type: 'string', description: 'User-facing label, one to five words.' },\n description: { type: 'string', description: 'One sentence explaining impact or trade-off.' },\n },\n required: ['label', 'description'],\n },\n },\n },\n required: ['id', 'header', 'question', 'options'],\n },\n },\n },\n required: ['questions'],\n additionalProperties: false,\n }\n}\n\nfunction modeSystem(mode: AgentMode, canAskUser: boolean): string {\n if (mode === 'basic') return [\n 'Work as a bounded tool-using agent. Use available tools proactively when they materially improve correctness.',\n 'Stay within the configured iteration budget, then give the best final answer supported by the gathered results.',\n ].join(' ')\n const ask = canAskUser\n ? `If a missing fact or material user choice blocks correct progress, call ${AGENT_CONTROL_TOOLS.requestUserInput} and continue after the answer.`\n : 'If blocked by missing user input, state that limitation plainly in the final response.'\n const hil = mode === 'deep-human-in-loop'\n ? 'For material choices, surface 2-3 concise options with the recommended option first; the UI also permits free-form feedback.'\n : ''\n return [\n 'Work autonomously in deep mode. After every tool result, compare the evidence against the user objective and all constraints; continue until gaps are closed.',\n `Do not treat a plausible draft as completion. When the work is actually complete, call ${AGENT_CONTROL_TOOLS.complete} with a summary and concrete evidence, then provide the final answer.`,\n '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 ask, hil,\n 'Never reveal private chain-of-thought. Use concise user-visible commentary for intent, progress, observations, and decisions.',\n ].filter(Boolean).join(' ')\n}\n\nfunction joinSystem(...parts: readonly (string | undefined)[]): string {\n return parts.filter((part): part is string => part !== undefined && part.length > 0).join('\\n\\n')\n}\n\nfunction record(value: unknown, label: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new Error(`${label} must be an object`)\n return value as Record<string, unknown>\n}\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.trim().length === 0) throw new Error(`${label} must be a non-empty string`)\n return value\n}\nfunction positiveFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${name} must be a positive finite number`)\n return value\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{AgentSdkError as e}from"../../../errors/agent-sdk-error.js";import{arrayData as t,boundedText as n,objectValue as r,ownData as i}from"../../../capability/common/data.js";import{MAX_SKILL_DESCRIPTION_CHARS as a,validateSkillId as o}from"../definition.js";import{capabilityIdentityError as s}from"../../../errors/capability-identity.js";import{SKILL_ERROR_CODES as c,SKILL_PROVIDER_LIMITS as l}from"./config.js";import{snapshotJsonValue as u}from"../../../primitives/json-snapshot.js";const d=new Set([`id`,`name`,`description`,`whenToUse`,`invocation`,`source`,`provider`,`locator`]),f=new Set([`id`,`source`,`provider`,`catalogRevision`,`locator`,`resourceBase`]);function p(a,o,u,d){try{let e=r(o);S(e,new Set([`revision`,`candidates`]));let f=n(i(e,`revision`),l.revisionBytes),p=t(i(e,`candidates`),u).map(e=>h(e,a.id)),m=new Map;for(let[e,t]of p.entries()){let n=m.get(t.id);if(n!==void 0)throw s(c.ID_CONFLICT,`skill-id`,n,e);m.set(t.id,e)}let _=p.map(e=>g(e,f)),v=Object.freeze({revision:f,candidates:Object.freeze(p),references:Object.freeze(_)});if(new TextEncoder().encode(JSON.stringify(v)).byteLength>d)throw C();return v}catch(t){throw t instanceof e?t:C()}}function m(t){try{let e=r(t);S(e,f);let a=x(i(e,`id`),256);o(a);let s=x(i(e,`provider`),l.identityBytes);return o(s,`skill provider`),Object.freeze({id:a,source:x(i(e,`source`),256),provider:s,catalogRevision:n(i(e,`catalogRevision`),l.revisionBytes),..._(e),...y(e)})}catch(t){throw t instanceof e&&t.code===c.REFERENCE_INVALID?t:w()}}function h(e,t){let n=r(e);S(n,d);let s=x(i(n,`id`),256);o(s);let c=x(i(n,`provider`),l.identityBytes);if(c!==t)throw C();let u=v(i(n,`invocation`,!1));return Object.freeze({id:s,name:x(i(n,`name`),256),description:x(i(n,`description`),a),...b(n,`whenToUse`,a),...u===void 0?{}:{invocation:u},source:x(i(n,`source`),256),provider:c,..._(n)})}function g(e,t){return Object.freeze({id:e.id,source:e.source,provider:e.provider,catalogRevision:t,...e.locator===void 0?{}:{locator:e.locator}})}function _(e){let t=i(e,`locator`,!1);return t===void 0?{}:{locator:u(t,{maxObjectFields:l.locatorFields,maxArrayItems:l.locatorArrayItems,maxDepth:l.locatorDepth,maxNodes:l.locatorNodes,maxKeyBytes:l.locatorKeyBytes,maxBytes:l.locatorBytes})}}function v(e){if(e===void 0)return;let t=r(e);S(t,new Set([`modelInvocable`,`userInvocable`]));let n=i(t,`modelInvocable`),a=i(t,`userInvocable`);if(typeof n!=`boolean`||typeof a!=`boolean`)throw C();return Object.freeze({modelInvocable:n,userInvocable:a})}function y(e){let t=i(e,`resourceBase`,!1);if(t===void 0)return{};let n=r(t);S(n,new Set([`kind`,`value`]));let a=i(n,`kind`);if(a!==`directory`&&a!==`url`&&a!==`opaque`)throw w();return{resourceBase:Object.freeze({kind:a,value:x(i(n,`value`),l.locatorBytes)})}}function b(e,t,n){let r=i(e,t,!1);return r===void 0?{}:{[t]:x(r,n)}}function x(e,t){if(typeof e!=`string`||e.trim().length===0||e.length>t||new TextEncoder().encode(e).byteLength>t)throw TypeError(`Invalid skill text`);return e}function S(e,t){if(Reflect.ownKeys(e).some(e=>typeof e!=`string`||!t.has(e)))throw TypeError(`Unsupported skill field`)}function C(){return new e(`Skill catalog snapshot is invalid`,c.CATALOG_INVALID)}function w(){return new e(`Persisted skill reference is invalid`,c.REFERENCE_INVALID)}export{p as captureSkillCatalogSnapshot,m as captureSkillReference};
1
+ import{AgentSdkError as e}from"../../../errors/agent-sdk-error.js";import{snapshotJsonValue as t}from"../../../primitives/json-snapshot.js";import{arrayData as n,boundedText as r,objectValue as i,ownData as a}from"../../../capability/common/data.js";import{MAX_SKILL_DESCRIPTION_CHARS as o,validateSkillId as s}from"../definition.js";import{capabilityIdentityError as c}from"../../../errors/capability-identity.js";import{SKILL_ERROR_CODES as l,SKILL_PROVIDER_LIMITS as u}from"./config.js";const d=new Set([`id`,`name`,`description`,`whenToUse`,`invocation`,`source`,`provider`,`locator`]),f=new Set([`id`,`source`,`provider`,`catalogRevision`,`locator`,`resourceBase`]);function p(t,o,s,d){try{let e=i(o);S(e,new Set([`revision`,`candidates`]));let f=r(a(e,`revision`),u.revisionBytes),p=n(a(e,`candidates`),s).map(e=>h(e,t.id)),m=new Map;for(let[e,t]of p.entries()){let n=m.get(t.id);if(n!==void 0)throw c(l.ID_CONFLICT,`skill-id`,n,e);m.set(t.id,e)}let _=p.map(e=>g(e,f)),v=Object.freeze({revision:f,candidates:Object.freeze(p),references:Object.freeze(_)});if(new TextEncoder().encode(JSON.stringify(v)).byteLength>d)throw C();return v}catch(t){throw t instanceof e?t:C()}}function m(t){try{let e=i(t);S(e,f);let n=x(a(e,`id`),256);s(n);let o=x(a(e,`provider`),u.identityBytes);return s(o,`skill provider`),Object.freeze({id:n,source:x(a(e,`source`),256),provider:o,catalogRevision:r(a(e,`catalogRevision`),u.revisionBytes),..._(e),...y(e)})}catch(t){throw t instanceof e&&t.code===l.REFERENCE_INVALID?t:w()}}function h(e,t){let n=i(e);S(n,d);let r=x(a(n,`id`),256);s(r);let c=x(a(n,`provider`),u.identityBytes);if(c!==t)throw C();let l=v(a(n,`invocation`,!1));return Object.freeze({id:r,name:x(a(n,`name`),256),description:x(a(n,`description`),o),...b(n,`whenToUse`,o),...l===void 0?{}:{invocation:l},source:x(a(n,`source`),256),provider:c,..._(n)})}function g(e,t){return Object.freeze({id:e.id,source:e.source,provider:e.provider,catalogRevision:t,...e.locator===void 0?{}:{locator:e.locator}})}function _(e){let n=a(e,`locator`,!1);return n===void 0?{}:{locator:t(n,{maxObjectFields:u.locatorFields,maxArrayItems:u.locatorArrayItems,maxDepth:u.locatorDepth,maxNodes:u.locatorNodes,maxKeyBytes:u.locatorKeyBytes,maxBytes:u.locatorBytes})}}function v(e){if(e===void 0)return;let t=i(e);S(t,new Set([`modelInvocable`,`userInvocable`]));let n=a(t,`modelInvocable`),r=a(t,`userInvocable`);if(typeof n!=`boolean`||typeof r!=`boolean`)throw C();return Object.freeze({modelInvocable:n,userInvocable:r})}function y(e){let t=a(e,`resourceBase`,!1);if(t===void 0)return{};let n=i(t);S(n,new Set([`kind`,`value`]));let r=a(n,`kind`);if(r!==`directory`&&r!==`url`&&r!==`opaque`)throw w();return{resourceBase:Object.freeze({kind:r,value:x(a(n,`value`),u.locatorBytes)})}}function b(e,t,n){let r=a(e,t,!1);return r===void 0?{}:{[t]:x(r,n)}}function x(e,t){if(typeof e!=`string`||e.trim().length===0||e.length>t||new TextEncoder().encode(e).byteLength>t)throw TypeError(`Invalid skill text`);return e}function S(e,t){if(Reflect.ownKeys(e).some(e=>typeof e!=`string`||!t.has(e)))throw TypeError(`Unsupported skill field`)}function C(){return new e(`Skill catalog snapshot is invalid`,l.CATALOG_INVALID)}function w(){return new e(`Persisted skill reference is invalid`,l.REFERENCE_INVALID)}export{p as captureSkillCatalogSnapshot,m as captureSkillReference};
2
2
  //# sourceMappingURL=snapshot.js.map
@@ -38,6 +38,11 @@ interface TeamSessionPort {
38
38
  readonly isRunning: boolean;
39
39
  inject(input: UserMessage): number;
40
40
  whenIdle(signal?: AbortSignal): Promise<void>;
41
+ /**
42
+ * Optional: whether anything still awaits an answer. A session that answers
43
+ * input queued during its own run reports false, and the wake-up skips it.
44
+ */
45
+ hasUnansweredInput?(): boolean;
41
46
  runPending(invocation?: {
42
47
  readonly signal?: AbortSignal;
43
48
  readonly onEvent?: (event: AgentRunEvent) => void | Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.d.ts","names":[],"sources":["../../../src/agent/team/contracts.ts"],"mappings":";;;;;;;;;;;;;;;KAiBY;;UAGK;WACN;WACA;WACA;WACA;;WAEA,kBAAkB;;;;;;;;;UAUZ;WACN;aAAuB;;WACvB;WACA;EACT,OAAO,OAAO;EACd,SAAS,SAAS,cAAc;EAChC,WAAW;aACA,SAAS;aACT,WAAW,OAAO,yBAAyB;MAClD;;;UAIW;EACf,OAAO,SAAS,iBAAiB,UAAU;EAC3C,SAAS,gBAAgB,SAAS,0BAA0B;EAC5D,gBAAgB"}
1
+ {"version":3,"file":"contracts.d.ts","names":[],"sources":["../../../src/agent/team/contracts.ts"],"mappings":";;;;;;;;;;;;;;;KAiBY;;UAGK;WACN;WACA;WACA;WACA;;WAEA,kBAAkB;;;;;;;;;UAUZ;WACN;aAAuB;;WACvB;WACA;EACT,OAAO,OAAO;EACd,SAAS,SAAS,cAAc;;;;;EAKhC;EACA,WAAW;aACA,SAAS;aACT,WAAW,OAAO,yBAAyB;MAClD;;;UAIW;EACf,OAAO,SAAS,iBAAiB,UAAU;EAC3C,SAAS,gBAAgB,SAAS,0BAA0B;EAC5D,gBAAgB"}
@@ -21,37 +21,9 @@ type DetachedSessionOptions = Omit<AgentSessionOptions, 'registry' | 'team' | 't
21
21
  declare const DEFAULT_SPAWN_SETUP_TIMEOUT_MS = 30000;
22
22
  /** Default bound on stopping one worker; see {@link ManagedAgentTeamOptions.closeTimeoutMs}. */
23
23
  declare const DEFAULT_WORKER_CLOSE_TIMEOUT_MS = 30000;
24
- /**
25
- * How much of the lead's conversation a new worker starts from.
26
- *
27
- * `fresh` is one task and nothing else. `fork` copies the lead's completed
28
- * conversation so far, so the worker begins already knowing what the lead
29
- * learned — the state of the workspace, the decisions taken, what the other
30
- * workers were given.
31
- *
32
- * The distinction exists because its absence is expensive in a specific way.
33
- * With only a task string, every worker re-derives the same context from
34
- * scratch: three workers spawned into an empty repository each listed the
35
- * directory, each concluded independently that nothing was there, and each
36
- * decided on its own to scaffold it. Both reference implementations offer the
37
- * same choice — Codex as `fork_context`/`fork_turns`, the DeepSeek harness as
38
- * `context: 'fresh' | 'fork'`, whose naming this follows.
39
- */
24
+ /** `fresh` starts from the task; `fork` copies the lead's completed conversation. */
40
25
  type ManagedAgentSpawnContext = 'fresh' | 'fork';
41
- /**
42
- * A worker kind the host declares up front.
43
- *
44
- * Without a declared set, `specialty` is free text the model invents at the
45
- * moment it spawns: the harness is handed `"Code review, accessibility,
46
- * security và quality audit"` and can make nothing of it — not that the role
47
- * reads rather than writes, not that it needs code to exist first. So it
48
- * cannot help order the work, and the lead is left inventing both the role and
49
- * its place in the plan in the same breath.
50
- *
51
- * Declaring roles turns that into a choice from a list the host wrote, with
52
- * `whenToUse` stating the precondition in the spawn schema where the lead
53
- * reads it. Codex does the same thing with `agent_type` and its role registry.
54
- */
26
+ /** Optional host-defined worker roles; the SDK supplies no domain-specific roles. */
55
27
  interface ManagedAgentRole {
56
28
  /** Referred to by `spawn_agent`; the enum the lead chooses from. */
57
29
  readonly name: string;
@@ -77,30 +49,9 @@ interface ManagedAgentSpawnRequest {
77
49
  readonly context?: ManagedAgentSpawnContext;
78
50
  /** One of {@link ManagedAgentTeamOptions.roles}, when the host declared any. */
79
51
  readonly role?: string;
80
- /**
81
- * Workers that must finish before this one starts.
82
- *
83
- * The harness holds it back until every one of them has settled, and then
84
- * gives it what they produced. This is the difference between dividing
85
- * agents and dividing work: a lead can spawn the whole plan in one step —
86
- * which is what it wants to do — and the ORDER is still respected, because
87
- * ordering is no longer something the model has to remember to enforce by
88
- * spawning late.
89
- *
90
- * A dependency that fails still releases its dependents, and they are told
91
- * it failed. Waiting only for success turns one broken worker into a
92
- * permanently stalled plan.
93
- */
52
+ /** Registered producers that must settle before dispatch; failures also release dependents. */
94
53
  readonly dependsOn?: readonly string[];
95
- /**
96
- * Files and directories this worker may write, workspace-relative.
97
- *
98
- * Declared so the harness can refuse a division that cannot work. Two
99
- * workers given overlapping scopes with no ordering between them will both
100
- * write those files, and the later write erases the earlier one — observed
101
- * as a UI worker announcing it would put its logic in the very page
102
- * component the logic worker had been assigned.
103
- */
54
+ /** Workspace-relative scheduling declarations, not filesystem authorization. */
104
55
  readonly writes?: readonly string[];
105
56
  }
106
57
  interface ResolvedManagedAgentSpawnRequest extends ManagedAgentSpawnRequest {
@@ -151,6 +102,16 @@ interface ManagedAgentTeamOptions {
151
102
  readonly leadDescription?: string;
152
103
  readonly team?: AgentTeam | AgentTeamOptions;
153
104
  readonly maxWorkers?: number;
105
+ /**
106
+ * Automatically hold/continue the lead for pending work and wake it for reports.
107
+ * Defaults to true for this convenience helper. Set false for host-driven turns;
108
+ * reports remain delivered quietly and all lifecycle APIs stay available.
109
+ */
110
+ readonly autoLeadCoordination?: boolean;
111
+ /** Team tools exposed to workers; defaults to reporting. Full also enables peer coordination. */
112
+ readonly workerTeamTools?: false | 'reporting' | 'full';
113
+ /** Treat a clean completion with empty text as failure. Defaults to false (tool-only work is valid). */
114
+ readonly requireWorkerText?: boolean;
154
115
  /** Maximum UTF-8 worker task bytes. Defaults to 64 KiB. */
155
116
  readonly maxTaskBytes?: number;
156
117
  /** Maximum UTF-8 specialty bytes. Defaults to 8 KiB. */
@@ -189,10 +150,10 @@ interface ManagedAgentTeamOptions {
189
150
  readonly writeScopePolicy?: WriteScopeConflictPolicy;
190
151
  /**
191
152
  * Cap on how much of a dependency's result is handed to its dependents.
192
- * Defaults to 8 KiB per dependency.
153
+ * Defaults to 8 KiB per dependency; at least 4 bytes. Full results remain readable by scoped tool.
193
154
  */
194
155
  readonly maxDependencyReportBytes?: number;
195
- /** End-to-end deadline for one generated worker. Defaults to 10 minutes. */
156
+ /** Active run deadline, excluding queued dependencies and setup. Defaults to 10 minutes. */
196
157
  readonly workerTimeoutMs?: number;
197
158
  /** Maximum wait per worker event observer callback. Defaults to 1 second. */
198
159
  readonly observerTimeoutMs?: number;
@@ -247,13 +208,8 @@ interface ManagedAgentTeamOptions {
247
208
  /**
248
209
  * A dynamic harness whose lead can create specialized workers with spawn_agent.
249
210
  *
250
- * `spawn_agent` blocks the lead for as long as its worker runs, so it declares
251
- * that blocking to the team as a wait edge. Cycle detection is only as good as
252
- * the graph it can see: an unrecorded edge does not merely go unchecked, it
253
- * lets the cycle it completes through, and a worker waiting for the lead that
254
- * is waiting for it deadlocks both until a timeout.
255
- *
256
- * Each worker is a real connected AgentSession and remains addressable afterward.
211
+ * Spawning starts independent work without blocking the lead. Dependencies refer
212
+ * to the commissioned producer instance; closing its address cannot rebind them.
257
213
  */
258
214
  declare class ManagedAgentTeam {
259
215
  readonly team: AgentTeam;
@@ -269,7 +225,11 @@ declare class ManagedAgentTeam {
269
225
  private readonly holdWaitMs;
270
226
  private readonly spawnTimeoutMs;
271
227
  private readonly workerRuntimes;
272
- private readonly reservedNames;
228
+ /** Closed roster entries may still own an in-flight follow-up after a bounded close. */
229
+ private readonly drainingWrites;
230
+ private readonly preparing;
231
+ private readonly lifecycle;
232
+ private disposeTask;
273
233
  private workerSequence;
274
234
  private readonly maxDependencyReportBytes;
275
235
  private readonly roles;
@@ -326,6 +286,8 @@ declare class ManagedAgentTeam {
326
286
  * started later; the two used to be the same moment.
327
287
  */
328
288
  private beginWorker;
289
+ /** One handoff path for both already-settled and asynchronously released dependencies. */
290
+ private startWorker;
329
291
  /**
330
292
  * The `role` parameter, when the host declared any roles.
331
293
  *
@@ -385,7 +347,9 @@ declare class ManagedAgentTeam {
385
347
  private awaitWorkerNews;
386
348
  /** Every worker reachable through `dependsOn`, transitively. */
387
349
  private ancestorsOf;
388
- /** Whether every named worker has reached a final state. */
350
+ /** Includes team-owned follow-ups queued between session runs. */
351
+ private workerHasWork;
352
+ /** Whether every named worker has reached a final state without conflicting active writes. */
389
353
  private dependenciesSettled;
390
354
  /**
391
355
  * Start whatever was waiting on the worker that just settled.
@@ -399,6 +363,8 @@ declare class ManagedAgentTeam {
399
363
  private releaseDependents;
400
364
  /** What the dependencies produced, as context for a dependent about to start. */
401
365
  private dependencyReport;
366
+ /** Only this worker's commissioned producer instances are readable, including after closure. */
367
+ private dependencyReadTool;
402
368
  /**
403
369
  * Watch a detached worker run to its end and report it.
404
370
  *
@@ -433,6 +399,8 @@ declare class ManagedAgentTeam {
433
399
  private deliveryFor;
434
400
  /** Set when a worker report was delivered quietly and no round has read it. */
435
401
  private unreadReports;
402
+ private leadSteer;
403
+ private leadSignal;
436
404
  /**
437
405
  * Wait until no worker is outstanding and the lead has nothing left to do.
438
406
  *
@@ -474,6 +442,7 @@ declare class ManagedAgentTeam {
474
442
  * @returns The status it held before being closed.
475
443
  */
476
444
  closeWorker(name: string, reason?: unknown): Promise<ManagedAgentWorkerStatus>;
445
+ private closeRuntime;
477
446
  /**
478
447
  * Stop every worker this harness started.
479
448
  *
@@ -1 +1 @@
1
- {"version":3,"file":"managed.d.ts","names":[],"sources":["../../../src/agent/team/managed.ts"],"mappings":";;;;;;;;;;;KAuBK,yBAAyB,KAAK;;;;;;;;;cAUtB;;cAGA;;;;;;;;;;;;;;;;;KA6ED;;;;;;;;;;;;;;;UAgBK;;WAEN;;WAEA;;WAEA;;WAEA;;;KAIC;UAEK;;WAEN;WACA;;WAEA;;;;;WAKA,UAAU;;WAEV;;;;;;;;;;;;;;;WAeA;;;;;;;;;;WAUA;;UAGM,yCAAyC;WAC/C;WACA,SAAS;WACT;WACA;;UAGM;WACN;WACA;WACA;WACA;WACA;;;;;;;;;;KAWC;UAGK;WACN;WACA;WACA;WACA;WACA;;WAEA,SAAS;WACT;;WAEA;;WAEA;WACA,QAAQ;;WAER;WACA,SAAS;WACT;;UAGM;WACN,UAAU;WACV,MAAM;WACN;WACA;WACA,OAAO,YAAY;WACnB;;WAEA;;WAEA;;;;;;;;;;;;WAYA,sBAAsB;;;;;;;;WAQtB,iBAAiB;;;;;;;;;;;;WAYjB,mBAAmB;;;;;WAKnB;;WAEA;;WAEA;;;;;;;;WAQA;;;;;;;;;;WAUA;;;WAGA;;;;;;;;;WASA;;WAEA,iBAAiB;WACjB,iBACP,SAAS,qCACN,eAAe,QAAQ;WACnB,qBAAqB;aAAoC,QAAQ,uBAAuB;;WACxF,uBAAuB;aAAoC,QAAQ,uBAAuB;;;WAE1F,+BACP,SAAS,sCACL;aAAoC,QAAQ,uBAAuB;OACrE,QAAQ;aAAoC,QAAQ,uBAAuB;;;WAEtE,iBACP,gBACA,OAAO,yBACG;;;;;;;;;;;;;cAsED;WACF,MAAM;WACN,MAAM;WACN;mBACQ;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;UACT;mBACS;mBACA;EAEjB,YAAY,SAAS;;;;;;;;;;;;;;;;;;UAyDb;;EA6DR,IAAI,OAAO,YAAY,aAAY,yBAA8B,QAAQ;;;;;;;;;;;;;EAgBzE,MAAM;;;;;;;;;;;;EAsBA,MACJ,SAAS,0BACT,SAAS,cACR,QAAQ;;;;;;;UAwHH;;;;;;;;;;UA2CA;;UAeA;;;;;;;;;UAqBA;;;;;;;;;;;UAsBA;;;;;;;;;;;;UAwCA;;UASA;;;;;;;;;;;UAeM;;UAgBN;;UAWA;;;;;;;;;;UAiBM;;UAyBN;;;;;;;;;UA2BM;;;;;;;;;;;;;;;;;UAgFA;;;;;;UAwBN;;UAWA;;;;;;;;;;;;;EAcF,UAAU,SAAS,cAAc;;EAcvC,oBAAoB;UAIZ;;;;;;;;;;;EA4BF,YACJ,cACA;aAAoB;aAA6B,SAAS;MACzD,QAAQ;;;;;;;;;;;EA4BL,YACJ,cACA,mBACC,QAAQ;;;;;;;;;EAmDL,QAAQ,mBAA6D;;EAM3E,aAAa;UAWL;;;;;;;;;UAyHA;UAQM;UAmBN;UAQM;;iBAMA,uBAAuB,SAAS,0BAA0B;;;;;;;;;;;;;;;;;;;;;;iBAuF1D,uBACd,UAAU,2BACA"}
1
+ {"version":3,"file":"managed.d.ts","names":[],"sources":["../../../src/agent/team/managed.ts"],"mappings":";;;;;;;;;;;KAuBK,yBAAyB,KAAK;;;;;;;;;cAUtB;;cAGA;;KA0BD;;UAGK;;WAEN;;WAEA;;WAEA;;WAEA;;;KAIC;UAEK;;WAEN;WACA;;WAEA;;;;;WAKA,UAAU;;WAEV;;WAEA;;WAEA;;UAGM,yCAAyC;WAC/C;WACA,SAAS;WACT;WACA;;UAGM;WACN;WACA;WACA;WACA;WACA;;;;;;;;;;KAWC;UAGK;WACN;WACA;WACA;WACA;WACA;;WAEA,SAAS;WACT;;WAEA;;WAEA;WACA,QAAQ;;WAER;WACA,SAAS;WACT;;UAGM;WACN,UAAU;WACV,MAAM;WACN;WACA;WACA,OAAO,YAAY;WACnB;;;;;;WAMA;;WAEA;;WAEA;;WAEA;;WAEA;;;;;;;;;;;;WAYA,sBAAsB;;;;;;;;WAQtB,iBAAiB;;;;;;;;;;;;WAYjB,mBAAmB;;;;;WAKnB;;WAEA;;WAEA;;;;;;;;WAQA;;;;;;;;;;WAUA;;;WAGA;;;;;;;;;WASA;;WAEA,iBAAiB;WACjB,iBACP,SAAS,qCACN,eAAe,QAAQ;WACnB,qBAAqB;aAAoC,QAAQ,uBAAuB;;WACxF,uBAAuB;aAAoC,QAAQ,uBAAuB;;;WAE1F,+BACP,SAAS,sCACL;aAAoC,QAAQ,uBAAuB;OACrE,QAAQ;aAAoC,QAAQ,uBAAuB;;;WAEtE,iBACP,gBACA,OAAO,yBACG;;;;;;;;cAuED;WACF,MAAM;WACN,MAAM;WACN;mBACQ;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;;mBAEA;mBACA;mBAKA;UACT;UACA;mBACS;mBACA;EAEjB,YAAY,SAAS;;;;;;;;;;;;;;;;;;UA0Db;;EA6DR,IAAI,OAAO,YAAY,aAAY,yBAA8B,QAAQ;;;;;;;;;;;;;EAiBzE,MAAM;;;;;;;;;;;;EAwBA,MACJ,SAAS,0BACT,SAAS,cACR,QAAQ;;;;;;;UA6IH;;UAoCM;;;;;;;;;;UA8CN;;UAeA;;;;;;;;;UAqBA;;;;;;;;;;;UAsBA;;;;;;;;;;;;UA6CA;;UASA;;;;;;;;;;;UAeM;;UA0BN;;UAUA;;UASA;;;;;;;;;;UAgBM;;UAaN;;UA2BA;;;;;;;;;UAoCM;;;;;;;;;;;;;;;;;UAmFA;;;;;;UA6BN;;UAWA;UACA;UACA;;;;;;;;;;;;;EAcF,UAAU,SAAS,cAAc;;EAiBvC,oBAAoB;UAIZ;;;;;;;;;;;EA4BF,YACJ,cACA;aAAoB;aAA6B,SAAS;MACzD,QAAQ;;;;;;;;;;;EA4BL,YACJ,cACA,mBACC,QAAQ;UASG;;;;;;;;;EAqEd,QAAQ,mBAA6D;;EAYrE,aAAa;UAWL;;;;;;;;;UA2GA;UAQM;UAmBN;UAQM;;iBAMA,uBAAuB,SAAS,0BAA0B;;;;;;;;;;;;;;;;;;;;;;iBAuF1D,uBACd,UAAU,2BACA"}