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

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 (60) hide show
  1. package/dist/agent/define/session/config.js +1 -1
  2. package/dist/agent/define/session/config.js.map +1 -1
  3. package/dist/agent/define/session/types.d.ts +14 -0
  4. package/dist/agent/define/session/types.d.ts.map +1 -1
  5. package/dist/agent/define/session.d.ts.map +1 -1
  6. package/dist/agent/define/session.js +1 -1
  7. package/dist/agent/define/session.js.map +1 -1
  8. package/dist/agent/loop/events.d.ts +24 -1
  9. package/dist/agent/loop/events.d.ts.map +1 -1
  10. package/dist/agent/loop/run-turn.js +1 -1
  11. package/dist/agent/loop/run-turn.js.map +1 -1
  12. package/dist/agent/loop/schedule.d.ts.map +1 -1
  13. package/dist/agent/loop/schedule.js +1 -1
  14. package/dist/agent/loop/schedule.js.map +1 -1
  15. package/dist/agent/loop/turn/config.js +1 -1
  16. package/dist/agent/loop/turn/config.js.map +1 -1
  17. package/dist/agent/loop/turn/model-request-boundary.js +1 -1
  18. package/dist/agent/loop/turn/model-request-boundary.js.map +1 -1
  19. package/dist/agent/loop/turn/model-round.js +1 -1
  20. package/dist/agent/loop/turn/model-round.js.map +1 -1
  21. package/dist/agent/loop/turn/types.d.ts +35 -2
  22. package/dist/agent/loop/turn/types.d.ts.map +1 -1
  23. package/dist/agent/loop/types.d.ts +16 -0
  24. package/dist/agent/loop/types.d.ts.map +1 -1
  25. package/dist/agent/mode/run-agent.d.ts +9 -0
  26. package/dist/agent/mode/run-agent.d.ts.map +1 -1
  27. package/dist/agent/mode/run-agent.js +2 -2
  28. package/dist/agent/mode/run-agent.js.map +1 -1
  29. package/dist/agent/mode/user-input.d.ts.map +1 -1
  30. package/dist/agent/mode/user-input.js +1 -1
  31. package/dist/agent/mode/user-input.js.map +1 -1
  32. package/dist/agent/team/managed.d.ts.map +1 -1
  33. package/dist/agent/team/managed.js +1 -1
  34. package/dist/agent/team/managed.js.map +1 -1
  35. package/dist/agent/tool/capture.js +1 -1
  36. package/dist/agent/tool/capture.js.map +1 -1
  37. package/dist/agent/tool/definition.d.ts +7 -0
  38. package/dist/agent/tool/definition.d.ts.map +1 -1
  39. package/dist/agent/tool/definition.js.map +1 -1
  40. package/dist/agent.js +1 -1
  41. package/dist/composition/agent/public-event.d.ts +19 -0
  42. package/dist/composition/agent/public-event.d.ts.map +1 -0
  43. package/dist/composition/agent/public-event.js +2 -0
  44. package/dist/composition/agent/public-event.js.map +1 -0
  45. package/dist/composition/agent/session.js +1 -1
  46. package/dist/composition/agent/session.js.map +1 -1
  47. package/dist/composition/agent/types.d.ts +11 -1
  48. package/dist/composition/agent/types.d.ts.map +1 -1
  49. package/dist/index.d.ts +2 -1
  50. package/dist/index.js +1 -1
  51. package/dist/observability/bus.js +1 -1
  52. package/dist/primitives/version.d.ts +1 -1
  53. package/dist/primitives/version.js +1 -1
  54. package/dist/primitives/version.js.map +1 -1
  55. package/dist/runtime/registry.js +1 -1
  56. package/dist/runtime/with-retry.d.ts +15 -0
  57. package/dist/runtime/with-retry.d.ts.map +1 -1
  58. package/dist/runtime/with-retry.js +1 -1
  59. package/dist/runtime/with-retry.js.map +1 -1
  60. package/package.json +1 -1
@@ -51,6 +51,22 @@ interface TurnBounds {
51
51
  /** Stop tool work this many tokens before the hard total to reserve a report.
52
52
  * Ignored with maxTotalTokens: 'auto'. Zero disables the reserve. */
53
53
  readonly finalReportReserveTokens: number;
54
+ /**
55
+ * Extra steps a turn may take after its budget forced a final answer, used
56
+ * only when the caller supplies `RunTurnOptions.finalize` (deep mode does,
57
+ * defaulting this to 2). In them only the tools it names run, so a run that
58
+ * answered on its last step can still confirm that answer instead of ending
59
+ * unconfirmed. Zero (the default) ends the turn at the forced answer.
60
+ */
61
+ readonly finalizeSteps: number;
62
+ /**
63
+ * Wall-clock budget for the turn's work, excluding time spent waiting for a
64
+ * person. When it passes, the turn stops working and answers from what it
65
+ * has, like any other spent budget, rather than being cancelled with
66
+ * nothing. A model round already in flight is not interrupted. Default
67
+ * 'auto' imposes no time budget.
68
+ */
69
+ readonly maxTurnDurationMs: number | 'auto';
54
70
  readonly maxParallel: number;
55
71
  /** Maximum serialized bytes retained for one finalized tool result. */
56
72
  readonly maxToolResultBytes: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/agent/loop/types.ts"],"mappings":";;;;UAQiB;;WAEN;WACA;;;;;;;;;;;;;WAaA;;;;;;;;;;;;;;;;WAgBA;WACA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;;WAGA;WACA;;WAEA;;;;;;;;;;WAUA;;;;;;;;WAQA,oBAAoB;;WAEpB;;WAEA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/agent/loop/types.ts"],"mappings":";;;;UAQiB;;WAEN;WACA;;;;;;;;;;;;;WAaA;;;;;;;;;;;;;;;;WAgBA;WACA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;;WAGA;;;;;;;;WAQA;;;;;;;;WAQA;WACA;;WAEA;;;;;;;;;;WAUA;;;;;;;;WAQA,oBAAoB;;WAEpB;;WAEA"}
@@ -32,11 +32,20 @@ interface DeepAgentOptions extends AgentRunCommon {
32
32
  readonly mode: 'deep';
33
33
  /** Optional in deep mode: expose a blocking clarification tool when configured. */
34
34
  readonly userInput?: UserInputBroker;
35
+ /** How long a question waits for its answer; see {@link HumanInLoopAgentOptions.userInputTimeoutMs}. */
36
+ readonly userInputTimeoutMs?: number;
35
37
  }
36
38
  interface HumanInLoopAgentOptions extends AgentRunCommon {
37
39
  readonly mode: 'deep-human-in-loop';
38
40
  /** Required in HIL mode: the tool call remains parked until this broker answers. */
39
41
  readonly userInput: UserInputBroker;
42
+ /**
43
+ * How long a question waits for its answer, independent of
44
+ * `bounds.maxToolDurationMs` (which defaults it). When it passes, the model
45
+ * is told the person did not answer and continues without the answer; it is
46
+ * not treated as the person dismissing the question.
47
+ */
48
+ readonly userInputTimeoutMs?: number;
40
49
  }
41
50
  type RunAgentOptions = BasicAgentOptions | DeepAgentOptions | HumanInLoopAgentOptions;
42
51
  interface CompletionSubmission {
@@ -1 +1 @@
1
- {"version":3,"file":"run-agent.d.ts","names":[],"sources":["../../../src/agent/mode/run-agent.ts"],"mappings":";;;;;;;;;cAmBa,qBAAmB;WACpB;WACQ;;;KAmBR;UAEF,uBAAuB,KAAK;;WAE3B,QAAQ;WACR,QAAQ;WACR;;;WAGA;WACA,SAAS,KAAK,QAAQ;WACtB,aAAa;WACb,QAAQ;;UAGF,0BAA0B;WAChC;;UAGM,yBAAyB;WAC/B;;WAEA,YAAY;;UAGN,gCAAgC;WACtC;;WAEA,WAAW;;KAGV,kBAAkB,oBAAoB,mBAAmB;UAEpD;WACN;WACA;;UAGM,wBAAwB;WAC9B,MAAM;;WAEN;WACA,aAAa;;UAGd;WACC;WACA,MAAM;WACN;;UAED;WACC;WACA,SAAS;;UAEV;WACC;WACA,SAAS;WACT,UAAU;;UAEX;WACC;WACA,SAAS;;UAGV;WACC;WACA,eAAe;WACf,SAAS;;KAGR,gBAAgB,aAAa,4BACrC,sBACA,wBACA,yBACA;;;;;;;;iBAqDY,SAAS,SAAS,kBAAkB,cAAc"}
1
+ {"version":3,"file":"run-agent.d.ts","names":[],"sources":["../../../src/agent/mode/run-agent.ts"],"mappings":";;;;;;;;;cAoBa,qBAAmB;WACpB;WACQ;;;KAmBR;UAEF,uBAAuB,KAAK;;WAE3B,QAAQ;WACR,QAAQ;WACR;;;WAGA;WACA,SAAS,KAAK,QAAQ;WACtB,aAAa;WACb,QAAQ;;UAGF,0BAA0B;WAChC;;UAGM,yBAAyB;WAC/B;;WAEA,YAAY;;WAEZ;;UAGM,gCAAgC;WACtC;;WAEA,WAAW;;;;;;;WAOX;;KAGC,kBAAkB,oBAAoB,mBAAmB;UAEpD;WACN;WACA;;UAGM,wBAAwB;WAC9B,MAAM;;WAEN;WACA,aAAa;;UAGd;WACC;WACA,MAAM;WACN;;UAED;WACC;WACA,SAAS;;UAEV;WACC;WACA,SAAS;WACT,UAAU;;UAEX;WACC;WACA,SAAS;;UAGV;WACC;WACA,eAAe;WACf,SAAS;;KAGR,gBAAgB,aAAa,4BACrC,sBACA,wBACA,yBACA;;;;;;;;iBAqDY,SAAS,SAAS,kBAAkB,cAAc"}
@@ -1,4 +1,4 @@
1
- import{detachedFrozen as e}from"../../primitives/snapshot.js";import{waitForSettlement as t}from"../../async/settlement.js";import{createMessage as n,createUserMessage as r}from"../../message/message.js";import{defineTool as i}from"../tool/definition.js";import{readSpillTool as a}from"../tool/output-budget.js";import{AwaitedEventQueue as o}from"../loop/queue.js";import{UNCHANGED_ANSWER_MARKER as s}from"../loop/control-text.js";import{runTurn as c}from"../loop/run-turn.js";const l=Object.freeze({complete:`submit_result`,requestUserInput:`request_user_input`});function u(n){return{async*[Symbol.asyncIterator](){let r=new o,i=new AbortController,a=P(n.teardownTimeoutMs??3e4,`teardownTimeoutMs`),s=n.signal===void 0?i.signal:AbortSignal.any([n.signal,i.signal]),c=Promise.resolve(),l=d(n,s,t=>{let n=c.then(()=>r.push(e(t)));return c=n.catch(()=>void 0),n}).then(async()=>{await c,r.close()},async e=>{await c,r.fail(e)});try{for(;;){let e=await r.take();if(e.done)break;yield e.value}await l}finally{if(i.abort(Error(`agent event consumer stopped`)),r.close(),!await t(l,a)){let e=Error(`agent producer ignored cancellation for more than ${a}ms`,{cause:i.signal.reason});throw e.code=`AGENT_TEARDOWN_TIMEOUT`,e}}}}}async function d(e,t,r){let i=new Map,o=async e=>{if(e.type===`step-start`&&i.clear(),e.type===`text-delta`){let t=((i.get(e.index)??``)+e.text).replaceAll(s,``),n=Math.min(t.length,s.length-1);for(;n>0&&!`<<deep-mode:answer-unchanged>>`.startsWith(t.slice(-n));)n--;i.set(e.index,n===0?``:t.slice(-n));let a=n===0?t:t.slice(0,-n);a!==``&&await r({...e,text:a});return}if(e.type===`text-end`){let t=i.get(e.index)??``;i.delete(e.index),t!==``&&!e.incomplete&&await r({...e,type:`text-delta`,text:t}),await r({...e,text:e.text.replaceAll(s,``)});return}await r(e)},u=e.mode??`basic`;if(![`basic`,`deep`,`deep-human-in-loop`].includes(u))throw RangeError(`unsupported agent mode "${String(u)}"`);let d=`userInput`in e?e.userInput:void 0;if(u===`deep-human-in-loop`&&(d===void 0||typeof d.request!=`function`))throw TypeError(`deep-human-in-loop mode requires a UserInputBroker`);let S=e.maxTurns??16;if(S!==`auto`&&(!Number.isSafeInteger(S)||S<1))throw RangeError(`maxTurns must be a positive safe integer or 'auto'`);await o({type:`agent-start`,mode:u,maxTurns:S});let E={completion:void 0,userAborted:!1,unverifiedAnswers:0,completionInvalidated:void 0,draftAnswer:void 0,draftSeq:void 0,orphanMarkerNudged:!1,markerCut:!1,markerReply:!1},D=u!==`basic`,O=e.mode===`deep`||e.mode===`deep-human-in-loop`?d:void 0,k=[];e.spillStore!==void 0&&k.push(a(e.spillStore)),D&&k.push(y(E,e.history,e.tools)),O!==void 0&&u!==`basic`&&k.push(b(u,O,E,o,e.accounting));let M=k.length===0?e.tools:C(e.tools,k),N=D?x(e.hooks,e.history,E,S):e.hooks,P={registry:e.registry,config:e.config,history:e.history,...M===void 0?{}:{tools:M},...e.nativeTools===void 0?{}:{nativeTools:e.nativeTools},...e.toolChoice===void 0?{}:{toolChoice:e.toolChoice},...e.imagePolicy===void 0?{}:{imagePolicy:e.imagePolicy},...e.documentPolicy===void 0?{}:{documentPolicy:e.documentPolicy},...e.validateOutput===void 0?{}:{validateOutput:e.validateOutput},...e.outputFormat===void 0?{}:{outputFormat:e.outputFormat},system:j(e.system,A(u,O!==void 0)),...e.interceptors===void 0?{}:{interceptors:w(e.interceptors)},...e.approvals===void 0?{}:{approvals:e.approvals},bounds:{...e.bounds,maxSteps:S},...N===void 0?{}:{hooks:N},signal:t,...e.logger===void 0?{}:{logger:e.logger},commentary:e.commentary??`auto`,teardownTimeoutMs:e.teardownTimeoutMs??3e4,...e.modelTimeoutMs===void 0?{}:{modelTimeoutMs:e.modelTimeoutMs},...e.maxModelRequestBytes===void 0?{}:{maxModelRequestBytes:e.maxModelRequestBytes},...e.maxModelResponseBytes===void 0?{}:{maxModelResponseBytes:e.maxModelResponseBytes},...e.maxModelStreamEvents===void 0?{}:{maxModelStreamEvents:e.maxModelStreamEvents},...e.hookTimeoutMs===void 0?{}:{hookTimeoutMs:e.hookTimeoutMs},...e.hookTeardownTimeoutMs===void 0?{}:{hookTeardownTimeoutMs:e.hookTeardownTimeoutMs},...e.trace===void 0?{}:{trace:e.trace},...e.accounting===void 0?{}:{accounting:e.accounting},...e.spillStore===void 0?{}:{spillStore:e.spillStore},...e.experimentalPrograms===void 0?{}:{experimentalPrograms:e.experimentalPrograms},...e.contextSections===void 0?{}:{contextSections:e.contextSections}},F,I=[],L,R=!1,z=``,B=new Map,V=[],H,U,W,G=!1,K=e.history.entries().length,q,J=!1,Y=async()=>{let e=V;V=[];for(let t of e)await o(t)},X=async()=>{let e=V;V=[];for(let t of e)t.type!==`text-delta`&&t.type!==`text-end`&&await o(t)},Z=async t=>{if(U!==void 0&&(t.type===`assistant-text`||t.type===`assistant-reasoning`)&&t.messageId===U.from){await o({...t,messageId:U.message.id,...t.type===`assistant-text`?{text:t.text.replaceAll(s,``)}:{}});return}if(W===void 0||t.type!==`assistant-text`||t.messageId!==W){if(H!==void 0&&t.type===`assistant-reasoning`&&t.messageId===H.from){await o({...t,messageId:H.message.id});return}if(H!==void 0&&t.type===`assistant-text`&&t.messageId===H.from){if(J)return;J=!0;let e=H.message.content.find(e=>e.type===`text`);await o({...t,messageId:H.message.id,text:e?.type===`text`?e.text:t.text});return}if(t.type===`step-start`&&(K=e.history.entries().length,H=void 0,U=void 0,W=void 0,G=!1,J=!1,E.markerCut=!1,E.markerReply=!1,await Y(),v(E,e.history),R=!0,z=``,B.clear()),R&&(t.type===`text-delta`||t.type===`text-end`)){B.set(t.index,t.type===`text-end`?t.text:(B.get(t.index)??``)+t.text),z=[...B.values()].join(``),V.push(t),!p(z)&&!z.trimStart().startsWith(`<<deep-mode:answer-unchanged>>`)?(R=!1,await Y()):t.type===`text-end`&&t.incomplete&&(E.markerCut=!0);return}if(R&&t.type===`assistant-message`){let n=t.message.content,r=E.draftAnswer,i=f(n),a=i!==void 0&&(i.trim()===`<<deep-mode:answer-unchanged>>`||E.markerCut&&p(i));if(R=!1,a){E.markerReply=!0,E.resolvedMarkerAnswer=r??``,H={from:t.message.id,message:h(r??``,n)},g(e.history,H.message,E.markerCut),G=!0,r===void 0&&(W=t.message.id),await X(),q!==void 0&&await o({type:`assistant-replacement`,fromMessageId:q,message:H.message}),await o({...t,message:H.message});return}if(i?.includes(`<<deep-mode:answer-unchanged>>`)){E.resolvedMarkerAnswer=i.replaceAll(s,``).trim();let r=h(i.replaceAll(s,``).trim(),n);g(e.history,r),H={from:t.message.id,message:r};let a=V.find(e=>e.type===`text-end`)??V.find(e=>e.type===`text-delta`);await X(),(a?.type===`text-end`||a?.type===`text-delta`)&&(await o({type:`text-delta`,trace:a.trace,index:a.index,phase:`final-answer`,text:E.resolvedMarkerAnswer}),await o({type:`text-end`,trace:a.trace,index:a.index,phase:`final-answer`,text:E.resolvedMarkerAnswer})),await o({...t,message:r});return}E.markerCut=!1,await Y()}else if(V.length>0){if(t.type===`turn-end`&&R&&p(z))R=!1,E.markerCut=!0,await X();else if(t.type===`turn-end`||t.type===`tool-call`)R=!1,await Y();else{V.push(t);return}}if(t.type===`assistant-message`&&H===void 0){let r=t.message,i=r.content.flatMap(e=>e.type===`text`?[e.text]:[]).join(``);if(delete E.resolvedMarkerAnswer,i.includes(`<<deep-mode:answer-unchanged>>`)){let i=n({role:`assistant`,source:r.source,content:r.content.map(e=>e.type===`text`?{...e,text:e.text.replaceAll(s,``)}:e)});g(e.history,i),U={from:r.id,message:i},await o({...t,message:i});return}D&&!r.content.some(e=>e.type===`tool-call`)&&i.trim()!==``&&(E.completion!==void 0&&q!==void 0&&await o({type:`assistant-replacement`,fromMessageId:q,message:r}),q=r.id)}if(t.type===`assistant-text`){await o({...t,text:t.text.replaceAll(s,``)});return}await o(t)}};for await(let t of c(P)){if(t.type===`step-start`?(I=[],L=void 0):t.type===`tool-call`?(I.push(t.call.toolName),t.call.toolName!==l.complete&&M?.get(t.call.toolName)?.completionExempt!==!0&&(E.completion!==void 0&&(E.completionInvalidated=`tool`),E.completion=void 0,E.unverifiedAnswers=0)):t.type===`tool-result`&&t.call.toolName===l.complete&&!t.result.isError?t.result.value?.accepted===!0&&(L=T(t.result.value)):t.type===`step-end`&&L!==void 0&&I.filter(e=>e===l.complete).length===1&&I.every(e=>e===l.complete||M?.get(e)?.completionExempt===!0)&&(E.completion=L,E.completionSeq=e.history.entries().length,E.completionInvalidated=void 0),t.type===`turn-end`){R&&V.length>0&&p(z)&&(E.markerCut=!0),F=m(t.outcome,E),F!==t.outcome&&E.draftAnswer!==void 0&&!G&&g(e.history,H?.message??h(F.text),E.markerCut),await Z({...t,outcome:F});continue}await Z(t)}if(F===void 0)throw Error(`runTurn ended without a turn-end event`);v(E,e.history);let Q=(u===`basic`?F.reason.kind===`completed`&&F.text.trim()!==``||F.reason.kind===`concluded-by-tool`:E.completion!==void 0&&!E.userAborted&&(F.reason.kind===`completed`||F.reason.kind===`concluded-by-tool`||F.reason.kind===`budget-exhausted`&&F.reason.forcedFinalAnswer)&&F.text.trim()!==``)&&!_(e.history,K);await o({type:`agent-end`,outcome:{...F,mode:u,completed:Q,...E.completion===void 0?{}:{completion:E.completion}}})}function f(e){let t=e.filter(e=>e.type!==`reasoning`);return t.length>0&&t.every(e=>e.type===`text`)?t.map(e=>e.type===`text`?e.text:``).join(``):void 0}function p(e){let t=e.trim();return t.length===0||s.startsWith(t)}function m(e,t){return e.text.trim()===`<<deep-mode:answer-unchanged>>`&&t.resolvedMarkerAnswer!==void 0?{...e,text:t.resolvedMarkerAnswer}:e.text.trim()===`<<deep-mode:answer-unchanged>>`?{...e,text:t.completion!==void 0&&(t.markerReply||t.markerCut)?t.draftAnswer??``:``}:e.text.includes(`<<deep-mode:answer-unchanged>>`)?{...e,text:e.text.replaceAll(s,``).trim()}:!t.markerReply&&!t.markerCut||!(t.markerCut&&e.text.trim()!==``&&p(e.text))&&e.text.trim()!==`<<deep-mode:answer-unchanged>>`?e:{...e,text:t.draftAnswer??``}}function h(e,t){return n({role:`assistant`,content:t===void 0?[{type:`text`,text:e,phase:`final-answer`}]:[...t.filter(e=>e.type===`reasoning`),{type:`text`,text:e,phase:`final-answer`}],source:{kind:`app`,producer:e===``?`deep-mode-invalid-marker`:`deep-mode-kept-answer`}})}function g(e,t,n=!1){let r=e.entries(),i;for(let e=r.length-1;e>=0;e--){let t=r[e];if(t?.event.kind===`assistant`){i=t;break}}let a=i?.event.kind===`assistant`?i.event.message.content.flatMap(e=>e.type===`text`?[e.text]:[]).join(``):void 0;i!==void 0&&a!==void 0&&(!a.includes(`<<deep-mode:answer-unchanged>>`)&&!(n&&a.trim()!==``&&p(a))||e.append({kind:`assistant`,message:t},{op:`replace`,from:i.seq,to:i.seq}))}function _(e,t){return e.entries().slice(t??0).some(e=>e.event.kind===`user`&&[`user`,`agent-message`,`a2a-message`].includes(e.event.message.source.kind))}function v(e,t){e.completion!==void 0&&_(t,e.completionSeq)&&(e.completion=void 0,e.completionInvalidated=`input`),!(e.draftAnswer===void 0||!_(t,e.draftSeq))&&(e.draftAnswer=void 0,e.draftSeq=void 0)}function y(e,t,n){return i({name:l.complete,description:`Submit the self-check only when the user objective and constraints are fully satisfied. After acceptance, give the user the final answer.`,budgetExempt:!0,parameters:{type:`object`,properties:{summary:{type:`string`,description:`Concise statement of what was completed.`},evidence:{type:`array`,items:{type:`string`},description:`Concrete checks or tool results showing the objective is satisfied.`}},required:[`summary`,`evidence`],additionalProperties:!1},parse:D,execute:r=>{v(e,t);let i=t.messages().findLast(e=>e.role===`assistant`)?.content.filter(e=>e.type===`tool-call`)??[];return i.filter(e=>e.name===l.complete).length!==1||i.some(e=>e.name!==l.complete&&n?.get(e.name)?.completionExempt!==!0)?{accepted:!1,instruction:`Review the tool results, then call submit_result exactly once without substantive sibling tools. This batch has no accepted self-check.`}:{accepted:!0,summary:r.summary,evidence:[...r.evidence],instruction:e.draftAnswer===void 0?`This self-check is accepted for the current run. Now deliver the answer or artifact requested by the current user or assigned task, preserving its requested content and format. For exact text, only JSON, only a number, or another constrained format, return only the requested output. The summary and evidence in this tool result are verification metadata; keep them out of the final answer unless the task requests them. If the task requests a report, provide the substantive findings or changes, supporting evidence or sources, and relevant limitations. Do not merely say the self-check passed or refer to an earlier message. Do not call submit_result again in this run unless you perform new substantive tool work that invalidates this submission. A later user request or worker follow-up starts a new run and needs its own self-check.`:`This self-check is accepted for the current run. You already gave the user a complete answer earlier in this run, before this check. If no user message or delegated task arrived after that answer and it still satisfies every current requirement, reply with exactly ${s} and nothing else. If a user message or delegated task arrived after that answer, give the complete answer to the latest request in full, even if the earlier answer seems correct. If this check found something to correct or add, also give the complete corrected answer in full, as if the earlier one did not exist: never summarize it, point back to it, or say the self-check passed. Do not call submit_result again in this run unless you perform new substantive tool work that invalidates this submission. A later user request or worker follow-up starts a new run and needs its own self-check.`}}})}function b(e,t,n,r,a){return i({name:l.requestUserInput,budgetExempt:!0,description:e===`deep-human-in-loop`?`Ask the user one to three short questions when a material choice or missing fact requires human input, then wait for the response. Provide 2-3 mutually exclusive suggestions; free-form input is added by the client.`:`Ask the user one to three short clarification questions only when blocked, then wait for the response. Provide suggested choices; free-form input is added by the client.`,parameters:k(),parse:O,execute:async({questions:e},i)=>{let o=a?.startOperation(`user-input`,{toolCallId:i.callId,data:{questionCount:e.length}}),s={requestId:i.callId,callId:i.callId,turn:i.turn,step:i.step,questions:e,isBlocking:!0};try{let c=t.request(s,i.signal);await r({type:`user-input-request`,request:s});let l=await c;return await r({type:`user-input-response`,request:s,response:l}),l===`abort`?(n.userAborted=!0,i.concludeTurn(),o!==void 0&&a?.endOperation(o,`aborted`),{aborted:!0}):(n.draftAnswer=void 0,n.draftSeq=void 0,n.completion=void 0,o!==void 0&&a?.endOperation(o,`success`),E(l,e))}catch(e){throw i.signal.aborted&&await r({type:`user-input-response`,request:s,response:`abort`}),o!==void 0&&a?.endOperation(o,i.signal.aborted?`aborted`:`error`,{error:e}),e}}})}function x(e,t,n,i){return{...e,onTurnEnd:async a=>{let o=t.entries().length,c=m(a.outcome,n);if(await e?.onTurnEnd?.(c===a.outcome?a:{...a,outcome:c}),a.outcome.reason.kind===`completed`&&a.canContinue&&n.completion!==void 0&&n.draftAnswer===void 0&&!n.orphanMarkerNudged&&n.markerReply&&a.outcome.text.trim()===`<<deep-mode:answer-unchanged>>`){n.orphanMarkerNudged=!0,t.append({kind:`user`,message:r({source:{kind:`app`,producer:`deep-mode-self-check`},content:[{type:`text`,text:`There is no earlier answer in this run eligible for ${s} to keep. A new user or delegated task after the earlier answer makes it ineligible too. Reply with the answer itself now, in the requested format.`}]})});return}a.outcome.reason.kind!==`completed`||!a.canContinue||i!==`auto`&&a.outcome.steps>=i||n.completion!==void 0||n.userAborted||(n.unverifiedAnswers++,!(n.unverifiedAnswers>=3)&&(a.outcome.text.trim()!==``&&a.outcome.text.trim()!==`<<deep-mode:answer-unchanged>>`&&(n.draftAnswer=a.outcome.text,n.draftSeq=o),t.append({kind:`user`,message:r({source:{kind:`app`,producer:`deep-mode-self-check`},content:[{type:`text`,text:(n.completionInvalidated===void 0?``:n.completionInvalidated===`input`?`Your previously accepted submission is no longer current because a new user request or delegated task arrived afterwards. Review the latest input and call ${l.complete} again when complete; the old instruction not to resubmit no longer applies. `:`Your previously accepted submission is no longer current because you called another substantive tool afterwards. Review the later tool results and call ${l.complete} again when complete; the old instruction not to resubmit no longer applies. `)+`Self-check required: this run has no accepted current self-check. Acceptance recorded in an earlier run does not complete this request or follow-up; an earlier instruction not to resubmit applied only to that earlier run. Compare the current result against the user's objective and every constraint. If anything is missing, continue with tools. If blocked and request_user_input is available, ask the user. Only when the work is actually complete, call ${l.complete}. Keep verification in that tool call and then deliver the current user or assigned task's requested output in its original format. This reminder does not change the task or request a process report. Rephrasing a completion claim without submitting does not satisfy this gate.`}]})})))}}}var S=class{definitions;constructor(e,t){let n=new Map;for(let t of e?.names()??[]){let r=e?.get(t);r!==void 0&&n.set(t,r)}for(let e of t){if(n.has(e.name))throw Error(`tool name "${e.name}" is reserved by the selected agent mode`);n.set(e.name,e)}this.definitions=n}get(e){return this.definitions.get(e)}has(e){return this.definitions.has(e)}names(){return[...this.definitions.keys()]}schemas(){return[...this.definitions.values()].map(({name:e,description:t,parameters:n})=>({name:e,description:t,parameters:structuredClone(n)}))}executionMode(e,t){let n=this.definitions.get(e);if(n===void 0)return`exclusive`;try{return n.isConcurrencySafe?.(t)===!0?`parallel`:`exclusive`}catch{return`exclusive`}}};function C(e,t){return new S(e,t)}function w(e){let t=new Set(Object.values(l));return e.map(e=>({name:e.name,...e.before===void 0?{}:{before:(n,r)=>t.has(n.toolName)?r():e.before(n,r)},...e.around===void 0?{}:{around:(n,r)=>t.has(n.toolName)?r():e.around(n,r)},...e.after===void 0?{}:{after:(n,r,i)=>t.has(n.toolName)?i():e.after(n,r,i)}}))}function T(e){let t=M(e,`submit_result result`);return D({summary:t.summary,evidence:t.evidence})}function E(e,t){let n=new Set(t.map(e=>e.id));for(let t of n){let n=e.answers[t];if(n===void 0||!Array.isArray(n.answers)||n.answers.length===0||n.answers.some(e=>typeof e!=`string`||e.trim().length===0))throw Error(`the user-input broker returned no valid answer for "${t}"`)}for(let t of Object.keys(e.answers))if(!n.has(t))throw Error(`the user-input broker returned an answer for unknown question "${t}"`);return e}function D(e){let t=M(e,`submit_result arguments`);if(typeof t.summary!=`string`||t.summary.trim().length===0)throw Error(`summary must be a non-empty string`);if(!Array.isArray(t.evidence)||t.evidence.some(e=>typeof e!=`string`||e.trim().length===0))throw Error(`evidence must be an array of non-empty strings`);return{summary:t.summary,evidence:t.evidence}}function O(e){let t=M(e,`request_user_input arguments`);if(!Array.isArray(t.questions)||t.questions.length<1||t.questions.length>3)throw Error(`questions must contain one to three items`);let n=new Set,r=t.questions.map((e,t)=>{let r=M(e,`questions[${t}]`),i=N(r.id,`questions[${t}].id`);if(!/^[a-z][a-z0-9_]*$/.test(i))throw Error(`questions[${t}].id must be snake_case`);if(n.has(i))throw Error(`question id "${i}" is duplicated`);n.add(i);let a=N(r.header,`questions[${t}].header`),o=N(r.question,`questions[${t}].question`);if(!Array.isArray(r.options)||r.options.length<2||r.options.length>3)throw Error(`questions[${t}].options must contain two or three choices`);let s=r.options.map((e,n)=>{let r=M(e,`questions[${t}].options[${n}]`);return{label:N(r.label,`questions[${t}].options[${n}].label`),description:N(r.description,`questions[${t}].options[${n}].description`)}});return Object.freeze({id:i,header:a,question:o,options:Object.freeze(s),allowFreeForm:!0})});return{questions:Object.freeze(r)}}function k(){return{type:`object`,properties:{questions:{type:`array`,minItems:1,maxItems:3,description:`Questions to show the user. Prefer one and do not exceed three.`,items:{type:`object`,additionalProperties:!1,properties:{id:{type:`string`,description:`Stable snake_case answer key.`},header:{type:`string`,description:`Short UI label, ideally 12 characters or fewer.`},question:{type:`string`,description:`Single-sentence question.`},options:{type:`array`,minItems:2,maxItems:3,description:`Mutually exclusive choices. Put the recommended choice first and suffix its label with "(Recommended)". Do not add Other; the client supplies free-form input.`,items:{type:`object`,additionalProperties:!1,properties:{label:{type:`string`,description:`User-facing label, one to five words.`},description:{type:`string`,description:`One sentence explaining impact or trade-off.`}},required:[`label`,`description`]}}},required:[`id`,`header`,`question`,`options`]}}},required:[`questions`],additionalProperties:!1}}function A(e,t){if(e===`basic`)return[`Work as a bounded tool-using agent. Use available tools proactively when they materially improve correctness.`,`Stay within the configured iteration budget, then give the best final answer supported by the gathered results.`].join(` `);let n=t?`If a missing fact or material user choice blocks correct progress, call ${l.requestUserInput} and continue after the answer.`:`If blocked by missing user input, state that limitation plainly in the final response.`,r=e===`deep-human-in-loop`?`For material choices, surface 2-3 concise options with the recommended option first; the UI also permits free-form feedback.`:``;return[`Work autonomously in deep mode. After every tool result, compare the evidence against the user objective and all constraints; continue until gaps are closed.`,`Do not treat a plausible draft as completion. When the work is actually complete, call ${l.complete} with a summary and concrete evidence, then provide the final answer.`,`Put verification summaries and evidence in the self-check tool call. Deliver the current user or assigned task's requested answer or artifact in its requested format, including exact text or JSON. Add verification commentary only when that format permits it.`,n,r,`Never reveal private chain-of-thought. Use concise user-visible commentary for intent, progress, observations, and decisions.`].filter(Boolean).join(` `)}function j(...e){return e.filter(e=>e!==void 0&&e.length>0).join(`
1
+ import{detachedFrozen as e}from"../../primitives/snapshot.js";import{waitForSettlement as t}from"../../async/settlement.js";import{createMessage as n,createUserMessage as r}from"../../message/message.js";import{defineTool as i}from"../tool/definition.js";import{readSpillTool as a}from"../tool/output-budget.js";import{AwaitedEventQueue as o}from"../loop/queue.js";import{UNCHANGED_ANSWER_MARKER as s}from"../loop/control-text.js";import{runTurn as c}from"../loop/run-turn.js";import{userInputResponseProblem as l}from"./user-input.js";const u=Object.freeze({complete:`submit_result`,requestUserInput:`request_user_input`});function d(n){return{async*[Symbol.asyncIterator](){let r=new o,i=new AbortController,a=F(n.teardownTimeoutMs??3e4,`teardownTimeoutMs`),s=n.signal===void 0?i.signal:AbortSignal.any([n.signal,i.signal]),c=Promise.resolve(),l=f(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 f(e,t,i){let o=new Map,l=async e=>{if(e.type===`step-start`&&o.clear(),e.type===`text-delta`){let t=((o.get(e.index)??``)+e.text).replaceAll(s,``),n=Math.min(t.length,s.length-1);for(;n>0&&!`<<deep-mode:answer-unchanged>>`.startsWith(t.slice(-n));)n--;o.set(e.index,n===0?``:t.slice(-n));let r=n===0?t:t.slice(0,-n);r!==``&&await i({...e,text:r});return}if(e.type===`text-end`){let t=o.get(e.index)??``;o.delete(e.index),t!==``&&!e.incomplete&&await i({...e,type:`text-delta`,text:t}),await i({...e,text:e.text.replaceAll(s,``)});return}await i(e)},d=e.mode??`basic`;if(![`basic`,`deep`,`deep-human-in-loop`].includes(d))throw RangeError(`unsupported agent mode "${String(d)}"`);let f=`userInput`in e?e.userInput:void 0;if(d===`deep-human-in-loop`&&(f===void 0||typeof f.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 l({type:`agent-start`,mode:d,maxTurns:C});let D={completion:void 0,userAborted:!1,unverifiedAnswers:0,completionInvalidated:void 0,draftAnswer:void 0,draftSeq:void 0,orphanMarkerNudged:!1,markerCut:!1,markerReply:!1},O=d!==`basic`,k=e.mode===`deep`||e.mode===`deep-human-in-loop`?f:void 0,A=[];if(e.spillStore!==void 0&&A.push(a(e.spillStore)),O&&A.push(b(D,e.history,e.tools)),k!==void 0&&d!==`basic`){let t=F((`userInputTimeoutMs`in e?e.userInputTimeoutMs:void 0)??e.bounds?.maxToolDurationMs??6e5,`userInputTimeoutMs`);A.push(x(d,k,D,l,t,e.accounting))}let N=A.length===0?e.tools:w(e.tools,A),P=O?S(e.hooks,e.history,D):e.hooks,I={registry:e.registry,config:e.config,history:e.history,...N===void 0?{}:{tools:N},...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:M(e.system,j(d,k!==void 0)),...e.interceptors===void 0?{}:{interceptors:T(e.interceptors)},...e.approvals===void 0?{}:{approvals:e.approvals},bounds:{...e.bounds,maxSteps:C,finalizeSteps:e.bounds?.finalizeSteps??(O?2:0)},...O?{finalize:{tools:[u.complete],prompt:t=>{if(!(D.completion!==void 0||D.userAborted))return t.text.trim()!==`<<deep-mode:answer-unchanged>>`&&(D.draftAnswer=t.text,D.draftSeq=e.history.entries().length),r({source:{kind:`app`,producer:`deep-mode-self-check`},content:[{type:`text`,text:`The work budget for this run is spent, and your answer above has no accepted self-check. No research or work tool will run now; only ${u.complete} can. If the answer is supported by the evidence already gathered, call ${u.complete} alone with that self-check, stating any gaps honestly, then deliver the answer in its requested format. If it is not supported, do not submit; your answer above stands as an unconfirmed result.`}]})},confirmed:()=>D.completion!==void 0}}:{},...P===void 0?{}:{hooks:P},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}},L,R=[],z,B=!1,V=``,H=new Map,U=[],W,G,K,q=!1,J=e.history.entries().length,Y,X=!1,Z=async()=>{let e=U;U=[];for(let t of e)await l(t)},Q=async()=>{let e=U;U=[];for(let t of e)t.type!==`text-delta`&&t.type!==`text-end`&&await l(t)},$=async t=>{if(G!==void 0&&(t.type===`assistant-text`||t.type===`assistant-reasoning`)&&t.messageId===G.from){await l({...t,messageId:G.message.id,...t.type===`assistant-text`?{text:t.text.replaceAll(s,``)}:{}});return}if(K===void 0||t.type!==`assistant-text`||t.messageId!==K){if(W!==void 0&&t.type===`assistant-reasoning`&&t.messageId===W.from){await l({...t,messageId:W.message.id});return}if(W!==void 0&&t.type===`assistant-text`&&t.messageId===W.from){if(X)return;X=!0;let e=W.message.content.find(e=>e.type===`text`);await l({...t,messageId:W.message.id,text:e?.type===`text`?e.text:t.text});return}if(t.type===`step-start`&&(J=e.history.entries().length,W=void 0,G=void 0,K=void 0,q=!1,X=!1,D.markerCut=!1,D.markerReply=!1,await Z(),y(D,e.history),B=!0,V=``,H.clear()),B&&(t.type===`text-delta`||t.type===`text-end`)){H.set(t.index,t.type===`text-end`?t.text:(H.get(t.index)??``)+t.text),V=[...H.values()].join(``),U.push(t),!m(V)&&!V.trimStart().startsWith(`<<deep-mode:answer-unchanged>>`)?(B=!1,await Z()):t.type===`text-end`&&t.incomplete&&(D.markerCut=!0);return}if(B&&t.type===`assistant-message`){let n=t.message.content,r=D.draftAnswer,i=p(n),a=i!==void 0&&(i.trim()===`<<deep-mode:answer-unchanged>>`||D.markerCut&&m(i));if(B=!1,a){D.markerReply=!0,D.resolvedMarkerAnswer=r??``,W={from:t.message.id,message:g(r??``,n)},_(e.history,W.message,D.markerCut),q=!0,r===void 0&&(K=t.message.id),await Q(),Y!==void 0&&await l({type:`assistant-replacement`,fromMessageId:Y,message:W.message}),await l({...t,message:W.message});return}if(i?.includes(`<<deep-mode:answer-unchanged>>`)){D.resolvedMarkerAnswer=i.replaceAll(s,``).trim();let r=g(i.replaceAll(s,``).trim(),n);_(e.history,r),W={from:t.message.id,message:r};let a=U.find(e=>e.type===`text-end`)??U.find(e=>e.type===`text-delta`);await Q(),(a?.type===`text-end`||a?.type===`text-delta`)&&(await l({type:`text-delta`,trace:a.trace,index:a.index,phase:`final-answer`,text:D.resolvedMarkerAnswer}),await l({type:`text-end`,trace:a.trace,index:a.index,phase:`final-answer`,text:D.resolvedMarkerAnswer})),await l({...t,message:r});return}D.markerCut=!1,await Z()}else if(U.length>0){if(t.type===`turn-end`&&B&&m(V))B=!1,D.markerCut=!0,await Q();else if(t.type===`turn-end`||t.type===`tool-call`)B=!1,await Z();else{U.push(t);return}}if(t.type===`assistant-message`&&W===void 0){let r=t.message,i=r.content.flatMap(e=>e.type===`text`?[e.text]:[]).join(``);if(delete D.resolvedMarkerAnswer,i.includes(`<<deep-mode:answer-unchanged>>`)){let i=n({role:`assistant`,source:r.source,content:r.content.map(e=>e.type===`text`?{...e,text:e.text.replaceAll(s,``)}:e)});_(e.history,i),G={from:r.id,message:i},await l({...t,message:i});return}O&&!r.content.some(e=>e.type===`tool-call`)&&i.trim()!==``&&(D.completion!==void 0&&Y!==void 0&&await l({type:`assistant-replacement`,fromMessageId:Y,message:r}),Y=r.id)}if(t.type===`assistant-text`){await l({...t,text:t.text.replaceAll(s,``)});return}await l(t)}};for await(let t of c(I)){if(t.type===`step-start`)R=[],z=void 0;else if(t.type===`tool-result`){let e=t.dispatched!==!1;e&&R.push(t.call.toolName),e&&t.call.toolName!==u.complete&&N?.get(t.call.toolName)?.completionExempt!==!0&&(D.completion!==void 0&&(D.completionInvalidated=`tool`),D.completion=void 0,D.unverifiedAnswers=0),t.call.toolName===u.complete&&!t.result.isError&&t.result.value?.accepted===!0&&(z=E(t.result.value))}else t.type===`step-end`&&z!==void 0&&R.filter(e=>e===u.complete).length===1&&R.every(e=>e===u.complete||N?.get(e)?.completionExempt===!0)&&(D.completion=z,D.completionSeq=e.history.entries().length,D.completionInvalidated=void 0);if(t.type===`turn-end`){B&&U.length>0&&m(V)&&(D.markerCut=!0),L=h(t.outcome,D),L!==t.outcome&&D.draftAnswer!==void 0&&!q&&_(e.history,W?.message??g(L.text),D.markerCut),await $({...t,outcome:L});continue}await $(t)}if(L===void 0)throw Error(`runTurn ended without a turn-end event`);y(D,e.history);let ee=(d===`basic`?L.reason.kind===`completed`&&L.text.trim()!==``||L.reason.kind===`concluded-by-tool`:D.completion!==void 0&&!D.userAborted&&(L.reason.kind===`completed`||L.reason.kind===`concluded-by-tool`||L.reason.kind===`budget-exhausted`&&L.reason.forcedFinalAnswer)&&L.text.trim()!==``)&&!v(e.history,J);await l({type:`agent-end`,outcome:{...L,mode:d,completed:ee,...D.completion===void 0?{}:{completion:D.completion}}})}function p(e){let t=e.filter(e=>e.type!==`reasoning`);return t.length>0&&t.every(e=>e.type===`text`)?t.map(e=>e.type===`text`?e.text:``).join(``):void 0}function m(e){let t=e.trim();return t.length===0||s.startsWith(t)}function h(e,t){return e.text.trim()===`<<deep-mode:answer-unchanged>>`&&t.resolvedMarkerAnswer!==void 0?{...e,text:t.resolvedMarkerAnswer}:e.text.trim()===`<<deep-mode:answer-unchanged>>`?{...e,text:t.completion!==void 0&&(t.markerReply||t.markerCut)?t.draftAnswer??``:``}:e.text.includes(`<<deep-mode:answer-unchanged>>`)?{...e,text:e.text.replaceAll(s,``).trim()}:!t.markerReply&&!t.markerCut||!(t.markerCut&&e.text.trim()!==``&&m(e.text))&&e.text.trim()!==`<<deep-mode:answer-unchanged>>`?e:{...e,text:t.draftAnswer??``}}function g(e,t){return n({role:`assistant`,content:t===void 0?[{type:`text`,text:e,phase:`final-answer`}]:[...t.filter(e=>e.type===`reasoning`),{type:`text`,text:e,phase:`final-answer`}],source:{kind:`app`,producer:e===``?`deep-mode-invalid-marker`:`deep-mode-kept-answer`}})}function _(e,t,n=!1){let r=e.entries(),i;for(let e=r.length-1;e>=0;e--){let t=r[e];if(t?.event.kind===`assistant`){i=t;break}}let a=i?.event.kind===`assistant`?i.event.message.content.flatMap(e=>e.type===`text`?[e.text]:[]).join(``):void 0;i!==void 0&&a!==void 0&&(!a.includes(`<<deep-mode:answer-unchanged>>`)&&!(n&&a.trim()!==``&&m(a))||e.append({kind:`assistant`,message:t},{op:`replace`,from:i.seq,to:i.seq}))}function v(e,t){return e.entries().slice(t??0).some(e=>e.event.kind===`user`&&[`user`,`agent-message`,`a2a-message`].includes(e.event.message.source.kind))}function y(e,t){e.completion!==void 0&&v(t,e.completionSeq)&&(e.completion=void 0,e.completionInvalidated=`input`),!(e.draftAnswer===void 0||!v(t,e.draftSeq))&&(e.draftAnswer=void 0,e.draftSeq=void 0)}function b(e,t,n){return i({name:u.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:O,execute:r=>{y(e,t);let i=t.messages().findLast(e=>e.role===`assistant`)?.content.filter(e=>e.type===`tool-call`)??[];return i.filter(e=>e.name===u.complete).length!==1||i.some(e=>e.name!==u.complete&&n?.get(e.name)?.completionExempt!==!0)?{accepted:!1,instruction:`Review the tool results, then call submit_result exactly once without substantive sibling tools. This batch has no accepted self-check.`}:{accepted:!0,summary:r.summary,evidence:[...r.evidence],instruction:e.draftAnswer===void 0?`This self-check is accepted for the current run. Now deliver the answer or artifact requested by the current user or assigned task, preserving its requested content and format. For exact text, only JSON, only a number, or another constrained format, return only the requested output. The summary and evidence in this tool result are verification metadata; keep them out of the final answer unless the task requests them. If the task requests a report, provide the substantive findings or changes, supporting evidence or sources, and relevant limitations. Do not merely say the self-check passed or refer to an earlier message. Do not call submit_result again in this run unless you perform new substantive tool work that invalidates this submission. A later user request or worker follow-up starts a new run and needs its own self-check.`:`This self-check is accepted for the current run. You already gave the user a complete answer earlier in this run, before this check. If no user message or delegated task arrived after that answer and it still satisfies every current requirement, reply with exactly ${s} and nothing else. If a user message or delegated task arrived after that answer, give the complete answer to the latest request in full, even if the earlier answer seems correct. If this check found something to correct or add, also give the complete corrected answer in full, as if the earlier one did not exist: never summarize it, point back to it, or say the self-check passed. Do not call submit_result again in this run unless you perform new substantive tool work that invalidates this submission. A later user request or worker follow-up starts a new run and needs its own self-check.`}}})}function x(e,t,n,r,a,o){return i({name:u.requestUserInput,budgetExempt:!0,awaitsPerson:!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:A(),parse:k,execute:async({questions:e},i)=>{let s=o?.startOperation(`user-input`,{toolCallId:i.callId,data:{questionCount:e.length}}),c={requestId:i.callId,callId:i.callId,turn:i.turn,step:i.step,questions:e,isBlocking:!0},l=AbortSignal.timeout(a);try{let u=t.request(c,AbortSignal.any([i.signal,l]));u.catch(()=>void 0),await r({type:`user-input-request`,request:c});let d=await new Promise((e,t)=>{let n=()=>{l.removeEventListener(`abort`,r),i.signal.removeEventListener(`abort`,r)},r=()=>{n(),e(`abort`)};if(l.aborted||i.signal.aborted){r();return}l.addEventListener(`abort`,r,{once:!0}),i.signal.addEventListener(`abort`,r,{once:!0}),u.then(t=>{n(),e(t)},e=>{n(),t(e)})});return await r({type:`user-input-response`,request:c,response:d}),d===`abort`&&l.aborted&&!i.signal.aborted?(s!==void 0&&o?.endOperation(s,`aborted`),{answered:!1,reason:`The user did not answer within ${Math.round(a/1e3)} seconds. Continue without their answer: state the assumption you make for each open question, and do not ask the same questions again in this run.`}):d===`abort`?(n.userAborted=!0,i.concludeTurn(),s!==void 0&&o?.endOperation(s,`aborted`),{aborted:!0}):(n.draftAnswer=void 0,n.draftSeq=void 0,n.completion=void 0,s!==void 0&&o?.endOperation(s,`success`),D(d,e))}catch(e){throw i.signal.aborted&&await r({type:`user-input-response`,request:c,response:`abort`}),s!==void 0&&o?.endOperation(s,i.signal.aborted?`aborted`:`error`,{error:e}),e}}})}function S(e,t,n){return{...e,onTurnEnd:async i=>{let a=t.entries().length,o=h(i.outcome,n);if(await e?.onTurnEnd?.(o===i.outcome?i:{...i,outcome:o}),i.outcome.reason.kind===`completed`&&i.canContinue&&n.completion!==void 0&&n.draftAnswer===void 0&&!n.orphanMarkerNudged&&n.markerReply&&i.outcome.text.trim()===`<<deep-mode:answer-unchanged>>`){n.orphanMarkerNudged=!0,t.append({kind:`user`,message:r({source:{kind:`app`,producer:`deep-mode-self-check`},content:[{type:`text`,text:`There is no earlier answer in this run eligible for ${s} to keep. A new user or delegated task after the earlier answer makes it ineligible too. Reply with the answer itself now, in the requested format.`}]})});return}i.outcome.reason.kind!==`completed`||!i.canContinue||n.completion!==void 0||n.userAborted||(n.unverifiedAnswers++,!(n.unverifiedAnswers>=3)&&(i.outcome.text.trim()!==``&&i.outcome.text.trim()!==`<<deep-mode:answer-unchanged>>`&&(n.draftAnswer=i.outcome.text,n.draftSeq=a),t.append({kind:`user`,message:r({source:{kind:`app`,producer:`deep-mode-self-check`},content:[{type:`text`,text:(n.completionInvalidated===void 0?``:n.completionInvalidated===`input`?`Your previously accepted submission is no longer current because a new user request or delegated task arrived afterwards. Review the latest input and call ${u.complete} again when complete; the old instruction not to resubmit no longer applies. `:`Your previously accepted submission is no longer current because you called another substantive tool afterwards. Review the later tool results and call ${u.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 ${u.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 C=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 w(e,t){return new C(e,t)}function T(e){let t=new Set(Object.values(u));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 E(e){let t=N(e,`submit_result result`);return O({summary:t.summary,evidence:t.evidence})}function D(e,t){let n=l(t,e);if(n!==void 0)throw Error(`the user-input broker returned ${n}`);return e}function O(e){let t=N(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 k(e){let t=N(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=N(e,`questions[${t}]`),i=P(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=P(r.header,`questions[${t}].header`),o=P(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=N(e,`questions[${t}].options[${n}]`);return{label:P(r.label,`questions[${t}].options[${n}].label`),description:P(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 A(){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 j(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 ${u.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 ${u.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 M(...e){return e.filter(e=>e!==void 0&&e.length>0).join(`
2
2
 
3
- `)}function M(e,t){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} must be an object`);return e}function N(e,t){if(typeof e!=`string`||e.trim().length===0)throw Error(`${t} must be a non-empty string`);return e}function P(e,t){if(!Number.isFinite(e)||e<=0)throw RangeError(`${t} must be a positive finite number`);return e}export{l as AGENT_CONTROL_TOOLS,s as UNCHANGED_ANSWER_MARKER,u as runAgent};
3
+ `)}function N(e,t){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`${t} must be an object`);return e}function P(e,t){if(typeof e!=`string`||e.trim().length===0)throw Error(`${t} must be a non-empty string`);return e}function F(e,t){if(!Number.isFinite(e)||e<=0)throw RangeError(`${t} must be a positive finite number`);return e}export{u as AGENT_CONTROL_TOOLS,s as UNCHANGED_ANSWER_MARKER,d 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 { 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 { UNCHANGED_ANSWER_MARKER } from '../loop/control-text.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 { UNCHANGED_ANSWER_MARKER }\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\ninterface AssistantReplacementEvent {\n readonly type: 'assistant-replacement'\n readonly fromMessageId: Message['id']\n readonly message: Message\n}\n\nexport type AgentRunEvent = AgentEvent | AssistantReplacementEvent\n | AgentModeStartEvent\n | UserInputRequestEvent\n | UserInputResponseEvent\n | AgentModeEndEvent\n\ninterface DeepState {\n completion: CompletionSubmission | undefined\n completionSeq?: number\n userAborted: boolean\n /** Answers without intervening substantive tool work or an accepted check. */\n unverifiedAnswers: number\n completionInvalidated: 'tool' | 'input' | undefined\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 * History length when {@link draftAnswer} was recorded. A message from the\n * user or another agent after that point changes the request the draft\n * answered, so the draft can no longer stand on its own.\n */\n draftSeq: number | 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 /** Canonical answer of a control reply, retained if a later round has no message. */\n resolvedMarkerAnswer?: string\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 emitRaw: (event: AgentRunEvent) => Promise<void>,\n): Promise<void> {\n const textTails = new Map<number, string>()\n const emit = async (event: AgentRunEvent): Promise<void> => {\n if (event.type === 'step-start') textTails.clear()\n if (event.type === 'text-delta') {\n const text = ((textTails.get(event.index) ?? '') + event.text).replaceAll(UNCHANGED_ANSWER_MARKER, '')\n let suffix = Math.min(text.length, UNCHANGED_ANSWER_MARKER.length - 1)\n while (suffix > 0 && !UNCHANGED_ANSWER_MARKER.startsWith(text.slice(-suffix))) suffix--\n textTails.set(event.index, suffix === 0 ? '' : text.slice(-suffix))\n const safe = suffix === 0 ? text : text.slice(0, -suffix)\n if (safe !== '') await emitRaw({ ...event, text: safe })\n return\n }\n if (event.type === 'text-end') {\n const tail = textTails.get(event.index) ?? ''\n textTails.delete(event.index)\n if (tail !== '' && !event.incomplete) await emitRaw({ ...event, type: 'text-delta', text: tail })\n await emitRaw({ ...event, text: event.text.replaceAll(UNCHANGED_ANSWER_MARKER, '') })\n return\n }\n await emitRaw(event)\n }\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: undefined,\n draftAnswer: undefined, draftSeq: 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, options.history, options.tools))\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 const candidateBlocks = new Map<number, string>()\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 let sanitized: { 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 let lastRequestSeq = options.history.entries().length\n let draftMessageId: Message['id'] | undefined\n let keptTextEmitted = 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 if (sanitized !== undefined && (event.type === 'assistant-text' || event.type === 'assistant-reasoning') && event.messageId === sanitized.from) {\n await emit({ ...event, messageId: sanitized.message.id, ...(event.type === 'assistant-text' ? { text: event.text.replaceAll(UNCHANGED_ANSWER_MARKER, '') } : {}) })\n return\n }\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 if (keptTextEmitted) return\n keptTextEmitted = true\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 lastRequestSeq = options.history.entries().length\n kept = undefined\n sanitized = undefined\n orphan = undefined\n keptRestored = false\n keptTextEmitted = false\n state.markerCut = false\n state.markerReply = false\n await flushHeld()\n // Inputs queued during the submitting tool round enter history only at\n // its step boundary, after submit_result has built its instruction.\n // Recheck before the confirming model request can use the old draft.\n invalidateDraftAfterSteering(state, options.history)\n // Reserve the marker in every mode and round, including later runs\n // imitating an earlier accept.\n markerCandidate = true\n candidateText = ''\n candidateBlocks.clear()\n }\n if (markerCandidate && (event.type === 'text-delta' || event.type === 'text-end')) {\n candidateBlocks.set(event.index, event.type === 'text-end' ? event.text : (candidateBlocks.get(event.index) ?? '') + event.text)\n candidateText = [...candidateBlocks.values()].join('')\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) && !candidateText.trimStart().startsWith(UNCHANGED_ANSWER_MARKER)) {\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 state.resolvedMarkerAnswer = draft ?? ''\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 if (draftMessageId !== undefined) await emit({ type: 'assistant-replacement', fromMessageId: draftMessageId, message: kept.message })\n await emit({ ...event, message: kept.message })\n return\n }\n if (only?.includes(UNCHANGED_ANSWER_MARKER)) {\n state.resolvedMarkerAnswer = only.replaceAll(UNCHANGED_ANSWER_MARKER, '').trim()\n const replacement = keptAnswerMessage(only.replaceAll(UNCHANGED_ANSWER_MARKER, '').trim(), content)\n restoreKeptAnswer(options.history, replacement)\n kept = { from: event.message.id, message: replacement }\n const textEvent = heldEvents.find(held => held.type === 'text-end')\n ?? heldEvents.find(held => held.type === 'text-delta')\n await dropHeldText()\n if (textEvent?.type === 'text-end' || textEvent?.type === 'text-delta') {\n await emit({ type: 'text-delta', trace: textEvent.trace, index: textEvent.index, phase: 'final-answer', text: state.resolvedMarkerAnswer })\n await emit({ type: 'text-end', trace: textEvent.trace, index: textEvent.index, phase: 'final-answer', text: state.resolvedMarkerAnswer })\n }\n await emit({ ...event, message: replacement })\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 if (event.type === 'assistant-message' && kept === undefined) {\n const message = event.message\n const combined = message.content.flatMap(block => block.type === 'text' ? [block.text] : []).join('')\n delete state.resolvedMarkerAnswer\n if (combined.includes(UNCHANGED_ANSWER_MARKER)) {\n const replacement = createMessage({ role: 'assistant', source: message.source, content: message.content.map(block => block.type === 'text'\n ? { ...block, text: block.text.replaceAll(UNCHANGED_ANSWER_MARKER, '') } : block) })\n restoreKeptAnswer(options.history, replacement)\n sanitized = { from: message.id, message: replacement }\n await emit({ ...event, message: replacement })\n return\n }\n if (deep && !message.content.some(block => block.type === 'tool-call') && combined.trim() !== '') {\n if (state.completion !== undefined && draftMessageId !== undefined) {\n await emit({ type: 'assistant-replacement', fromMessageId: draftMessageId, message })\n }\n draftMessageId = message.id\n }\n }\n if (event.type === 'assistant-text') {\n await emit({ ...event, text: event.text.replaceAll(UNCHANGED_ANSWER_MARKER, '') })\n return\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 = 'tool'\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 if ((event.result.value as JsonObject | undefined)?.accepted === true) 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.completionSeq = options.history.entries().length\n state.completionInvalidated = undefined\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 invalidateDraftAfterSteering(state, options.history)\n const completionEligible = mode === 'basic'\n ? (terminal.reason.kind === 'completed' && terminal.text.trim() !== '') || 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 completed = completionEligible && !taskChangedSince(options.history, lastRequestSeq)\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 combined text, 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 > 0 && said.every(block => block.type === 'text')\n ? said.map(block => block.type === 'text' ? block.text : '').join('') : 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 (outcome.text.trim() === UNCHANGED_ANSWER_MARKER && state.resolvedMarkerAnswer !== undefined) {\n return { ...outcome, text: state.resolvedMarkerAnswer }\n }\n if (outcome.text.trim() === UNCHANGED_ANSWER_MARKER) return { ...outcome, text: state.completion !== undefined && (state.markerReply || state.markerCut) ? state.draftAnswer ?? '' : '' }\n if (outcome.text.includes(UNCHANGED_ANSWER_MARKER)) return { ...outcome, text: outcome.text.replaceAll(UNCHANGED_ANSWER_MARKER, '').trim() }\n if (!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.filter(block => block.type === 'reasoning'),\n { type: 'text' as const, text: draftAnswer, phase: 'final-answer' as const }],\n source: { kind: 'app', producer: draftAnswer === '' ? 'deep-mode-invalid-marker' : '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'\n ? target.event.message.content.flatMap(block => block.type === 'text' ? [block.text] : []).join('') : undefined\n if (target === undefined || only === undefined) return\n if (!only.includes(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\n/** Whether a new user or delegated task arrived after the given history position. */\nfunction taskChangedSince(history: RunAgentOptions['history'], seq: number | undefined): boolean {\n return history.entries().slice(seq ?? 0)\n .some(entry => entry.event.kind === 'user' && ['user', 'agent-message', 'a2a-message']\n .includes(entry.event.message.source.kind))\n}\n\nfunction invalidateDraftAfterSteering(state: DeepState, history: RunAgentOptions['history']): void {\n if (state.completion !== undefined && taskChangedSince(history, state.completionSeq)) {\n state.completion = undefined\n state.completionInvalidated = 'input'\n }\n if (state.draftAnswer === undefined || !taskChangedSince(history, state.draftSeq)) return\n state.draftAnswer = undefined\n state.draftSeq = undefined\n}\n\nfunction completionTool(state: DeepState, history: RunAgentOptions['history'], tools?: ToolCatalog): 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 // A newer user or delegated task changes what the draft answered, so\n // \"the earlier answer still stands\" is no longer a truthful reply: the\n // model is asked for the answer in full, and a marker it sends anyway is\n // treated as having nothing to keep.\n invalidateDraftAfterSteering(state, history)\n const calls = history.messages().findLast(message => message.role === 'assistant')?.content\n .filter(block => block.type === 'tool-call') ?? []\n if (calls.filter(call => call.name === AGENT_CONTROL_TOOLS.complete).length !== 1\n || calls.some(call => call.name !== AGENT_CONTROL_TOOLS.complete && tools?.get(call.name)?.completionExempt !== true)) {\n return { accepted: false, instruction: 'Review the tool results, then call submit_result exactly once without substantive sibling tools. This batch has no accepted self-check.' }\n }\n return {\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 no user message or delegated task arrived after that answer and it still satisfies every current requirement, reply with exactly ${UNCHANGED_ANSWER_MARKER} and nothing else. If a user message or delegated task arrived after that answer, give the complete answer to the latest request in full, even if the earlier answer seems correct. If this check found something to correct or add, also give the complete corrected answer in full, as if the earlier one did not exist: never summarize it, point back to it, or say the self-check passed. Do not call submit_result again in this run unless you perform new substantive tool work that invalidates this submission. A later user request or worker follow-up starts a new run and needs its own self-check.`,\n }\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 state.draftAnswer = undefined\n state.draftSeq = undefined\n state.completion = undefined\n if (operation !== undefined) accounting?.endOperation(operation, 'success')\n return validateUserResponse(response, questions) as unknown as JsonObject\n } catch (error) {\n if (ctx.signal.aborted) await emit({ type: 'user-input-response', request, response: 'abort' })\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 // Capture before an async host hook can append another request. That\n // request was not part of the model round that produced this draft.\n const draftSeq = history.entries().length\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 eligible for ${UNCHANGED_ANSWER_MARKER} to keep. A new user or delegated task after the earlier answer makes it ineligible too. Reply with the answer itself now, in the requested format.` }],\n }) })\n return\n }\n if (context.outcome.reason.kind !== 'completed'\n || !context.canContinue\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 state.draftSeq = draftSeq\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 !== undefined\n ? state.completionInvalidated === 'input'\n ? `Your previously accepted submission is no longer current because a new user request or delegated task arrived afterwards. Review the latest input and call ${AGENT_CONTROL_TOOLS.complete} again when complete; the old instruction not to resubmit no longer applies. `\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
+ {"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 { UNCHANGED_ANSWER_MARKER } from '../loop/control-text.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, UserInputDecision, UserInputQuestion, UserInputRequest, UserInputResponse,\n} from './user-input.ts'\nimport { userInputResponseProblem } 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 { UNCHANGED_ANSWER_MARKER }\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 /** How long a question waits for its answer; see {@link HumanInLoopAgentOptions.userInputTimeoutMs}. */\n readonly userInputTimeoutMs?: number\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 * How long a question waits for its answer, independent of\n * `bounds.maxToolDurationMs` (which defaults it). When it passes, the model\n * is told the person did not answer and continues without the answer; it is\n * not treated as the person dismissing the question.\n */\n readonly userInputTimeoutMs?: number\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\ninterface AssistantReplacementEvent {\n readonly type: 'assistant-replacement'\n readonly fromMessageId: Message['id']\n readonly message: Message\n}\n\nexport type AgentRunEvent = AgentEvent | AssistantReplacementEvent\n | AgentModeStartEvent\n | UserInputRequestEvent\n | UserInputResponseEvent\n | AgentModeEndEvent\n\ninterface DeepState {\n completion: CompletionSubmission | undefined\n completionSeq?: number\n userAborted: boolean\n /** Answers without intervening substantive tool work or an accepted check. */\n unverifiedAnswers: number\n completionInvalidated: 'tool' | 'input' | undefined\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 * History length when {@link draftAnswer} was recorded. A message from the\n * user or another agent after that point changes the request the draft\n * answered, so the draft can no longer stand on its own.\n */\n draftSeq: number | 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 /** Canonical answer of a control reply, retained if a later round has no message. */\n resolvedMarkerAnswer?: string\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 emitRaw: (event: AgentRunEvent) => Promise<void>,\n): Promise<void> {\n const textTails = new Map<number, string>()\n const emit = async (event: AgentRunEvent): Promise<void> => {\n if (event.type === 'step-start') textTails.clear()\n if (event.type === 'text-delta') {\n const text = ((textTails.get(event.index) ?? '') + event.text).replaceAll(UNCHANGED_ANSWER_MARKER, '')\n let suffix = Math.min(text.length, UNCHANGED_ANSWER_MARKER.length - 1)\n while (suffix > 0 && !UNCHANGED_ANSWER_MARKER.startsWith(text.slice(-suffix))) suffix--\n textTails.set(event.index, suffix === 0 ? '' : text.slice(-suffix))\n const safe = suffix === 0 ? text : text.slice(0, -suffix)\n if (safe !== '') await emitRaw({ ...event, text: safe })\n return\n }\n if (event.type === 'text-end') {\n const tail = textTails.get(event.index) ?? ''\n textTails.delete(event.index)\n if (tail !== '' && !event.incomplete) await emitRaw({ ...event, type: 'text-delta', text: tail })\n await emitRaw({ ...event, text: event.text.replaceAll(UNCHANGED_ANSWER_MARKER, '') })\n return\n }\n await emitRaw(event)\n }\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: undefined,\n draftAnswer: undefined, draftSeq: 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, options.history, options.tools))\n if (broker !== undefined && mode !== 'basic') {\n // A question used to share the tool time limit; that stays the default.\n const waitMs = positiveFinite(\n ('userInputTimeoutMs' in options ? options.userInputTimeoutMs : undefined)\n ?? options.bounds?.maxToolDurationMs ?? 10 * 60_000,\n 'userInputTimeoutMs',\n )\n internalTools.push(userInputTool(mode, broker, state, emit, waitMs, 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) : 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 // Deep mode must confirm its answer; a budget that forces the answer on the\n // last step leaves two exempt-only steps to submit it rather than failing.\n bounds: { ...options.bounds, maxSteps: maxTurns,\n finalizeSteps: options.bounds?.finalizeSteps ?? (deep ? 2 : 0) },\n // A deep run must confirm its answer. When the budget forced that answer\n // before a submission, a short window lets the model submit it; only the\n // submission can run there, never more work or a question to a person.\n ...deep ? { finalize: {\n tools: [AGENT_CONTROL_TOOLS.complete],\n prompt: (forced: { readonly text: string }) => {\n if (state.completion !== undefined || state.userAborted) return undefined\n if (forced.text.trim() !== UNCHANGED_ANSWER_MARKER) {\n state.draftAnswer = forced.text\n state.draftSeq = options.history.entries().length\n }\n return createUserMessage({\n source: { kind: 'app', producer: 'deep-mode-self-check' },\n content: [{ type: 'text', text: `The work budget for this run is spent, and your answer above has no accepted self-check. No research or work tool will run now; only ${AGENT_CONTROL_TOOLS.complete} can. If the answer is supported by the evidence already gathered, call ${AGENT_CONTROL_TOOLS.complete} alone with that self-check, stating any gaps honestly, then deliver the answer in its requested format. If it is not supported, do not submit; your answer above stands as an unconfirmed result.` }],\n })\n },\n confirmed: () => state.completion !== undefined,\n } } : {},\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 const candidateBlocks = new Map<number, string>()\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 let sanitized: { 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 let lastRequestSeq = options.history.entries().length\n let draftMessageId: Message['id'] | undefined\n let keptTextEmitted = 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 if (sanitized !== undefined && (event.type === 'assistant-text' || event.type === 'assistant-reasoning') && event.messageId === sanitized.from) {\n await emit({ ...event, messageId: sanitized.message.id, ...(event.type === 'assistant-text' ? { text: event.text.replaceAll(UNCHANGED_ANSWER_MARKER, '') } : {}) })\n return\n }\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 if (keptTextEmitted) return\n keptTextEmitted = true\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 lastRequestSeq = options.history.entries().length\n kept = undefined\n sanitized = undefined\n orphan = undefined\n keptRestored = false\n keptTextEmitted = false\n state.markerCut = false\n state.markerReply = false\n await flushHeld()\n // Inputs queued during the submitting tool round enter history only at\n // its step boundary, after submit_result has built its instruction.\n // Recheck before the confirming model request can use the old draft.\n invalidateDraftAfterSteering(state, options.history)\n // Reserve the marker in every mode and round, including later runs\n // imitating an earlier accept.\n markerCandidate = true\n candidateText = ''\n candidateBlocks.clear()\n }\n if (markerCandidate && (event.type === 'text-delta' || event.type === 'text-end')) {\n candidateBlocks.set(event.index, event.type === 'text-end' ? event.text : (candidateBlocks.get(event.index) ?? '') + event.text)\n candidateText = [...candidateBlocks.values()].join('')\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) && !candidateText.trimStart().startsWith(UNCHANGED_ANSWER_MARKER)) {\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 state.resolvedMarkerAnswer = draft ?? ''\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 if (draftMessageId !== undefined) await emit({ type: 'assistant-replacement', fromMessageId: draftMessageId, message: kept.message })\n await emit({ ...event, message: kept.message })\n return\n }\n if (only?.includes(UNCHANGED_ANSWER_MARKER)) {\n state.resolvedMarkerAnswer = only.replaceAll(UNCHANGED_ANSWER_MARKER, '').trim()\n const replacement = keptAnswerMessage(only.replaceAll(UNCHANGED_ANSWER_MARKER, '').trim(), content)\n restoreKeptAnswer(options.history, replacement)\n kept = { from: event.message.id, message: replacement }\n const textEvent = heldEvents.find(held => held.type === 'text-end')\n ?? heldEvents.find(held => held.type === 'text-delta')\n await dropHeldText()\n if (textEvent?.type === 'text-end' || textEvent?.type === 'text-delta') {\n await emit({ type: 'text-delta', trace: textEvent.trace, index: textEvent.index, phase: 'final-answer', text: state.resolvedMarkerAnswer })\n await emit({ type: 'text-end', trace: textEvent.trace, index: textEvent.index, phase: 'final-answer', text: state.resolvedMarkerAnswer })\n }\n await emit({ ...event, message: replacement })\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 if (event.type === 'assistant-message' && kept === undefined) {\n const message = event.message\n const combined = message.content.flatMap(block => block.type === 'text' ? [block.text] : []).join('')\n delete state.resolvedMarkerAnswer\n if (combined.includes(UNCHANGED_ANSWER_MARKER)) {\n const replacement = createMessage({ role: 'assistant', source: message.source, content: message.content.map(block => block.type === 'text'\n ? { ...block, text: block.text.replaceAll(UNCHANGED_ANSWER_MARKER, '') } : block) })\n restoreKeptAnswer(options.history, replacement)\n sanitized = { from: message.id, message: replacement }\n await emit({ ...event, message: replacement })\n return\n }\n if (deep && !message.content.some(block => block.type === 'tool-call') && combined.trim() !== '') {\n if (state.completion !== undefined && draftMessageId !== undefined) {\n await emit({ type: 'assistant-replacement', fromMessageId: draftMessageId, message })\n }\n draftMessageId = message.id\n }\n }\n if (event.type === 'assistant-text') {\n await emit({ ...event, text: event.text.replaceAll(UNCHANGED_ANSWER_MARKER, '') })\n return\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-result') {\n // Judged on the result, not the request: a call whose body never ran\n // (declined by a budget, denied by policy, answered from an earlier\n // identical result) did no new work, so it must not void an accepted\n // submission. The flag comes from the scheduler; tool metadata cannot set it.\n const performed = event.dispatched !== false\n if (performed) 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 (performed && event.call.toolName !== AGENT_CONTROL_TOOLS.complete\n && tools?.get(event.call.toolName)?.completionExempt !== true) {\n if (state.completion !== undefined) state.completionInvalidated = 'tool'\n state.completion = undefined\n state.unverifiedAnswers = 0\n }\n if (event.call.toolName === AGENT_CONTROL_TOOLS.complete && !event.result.isError\n && (event.result.value as JsonObject | undefined)?.accepted === true) {\n completionCandidate = completionFromResult(event.result.value)\n }\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.completionSeq = options.history.entries().length\n state.completionInvalidated = undefined\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 invalidateDraftAfterSteering(state, options.history)\n const completionEligible = mode === 'basic'\n ? (terminal.reason.kind === 'completed' && terminal.text.trim() !== '') || 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 completed = completionEligible && !taskChangedSince(options.history, lastRequestSeq)\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 combined text, 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 > 0 && said.every(block => block.type === 'text')\n ? said.map(block => block.type === 'text' ? block.text : '').join('') : 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 (outcome.text.trim() === UNCHANGED_ANSWER_MARKER && state.resolvedMarkerAnswer !== undefined) {\n return { ...outcome, text: state.resolvedMarkerAnswer }\n }\n if (outcome.text.trim() === UNCHANGED_ANSWER_MARKER) return { ...outcome, text: state.completion !== undefined && (state.markerReply || state.markerCut) ? state.draftAnswer ?? '' : '' }\n if (outcome.text.includes(UNCHANGED_ANSWER_MARKER)) return { ...outcome, text: outcome.text.replaceAll(UNCHANGED_ANSWER_MARKER, '').trim() }\n if (!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.filter(block => block.type === 'reasoning'),\n { type: 'text' as const, text: draftAnswer, phase: 'final-answer' as const }],\n source: { kind: 'app', producer: draftAnswer === '' ? 'deep-mode-invalid-marker' : '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'\n ? target.event.message.content.flatMap(block => block.type === 'text' ? [block.text] : []).join('') : undefined\n if (target === undefined || only === undefined) return\n if (!only.includes(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\n/** Whether a new user or delegated task arrived after the given history position. */\nfunction taskChangedSince(history: RunAgentOptions['history'], seq: number | undefined): boolean {\n return history.entries().slice(seq ?? 0)\n .some(entry => entry.event.kind === 'user' && ['user', 'agent-message', 'a2a-message']\n .includes(entry.event.message.source.kind))\n}\n\nfunction invalidateDraftAfterSteering(state: DeepState, history: RunAgentOptions['history']): void {\n if (state.completion !== undefined && taskChangedSince(history, state.completionSeq)) {\n state.completion = undefined\n state.completionInvalidated = 'input'\n }\n if (state.draftAnswer === undefined || !taskChangedSince(history, state.draftSeq)) return\n state.draftAnswer = undefined\n state.draftSeq = undefined\n}\n\nfunction completionTool(state: DeepState, history: RunAgentOptions['history'], tools?: ToolCatalog): 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 // A newer user or delegated task changes what the draft answered, so\n // \"the earlier answer still stands\" is no longer a truthful reply: the\n // model is asked for the answer in full, and a marker it sends anyway is\n // treated as having nothing to keep.\n invalidateDraftAfterSteering(state, history)\n const calls = history.messages().findLast(message => message.role === 'assistant')?.content\n .filter(block => block.type === 'tool-call') ?? []\n if (calls.filter(call => call.name === AGENT_CONTROL_TOOLS.complete).length !== 1\n || calls.some(call => call.name !== AGENT_CONTROL_TOOLS.complete && tools?.get(call.name)?.completionExempt !== true)) {\n return { accepted: false, instruction: 'Review the tool results, then call submit_result exactly once without substantive sibling tools. This batch has no accepted self-check.' }\n }\n return {\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 no user message or delegated task arrived after that answer and it still satisfies every current requirement, reply with exactly ${UNCHANGED_ANSWER_MARKER} and nothing else. If a user message or delegated task arrived after that answer, give the complete answer to the latest request in full, even if the earlier answer seems correct. If this check found something to correct or add, also give the complete corrected answer in full, as if the earlier one did not exist: never summarize it, point back to it, or say the self-check passed. Do not call submit_result again in this run unless you perform new substantive tool work that invalidates this submission. A later user request or worker follow-up starts a new run and needs its own self-check.`,\n }\n },\n })\n}\n\nfunction userInputTool(\n mode: Exclude<AgentMode, 'basic'>,\n broker: UserInputBroker,\n state: DeepState,\n emit: (event: AgentRunEvent) => Promise<void>,\n waitMs: number,\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 // The wait is bounded below by `waitMs`, not by the turn's tool limit.\n awaitsPerson: 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 const unanswered = AbortSignal.timeout(waitMs)\n try {\n const pending = broker.request(request, AbortSignal.any([ctx.signal, unanswered]))\n // Observe the broker immediately, including rejection while publication\n // is backpressured or after the question's timeout has already won.\n void pending.catch(() => undefined)\n await emit({ type: 'user-input-request', request })\n // The wait limit holds even for a broker that ignores the signal: an\n // answer arriving after it, or never, cannot keep the run waiting,\n // since `awaitsPerson` leaves no scheduler deadline above it.\n const response = await new Promise<UserInputDecision>((resolve, reject) => {\n const cleanup = (): void => {\n unanswered.removeEventListener('abort', onEnd)\n ctx.signal.removeEventListener('abort', onEnd)\n }\n const onEnd = (): void => { cleanup(); resolve('abort') }\n if (unanswered.aborted || ctx.signal.aborted) { onEnd(); return }\n unanswered.addEventListener('abort', onEnd, { once: true })\n ctx.signal.addEventListener('abort', onEnd, { once: true })\n void pending.then(\n response => { cleanup(); resolve(response) },\n error => { cleanup(); reject(error) },\n )\n })\n await emit({ type: 'user-input-response', request, response })\n // The wait ran out, the person did not dismiss anything: the run goes\n // on without the answer instead of being recorded as user-aborted.\n if (response === 'abort' && unanswered.aborted && !ctx.signal.aborted) {\n if (operation !== undefined) accounting?.endOperation(operation, 'aborted')\n return { answered: false, reason: `The user did not answer within ${Math.round(waitMs / 1000)} seconds. Continue without their answer: state the assumption you make for each open question, and do not ask the same questions again in this run.` }\n }\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 state.draftAnswer = undefined\n state.draftSeq = undefined\n state.completion = undefined\n if (operation !== undefined) accounting?.endOperation(operation, 'success')\n return validateUserResponse(response, questions) as unknown as JsonObject\n } catch (error) {\n if (ctx.signal.aborted) await emit({ type: 'user-input-response', request, response: 'abort' })\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): TurnHooks {\n return {\n ...userHooks,\n onTurnEnd: async context => {\n // Capture before an async host hook can append another request. That\n // request was not part of the model round that produced this draft.\n const draftSeq = history.entries().length\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 eligible for ${UNCHANGED_ANSWER_MARKER} to keep. A new user or delegated task after the earlier answer makes it ineligible too. Reply with the answer itself now, in the requested format.` }],\n }) })\n return\n }\n // `canContinue` already counts work steps; `outcome.steps` also counts\n // retried requests, which must not shorten the gate's reach.\n if (context.outcome.reason.kind !== 'completed'\n || !context.canContinue\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 state.draftSeq = draftSeq\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 !== undefined\n ? state.completionInvalidated === 'input'\n ? `Your previously accepted submission is no longer current because a new user request or delegated task arrived afterwards. Review the latest input and call ${AGENT_CONTROL_TOOLS.complete} again when complete; the old instruction not to resubmit no longer applies. `\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 problem = userInputResponseProblem(questions, response)\n if (problem !== undefined) throw new Error(`the user-input broker returned ${problem}`)\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 +1 @@
1
- {"version":3,"file":"user-input.d.ts","names":[],"sources":["../../../src/agent/mode/user-input.ts"],"mappings":";;UAKiB;;WAEN;;WAEA;;UAGM;;WAEN;;WAEA;;WAEA;;WAEA,kBAAkB;;WAElB;;UAGM;;WAEN,WAAW;WACX,QAAQ;WACR;WACA;WACA,oBAAoB;WACpB;;UAGM;;WAEN;;UAGM;;WAEN,SAAS,SAAS,eAAe;;KAGhC,oBAAoB;UAEf;WACN,UAAU,SAAS,kBAAkB,SAAS,gBAAgB,QAAQ;;UAGhE,mCAAmC;EAClD,oBAAoB;EACpB,UAAU,WAAW,SAAS;EAC9B,QAAQ,WAAW,YAAY,UAAU;EACzC;;UAGe;;WAEN;;;;;;iBAYK,sBAAsB,UAAS,oCAAyC;;iBA8DxE,qBACd,UAAU,sBAAsB,SAAS,qBAAqB,oBAAoB,QAAQ,sBACzF"}
1
+ {"version":3,"file":"user-input.d.ts","names":[],"sources":["../../../src/agent/mode/user-input.ts"],"mappings":";;UAKiB;;WAEN;;WAEA;;UAGM;;WAEN;;WAEA;;WAEA;;WAEA,kBAAkB;;WAElB;;UAGM;;WAEN,WAAW;WACX,QAAQ;WACR;WACA;WACA,oBAAoB;WACpB;;UAGM;;WAEN;;UAGM;;WAEN,SAAS,SAAS,eAAe;;KAGhC,oBAAoB;UAuBf;WACN,UAAU,SAAS,kBAAkB,SAAS,gBAAgB,QAAQ;;UAGhE,mCAAmC;EAClD,oBAAoB;EACpB,UAAU,WAAW,SAAS;EAC9B,QAAQ,WAAW,YAAY,UAAU;EACzC;;UAGe;;WAEN;;;;;;iBAYK,sBAAsB,UAAS,oCAAyC;;iBAiExE,qBACd,UAAU,sBAAsB,SAAS,qBAAqB,oBAAoB,QAAQ,sBACzF"}
@@ -1,2 +1,2 @@
1
- import{detachedFrozen as e}from"../../primitives/snapshot.js";function t(t={}){let r=n(t.maxPending??1024,`user-input maxPending`),i=new Map,a=new Set;return{request(t,n){if(n?.aborted===!0)return Promise.resolve(`abort`);if(i.has(t.requestId))return Promise.reject(Error(`user-input request '${t.requestId}' is already pending`));if(i.size>=r)return Promise.reject(Error(`user-input broker reached its ${r}-request limit`));let o=e(t);return new Promise(e=>{let r=!1,s=a=>{r||(r=!0,i.delete(t.requestId),n?.removeEventListener(`abort`,c),e(a))};function c(){s(`abort`)}i.set(t.requestId,{request:o,settle:s}),n?.addEventListener(`abort`,c,{once:!0});for(let e of[...a])try{e(o)}catch{}})},pending(){return[...i.values()].map(e=>e.request)},onRequest(e){return a.add(e),()=>void a.delete(e)},resolve(t,n){let r=i.get(t);return r!==void 0&&(r.settle(e(n)),!0)},abortAll(){for(let e of[...i.values()])e.settle(`abort`)}}}function n(e,t){if(!Number.isSafeInteger(e)||e<1)throw RangeError(`${t} must be a positive safe integer`);return e}function r(e){return{request:t=>Promise.resolve(typeof e==`function`?e(t):e)}}export{t as createUserInputBroker,r as fixedUserInputBroker};
1
+ import{detachedFrozen as e}from"../../primitives/snapshot.js";function t(e,t){let n=t?.answers;if(typeof n!=`object`||!n||Array.isArray(n))return`the response has no answers`;let r=new Set(e.map(e=>e.id));for(let e of r){let t=n[e];if(typeof t!=`object`||!t||!Array.isArray(t.answers)||t.answers.length===0||t.answers.some(e=>typeof e!=`string`||e.trim().length===0))return`no valid answer for "${e}"`}for(let e of Object.keys(n))if(!r.has(e))return`an answer for unknown question "${e}"`}function n(n={}){let i=r(n.maxPending??1024,`user-input maxPending`),a=new Map,o=new Set;return{request(t,n){if(n?.aborted===!0)return Promise.resolve(`abort`);if(a.has(t.requestId))return Promise.reject(Error(`user-input request '${t.requestId}' is already pending`));if(a.size>=i)return Promise.reject(Error(`user-input broker reached its ${i}-request limit`));let r=e(t);return new Promise(e=>{let i=!1,s=r=>{i||(i=!0,a.delete(t.requestId),n?.removeEventListener(`abort`,c),e(r))};function c(){s(`abort`)}a.set(t.requestId,{request:r,settle:s}),n?.addEventListener(`abort`,c,{once:!0});for(let e of[...o])try{e(r)}catch{}})},pending(){return[...a.values()].map(e=>e.request)},onRequest(e){return o.add(e),()=>void o.delete(e)},resolve(n,r){let i=a.get(n);return i===void 0||t(i.request.questions,r)!==void 0?!1:(i.settle(e(r)),!0)},abortAll(){for(let e of[...a.values()])e.settle(`abort`)}}}function r(e,t){if(!Number.isSafeInteger(e)||e<1)throw RangeError(`${t} must be a positive safe integer`);return e}function i(e){return{request:t=>Promise.resolve(typeof e==`function`?e(t):e)}}export{n as createUserInputBroker,i as fixedUserInputBroker,t as userInputResponseProblem};
2
2
  //# sourceMappingURL=user-input.js.map