eve 0.24.4 → 0.24.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/src/channel/cancel.d.ts +8 -0
  3. package/dist/src/channel/cancel.js +1 -0
  4. package/dist/src/channel/routes.d.ts +25 -4
  5. package/dist/src/channel/session.d.ts +10 -1
  6. package/dist/src/channel/session.js +1 -1
  7. package/dist/src/channel/types.d.ts +21 -0
  8. package/dist/src/chunks/{use-eve-agent-Dwa2j1wE.js → use-eve-agent-6BO9gFVq.js} +61 -6
  9. package/dist/src/chunks/{use-eve-agent-BP9FpQsJ.js → use-eve-agent-B1MJNRE-.js} +61 -6
  10. package/dist/src/cli/commands/build.d.ts +14 -0
  11. package/dist/src/cli/commands/build.js +1 -0
  12. package/dist/src/cli/commands/channels.js +1 -1
  13. package/dist/src/cli/commands/link.d.ts +6 -5
  14. package/dist/src/cli/commands/link.js +1 -1
  15. package/dist/src/cli/run.d.ts +3 -2
  16. package/dist/src/cli/run.js +1 -1
  17. package/dist/src/client/index.d.ts +1 -1
  18. package/dist/src/client/ndjson.js +1 -1
  19. package/dist/src/client/open-stream.d.ts +3 -2
  20. package/dist/src/client/open-stream.js +1 -1
  21. package/dist/src/client/session.d.ts +19 -3
  22. package/dist/src/client/session.js +1 -1
  23. package/dist/src/client/types.d.ts +8 -0
  24. package/dist/src/compiled/.vendor-stamp.json +5 -5
  25. package/dist/src/compiled/@workflow/core/index.js +2 -2
  26. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +55 -0
  27. package/dist/src/compiled/@workflow/core/runtime/run-id-time.d.ts +9 -0
  28. package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +2 -0
  29. package/dist/src/compiled/@workflow/core/runtime/step-latency.d.ts +70 -4
  30. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +10 -1
  31. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  32. package/dist/src/compiled/@workflow/core/step/context-storage.d.ts +6 -0
  33. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +25 -0
  34. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  35. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  36. package/dist/src/compiled/@workflow/errors/index.d.ts +16 -0
  37. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  38. package/dist/src/compiled/@workflow/world/attributes.d.ts +7 -0
  39. package/dist/src/compiled/@workflow/world/events.d.ts +16 -0
  40. package/dist/src/compiled/@workflow/world/index.d.ts +1 -1
  41. package/dist/src/compiled/@workflow/world-local/index.js +3 -3
  42. package/dist/src/compiled/@workflow/world-vercel/index.js +16 -16
  43. package/dist/src/compiled/_chunks/workflow/attribute-changes-DXbmITuI.js +20 -0
  44. package/dist/src/compiled/_chunks/workflow/{dist-DpDDcpTl.js → dist-BYo8Gno2.js} +1 -1
  45. package/dist/src/compiled/_chunks/workflow/{dist-Blxnyb7-.js → dist-CSfKNxQW.js} +1 -1
  46. package/dist/src/compiled/_chunks/workflow/resume-hook-DvvgYsRt.js +1 -0
  47. package/dist/src/compiled/_chunks/workflow/run-BdvQmV5a.js +1 -0
  48. package/dist/src/compiled/_chunks/workflow/run-id-BdE0MZz9.js +1 -0
  49. package/dist/src/compiled/_chunks/workflow/sleep-DzxrwWTs.js +1 -0
  50. package/dist/src/evals/assertions/run.d.ts +3 -3
  51. package/dist/src/evals/context.js +1 -1
  52. package/dist/src/evals/index.d.ts +2 -1
  53. package/dist/src/evals/match.d.ts +4 -0
  54. package/dist/src/evals/match.js +1 -1
  55. package/dist/src/evals/runner/derive-run-facts.js +1 -1
  56. package/dist/src/evals/session.d.ts +10 -2
  57. package/dist/src/evals/session.js +1 -1
  58. package/dist/src/evals/target.js +1 -1
  59. package/dist/src/evals/types.d.ts +52 -2
  60. package/dist/src/execution/cancel-descendant-turns-step.d.ts +6 -0
  61. package/dist/src/execution/cancel-descendant-turns-step.js +1 -0
  62. package/dist/src/execution/create-session-step.js +1 -1
  63. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  64. package/dist/src/execution/dispatch-workflow-runtime-actions-step.js +1 -1
  65. package/dist/src/execution/node-step.js +1 -1
  66. package/dist/src/execution/remote-agent-dispatch.d.ts +6 -0
  67. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  68. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  69. package/dist/src/execution/subagent-event-proxy-step.js +1 -1
  70. package/dist/src/execution/turn-cancellation-control.d.ts +0 -13
  71. package/dist/src/execution/turn-cancellation-control.js +1 -1
  72. package/dist/src/execution/turn-cancellation-token.d.ts +9 -0
  73. package/dist/src/execution/turn-cancellation-token.js +1 -0
  74. package/dist/src/execution/turn-workflow.js +1 -1
  75. package/dist/src/execution/workflow-runtime.d.ts +3 -1
  76. package/dist/src/execution/workflow-runtime.js +1 -1
  77. package/dist/src/execution/workflow-steps.js +1 -1
  78. package/dist/src/harness/advertised-tools.js +1 -1
  79. package/dist/src/harness/execute-tool.d.ts +0 -1
  80. package/dist/src/harness/runtime-actions.d.ts +16 -12
  81. package/dist/src/harness/runtime-actions.js +1 -1
  82. package/dist/src/internal/application/build-profile.d.ts +64 -0
  83. package/dist/src/internal/application/build-profile.js +1 -0
  84. package/dist/src/internal/application/package.js +1 -1
  85. package/dist/src/internal/authored-module-loader.d.ts +10 -0
  86. package/dist/src/internal/authored-module-loader.js +2 -2
  87. package/dist/src/internal/authored-module-map-loader.js +1 -1
  88. package/dist/src/internal/materialized-authored-modules.d.ts +2 -4
  89. package/dist/src/internal/materialized-authored-modules.js +1 -1
  90. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  91. package/dist/src/internal/nitro/host/build-application.js +1 -1
  92. package/dist/src/internal/nitro/host/types.d.ts +2 -0
  93. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  94. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +7 -1
  95. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  96. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  97. package/dist/src/internal/nitro/routes/channel-route-context.d.ts +3 -0
  98. package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
  99. package/dist/src/internal/nitro/routes/runtime-stack.js +1 -1
  100. package/dist/src/internal/nitro/routes/schedule-task.js +1 -1
  101. package/dist/src/protocol/cancel-turn.d.ts +11 -0
  102. package/dist/src/protocol/cancel-turn.js +1 -0
  103. package/dist/src/protocol/routes.d.ts +10 -0
  104. package/dist/src/protocol/routes.js +1 -1
  105. package/dist/src/public/channels/eve.d.ts +2 -1
  106. package/dist/src/public/channels/eve.js +1 -1
  107. package/dist/src/public/channels/index.d.ts +1 -1
  108. package/dist/src/public/channels/linear/api.d.ts +0 -1
  109. package/dist/src/public/channels/linear/api.js +17 -22
  110. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  111. package/dist/src/public/definitions/channel.d.ts +21 -11
  112. package/dist/src/public/next/index.js +1 -1
  113. package/dist/src/public/next/resolve-eve-binary.d.ts +12 -0
  114. package/dist/src/public/next/resolve-eve-binary.js +1 -0
  115. package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
  116. package/dist/src/runtime/framework-tools/agent.d.ts +13 -0
  117. package/dist/src/runtime/framework-tools/agent.js +1 -0
  118. package/dist/src/runtime/framework-tools/index.d.ts +7 -2
  119. package/dist/src/runtime/framework-tools/index.js +1 -1
  120. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  121. package/dist/src/runtime/types.d.ts +2 -1
  122. package/dist/src/setup/boxes/reconcile-host-framework-preset.d.ts +26 -0
  123. package/dist/src/setup/boxes/reconcile-host-framework-preset.js +1 -0
  124. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  125. package/dist/src/setup/index.js +1 -1
  126. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  127. package/dist/src/setup/scaffold/create/project.js +2 -2
  128. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  129. package/dist/src/setup/scaffold/create/web-template.js +1 -0
  130. package/dist/src/setup/scaffold/index.d.ts +1 -1
  131. package/dist/src/setup/scaffold/index.js +1 -1
  132. package/dist/src/setup/scaffold/update/channels.d.ts +7 -1
  133. package/dist/src/setup/scaffold/update/channels.js +2 -2
  134. package/dist/src/setup/scaffold/update/connections.js +3 -3
  135. package/dist/src/setup/vercel-project-framework.d.ts +12 -0
  136. package/dist/src/setup/vercel-project-framework.js +1 -1
  137. package/dist/src/svelte/index.js +1 -1
  138. package/dist/src/svelte/use-eve-agent.js +1 -1
  139. package/dist/src/vue/index.js +1 -1
  140. package/dist/src/vue/use-eve-agent.js +1 -1
  141. package/docs/channels/custom.mdx +32 -2
  142. package/docs/channels/eve.mdx +11 -1
  143. package/docs/concepts/default-harness.md +2 -0
  144. package/docs/concepts/sessions-runs-and-streaming.md +13 -0
  145. package/docs/evals/assertions.mdx +2 -2
  146. package/docs/evals/cases.mdx +31 -0
  147. package/docs/evals/overview.mdx +1 -1
  148. package/docs/evals/targets.mdx +2 -1
  149. package/docs/guides/client/continuations.mdx +2 -0
  150. package/docs/guides/client/streaming.mdx +17 -1
  151. package/docs/guides/frontend/overview.mdx +4 -2
  152. package/docs/guides/frontend/use-eve-agent-svelte.mdx +2 -2
  153. package/docs/guides/frontend/use-eve-agent-vue.mdx +2 -2
  154. package/docs/guides/remote-agents.md +2 -0
  155. package/docs/reference/cli.md +15 -2
  156. package/docs/subagents.mdx +10 -0
  157. package/package.json +7 -7
  158. package/dist/src/compiled/_chunks/workflow/attribute-changes-MGTOG_uX.js +0 -20
  159. package/dist/src/compiled/_chunks/workflow/resume-hook-DHP5ql3-.js +0 -1
  160. package/dist/src/compiled/_chunks/workflow/run-D8hv1ptT.js +0 -1
  161. package/dist/src/compiled/_chunks/workflow/sleep-uA9pS-PT.js +0 -1
@@ -0,0 +1 @@
1
+ import{r as e}from"./chunk-BHKSVoKr.js";import{T as t,n,o as r}from"./dist-BYo8Gno2.js";import{Dn as i,Gt as a,H as o,Mn as s,Q as c,S as l,X as u,a as d,at as f,en as p,g as m,k as h,n as g,ot as _,r as v,st as y,un as b,yn as x}from"./attribute-changes-DXbmITuI.js";import{s as S}from"./dist-CSfKNxQW.js";var C=e({getHookByToken:()=>T,resumeHook:()=>E,resumeWebhook:()=>D});async function w(e){let t=await i(),n=await t.hooks.getByToken(e),r=await t.runs.get(n.runId),a=await t.getEncryptionKeyForRun?.(r),o=a?await s(a):void 0;return n.metadata!==void 0&&(n.metadata=await h(n.metadata,n.runId,o)),{hook:n,run:r,encryptionKey:o}}async function T(e){let{hook:t}=await w(e);return t}async function E(e,t,n){return await v(()=>c(`hook.resume`,async r=>{let c=await i();try{let i,f,h;if(typeof e==`string`){let t=await w(e);i=t.hook,f=t.run,h=n??t.encryptionKey}else if(i=e,f=await c.runs.get(i.runId),n)h=n;else{let e=await c.getEncryptionKeyForRun?.(f);h=e?await s(e):void 0}r?.setAttributes({...y(i.token),..._(i.hookId),...p(i.runId)});let v=f.executionContext?.workflowCoreVersion,x=m(typeof v==`string`?v:void 0);x.supportedFormats.has(b.ENCRYPTED)||(h=void 0);let C=(f.specVersion??0)>=5&&x.supportedFormats.has(b.GZIP),T=[],E=S(i.specVersion),D=await l(t,i.runId,h,T,globalThis,E,x.framedByteStreams,C);g(Promise.all(T),e=>{e!==void 0&&o.warn(`Background flush of hook payload ops failed`,{workflowRunId:i.runId,hookId:i.hookId,error:e instanceof Error?e.message:String(e)})}),await c.events.create(i.runId,{eventType:`hook_received`,specVersion:5,correlationId:i.hookId,eventData:{...E?{}:{token:i.token},payload:D}},{v1Compat:E}),r?.setAttributes({...a(f.workflowName)});let O=await u(f.executionContext?.traceCarrier);return O&&r?.addLink?.(O),await c.queue(d(f.workflowName),{runId:i.runId,traceCarrier:f.executionContext?.traceCarrier??void 0},{deploymentId:f.deploymentId,specVersion:f.specVersion??1}),i}catch(t){throw r?.setAttributes({...y(typeof e==`string`?e:e.token),...f(!1)}),t}}))}async function D(e,i){let{hook:a,encryptionKey:o}=await w(e);if(a.isWebhook===!1)throw new r(e);let s,c;if(a.metadata&&typeof a.metadata==`object`&&`respondWith`in a.metadata)if(a.metadata.respondWith===`manual`){let{readable:e,writable:t}=new TransformStream;c=e,i[x]=t}else if(a.metadata.respondWith instanceof Response)s=a.metadata.respondWith;else throw new t(`Invalid \`respondWith\` value: ${a.metadata.respondWith}`,{slug:n.WEBHOOK_INVALID_RESPOND_WITH_VALUE});else s=new Response(null,{status:202});if(await E(a,i,o),c){let e=c.getReader(),t=await e.read();t.value&&(s=t.value),e.cancel()}if(!s)throw new t(`Workflow run did not send a response`,{slug:n.WEBHOOK_RESPONSE_NOT_SENT});return s}export{C as i,E as n,D as r,T as t};
@@ -0,0 +1 @@
1
+ import{h as e}from"./dist-CttsoN4D.js";import{C as t,D as n,E as r,S as i,T as a,b as o,c as s,f as c,h as l,m as u,r as d,t as f,w as p,x as m}from"./dist-BYo8Gno2.js";import{B as h,C as ee,Dn as g,E as _,En as v,Gt as y,H as b,Kt as x,M as S,Mn as C,N as w,O as T,On as E,Q as D,Rt as O,Tn as k,V as A,Z as j,a as M,en as N,g as P,h as F,n as te,r as I,s as ne,t as re,tn as ie,tt as L,un as R}from"./attribute-changes-DXbmITuI.js";import{K as z,i as B,o as V,q as H,s as U}from"./dist-CSfKNxQW.js";const W=new Set([`PARSE_ERROR`,`SCHEMA_VALIDATION`,n.WORLD_CONTRACT_ERROR]),G=new Set([`TRANSPORT`,`TIMEOUT`]),K=[a.is,u.is,o.is,c.is];function q(e){if(!r.is(e)||e.status!==void 0)return!1;let t=`cause`in e?e.cause:void 0;return e.code!==void 0&&W.has(e.code)||e.message.startsWith(`Failed to parse response body for `)||e.message.startsWith(`Schema validation failed for `)||typeof t==`object`&&!!t&&`name`in t&&t.name===`ZodError`}function J(e){return l.is(e)?!0:r.is(e)?e.status!==void 0&&e.status>=500?!0:e.code!==void 0&&G.has(e.code):!1}function ae(e){if(s.is(e))return n.REPLAY_DIVERGENCE;if(f.is(e))return n.CORRUPTED_EVENT_LOG;if(q(e)||J(e))return n.WORLD_CONTRACT_ERROR;for(let t of K)if(t(e))return n.RUNTIME_ERROR;return n.USER_ERROR}const oe=V();function se(){let e=A.getStore(),t=e?.workflowMetadata?.workflowRunId;if(t)return{[H]:e.rootRunId??t,[z]:t}}let Y=!1;async function X(t,n,r){"use step";return await I(()=>{let i=t?.workflowId;if(!i)throw new a(`'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.`,{slug:`start-invalid-workflow-function`});return D(`workflow.start ${e(i)}`,async e=>{e?.setAttributes({...y(i),...x(`start`)});let t=[],o=r??{};Array.isArray(n)?t=n:typeof n==`object`&&(o=n),e?.setAttributes({...O(t.length)});let s=o.world??await g();E(s);let c=await s.getDeploymentId(),l=o.deploymentId??c;l===`latest`&&(s.resolveLatestDeploymentId?l=await s.resolveLatestDeploymentId():(Y||(Y=!0,b.warn(`deploymentId: 'latest' has no effect in this world and was ignored. It is only supported by worlds with atomic deployments, such as Vercel. The run will target the current deployment.`,{currentDeploymentId:c})),l=c));let u,f;if(l===c)u=!0,f=!0;else if(typeof s.streams?.get!=`function`)u=!1,f=!1;else{let e=P((await ne(s,`workflow`,{deploymentId:l,timeout:2e3,namespace:o.namespace}).catch(()=>void 0))?.workflowCoreVersion);u=e.framedByteStreams,f=e.supportedFormats.has(R.GZIP)}let p=[],m=`wrun_${s.createRunId?s.createRunId(o):oe()}`,h=await j(),_=o.specVersion??s.specVersion,v=U(_),S=o.allowReservedAttributes===!0,w;if(o.attributes&&Object.keys(o.attributes).length>0){if(_<4)throw new a(`Initial workflow attributes require a World that supports spec version 4 or later.`);for(let[e,t]of Object.entries(o.attributes))if(typeof t!=`string`)throw new a(`Initial workflow attribute ${JSON.stringify(e)} must be a string value.`);let e=re(o.attributes,{allowReservedAttributes:S});w=Object.fromEntries(e.map(({key:e,value:t})=>[e,t]))}let T=_>=4?se():void 0,D=T?{...T,...w}:w,k=D?{attributes:D,...S||T!=null?{allowReservedAttributes:!0}:{}}:{};if(o.replayedFromRunId!==void 0&&!B.safeParse(o.replayedFromRunId).success)throw new a(`replayedFromRunId must be a run ID (wrun_<ulid>); received ${JSON.stringify(String(o.replayedFromRunId).slice(0,64))}.`);let A=await s.getEncryptionKeyForRun?.(m,{...o,deploymentId:l}),I=A?await C(A):void 0,z=await ee(t,m,I,p,globalThis,v,u,f&&_>=5),V={traceCarrier:h,workflowCoreVersion:F,features:{encryption:!!I},...o.replayedFromRunId?{replayedFromRunId:o.replayedFromRunId}:{}},[H,W]=await Promise.allSettled([s.events.create(m,{eventType:`run_created`,specVersion:_,eventData:{deploymentId:l,workflowName:i,input:z,executionContext:V,...k}},{v1Compat:v}),s.queue(M(i,o.namespace),{runId:m,traceCarrier:h,..._>=3?{runInput:{input:z,deploymentId:l,workflowName:i,specVersion:_,executionContext:V,...k}}:{}},{deploymentId:l,specVersion:_,...o.region===void 0?{}:{region:o.region}})]);if(W.status===`rejected`)throw W.reason;let G=!1;if(H.status===`rejected`){let e=H.reason;if(!d.is(e))if(J(e))G=!0,b.warn(`Run creation event failed, but the run was accepted via the queue. The run_created event will be re-tried async by the runtime.`,{workflowRunId:m,error:e.message});else throw e}else{let e=H.value;if(!e.run)throw new a(`Missing 'run' in server response for 'run_created' event`);if(!v&&e.run.runId!==m)throw new a(`Server returned different runId than requested: expected ${m}, got ${e.run.runId}`)}return te(Promise.all(p),e=>{b.warn(`Background flush of workflow argument streams failed`,{workflowRunId:m,error:e instanceof Error?e.message:String(e)})}),e?.setAttributes({...N(m),...L(l),...H.status===`fulfilled`&&H.value.run?ie(H.value.run.status):{}}),new $(m,{resilientStart:G})})})}const ce=e=>Array.isArray(e)?e:[e];async function Z(e,t,n={}){try{let r=await e.runs.get(t,{resolveData:`all`}),i=await e.getEncryptionKeyForRun?.(r),a=i?await C(i):void 0,o=ce(await S(r.input,t,a,globalThis)),s=n.specVersion??r.specVersion??1,c=n.deploymentId??r.deploymentId;return(await X({workflowId:r.workflowName},o,{deploymentId:c,world:e,specVersion:s,replayedFromRunId:t,namespace:n.namespace})).runId}catch(e){throw Error(`Failed to recreate run from ${t}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}async function le(e,t,n){try{let r=(await e.runs.get(t,{resolveData:`none`})).specVersion??1,i=U(r),a={eventType:`run_cancelled`,specVersion:r,...n?.cancelReason===void 0?{}:{eventData:{cancelReason:n.cancelReason}}};await e.events.create(t,a,{v1Compat:i})}catch(e){throw Error(`Failed to cancel run ${t}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}async function ue(e,t,n){try{let r=await e.runs.get(t,{resolveData:`none`});await e.queue(M(r.workflowName,n?.namespace),{runId:t},{deploymentId:r.deploymentId,specVersion:r.specVersion??1})}catch(e){throw Error(`Failed to re-enqueue run ${t}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}async function Q(e,t,n){try{let r=await e.runs.get(t,{resolveData:`none`}),i=U(r.specVersion),a=[],o=null;do{let n=await e.events.list({runId:t,pagination:{limit:1e3,...o?{cursor:o}:{}},resolveData:`none`});a.push(...n.data),o=n.hasMore?n.cursor:null}while(o);let s=a.filter(e=>e.eventType===`wait_created`),c=new Set(a.filter(e=>e.eventType===`wait_completed`).map(e=>e.correlationId)),l=s.filter(e=>!c.has(e.correlationId));if(n?.correlationIds&&n.correlationIds.length>0){let e=new Set(n.correlationIds);l=l.filter(t=>t.correlationId&&e.has(t.correlationId))}let u=[],f=0;for(let n of l){if(!n.correlationId)continue;let a=i?{eventType:`wait_completed`,correlationId:n.correlationId}:{eventType:`wait_completed`,correlationId:n.correlationId,specVersion:r.specVersion,eventData:{resumeAt:n.eventData.resumeAt}};try{await e.events.create(t,a,{v1Compat:i}),f++}catch(e){d.is(e)?f++:u.push(e instanceof Error?e:Error(String(e)))}}if(f>0&&await e.queue(M(r.workflowName,n?.namespace),{runId:t},{deploymentId:r.deploymentId,specVersion:r.specVersion??1}),u.length>0)throw AggregateError(u,`Failed to complete ${u.length}/${l.length} pending wait(s) for run ${t}`);return{stoppedCount:f}}catch(e){throw e instanceof AggregateError?e:Error(`Failed to wake up run ${t}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}async function de(e,t,n,r){try{return await e.streams.get(t,n,r?.startIndex)}catch(e){throw Error(`Failed to read stream ${n}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}async function fe(e,t){try{return await e.streams.list(t)}catch(e){throw Error(`Failed to list streams for run ${t}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}var $=class e{static[v](e){return{runId:e.runId,resilientStart:e.#r}}static[k](t){return new e(t.runId,{resilientStart:t.resilientStart})}runId;#e;get#t(){return this.#e||=g(),this.#e}#n=null;#r=!1;constructor(e,t){this.runId=e,this.#r=t?.resilientStart??!1}#i(){return this.#n||=(async()=>{let e=await this.#t,t=await e.runs.get(this.runId),n=await e.getEncryptionKeyForRun?.(t);return n?await C(n):void 0})(),this.#n}#a(){return()=>this.#i()}async wakeUp(e){"use step";return Q(await this.#t,this.runId,e)}async cancel(e){"use step";await(await this.#t).events.create(this.runId,{eventType:`run_cancelled`,specVersion:5,...e?.cancelReason===void 0?{}:{eventData:{cancelReason:e.cancelReason}}})}get exists(){"use step";return this.#t.then(e=>e.runs.get(this.runId,{resolveData:`none`}).then(()=>!0).catch(e=>{if(p.is(e))return!1;throw e}))}get status(){"use step";return this.#t.then(e=>e.runs.get(this.runId).then(e=>e.status))}get returnValue(){"use step";return this.#o()}get workflowName(){"use step";return this.#t.then(e=>e.runs.get(this.runId).then(e=>e.workflowName))}get createdAt(){"use step";return this.#t.then(e=>e.runs.get(this.runId).then(e=>e.createdAt))}get startedAt(){"use step";return this.#t.then(e=>e.runs.get(this.runId).then(e=>e.startedAt))}get completedAt(){"use step";return this.#t.then(e=>e.runs.get(this.runId).then(e=>e.completedAt))}get readable(){return this.getReadable()}getReadable(e={}){"use step";let{ops:t=[],global:n=globalThis,startIndex:r,namespace:i}=e,a=h(this.runId,i),o=this.#a(),s=_(n,t,this.runId,o).ReadableStream({name:a,startIndex:r}),c=this.#t,l=this.runId;return Object.assign(s,{getTailIndex:async()=>(await(await c).streams.getInfo(l,a)).tailIndex})}async#o(){let e=await this.#t,n=0,r=this.#r?3:0,a=[1e3,3e3,6e3];for(;;)try{let n=await e.runs.get(this.runId);if(n.status===`completed`){let e=await this.#i();return await w(n.output,this.runId,e)}if(n.status===`cancelled`)throw new m(this.runId);if(n.status===`failed`){let e=await this.#i(),t;try{t=await T(n.error,this.runId,e)}catch{t=Error(`Failed to hydrate workflow run error`)}throw new i(this.runId,t,{errorCode:n.errorCode})}throw new t(this.runId,n.status)}catch(e){if(t.is(e)){await new Promise(e=>setTimeout(e,1e3));continue}if(p.is(e)&&n<r){let e=a[n];n++,await new Promise(t=>setTimeout(t,e));continue}throw e}}};function pe(e){return new $(e)}export{de as a,Q as c,J as d,q as f,fe as i,X as l,pe as n,Z as o,le as r,ue as s,$ as t,ae as u};
@@ -0,0 +1 @@
1
+ const e=`0123456789ABCDEFGHJKMNPQRSTVWXYZ`,t=(()=>{let t=new Int8Array(128).fill(-1);for(let n=0;n<32;n++)t[e.charCodeAt(n)]=n;for(let n=0;n<32;n++){let r=e[n].toLowerCase();r!==e[n]&&(t[r.charCodeAt(0)]=n)}return t})();function n(e){if(typeof e!=`string`)throw TypeError(`Expected ULID string, got ${typeof e}`);if(e.length!==26)throw Error(`Invalid ULID length: expected 26, got ${e.length}`);let n=new Uint8Array(26);for(let r=0;r<26;r++){let i=e.charCodeAt(r),a=i<128?t[i]:-1;if(a<0)throw Error(`Invalid Crockford-Base32 character at index ${r}: ${JSON.stringify(e[r])}`);n[r]=a}if(n[0]&24)throw Error(`Invalid ULID: top 2 bits must be zero (first char > '7'): ${JSON.stringify(e[0])}`);let r=new Uint8Array(16),i=n[0]&7,a=3,o=0;for(let e=1;e<26;e++)for(i=i<<5|n[e],a+=5;a>=8;)a-=8,r[o++]=i>>a&255;if(o!==16||a!==0)throw Error(`Internal error: ULID bit packing did not consume cleanly`);return r}function r(t){if(t.length!==16)throw Error(`Invalid byte length: expected 16, got ${t.length}`);let n=0,r=0;n=0,r=2;let i=``;for(let a=0;a<16;a++)for(n=n<<8|t[a],r+=8;r>=5;)r-=5,i+=e[n>>r&31];if(i.length!==26||r!==0)throw Error(`Internal error: ULID bit packing did not flush cleanly`);return i}const i={unknown:0,iad1:1,sfo1:2,pdx1:3,cle1:4,yul1:5,gru1:6,dub1:7,lhr1:8,cdg1:9,fra1:10,bru1:11,arn1:12,hel1:13,zrh1:14,cpt1:15,dxb1:16,bom1:17,sin1:18,hkg1:19,hnd1:20,icn1:21,kix1:22,syd1:23},a=`iad1`,o=new Map(Object.entries(i).filter(e=>e[0]!==`unknown`).map(([e,t])=>[t,e]));function s(e){return o.get(e)??null}function c(e){return e!==void 0&&e!==`unknown`&&Object.hasOwn(i,e)}function l(e){return typeof e==`string`&&e!==`unknown`&&Object.hasOwn(i,e)}function u(e,t,a={}){let o;if(typeof t==`number`){if(!Number.isInteger(t)||t<0||t>63)throw RangeError(`regionId must be an integer in [0, 63]; got ${t}`);o=t}else if(l(t))o=i[t];else throw Error(`Unknown region: ${String(t)}`);let s=a.version??1;if(!Number.isInteger(s)||s<0||s>31)throw RangeError(`version must be an integer in [0, 31]; got ${s}`);let c=n(e);c[0]|=128;let u=(o&63)<<2,d=s>>3&3,f=(s&7)<<5;return c[6]=c[6]&-256|u|d,c[7]=c[7]&-225|f,r(c)}function d(e){let t=n(e),i=(t[0]&128)!=0;t[0]&=-129;let a=r(t);if(!i)return{tagged:!1,ulid:a,version:null,regionId:null,region:null};let o=(t[6]&252)>>2;return{tagged:!0,ulid:a,version:(t[6]&3)<<3|(t[7]&224)>>5,regionId:o,region:s(o)}}export{c as a,i,u as n,r as o,a as r,n as s,d as t};
@@ -0,0 +1 @@
1
+ import{Cn as e,Fn as t}from"./attribute-changes-DXbmITuI.js";async function n(r){let i=globalThis[e];return i||t(`sleep()`,`https://workflow-sdk.dev/docs/api-reference/workflow/sleep`,n),i(r)}export{n as t};
@@ -59,9 +59,9 @@ export declare function maxToolCalls(max: number): RunAssertion;
59
59
  */
60
60
  export declare function noFailedActions(): RunAssertion;
61
61
  /**
62
- * Asserts a subagent delegation to `name` occurred. `remoteUrl` matches the
63
- * `subagent.called` remote metadata, `output` matches the `subagent.completed`
64
- * output.
62
+ * Asserts a subagent delegation to `name` occurred. Identity and remote
63
+ * metadata come from `subagent.called`; `output` comes from
64
+ * `subagent.completed`.
65
65
  */
66
66
  export declare function calledSubagent(name: string, options?: EveEvalSubagentCallMatchOptions): RunAssertion;
67
67
  /**
@@ -1 +1 @@
1
- import"#evals/assertions/collector.js";import"#evals/session.js";import{createScopedAssertions}from"#evals/assertions/scoped.js";import{buildJudgeContext}from"#evals/judge.js";import{EvalRequirementFailed,EvalSkipped}from"#evals/control-flow.js";function createEvalContext(n){let i=n.collector,a=``,primary=()=>n.manager.primary,replyMessage=()=>n.manager.lastTurnSession()?.lastTurn?.message??null,o=buildJudgeContext({collector:i,getReply:replyMessage,getInput:()=>a,judge:n.judge});return{context:{get events(){return primary().events},get pendingInputRequests(){return primary().pendingInputRequests},get state(){return primary().state},get sessionId(){return primary().sessionId},requireInputRequest:e=>primary().requireInputRequest(e),respond:(...e)=>primary().respond(...e),respondAll:e=>primary().respondAll(e),send:e=>(a=promptText(e),primary().send(e)),sendFile:(e,t,n)=>(a=e,primary().sendFile(e,t,n)),signal:n.signal,target:n.target,get reply(){return replyMessage()},log:n.log,sleep:e=>sleep(e,n.signal),newSession:()=>n.manager.newSession(),...createScopedAssertions(i,{timing:`final`,select:e=>e}),check:(e,t)=>recordCheck(i,e,t),require:(e,t)=>requireCheck(i,e,t),skip:e=>{throw e.trim().length===0?Error(`skip() requires a non-empty reason.`):i.hasEntries||n.manager.hasActivity()?Error(`skip() must be called before sending messages or recording assertions.`):new EvalSkipped(e)},judge:o},collector:i}}async function requireCheck(e,t,r){let i=r.gate(r.threshold);if(!await e.recordRequirement({name:i.name,threshold:i.threshold,score:async()=>({score:await i.score(t)})}))throw new EvalRequirementFailed;return t}function recordCheck(e,t,n){return e.recordValue({name:n.name,severity:n.severity,threshold:n.threshold,score:async()=>({score:await n.score(t)})})}function promptText(e){if(typeof e==`string`)return e;let t=e.message;return typeof t==`string`?t:``}function sleep(e=1e3,t){if(!Number.isFinite(e)||e<0)throw Error(`sleep() duration must be a non-negative finite number.`);return t?.aborted?Promise.reject(t.reason):new Promise((n,r)=>{let i=setTimeout(n,e);t?.addEventListener(`abort`,()=>{clearTimeout(i),r(t.reason)},{once:!0})})}export{createEvalContext};
1
+ import"#evals/assertions/collector.js";import"#evals/session.js";import{createScopedAssertions}from"#evals/assertions/scoped.js";import{buildJudgeContext}from"#evals/judge.js";import{EvalRequirementFailed,EvalSkipped}from"#evals/control-flow.js";function createEvalContext(n){let i=n.collector,a=``,primary=()=>n.manager.primary,replyMessage=()=>n.manager.lastTurnSession()?.lastTurn?.message??null,o=buildJudgeContext({collector:i,getReply:replyMessage,getInput:()=>a,judge:n.judge});return{context:{get events(){return primary().events},get pendingInputRequests(){return primary().pendingInputRequests},get state(){return primary().state},get sessionId(){return primary().sessionId},cancel:()=>primary().cancel(),requireInputRequest:e=>primary().requireInputRequest(e),respond:(...e)=>primary().respond(...e),respondAll:e=>primary().respondAll(e),send:e=>(a=promptText(e),primary().send(e)),start:e=>(a=promptText(e),primary().start(e)),sendFile:(e,t,n)=>(a=e,primary().sendFile(e,t,n)),signal:n.signal,target:n.target,get reply(){return replyMessage()},log:n.log,sleep:e=>sleep(e,n.signal),newSession:()=>n.manager.newSession(),...createScopedAssertions(i,{timing:`final`,select:e=>e}),check:(e,t)=>recordCheck(i,e,t),require:(e,t)=>requireCheck(i,e,t),skip:e=>{throw e.trim().length===0?Error(`skip() requires a non-empty reason.`):i.hasEntries||n.manager.hasActivity()?Error(`skip() must be called before sending messages or recording assertions.`):new EvalSkipped(e)},judge:o},collector:i}}async function requireCheck(e,t,r){let i=r.gate(r.threshold);if(!await e.recordRequirement({name:i.name,threshold:i.threshold,score:async()=>({score:await i.score(t)})}))throw new EvalRequirementFailed;return t}function recordCheck(e,t,n){return e.recordValue({name:n.name,severity:n.severity,threshold:n.threshold,score:async()=>({score:await n.score(t)})})}function promptText(e){if(typeof e==`string`)return e;let t=e.message;return typeof t==`string`?t:``}function sleep(e=1e3,t){if(!Number.isFinite(e)||e<0)throw Error(`sleep() duration must be a non-negative finite number.`);return t?.aborted?Promise.reject(t.reason):new Promise((n,r)=>{let i=setTimeout(n,e);t?.addEventListener(`abort`,()=>{clearTimeout(i),r(t.reason)},{once:!0})})}export{createEvalContext};
@@ -4,6 +4,7 @@ export { EveEvalTurnFailedError } from "#evals/session.js";
4
4
  export { mockModel } from "#evals/mock-model.js";
5
5
  export type { RuntimeIdentity } from "#protocol/message.js";
6
6
  export type { InputRequest } from "#runtime/input/types.js";
7
+ export type { CancelSessionResult } from "#client/types.js";
7
8
  export type { EveEvalCountMatcher, EveEvalEventMatch, EveEvalInputRequestMatchOptions, EveEvalValueMatcher, EveEvalToolCallMatchOptions, EveEvalSkillLoadMatchOptions, EveEvalSubagentCallMatchOptions, } from "#evals/match.js";
8
- export type { Assertion, AssertionHandle, AssertionResult, AssertionSeverity, AutoevalsJudges, EveEvalActionStatus, EveEvalAssertions, EveEvalContext, EveEvalDerivedFacts, EveEvalJudgeConfig, EveEvalRunSummary, EveEvalSession, EveEvalSessionResult, EveEvalScheduleDispatchResult, EveEvalSubagentCall, EveEval, EveEvalConfig, EveEvalConfigInput, EveEvalDefinition, EveEvalInput, EveEvalResult, EveEvalTarget, EveEvalTargetCapabilities, EveEvalTargetHandle, EveEvalTaskResult, EveEvalToolCall, EveEvalTurn, EveEvalVerdict, JudgeContext, JudgeOpts, } from "#evals/types.js";
9
+ export type { Assertion, AssertionHandle, AssertionResult, AssertionSeverity, AutoevalsJudges, EveEvalActionStatus, EveEvalAssertions, EveEvalContext, EveEvalDerivedFacts, EveEvalJudgeConfig, EveEvalRunSummary, EveEvalSession, EveEvalSessionResult, EveEvalScheduleDispatchResult, EveEvalSubagentCall, EveEval, EveEvalConfig, EveEvalConfigInput, EveEvalDefinition, EveEvalInput, EveEvalLiveTurn, EveEvalResult, EveEvalTarget, EveEvalTargetCapabilities, EveEvalTargetHandle, EveEvalTaskResult, EveEvalToolCall, EveEvalTurn, EveEvalStreamEvent, EveEvalWaitForEventOptions, EveEvalVerdict, JudgeContext, JudgeOpts, } from "#evals/types.js";
9
10
  export type { MockModelMessage, MockModelOptions, MockModelRequest, MockModelResponder, MockModelResponse, MockModelTool, MockModelToolCall, MockModelToolResult, MockModelUsage, } from "#evals/mock-model.js";
@@ -47,6 +47,10 @@ export type EveEvalSkillLoadMatchOptions = Omit<EveEvalToolCallMatchOptions, "in
47
47
  * Constraints applied to subagent calls by `t.calledSubagent`.
48
48
  */
49
49
  export interface EveEvalSubagentCallMatchOptions {
50
+ /** Matcher over the runtime-action call id. */
51
+ readonly callId?: EveEvalValueMatcher<string | undefined>;
52
+ /** Matcher over the durable child session id, when delegation started. */
53
+ readonly childSessionId?: EveEvalValueMatcher<string | undefined>;
50
54
  /** Matcher over the `subagent.called` remote URL. */
51
55
  readonly remoteUrl?: EveEvalValueMatcher<string | undefined>;
52
56
  /** Matcher over the `subagent.completed` output. */
@@ -1 +1 @@
1
- function matchesValue(e,t){return e instanceof RegExp?testRegExpAgainst(e,t):typeof e==`function`?e(t):Array.isArray(e)?!Array.isArray(t)||t.length!==e.length?!1:e.every((e,n)=>matchesValue(e,t[n])):isPlainObject(e)?isPlainObject(t)?Object.entries(e).every(([e,n])=>matchesValue(n,t[e])):!1:Object.is(e,t)}function toolCallMatches(e,t){return!(t.input!==void 0&&!matchesValue(t.input,e.input)||t.output!==void 0&&!matchesValue(t.output,e.output)||e.status!==(t.status??`completed`))}function subagentCallMatches(e,t){return!(t.remoteUrl!==void 0&&!matchesValue(t.remoteUrl,e.remoteUrl)||t.output!==void 0&&!matchesValue(t.output,e.output)||e.status!==(t.status??`completed`))}function inputRequestMatches(e,t){if(t.display!==void 0&&!matchesValue(t.display,e.display)||t.prompt!==void 0&&!matchesValue(t.prompt,e.prompt))return!1;if(t.optionIds!==void 0){let n=(e.options??[]).map(e=>e.id);if(!matchesValue(t.optionIds,n))return!1}return!(t.toolName!==void 0&&(e.action.kind!==`tool-call`||e.action.toolName!==t.toolName)||t.input!==void 0&&(e.action.kind!==`tool-call`||!matchesValue(t.input,e.action.input)))}function eventMatches(e,t){return e.type===t.type&&(t.data===void 0||matchesValue(t.data,`data`in e?e.data:void 0))}function deepEquals(e,t){if(Object.is(e,t))return!0;if(Array.isArray(e)||Array.isArray(t))return!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length?!1:e.every((e,n)=>deepEquals(e,t[n]));if(isPlainObject(e)&&isPlainObject(t)){let n=Object.keys(e),r=Object.keys(t);return n.length===r.length?n.every(n=>deepEquals(e[n],t[n])):!1}return!1}function testRegExpAgainst(e,t){if(typeof t==`string`)return testRegExp(e,t);if(t===void 0)return!1;let n=JSON.stringify(t);return n!==void 0&&testRegExp(e,n)}function testRegExp(e,t){return(e.global||e.sticky)&&(e.lastIndex=0),e.test(t)}function isPlainObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{deepEquals,eventMatches,inputRequestMatches,matchesValue,subagentCallMatches,testRegExp,toolCallMatches};
1
+ function matchesValue(e,t){return e instanceof RegExp?testRegExpAgainst(e,t):typeof e==`function`?e(t):Array.isArray(e)?!Array.isArray(t)||t.length!==e.length?!1:e.every((e,n)=>matchesValue(e,t[n])):isPlainObject(e)?isPlainObject(t)?Object.entries(e).every(([e,n])=>matchesValue(n,t[e])):!1:Object.is(e,t)}function toolCallMatches(e,t){return!(t.input!==void 0&&!matchesValue(t.input,e.input)||t.output!==void 0&&!matchesValue(t.output,e.output)||e.status!==(t.status??`completed`))}function subagentCallMatches(e,t){return!(t.callId!==void 0&&!matchesValue(t.callId,e.callId)||t.childSessionId!==void 0&&!matchesValue(t.childSessionId,e.childSessionId)||t.remoteUrl!==void 0&&!matchesValue(t.remoteUrl,e.remoteUrl)||t.output!==void 0&&!matchesValue(t.output,e.output)||e.status!==(t.status??`completed`))}function inputRequestMatches(e,t){if(t.display!==void 0&&!matchesValue(t.display,e.display)||t.prompt!==void 0&&!matchesValue(t.prompt,e.prompt))return!1;if(t.optionIds!==void 0){let n=(e.options??[]).map(e=>e.id);if(!matchesValue(t.optionIds,n))return!1}return!(t.toolName!==void 0&&(e.action.kind!==`tool-call`||e.action.toolName!==t.toolName)||t.input!==void 0&&(e.action.kind!==`tool-call`||!matchesValue(t.input,e.action.input)))}function eventMatches(e,t){return e.type===t.type&&(t.data===void 0||matchesValue(t.data,`data`in e?e.data:void 0))}function deepEquals(e,t){if(Object.is(e,t))return!0;if(Array.isArray(e)||Array.isArray(t))return!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length?!1:e.every((e,n)=>deepEquals(e,t[n]));if(isPlainObject(e)&&isPlainObject(t)){let n=Object.keys(e),r=Object.keys(t);return n.length===r.length?n.every(n=>deepEquals(e[n],t[n])):!1}return!1}function testRegExpAgainst(e,t){if(typeof t==`string`)return testRegExp(e,t);if(t===void 0)return!1;let n=JSON.stringify(t);return n!==void 0&&testRegExp(e,n)}function testRegExp(e,t){return(e.global||e.sticky)&&(e.lastIndex=0),e.test(t)}function isPlainObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{deepEquals,eventMatches,inputRequestMatches,matchesValue,subagentCallMatches,testRegExp,toolCallMatches};
@@ -1 +1 @@
1
- const TURN_EPILOGUE_EVENT_TYPES=new Set([`turn.completed`,`session.waiting`,`session.completed`]);function deriveRunFacts(e,t){let n=t?.sessionId,r=[],i=new Map,a=[],o=new Map,s=[],c=-1,l=0,u=0,d,ensureToolCall=(e,t,a)=>{let o=i.get(e);if(o!==void 0)return o;let s={name:t,input:a,output:void 0,status:`pending`,turnIndex:Math.max(c,0),sessionId:n};return r.push(s),i.set(e,s),s},ensureSubagentCall=(e,t)=>{let r=o.get(e);if(r!==void 0)return r;let i={name:t,status:`pending`,turnIndex:Math.max(c,0),sessionId:n};return a.push(i),o.set(e,i),i};for(let t of e)switch(t.type){case`turn.started`:c+=1;break;case`actions.requested`:for(let e of t.data.actions)e.kind===`tool-call`&&ensureToolCall(e.callId,e.toolName,e.input);break;case`action.result`:{let{result:e,status:n}=t.data;if(e.kind===`tool-result`){let t=ensureToolCall(e.callId,e.toolName,{});t.output=e.output,t.status=n}else if(e.kind===`subagent-result`){let t=ensureSubagentCall(e.callId,e.subagentName);t.output=t.output??e.output,t.status=n}break}case`subagent.called`:{let e=ensureSubagentCall(t.data.callId,t.data.name);t.data.remote!==void 0&&(e.remoteUrl=t.data.remote.url);break}case`subagent.started`:ensureSubagentCall(t.data.callId,t.data.subagentName);break;case`subagent.completed`:{let e=ensureSubagentCall(t.data.callId,t.data.subagentName);e.output=t.data.output,e.status===`pending`&&(e.status=`completed`);break}case`input.requested`:s.push(...t.data.requests);for(let e of t.data.requests)ensureToolCall(e.action.callId,e.action.toolName,e.action.input);break;case`message.completed`:t.data.finishReason!==`tool-calls`&&(l+=1);break;case`reasoning.completed`:u+=1;break;case`session.failed`:d=t.data.code;break}return{toolCalls:r,toolCallCount:r.length,subagentCalls:a,subagentCallCount:a.length,inputRequests:s,parked:endedParkedOnInput(e),messageCount:l,reasoningBlockCount:u,failureCode:d}}function createEmptyDerivedFacts(){return{toolCalls:[],toolCallCount:0,subagentCalls:[],subagentCallCount:0,inputRequests:[],parked:!1,messageCount:0,reasoningBlockCount:0}}function endedParkedOnInput(t){for(let n=t.length-1;n>=0;n--){let r=t[n];if(!(r===void 0||TURN_EPILOGUE_EVENT_TYPES.has(r.type)))return r.type===`input.requested`}return!1}export{createEmptyDerivedFacts,deriveRunFacts};
1
+ const TURN_EPILOGUE_EVENT_TYPES=new Set([`turn.completed`,`session.waiting`,`session.completed`]);function deriveRunFacts(e,t){let n=t?.sessionId,r=[],i=new Map,a=[],o=new Map,s=[],c=-1,l=0,u=0,d,ensureToolCall=(e,t,a)=>{let o=i.get(e);if(o!==void 0)return o;let s={name:t,input:a,output:void 0,status:`pending`,turnIndex:Math.max(c,0),sessionId:n};return r.push(s),i.set(e,s),s},ensureSubagentCall=(e,t)=>{let r=o.get(e);if(r!==void 0)return r;let i={callId:e,name:t,status:`pending`,turnIndex:Math.max(c,0),sessionId:n};return a.push(i),o.set(e,i),i};for(let t of e)switch(t.type){case`turn.started`:c+=1;break;case`actions.requested`:for(let e of t.data.actions)e.kind===`tool-call`&&ensureToolCall(e.callId,e.toolName,e.input);break;case`action.result`:{let{result:e,status:n}=t.data;if(e.kind===`tool-result`){let t=ensureToolCall(e.callId,e.toolName,{});t.output=e.output,t.status=n}else if(e.kind===`subagent-result`){let t=ensureSubagentCall(e.callId,e.subagentName);t.output=t.output??e.output,t.status=n}break}case`subagent.called`:{let e=ensureSubagentCall(t.data.callId,t.data.name);e.childSessionId=t.data.childSessionId,t.data.remote!==void 0&&(e.remoteUrl=t.data.remote.url);break}case`subagent.started`:ensureSubagentCall(t.data.callId,t.data.subagentName);break;case`subagent.completed`:{let e=ensureSubagentCall(t.data.callId,t.data.subagentName);e.output=t.data.output,e.status===`pending`&&(e.status=`completed`);break}case`input.requested`:s.push(...t.data.requests);for(let e of t.data.requests)ensureToolCall(e.action.callId,e.action.toolName,e.action.input);break;case`message.completed`:t.data.finishReason!==`tool-calls`&&(l+=1);break;case`reasoning.completed`:u+=1;break;case`session.failed`:d=t.data.code;break}return{toolCalls:r,toolCallCount:r.length,subagentCalls:a,subagentCallCount:a.length,inputRequests:s,parked:endedParkedOnInput(e),messageCount:l,reasoningBlockCount:u,failureCode:d}}function createEmptyDerivedFacts(){return{toolCalls:[],toolCallCount:0,subagentCalls:[],subagentCallCount:0,inputRequests:[],parked:!1,messageCount:0,reasoningBlockCount:0}}function endedParkedOnInput(t){for(let n=t.length-1;n>=0;n--){let r=t[n];if(!(r===void 0||TURN_EPILOGUE_EVENT_TYPES.has(r.type)))return r.type===`input.requested`}return!1}export{createEmptyDerivedFacts,deriveRunFacts};
@@ -1,10 +1,10 @@
1
1
  import type { Client } from "#client/client.js";
2
2
  import type { ClientSession } from "#client/session.js";
3
- import type { SendTurnInput, SessionState } from "#client/types.js";
3
+ import type { CancelSessionResult, SendTurnInput, SessionState } from "#client/types.js";
4
4
  import type { HandleMessageStreamEvent, TurnFailureStreamEvent } from "#protocol/message.js";
5
5
  import type { InputRequest, InputResponse } from "#runtime/input/types.js";
6
6
  import { AssertionCollector } from "#evals/assertions/collector.js";
7
- import type { EveEvalAssertions, EveEvalOutputAssertions, EveEvalSession, EveEvalSessionResult, EveEvalTurn } from "#evals/types.js";
7
+ import type { EveEvalAssertions, EveEvalLiveTurn, EveEvalOutputAssertions, EveEvalSession, EveEvalSessionResult, EveEvalTurn } from "#evals/types.js";
8
8
  import type { EveEvalInputRequestMatchOptions } from "#evals/match.js";
9
9
  /**
10
10
  * Error thrown by {@link EveEvalTurn.expectOk} when a turn failed.
@@ -28,14 +28,19 @@ export declare class EvalSessionDriver implements EveEvalSession {
28
28
  get pendingInputRequests(): readonly InputRequest[];
29
29
  get sessionId(): string | undefined;
30
30
  get state(): SessionState;
31
+ cancel(): Promise<CancelSessionResult>;
31
32
  requireInputRequest(filter?: EveEvalInputRequestMatchOptions): InputRequest;
32
33
  respond(...responses: InputResponse[]): Promise<EveEvalTurn>;
33
34
  respondAll(optionId: string): Promise<EveEvalTurn>;
34
35
  send(input: SendTurnInput): Promise<EveEvalTurn>;
36
+ start(input: SendTurnInput): Promise<EveEvalLiveTurn>;
35
37
  sendFile(text: string, filePath: string, mediaType?: string): Promise<EveEvalTurn>;
36
38
  readTurn(options?: {
37
39
  readonly startIndex?: number;
38
40
  }): Promise<EveEvalTurn>;
41
+ watchTurn(options?: {
42
+ readonly startIndex?: number;
43
+ }, sessionId?: string): EveEvalLiveTurn;
39
44
  snapshot(primary: boolean): EveEvalSessionResult;
40
45
  }
41
46
  export declare class EvalSessionManager {
@@ -50,6 +55,9 @@ export declare class EvalSessionManager {
50
55
  attachSession(sessionId: string, options?: {
51
56
  readonly startIndex?: number;
52
57
  }): Promise<EvalSessionDriver>;
58
+ watchTurn(sessionId: string, options?: {
59
+ readonly startIndex?: number;
60
+ }): EveEvalLiveTurn;
53
61
  snapshots(): readonly EveEvalSessionResult[];
54
62
  lastTurnSession(): EvalSessionDriver | undefined;
55
63
  hasActivity(): boolean;
@@ -1 +1 @@
1
- import{basename,extname}from"node:path";import{readFile}from"node:fs/promises";import{deriveResultStatus,extractCompletedMessage,extractInputRequests}from"#client/session-utils.js";import{createTextWithFileContent}from"#client/file-parts.js";import{isCurrentTurnBoundaryEvent,isTurnFailureEvent}from"#protocol/message.js";import{extractCompletedResult}from"#client/output-schema.js";import{inputRequestMatches,toolCallMatches}from"#evals/match.js";import{AssertionCollector}from"#evals/assertions/collector.js";import{createOutputAssertions,createScopedAssertions}from"#evals/assertions/scoped.js";import{EvalRequirementFailed}from"#evals/control-flow.js";import{deriveRunFacts}from"#evals/runner/derive-run-facts.js";var EveEvalTurnFailedError=class extends Error{event;turn;constructor(e){let t=e.events.find(isTurnFailureEvent),n=t===void 0?`turn ended with status "${e.status}"`:`${t.type}: ${t.data.code} ${t.data.message}`.trim();super(`Eval turn failed: ${n}`),this.name=`EveEvalTurnFailedError`,this.event=t,this.turn=e}},EvalSessionDriver=class{#e;#t;#n;#r=[];#i;#a=[];constructor(e){this.#n=e.collector,this.#e=e.session,this.#t=e.signal,Object.assign(this,createScopedAssertions(this.#n,{timing:`snapshot`,select:()=>this.#s()}),createOutputAssertions(this.#n,{timing:`snapshot`,select:()=>this.#s()}))}get events(){return this.#r}get lastTurn(){return this.#i}get pendingInputRequests(){return this.#a}get sessionId(){return this.#e.state.sessionId??this.#i?.sessionId}get state(){return this.#e.state}requireInputRequest(e={}){this.#a.length===0&&this.#c(`requireInputRequest`,`expected one pending input request, but the last turn did not park`);let t=this.#a.filter(t=>inputRequestMatches(t,e));return(this.#a.length!==1||t.length!==1)&&this.#c(`requireInputRequest`,`expected exactly one pending input request matching ${formatInputRequestFilter(e)}, found ${t.length} match(es) across ${this.#a.length} pending request(s)`),this.#n.recordOutcome({name:`requireInputRequest`,outcome:{score:1}}),t[0]}async respond(...e){if(e.length===0)throw Error(`respond() requires at least one input response.`);return await this.send({inputResponses:e})}async respondAll(e){let t=this.#a;if(t.length===0)throw Error(`respondAll() requires at least one pending input request.`);for(let n of t)assertRequestHasOption(n,e);return await this.respond(...t.map(t=>({optionId:e,requestId:t.requestId})))}async send(e){let t=await(await this.#e.send(attachSignal(e,this.#t))).result();return this.#o({data:t.data,events:t.events,inputRequests:t.inputRequests,message:t.message,sessionId:t.sessionId,status:t.status})}async sendFile(t,r,i){let a=createTextWithFileContent({bytes:await readFile(r),filename:basename(r),mediaType:i??inferMediaType(r),text:t});return await this.send({message:a})}async readTurn(e){let t=this.sessionId,n=[],o=!1;for await(let t of this.#e.stream({signal:this.#t,startIndex:e?.startIndex}))if(n.push(t),isCurrentTurnBoundaryEvent(t)){o=!0;break}if(!o)throw Error(`Stream for session "${this.sessionId??`(unknown)`}" closed before a turn boundary.`);return this.#o({data:extractCompletedResult(n),events:n,inputRequests:extractInputRequests(n),message:extractCompletedMessage(n),sessionId:requireSessionId(t),status:deriveResultStatus(n)})}snapshot(e){let t=this.sessionId;return{derived:deriveRunFacts(this.#r,{sessionId:t}),events:[...this.#r],primary:e,sessionId:t,state:this.#e.state}}#o(e){this.#r.push(...e.events),this.#a=e.status===`waiting`?e.inputRequests:[];let t=deriveRunFacts(e.events,{sessionId:e.sessionId}),n=new EvalTurn({collector:this.#n,data:e.data,derived:t,events:e.events,inputRequests:e.inputRequests,message:e.message,sessionId:e.sessionId,status:e.status,toolCalls:t.toolCalls});return this.#i=n,n}#s(){let e=this.sessionId;return{derived:deriveRunFacts(this.#r,{sessionId:e}),events:[...this.#r],output:outputOf(this.#i),status:this.#i?.status??`completed`}}#c(e,t){throw this.#n.recordOutcome({name:e,outcome:{score:0,message:t}}),new EvalRequirementFailed}},EvalTurn=class{data;events;inputRequests;message;sessionId;status;toolCalls;#e;#t;constructor(e){this.data=e.data,this.events=e.events,this.inputRequests=e.inputRequests,this.message=e.message,this.sessionId=e.sessionId,this.status=e.status,this.toolCalls=e.toolCalls,this.#e=e.collector,this.#t=e.derived,Object.assign(this,createScopedAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}),createOutputAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}))}expectOk(){if(this.status!==`failed`)return this;throw new EveEvalTurnFailedError(this)}requireToolCall(e,t={}){let n=this.toolCalls.filter(n=>n.name===e&&toolCallMatches(n,t));return n.length!==1&&inputRequirementFailed(this.#e,`requireToolCall`,`expected exactly one matching "${e}" tool call in this turn, found ${n.length}; observed [${this.toolCalls.map(e=>e.name).join(`, `)}]`),this.#e.recordOutcome({name:`requireToolCall`,outcome:{score:1}}),n[0]}#n(){return{derived:this.#t,events:this.events,output:outputOf(this),status:this.status}}},EvalSessionManager=class{#e;#t;#n;#r=[];#i;constructor(e){this.#e=e.client,this.#n=e.collector??new AssertionCollector,this.#t=e.signal}get primary(){return this.#i??=this.#a(),this.#i}newSession(){return this.#a()}async attachSession(e,t){let n=new EvalSessionDriver({collector:this.#n,session:this.#e.session({sessionId:e,streamIndex:t?.startIndex??0}),signal:this.#t});return this.#r.push(n),await n.readTurn(t),n}snapshots(){return this.#r.map(e=>e.snapshot(e===this.#i))}lastTurnSession(){return this.#i?.lastTurn===void 0?this.#r.find(e=>e.lastTurn!==void 0):this.#i}hasActivity(){return this.#r.length>0}#a(){let e=new EvalSessionDriver({collector:this.#n,session:this.#e.session(),signal:this.#t});return this.#r.push(e),e}};function attachSignal(e,t){if(t===void 0)return e;if(typeof e==`string`)return{message:e,signal:t};let n=e;return n.signal===void 0?{...n,signal:t}:n}function formatInputRequestFilter(e){return JSON.stringify(e)}function inputRequirementFailed(e,t,n){throw e.recordOutcome({name:t,outcome:{score:0,message:n}}),new EvalRequirementFailed}function outputOf(e){return e===void 0?null:e.data===void 0?e.message??null:e.data}function requireSessionId(e){if(e===void 0)throw Error(`Eval session produced a turn without a session id.`);return e}function assertRequestHasOption(e,t){if(e.options===void 0||e.options.length===0)throw Error(`Input request "${e.requestId}" has no selectable options.`);if(!e.options.some(e=>e.id===t))throw Error(`Input request "${e.requestId}" does not offer option "${t}".`)}function inferMediaType(e){switch(extname(e).toLowerCase()){case`.gif`:return`image/gif`;case`.jpg`:case`.jpeg`:return`image/jpeg`;case`.png`:return`image/png`;case`.webp`:return`image/webp`;default:return`application/octet-stream`}}export{EvalSessionDriver,EvalSessionManager,EveEvalTurnFailedError};
1
+ import{basename,extname}from"node:path";import{readFile}from"node:fs/promises";import{deriveResultStatus,extractCompletedMessage,extractInputRequests}from"#client/session-utils.js";import{createTextWithFileContent}from"#client/file-parts.js";import{isCurrentTurnBoundaryEvent,isTurnFailureEvent}from"#protocol/message.js";import{extractCompletedResult}from"#client/output-schema.js";import{inputRequestMatches,matchesValue,toolCallMatches}from"#evals/match.js";import{AssertionCollector}from"#evals/assertions/collector.js";import{createOutputAssertions,createScopedAssertions}from"#evals/assertions/scoped.js";import{EvalRequirementFailed}from"#evals/control-flow.js";import{deriveRunFacts}from"#evals/runner/derive-run-facts.js";var EveEvalTurnFailedError=class extends Error{event;turn;constructor(e){let t=e.events.find(isTurnFailureEvent),n=t===void 0?`turn ended with status "${e.status}"`:`${t.type}: ${t.data.code} ${t.data.message}`.trim();super(`Eval turn failed: ${n}`),this.name=`EveEvalTurnFailedError`,this.event=t,this.turn=e}},EvalSessionDriver=class{#e;#t;#n;#r=[];#i;#a=[];constructor(e){this.#n=e.collector,this.#e=e.session,this.#t=e.signal,Object.assign(this,createScopedAssertions(this.#n,{timing:`snapshot`,select:()=>this.#c()}),createOutputAssertions(this.#n,{timing:`snapshot`,select:()=>this.#c()}))}get events(){return this.#r}get lastTurn(){return this.#i}get pendingInputRequests(){return this.#a}get sessionId(){return this.#e.state.sessionId??this.#i?.sessionId}get state(){return this.#e.state}async cancel(){return await this.#e.cancel()}requireInputRequest(e={}){this.#a.length===0&&this.#l(`requireInputRequest`,`expected one pending input request, but the last turn did not park`);let t=this.#a.filter(t=>inputRequestMatches(t,e));return(this.#a.length!==1||t.length!==1)&&this.#l(`requireInputRequest`,`expected exactly one pending input request matching ${formatInputRequestFilter(e)}, found ${t.length} match(es) across ${this.#a.length} pending request(s)`),this.#n.recordOutcome({name:`requireInputRequest`,outcome:{score:1}}),t[0]}async respond(...e){if(e.length===0)throw Error(`respond() requires at least one input response.`);return await this.send({inputResponses:e})}async respondAll(e){let t=this.#a;if(t.length===0)throw Error(`respondAll() requires at least one pending input request.`);for(let n of t)assertRequestHasOption(n,e);return await this.respond(...t.map(t=>({optionId:e,requestId:t.requestId})))}async send(e){return await(await this.start(e)).result()}async start(e){let t=await this.#e.send(attachSignal(e,this.#t));return new EvalLiveTurn({events:t,record:e=>this.#s(t.sessionId,e),session:this,sessionId:t.sessionId})}async sendFile(t,r,i){let a=createTextWithFileContent({bytes:await readFile(r),filename:basename(r),mediaType:i??inferMediaType(r),text:t});return await this.send({message:a})}async readTurn(e){let t=this.sessionId;return await this.watchTurn(e,requireSessionId(t)).result()}watchTurn(e,t=requireSessionId(this.sessionId)){return new EvalLiveTurn({events:this.#e.stream({signal:this.#t,startIndex:e?.startIndex}),record:e=>this.#s(t,e),session:this,sessionId:t})}snapshot(e){let t=this.sessionId;return{derived:deriveRunFacts(this.#r,{sessionId:t}),events:[...this.#r],primary:e,sessionId:t,state:this.#e.state}}#o(e){this.#r.push(...e.events),this.#a=e.status===`waiting`?e.inputRequests:[];let t=deriveRunFacts(e.events,{sessionId:e.sessionId}),n=new EvalTurn({collector:this.#n,data:e.data,derived:t,events:e.events,inputRequests:e.inputRequests,message:e.message,sessionId:e.sessionId,status:e.status,toolCalls:t.toolCalls});return this.#i=n,n}#s(e,t){return this.#o({data:extractCompletedResult(t),events:t,inputRequests:extractInputRequests(t),message:extractCompletedMessage(t),sessionId:e,status:deriveResultStatus(t)})}#c(){let e=this.sessionId;return{derived:deriveRunFacts(this.#r,{sessionId:e}),events:[...this.#r],output:outputOf(this.#i),status:this.#i?.status??`completed`}}#l(e,t){throw this.#n.recordOutcome({name:e,outcome:{score:0,message:t}}),new EvalRequirementFailed}},EvalLiveTurn=class{session;sessionId;#e;#t=[];#n=new Set;#r;constructor(e){this.session=e.session,this.sessionId=e.sessionId,this.#e=this.#i(e.events,e.record),this.#e.catch(()=>{})}get events(){return this.#t}async cancel(){return await this.session.cancel()}async result(){return await this.#e}async waitForEvent(e,t){let matches=n=>n.type===e&&(t?.data===void 0||matchesValue(t.data,`data`in n?n.data:void 0)),n=this.#t.find(matches);if(n!==void 0)return n;if(this.#r!==void 0)throw this.#r;return await new Promise((e,t)=>{let n={matches,reject:t,resolve:t=>e(t)};this.#n.add(n)})}async#i(e,t){try{let n=!1;for await(let t of e)if(this.#t.push(t),this.#a(t),isTurnFailureEvent(t)&&this.#o(Error(`Session ${this.sessionId} failed before the expected event (${t.type}).`)),isCurrentTurnBoundaryEvent(t)){n=!0,this.#o(Error(`Session ${this.sessionId} reached ${t.type} before the expected event.`));break}if(!n)throw Error(`Stream for session "${this.sessionId}" closed before a turn boundary.`);return t(this.#t)}catch(e){let t=e instanceof Error?e:Error(String(e));throw this.#o(t),e}}#a(e){for(let t of this.#n)t.matches(e)&&(this.#n.delete(t),t.resolve(e))}#o(e){if(this.#r===void 0){this.#r=e;for(let t of this.#n)t.reject(e);this.#n.clear()}}},EvalTurn=class{data;events;inputRequests;message;sessionId;status;toolCalls;#e;#t;constructor(e){this.data=e.data,this.events=e.events,this.inputRequests=e.inputRequests,this.message=e.message,this.sessionId=e.sessionId,this.status=e.status,this.toolCalls=e.toolCalls,this.#e=e.collector,this.#t=e.derived,Object.assign(this,createScopedAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}),createOutputAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}))}expectOk(){if(this.status!==`failed`)return this;throw new EveEvalTurnFailedError(this)}requireToolCall(e,t={}){let n=this.toolCalls.filter(n=>n.name===e&&toolCallMatches(n,t));return n.length!==1&&inputRequirementFailed(this.#e,`requireToolCall`,`expected exactly one matching "${e}" tool call in this turn, found ${n.length}; observed [${this.toolCalls.map(e=>e.name).join(`, `)}]`),this.#e.recordOutcome({name:`requireToolCall`,outcome:{score:1}}),n[0]}#n(){return{derived:this.#t,events:this.events,output:outputOf(this),status:this.status}}},EvalSessionManager=class{#e;#t;#n;#r=[];#i;constructor(e){this.#e=e.client,this.#n=e.collector??new AssertionCollector,this.#t=e.signal}get primary(){return this.#i??=this.#a(),this.#i}newSession(){return this.#a()}async attachSession(e,t){let n=this.#o(e,t);return await n.readTurn(t),n}watchTurn(e,t){return this.#o(e,t).watchTurn(t,e)}snapshots(){return this.#r.map(e=>e.snapshot(e===this.#i))}lastTurnSession(){return this.#i?.lastTurn===void 0?this.#r.find(e=>e.lastTurn!==void 0):this.#i}hasActivity(){return this.#r.length>0}#a(){let e=new EvalSessionDriver({collector:this.#n,session:this.#e.session(),signal:this.#t});return this.#r.push(e),e}#o(e,t){let n=new EvalSessionDriver({collector:this.#n,session:this.#e.session({sessionId:e,streamIndex:t?.startIndex??0}),signal:this.#t});return this.#r.push(n),n}};function attachSignal(e,t){if(t===void 0)return e;if(typeof e==`string`)return{message:e,signal:t};let n=e;return n.signal===void 0?{...n,signal:t}:n}function formatInputRequestFilter(e){return JSON.stringify(e)}function inputRequirementFailed(e,t,n){throw e.recordOutcome({name:t,outcome:{score:0,message:n}}),new EvalRequirementFailed}function outputOf(e){return e===void 0?null:e.data===void 0?e.message??null:e.data}function requireSessionId(e){if(e===void 0)throw Error(`Eval session produced a turn without a session id.`);return e}function assertRequestHasOption(e,t){if(e.options===void 0||e.options.length===0)throw Error(`Input request "${e.requestId}" has no selectable options.`);if(!e.options.some(e=>e.id===t))throw Error(`Input request "${e.requestId}" does not offer option "${t}".`)}function inferMediaType(e){switch(extname(e).toLowerCase()){case`.gif`:return`image/gif`;case`.jpg`:case`.jpeg`:return`image/jpeg`;case`.png`:return`image/png`;case`.webp`:return`image/webp`;default:return`application/octet-stream`}}export{EvalSessionDriver,EvalSessionManager,EveEvalTurnFailedError};
@@ -1 +1 @@
1
- import{createEveDevDispatchSchedulePath}from"#protocol/routes.js";import{toErrorMessage}from"#shared/errors.js";import"#client/client.js";import{stripNpmPackageScope}from"#shared/package-name.js";import{EvalSessionManager}from"#evals/session.js";import{setTimeout}from"node:timers/promises";async function resolveEvalTargetHandle(e){await waitForTargetHealth(e.client,e.url);let t=await e.client.info();if(assertAgentInfoShape(t,e.url),e.expectedAgentName!==void 0&&!matchesExpectedAgentName(e.expectedAgentName,t.agent.name))throw Error(`Expected eval target ${JSON.stringify(e.expectedAgentName)} at ${e.url}, but ${JSON.stringify(t.agent.name)} is responding there.`);return createEvalTargetHandle({capabilities:capabilitiesFromInfo(t),client:e.client,kind:e.kind,url:e.url})}function createEvalTargetHandle(e){return createHandle({capabilities:e.capabilities,client:e.client,kind:e.kind,sessions:void 0,url:e.url})}function scopeEvalTargetHandle(e,t){return createHandle({capabilities:e.capabilities,client:void 0,delegate:e,kind:e.kind,sessions:t.sessions,url:e.url})}function createHandle(t){let n=t.delegate,i=t.client,fetchTarget=async(e,t)=>{if(n!==void 0)return await n.fetch(e,t);if(i===void 0)throw Error(`Eval target cannot fetch without a client.`);return await i.fetch(e,t)};return{capabilities:t.capabilities,kind:t.kind,url:t.url,async attachSession(e,a){if(t.sessions!==void 0)return await t.sessions.attachSession(e,a);if(n!==void 0)return await n.attachSession(e,a);if(i===void 0)throw Error(`Eval target cannot attach sessions without a client.`);return await new EvalSessionManager({client:i}).attachSession(e,a)},async dispatchSchedule(n){if(!t.capabilities.devRoutes)throw Error(`target.dispatchSchedule() requires a target with dev routes enabled.`);let r=await fetchTarget(createEveDevDispatchSchedulePath(n),{method:`POST`});if(!r.ok){let e=await readResponseBodySafely(r);throw Error(`Schedule dispatch failed: ${r.status} ${r.statusText}`+(e.length>0?`, ${e}`:``))}return parseScheduleDispatchResult(await r.json())},async fetch(e,t){return await fetchTarget(e,t)}}}function capabilitiesFromInfo(e){return{devRoutes:e.capabilities?.devRoutes??e.mode===`development`}}function matchesExpectedAgentName(e,t){return t===e||t===stripNpmPackageScope(e)}async function waitForTargetHealth(e,n){let r=Date.now()+6e4,a;for(;Date.now()<r;)try{await e.health();return}catch(e){a=toErrorMessage(e),await setTimeout(250)}throw Error(`Timed out waiting for eval target health at ${n}.`+(a===void 0?``:` Last error: ${a}`))}function assertAgentInfoShape(e,t){if(e.kind!==`eve-agent-info`||e.version!==1)throw Error(`Eval target ${t} returned an unrecognized /eve/v1/info payload.`)}function parseScheduleDispatchResult(e){if(typeof e!=`object`||!e||!(`scheduleId`in e)||typeof e.scheduleId!=`string`||!(`sessionIds`in e)||!Array.isArray(e.sessionIds)||e.sessionIds.some(e=>typeof e!=`string`))throw Error(`Schedule dispatch returned an unexpected response shape: ${JSON.stringify(e)}`);return{scheduleId:e.scheduleId,sessionIds:[...e.sessionIds]}}async function readResponseBodySafely(e){try{return(await e.text()).trim()}catch{return``}}export{createEvalTargetHandle,resolveEvalTargetHandle,scopeEvalTargetHandle};
1
+ import{createEveDevDispatchSchedulePath}from"#protocol/routes.js";import{toErrorMessage}from"#shared/errors.js";import"#client/client.js";import{stripNpmPackageScope}from"#shared/package-name.js";import{EvalSessionManager}from"#evals/session.js";import{setTimeout}from"node:timers/promises";async function resolveEvalTargetHandle(e){await waitForTargetHealth(e.client,e.url);let t=await e.client.info();if(assertAgentInfoShape(t,e.url),e.expectedAgentName!==void 0&&!matchesExpectedAgentName(e.expectedAgentName,t.agent.name))throw Error(`Expected eval target ${JSON.stringify(e.expectedAgentName)} at ${e.url}, but ${JSON.stringify(t.agent.name)} is responding there.`);return createEvalTargetHandle({capabilities:capabilitiesFromInfo(t),client:e.client,kind:e.kind,url:e.url})}function createEvalTargetHandle(e){return createHandle({capabilities:e.capabilities,client:e.client,kind:e.kind,sessions:void 0,url:e.url})}function scopeEvalTargetHandle(e,t){return createHandle({capabilities:e.capabilities,client:void 0,delegate:e,kind:e.kind,sessions:t.sessions,url:e.url})}function createHandle(t){let n=t.delegate,i=t.client,fetchTarget=async(e,t)=>{if(n!==void 0)return await n.fetch(e,t);if(i===void 0)throw Error(`Eval target cannot fetch without a client.`);return await i.fetch(e,t)};return{capabilities:t.capabilities,kind:t.kind,url:t.url,async attachSession(e,a){if(t.sessions!==void 0)return await t.sessions.attachSession(e,a);if(n!==void 0)return await n.attachSession(e,a);if(i===void 0)throw Error(`Eval target cannot attach sessions without a client.`);return await new EvalSessionManager({client:i}).attachSession(e,a)},watchTurn(e,a){if(t.sessions!==void 0)return t.sessions.watchTurn(e,a);if(n!==void 0)return n.watchTurn(e,a);if(i===void 0)throw Error(`Eval target cannot watch sessions without a client.`);return new EvalSessionManager({client:i}).watchTurn(e,a)},async dispatchSchedule(n){if(!t.capabilities.devRoutes)throw Error(`target.dispatchSchedule() requires a target with dev routes enabled.`);let r=await fetchTarget(createEveDevDispatchSchedulePath(n),{method:`POST`});if(!r.ok){let e=await readResponseBodySafely(r);throw Error(`Schedule dispatch failed: ${r.status} ${r.statusText}`+(e.length>0?`, ${e}`:``))}return parseScheduleDispatchResult(await r.json())},async fetch(e,t){return await fetchTarget(e,t)}}}function capabilitiesFromInfo(e){return{devRoutes:e.capabilities?.devRoutes??e.mode===`development`}}function matchesExpectedAgentName(e,t){return t===e||t===stripNpmPackageScope(e)}async function waitForTargetHealth(e,n){let r=Date.now()+6e4,a;for(;Date.now()<r;)try{await e.health();return}catch(e){a=toErrorMessage(e),await setTimeout(250)}throw Error(`Timed out waiting for eval target health at ${n}.`+(a===void 0?``:` Last error: ${a}`))}function assertAgentInfoShape(e,t){if(e.kind!==`eve-agent-info`||e.version!==1)throw Error(`Eval target ${t} returned an unrecognized /eve/v1/info payload.`)}function parseScheduleDispatchResult(e){if(typeof e!=`object`||!e||!(`scheduleId`in e)||typeof e.scheduleId!=`string`||!(`sessionIds`in e)||!Array.isArray(e.sessionIds)||e.sessionIds.some(e=>typeof e!=`string`))throw Error(`Schedule dispatch returned an unexpected response shape: ${JSON.stringify(e)}`);return{scheduleId:e.scheduleId,sessionIds:[...e.sessionIds]}}async function readResponseBodySafely(e){try{return(await e.text()).trim()}catch{return``}}export{createEvalTargetHandle,resolveEvalTargetHandle,scopeEvalTargetHandle};
@@ -1,7 +1,7 @@
1
1
  import type { LanguageModel } from "ai";
2
2
  import type { StandardSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
3
3
  import type { HandleMessageStreamEvent, RuntimeIdentity } from "#protocol/message.js";
4
- import type { SendTurnInput, SessionState } from "#client/types.js";
4
+ import type { CancelSessionResult, SendTurnInput, SessionState } from "#client/types.js";
5
5
  import type { InputRequest, InputResponse } from "#runtime/input/types.js";
6
6
  import type { JsonObject, JsonValue } from "#shared/json.js";
7
7
  import type { AgentModelOptionsDefinition } from "#shared/agent-definition.js";
@@ -32,6 +32,10 @@ export interface EveEvalToolCall {
32
32
  * (`subagent.called` / `subagent.started`, joined with `subagent.completed`).
33
33
  */
34
34
  export interface EveEvalSubagentCall {
35
+ /** Runtime-action call id joining this delegation's lifecycle events, when observed. */
36
+ readonly callId?: string;
37
+ /** Durable child session id for local and remote workflow delegations. */
38
+ readonly childSessionId?: string;
35
39
  /** Subagent name. */
36
40
  readonly name: string;
37
41
  /** Remote agent URL for remote delegations (`subagent.called` remote metadata). */
@@ -183,6 +187,34 @@ export interface EveEvalOutputAssertions {
183
187
  outputEquals(value: unknown): AssertionHandle;
184
188
  outputMatches(schema: StandardSchemaV1): AssertionHandle;
185
189
  }
190
+ /** Typed stream event returned by {@link EveEvalLiveTurn.waitForEvent}. */
191
+ export type EveEvalStreamEvent<TType extends HandleMessageStreamEvent["type"] = HandleMessageStreamEvent["type"]> = Extract<HandleMessageStreamEvent, {
192
+ type: TType;
193
+ }>;
194
+ /** Matcher options for waiting until one live turn emits a specific event. */
195
+ export type EveEvalWaitForEventOptions<TType extends HandleMessageStreamEvent["type"]> = Omit<Extract<EveEvalEventMatch, {
196
+ type: TType;
197
+ }>, "count" | "type">;
198
+ /**
199
+ * One accepted turn whose event stream is still in progress.
200
+ *
201
+ * The handle owns the stream consumer: event waiters observe its buffer and
202
+ * {@link result} settles and records that same stream exactly once.
203
+ */
204
+ export interface EveEvalLiveTurn {
205
+ /** Events observed on this turn so far. */
206
+ readonly events: readonly HandleMessageStreamEvent[];
207
+ /** Session driver that started or owns this turn. */
208
+ readonly session: EveEvalSession;
209
+ /** Durable session id available as soon as the turn is accepted or attached. */
210
+ readonly sessionId: string;
211
+ /** Request cooperative cancellation of this turn's session. */
212
+ cancel(): Promise<CancelSessionResult>;
213
+ /** Wait for the turn boundary and return the recorded immutable result. */
214
+ result(): Promise<EveEvalTurn>;
215
+ /** Wait until the live stream emits one typed event matching `options`. */
216
+ waitForEvent<TType extends HandleMessageStreamEvent["type"]>(type: TType, options?: EveEvalWaitForEventOptions<TType>): Promise<EveEvalStreamEvent<TType>>;
217
+ }
186
218
  /** Operations and state shared by the primary eval context and independent sessions. */
187
219
  export interface EveEvalSessionDriver {
188
220
  /** All events observed on this session so far. */
@@ -193,6 +225,8 @@ export interface EveEvalSessionDriver {
193
225
  readonly state: SessionState;
194
226
  /** eve session id after the first successful send. */
195
227
  readonly sessionId: string | undefined;
228
+ /** Request cooperative cancellation of this session's active turn. */
229
+ cancel(): Promise<CancelSessionResult>;
196
230
  /** Require exactly one pending input request matching `filter`, or abort dependent control flow. */
197
231
  requireInputRequest(filter?: EveEvalInputRequestMatchOptions): InputRequest;
198
232
  /** Resolve specific pending requests and run the resumed turn. */
@@ -201,6 +235,8 @@ export interface EveEvalSessionDriver {
201
235
  respondAll(optionId: string): Promise<EveEvalTurn>;
202
236
  /** Send one turn through this session. */
203
237
  send(input: SendTurnInput): Promise<EveEvalTurn>;
238
+ /** Start one turn and return as soon as its session is accepted. */
239
+ start(input: SendTurnInput): Promise<EveEvalLiveTurn>;
204
240
  /** Send one text turn with a local file attached as a data URL. */
205
241
  sendFile(text: string, filePath: string, mediaType?: string): Promise<EveEvalTurn>;
206
242
  }
@@ -320,10 +356,24 @@ export interface EveEvalTargetHandle extends EveEvalTarget {
320
356
  dispatchSchedule(scheduleId: string): Promise<EveEvalScheduleDispatchResult>;
321
357
  /** Authenticated fetch against the target base URL. */
322
358
  fetch(path: string, init?: RequestInit): Promise<Response>;
323
- /** Attach to a pre-existing session and consume one turn boundary. */
359
+ /**
360
+ * Attach to a pre-existing session and consume one turn boundary.
361
+ *
362
+ * When that boundary is `session.waiting`, the attached session recovers
363
+ * the current continuation token from the stream, so `session.send(...)`
364
+ * and `session.respond(...)` continue the same durable session.
365
+ */
324
366
  attachSession(sessionId: string, opts?: {
325
367
  readonly startIndex?: number;
326
368
  }): Promise<EveEvalSession>;
369
+ /**
370
+ * Observe one in-progress turn from a session created outside the eval.
371
+ * The returned live-turn handle starts consuming immediately and owns the
372
+ * stream through its next turn boundary.
373
+ */
374
+ watchTurn(sessionId: string, opts?: {
375
+ readonly startIndex?: number;
376
+ }): EveEvalLiveTurn;
327
377
  }
328
378
  /**
329
379
  * Shared fields between the user-facing input and the validated eval.
@@ -0,0 +1,6 @@
1
+ import { type DurableSessionState } from "#execution/durable-session-store.js";
2
+ /** Cancels every successfully adopted child in the current pending batch. */
3
+ export declare function cancelDescendantTurnsStep(input: {
4
+ readonly serializedContext: Record<string, unknown>;
5
+ readonly sessionState: DurableSessionState;
6
+ }): Promise<void>;
@@ -0,0 +1 @@
1
+ import{createLogger,logError}from"#internal/logging.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{deserializeContext}from"#context/serialize.js";import{readDurableSession}from"#execution/durable-session-store.js";import{cancelRemoteAgentTurn,isRetryableRemoteAgentCancelError,resolveRemoteAgentForAction}from"#execution/remote-agent-dispatch.js";import{requestWorkflowTurnCancellation}from"#execution/workflow-runtime.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";const log=createLogger(`execution.cancel-descendant-turns`);async function cancelDescendantTurnsStep(e){"use step";let r;try{r=getPendingRuntimeActionBatch((await readDurableSession(e.sessionState)).state)}catch(n){logError(log,`failed to read pending descendants during cancellation`,n,{sessionId:e.sessionState.sessionId});return}if(r===void 0)return;let i=r.childSessionIds;if(i===void 0)return;let a,getRemoteRegistry=()=>a??=deserializeContext(e.serializedContext).then(e=>e.require(BundleKey).subagentRegistry.subagentsByNodeId),o=r.actions.flatMap(e=>{let t=i[e.callId];return t===void 0?[]:e.kind===`subagent-call`?[cancelLocalDescendant({action:e,childSessionId:t})]:e.kind===`remote-agent-call`?[cancelRemoteDescendant({action:e,childSessionId:t,remoteRegistry:getRemoteRegistry()})]:[]});await Promise.all(o)}async function cancelLocalDescendant(e){try{await requestCancellationWithRetry({request:()=>requestWorkflowTurnCancellation({sessionId:e.childSessionId}),shouldRetryError:()=>!1})}catch(n){logError(log,`failed to cancel local descendant turn`,n,{callId:e.action.callId,childSessionId:e.childSessionId,subagentName:e.action.subagentName})}}async function cancelRemoteDescendant(e){try{let t=await e.remoteRegistry,n=resolveRemoteAgentForAction({nodeId:e.action.nodeId,remoteAgentName:e.action.remoteAgentName,registry:t});await requestCancellationWithRetry({request:()=>cancelRemoteAgentTurn({remote:n,sessionId:e.childSessionId}),shouldRetryError:isRetryableRemoteAgentCancelError})}catch(n){logError(log,`failed to cancel remote descendant turn`,n,{callId:e.action.callId,childSessionId:e.childSessionId,remoteAgentName:e.action.remoteAgentName})}}async function requestCancellationWithRetry(e){for(let t=1;t<=12;t+=1){try{if((await e.request()).status===`accepted`||t===12)return}catch(n){if(!e.shouldRetryError(n)||t===12)throw n}await new Promise(e=>setTimeout(e,250))}}export{cancelDescendantTurnsStep};
@@ -1 +1 @@
1
- import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{resolveDurableCompiledArtifactsSource}from"#runtime/durable-compiled-artifacts-source.js";import{createDurableSessionState}from"#execution/durable-session-store.js";import{createSession}from"#execution/session.js";import{resolveInheritedTokenLimit}from"#execution/run-session-limits.js";async function createSessionStep(e){"use step";let t=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:resolveDurableCompiledArtifactsSource(e.compiledArtifactsSource),nodeId:e.nodeId});return{state:createDurableSessionState({session:createSession({compactionOverrides:{thresholdPercent:t.resolvedAgent.config.compaction?.thresholdPercent},continuationToken:e.continuationToken,limits:{maxInputTokensPerSession:resolveInheritedTokenLimit({configured:t.resolvedAgent.config.limits?.maxInputTokensPerSession,inherited:e.inheritedLimits?.maxInputTokensPerSession}),maxOutputTokensPerSession:resolveInheritedTokenLimit({configured:t.resolvedAgent.config.limits?.maxOutputTokensPerSession,inherited:e.inheritedLimits?.maxOutputTokensPerSession})},outputSchema:e.outputSchema,rootSessionId:e.rootSessionId,sessionId:e.sessionId,subagentDepth:e.subagentDepth,turnAgent:t.turnAgent,workflowMaxSubagents:t.resolvedAgent.workflowTool?.maxSubagents})})}}export{createSessionStep};
1
+ import{createDurableSessionState}from"#execution/durable-session-store.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{resolveDurableCompiledArtifactsSource}from"#runtime/durable-compiled-artifacts-source.js";import{createSession}from"#execution/session.js";import{resolveInheritedTokenLimit}from"#execution/run-session-limits.js";async function createSessionStep(e){"use step";let t=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:resolveDurableCompiledArtifactsSource(e.compiledArtifactsSource),nodeId:e.nodeId});return{state:createDurableSessionState({session:createSession({compactionOverrides:{thresholdPercent:t.resolvedAgent.config.compaction?.thresholdPercent},continuationToken:e.continuationToken,limits:{maxInputTokensPerSession:resolveInheritedTokenLimit({configured:t.resolvedAgent.config.limits?.maxInputTokensPerSession,inherited:e.inheritedLimits?.maxInputTokensPerSession}),maxOutputTokensPerSession:resolveInheritedTokenLimit({configured:t.resolvedAgent.config.limits?.maxOutputTokensPerSession,inherited:e.inheritedLimits?.maxOutputTokensPerSession})},outputSchema:e.outputSchema,rootSessionId:e.rootSessionId,sessionId:e.sessionId,subagentDepth:e.subagentDepth,turnAgent:t.turnAgent,workflowMaxSubagents:t.resolvedAgent.workflowTool?.maxSubagents})})}}export{createSessionStep};
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ChannelInstrumentationKey,InitiatorAuthKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{createSubagentCalledEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession}from"#execution/session.js";import{deserializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{getPendingRuntimeActionBatch,recordPendingSubagentChildToken}from"#harness/runtime-actions.js";import{resolveRemoteAgentForAction,startRemoteAgentSession}from"#execution/remote-agent-dispatch.js";import{buildSubagentRunInput}from"#execution/subagent-tool.js";import{createWorkflowRuntime,workflowEntryReference}from"#execution/workflow-runtime.js";import{resolveSubagentDepth}from"#harness/subagent-depth.js";const log=createLogger(`execution.dispatch-runtime-actions`);async function dispatchRuntimeActionsStep(e){"use step";let s=await readDurableSession(e.sessionState),f=getPendingRuntimeActionBatch(s.state);if(f===void 0||f.actions.length===0)return{results:[],sessionState:e.sessionState};let p=await deserializeContext(e.serializedContext),m=p.require(BundleKey),h=hydrateDurableSession({compactionOverrides:{thresholdPercent:m.resolvedAgent.config.compaction?.thresholdPercent},durable:s,turnAgent:m.turnAgent}),g=p.require(ChannelKey),_=p.get(AuthKey)??null,v=p.get(CapabilitiesKey),y=p.get(ChannelInstrumentationKey),b=p.get(InitiatorAuthKey)??null,x=e.parentWritable.getWriter(),S=buildAdapterContext(g,p),C=resolveSubagentDepth(h),w=f.actions.filter(e=>e.kind===`subagent-call`).length,T=h,E=[];try{for(let r of f.actions){if(isRecursiveAgentAction(r,m.subagentRegistry.subagentsByNodeId)&&(h.rootSessionId!==void 0||C.currentDepth>0)){log.warn(`recursive agent call blocked outside the root session`,{callId:r.callId,currentDepth:C.currentDepth,nodeId:r.nodeId,subagentName:r.subagentName}),E.push(createRecursiveAgentRootOnlyResult(r));continue}let i,a,o,s;switch(r.kind){case`subagent-call`:{let t=m.subagentRegistry.subagentsByNodeId.get(r.nodeId),n=t?.definition.kind===`subagent`?{description:t.definition.description,type:`local`}:{type:`runtime`},o=createWorkflowRuntime({compiledArtifactsSource:m.compiledArtifactsSource,nodeId:r.nodeId}),{childContinuationToken:c,runInput:l}=buildSubagentRunInput({action:r,auth:_,batchEvent:f.event,capabilities:v,channelMetadata:y,fanoutSize:w,initiatorAuth:b,parentContinuationToken:e.parentContinuationToken,session:h,source:n}),u=await o.run(l);T=recordPendingSubagentChildToken({callId:r.callId,childContinuationToken:c,session:T}),i=u.sessionId,a=r.name,s=r.subagentName;break}case`remote-agent-call`:{let n;try{n=resolveRemoteAgentForAction({nodeId:r.nodeId,remoteAgentName:r.remoteAgentName,registry:m.subagentRegistry.subagentsByNodeId}),i=await startRemoteAgentSession({action:r,callbackBaseUrl:e.callbackBaseUrl,callbackToken:e.parentContinuationToken,remote:n,session:h})}catch(e){logError(log,`remote agent start failed`,e,{remoteAgentName:r.remoteAgentName,nodeId:r.nodeId,callId:r.callId}),E.push(createRemoteAgentStartFailureResult({action:r,error:e}));continue}a=r.name,o={url:n.url},s=r.remoteAgentName;break}default:throw Error(`Unsupported runtime action kind "${r.kind}" in workflow runtime.`)}let d=await callAdapterEventHandler(g,createSubagentCalledEvent({callId:r.callId,childSessionId:i,name:a,remote:o,sequence:f.event.sequence,sessionId:h.sessionId,toolName:s,turnId:f.event.turnId,workflowId:workflowEntryReference.workflowId}),S);await x.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(d)))}}finally{x.releaseLock()}return{results:E,sessionState:T===h?e.sessionState:createDurableSessionState({session:T})}}function createRemoteAgentStartFailureResult(e){return{callId:e.action.callId,isError:!0,kind:`subagent-result`,output:{code:`REMOTE_AGENT_START_FAILED`,message:toErrorMessage(e.error)},subagentName:e.action.remoteAgentName}}function createRecursiveAgentRootOnlyResult(e){return{callId:e.callId,isError:!0,kind:`subagent-result`,output:{code:`RECURSIVE_AGENT_ROOT_ONLY`,message:`The built-in "agent" tool is only available to the root session.`},subagentName:e.subagentName}}function isRecursiveAgentAction(e,t){return e.kind===`subagent-call`&&e.subagentName===`agent`&&!t.has(e.nodeId)}export{dispatchRuntimeActionsStep};
1
+ import{createLogger,logError}from"#internal/logging.js";import{callAdapterEventHandler}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ChannelInstrumentationKey,InitiatorAuthKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{createSubagentCalledEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{deserializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{resolveRemoteAgentForAction,startRemoteAgentSession}from"#execution/remote-agent-dispatch.js";import{createWorkflowRuntime,workflowEntryReference}from"#execution/workflow-runtime.js";import{getPendingRuntimeActionBatch,recordPendingSubagentChild}from"#harness/runtime-actions.js";import{hydrateDurableSession}from"#execution/session.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{buildSubagentRunInput}from"#execution/subagent-tool.js";import{resolveSubagentDepth}from"#harness/subagent-depth.js";const log=createLogger(`execution.dispatch-runtime-actions`);async function dispatchRuntimeActionsStep(e){"use step";let f=await readDurableSession(e.sessionState),p=getPendingRuntimeActionBatch(f.state);if(p===void 0||p.actions.length===0)return{results:[],sessionState:e.sessionState};let m=await deserializeContext(e.serializedContext),h=m.require(BundleKey),g=hydrateDurableSession({compactionOverrides:{thresholdPercent:h.resolvedAgent.config.compaction?.thresholdPercent},durable:f,turnAgent:h.turnAgent}),_=m.require(ChannelKey),v=m.get(AuthKey)??null,y=m.get(CapabilitiesKey),b=m.get(ChannelInstrumentationKey),x=m.get(InitiatorAuthKey)??null,S=e.parentWritable.getWriter(),C=buildAdapterContext(_,m),w=resolveSubagentDepth(g),T=p.actions.filter(e=>e.kind===`subagent-call`).length,E=g,D=[];try{for(let r of p.actions){if(isRecursiveAgentAction(r,h.subagentRegistry.subagentsByNodeId)&&(g.rootSessionId!==void 0||w.currentDepth>0)){log.warn(`recursive agent call blocked outside the root session`,{callId:r.callId,currentDepth:w.currentDepth,nodeId:r.nodeId,subagentName:r.subagentName}),D.push(createRecursiveAgentRootOnlyResult(r));continue}let i,a,o,u;switch(r.kind){case`subagent-call`:{let n=h.subagentRegistry.subagentsByNodeId.get(r.nodeId),o=n?.definition.kind===`subagent`?{description:n.definition.description,type:`local`}:{type:`runtime`},s=createWorkflowRuntime({compiledArtifactsSource:h.compiledArtifactsSource,nodeId:r.nodeId}),{childContinuationToken:c,runInput:l}=buildSubagentRunInput({action:r,auth:v,batchEvent:p.event,capabilities:y,channelMetadata:b,fanoutSize:T,initiatorAuth:x,parentContinuationToken:e.parentContinuationToken,session:g,source:o});try{i=(await s.run(l)).sessionId}catch(e){logError(log,`local subagent start failed`,e,{callId:r.callId,nodeId:r.nodeId,subagentName:r.subagentName}),D.push({callId:r.callId,isError:!0,kind:`subagent-result`,output:{code:`SUBAGENT_START_FAILED`,message:toErrorMessage(e)},subagentName:r.subagentName});continue}E=recordPendingSubagentChild({callId:r.callId,child:{continuationToken:c,kind:`local`,sessionId:i},session:E}),a=r.name,u=r.subagentName;break}case`remote-agent-call`:{let n;try{n=resolveRemoteAgentForAction({nodeId:r.nodeId,remoteAgentName:r.remoteAgentName,registry:h.subagentRegistry.subagentsByNodeId}),i=await startRemoteAgentSession({action:r,callbackBaseUrl:e.callbackBaseUrl,callbackToken:e.parentContinuationToken,remote:n,session:g})}catch(e){logError(log,`remote agent start failed`,e,{remoteAgentName:r.remoteAgentName,nodeId:r.nodeId,callId:r.callId}),D.push(createRemoteAgentStartFailureResult({action:r,error:e}));continue}a=r.name,o={url:n.url},u=r.remoteAgentName,E=recordPendingSubagentChild({callId:r.callId,child:{kind:`remote`,sessionId:i},session:E});break}default:throw Error(`Unsupported runtime action kind "${r.kind}" in workflow runtime.`)}let d=await callAdapterEventHandler(_,createSubagentCalledEvent({callId:r.callId,childSessionId:i,name:a,remote:o,sequence:p.event.sequence,sessionId:g.sessionId,toolName:u,turnId:p.event.turnId,workflowId:workflowEntryReference.workflowId}),C);await S.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(d)))}}finally{S.releaseLock()}return{results:D,sessionState:E===g?e.sessionState:createDurableSessionState({session:E})}}function createRemoteAgentStartFailureResult(e){return{callId:e.action.callId,isError:!0,kind:`subagent-result`,output:{code:`REMOTE_AGENT_START_FAILED`,message:toErrorMessage(e.error)},subagentName:e.action.remoteAgentName}}function createRecursiveAgentRootOnlyResult(e){return{callId:e.callId,isError:!0,kind:`subagent-result`,output:{code:`RECURSIVE_AGENT_ROOT_ONLY`,message:`The built-in "agent" tool is only available to the root session.`},subagentName:e.subagentName}}function isRecursiveAgentAction(e,t){return e.kind===`subagent-call`&&e.subagentName===`agent`&&!t.has(e.nodeId)}export{dispatchRuntimeActionsStep};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession}from"#execution/session.js";import{deserializeContext}from"#context/serialize.js";import{setPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{getSubagentDelegationName,isSubagentDelegationAction}from"#harness/subagent-depth.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{getPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{buildRuntimeActionsFromWorkflowInterrupt}from"#harness/workflow-runtime-action-state.js";import{planWorkflowSubagentDispatch}from"#harness/workflow-subagent-limit.js";const log=createLogger(`execution.dispatch-workflow-runtime-actions`);async function dispatchWorkflowRuntimeActionsStep(e){"use step";let n=await readDurableSession(e.sessionState),r=getPendingWorkflowInterrupt(n.state);if(r===void 0)return{results:[],sessionState:e.sessionState};let i=buildRuntimeActionsFromWorkflowInterrupt(r.interrupt);if(i.length===0)return{results:[],sessionState:e.sessionState};let a=(await deserializeContext(e.serializedContext)).require(BundleKey),o=planWorkflowSubagentDispatch({actions:i,interrupt:r.interrupt,maxSubagents:n.workflowMaxSubagents}),s=o.blocked.map(e=>(log.warn(`workflow subagent limit reached; blocking delegated call`,{callId:e.callId,maxSubagents:o.maxSubagents,subagentName:isSubagentDelegationAction(e)?getSubagentDelegationName(e):e.kind,usedCalls:o.usedCalls}),createWorkflowSubagentLimitResult({action:e,plan:o})));if(o.allowed.length===0)return{results:s,sessionState:e.sessionState};let c=hydrateDurableSession({compactionOverrides:{thresholdPercent:a.resolvedAgent.config.compaction?.thresholdPercent},durable:n,turnAgent:a.turnAgent}),l=setPendingRuntimeActionBatch({actions:o.allowed,event:{sequence:0,stepIndex:0,turnId:`workflow-dispatch`},responseMessages:[],session:c}),u=await dispatchRuntimeActionsStep({callbackBaseUrl:e.callbackBaseUrl,parentContinuationToken:e.parentContinuationToken,parentWritable:e.parentWritable,serializedContext:e.serializedContext,sessionState:createDurableSessionState({session:l})});return s.length===0?u:{results:[...u.results,...s],sessionState:u.sessionState}}function createWorkflowSubagentLimitResult(e){let t=isSubagentDelegationAction(e.action)?getSubagentDelegationName(e.action):e.action.kind;return{callId:e.action.callId,isError:!0,kind:`subagent-result`,output:{code:`WORKFLOW_SUBAGENT_LIMIT_REACHED`,maxSubagents:e.plan.maxSubagents,message:`Workflow subagent limit reached (${String(e.plan.maxSubagents)}); "${t}" was not called.`},subagentName:t}}export{dispatchWorkflowRuntimeActionsStep};
1
+ import{createLogger}from"#internal/logging.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{deserializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{setPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{hydrateDurableSession}from"#execution/session.js";import{getSubagentDelegationName,isSubagentDelegationAction}from"#harness/subagent-depth.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{getPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{buildRuntimeActionsFromWorkflowInterrupt}from"#harness/workflow-runtime-action-state.js";import{planWorkflowSubagentDispatch}from"#harness/workflow-subagent-limit.js";const log=createLogger(`execution.dispatch-workflow-runtime-actions`);async function dispatchWorkflowRuntimeActionsStep(e){"use step";let n=await readDurableSession(e.sessionState),r=getPendingWorkflowInterrupt(n.state);if(r===void 0)return{results:[],sessionState:e.sessionState};let i=buildRuntimeActionsFromWorkflowInterrupt(r.interrupt);if(i.length===0)return{results:[],sessionState:e.sessionState};let a=(await deserializeContext(e.serializedContext)).require(BundleKey),o=planWorkflowSubagentDispatch({actions:i,interrupt:r.interrupt,maxSubagents:n.workflowMaxSubagents}),s=o.blocked.map(e=>(log.warn(`workflow subagent limit reached; blocking delegated call`,{callId:e.callId,maxSubagents:o.maxSubagents,subagentName:isSubagentDelegationAction(e)?getSubagentDelegationName(e):e.kind,usedCalls:o.usedCalls}),createWorkflowSubagentLimitResult({action:e,plan:o})));if(o.allowed.length===0)return{results:s,sessionState:e.sessionState};let c=hydrateDurableSession({compactionOverrides:{thresholdPercent:a.resolvedAgent.config.compaction?.thresholdPercent},durable:n,turnAgent:a.turnAgent}),l=setPendingRuntimeActionBatch({actions:o.allowed,event:{sequence:0,stepIndex:0,turnId:`workflow-dispatch`},responseMessages:[],session:c}),u=await dispatchRuntimeActionsStep({callbackBaseUrl:e.callbackBaseUrl,parentContinuationToken:e.parentContinuationToken,parentWritable:e.parentWritable,serializedContext:e.serializedContext,sessionState:createDurableSessionState({session:l})});return s.length===0?u:{results:[...u.results,...s],sessionState:u.sessionState}}function createWorkflowSubagentLimitResult(e){let t=isSubagentDelegationAction(e.action)?getSubagentDelegationName(e.action):e.action.kind;return{callId:e.action.callId,isError:!0,kind:`subagent-result`,output:{code:`WORKFLOW_SUBAGENT_LIMIT_REACHED`,maxSubagents:e.plan.maxSubagents,message:`Workflow subagent limit reached (${String(e.plan.maxSubagents)}); "${t}" was not called.`},subagentName:t}}export{dispatchWorkflowRuntimeActionsStep};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{jsonSchema}from"ai";import{resolveRuntimeModelReference}from"#runtime/agent/resolve-model.js";import{dispatchDynamicModelEvent}from"#context/dynamic-model-lifecycle.js";import{createToolLoopHarness}from"#harness/tool-loop.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{findRegisteredRuntimeTool}from"#runtime/tools/registry.js";import{SUBAGENT_TOOL_INPUT_SCHEMA}from"#runtime/subagents/registry.js";import{preserveFrameworkStateOnCompaction}from"#execution/compaction.js";import{createToolExecuteWithAuth}from"#execution/tool-auth.js";const log=createLogger(`execution.node-step`),BUILT_IN_AGENT_TOOL_DESCRIPTION=[`Delegate a focused subtask to a fresh copy of yourself.`,`Use it to isolate complex work or split a large task into independent pieces.`,"Issue multiple `agent` calls in one response to run a small fixed set in parallel.","Each child has fresh history and state but shares your tools and sandbox, so include essential context in `message` and give parallel writers non-overlapping scopes."].join(` `);function createExecutionNodeStep(e){let t=createRuntimeModelResolver(e.modelResolutionScope),n=e.node.turnAgent.dynamicModel===void 0?void 0:createRuntimeDynamicModelEventDispatcher(e.modelResolutionScope,e.node.turnAgent.dynamicModel),r=createNodeHarnessTools({node:e.node});return createToolLoopHarness({abortSignal:e.abortSignal,capabilities:e.capabilities,workflow:e.node.agent.workflowTool!==void 0,workflowMaxSubagents:e.workflowMaxSubagents,handleEvent:e.handleEvent,mode:e.mode,onCompaction:preserveFrameworkStateOnCompaction,dispatchDynamicModelEvent:n,resolveModel:t,runtimeIdentity:buildRuntimeIdentity(e.node),tools:r})}function buildRuntimeIdentity(e){let n=resolveInstalledPackageInfo(),r={agentId:e.turnAgent.id,agentName:e.agent.config?.name,eveVersion:n.version,modelId:e.turnAgent.dynamicModel===void 0?e.turnAgent.model.id:`dynamic:${e.turnAgent.model.id}`},i=process.env.VERCEL_GIT_COMMIT_SHA?.trim(),a=process.env.VERCEL_GIT_COMMIT_REF?.trim(),o=process.env.VERCEL_DEPLOYMENT_CREATED_AT?.trim();return i||a||o?{...r,build:{deployedAt:o||void 0,gitBranch:a||void 0,gitSha:i||void 0}}:r}function createRuntimeModelResolver(e){return t=>resolveRuntimeModelReference(t,e)}function createRuntimeDynamicModelEventDispatcher(e,t){return n=>dispatchDynamicModelEvent({ctx:n.ctx,dynamicModel:t,event:n.event,fallback:n.fallback,messages:n.messages,scope:e})}function createNodeHarnessTools(e){let t=new Map;for(let n of e.node.turnAgent.tools){let r=resolveHarnessToolDefinition({node:e.node,tool:n});r!==null&&t.set(n.name,r)}return e.node.nodeId===ROOT_RUNTIME_AGENT_NODE_ID&&!t.has(`agent`)&&t.set(`agent`,{description:BUILT_IN_AGENT_TOOL_DESCRIPTION,inputSchema:jsonSchema(SUBAGENT_TOOL_INPUT_SCHEMA),name:`agent`,runtimeAction:{kind:`subagent-call`,nodeId:e.node.nodeId,recursive:!0,subagentName:`agent`}}),t}function resolveHarnessToolDefinition(e){if(e.tool.kind===`subagent`)return{description:e.tool.description??``,inputSchema:jsonSchema(e.tool.inputSchema??{}),name:e.tool.name,outputSchema:e.tool.outputSchema===void 0?void 0:jsonSchema(e.tool.outputSchema),runtimeAction:{kind:`subagent-call`,nodeId:e.tool.nodeId,subagentName:e.tool.name}};if(e.tool.kind===`remote`)return{description:e.tool.description??``,inputSchema:jsonSchema(e.tool.inputSchema??{}),name:e.tool.name,outputSchema:e.tool.outputSchema===void 0?void 0:jsonSchema(e.tool.outputSchema),runtimeAction:{kind:`remote-agent-call`,nodeId:e.tool.nodeId,remoteAgentName:e.tool.name,subagentName:e.tool.name}};let t=findRegisteredRuntimeTool(e.node.toolRegistry,e.tool.name);if(t===null)return log.warn(`declared tool is not registered — omitting from toolset`,{toolName:e.tool.name,nodeId:e.node.nodeId}),null;let r=t.definition,i=r.sourceId.startsWith(`eve:`),a=r.execute;return{approvalKey:r.approvalKey,description:r.description,execute:resolveAuthoredExecute({isFrameworkTool:i,rawExecute:a,scope:r.name}),inputSchema:r.inputStandardSchema??jsonSchema(r.inputSchema??{}),name:r.name,approval:r.approval,outputSchema:r.outputStandardSchema??maybeJsonSchema(r.outputSchema),toModelOutput:r.toModelOutput}}function resolveAuthoredExecute(e){let{isFrameworkTool:t,rawExecute:n,scope:r}=e;return n===void 0?void 0:t?n:createToolExecuteWithAuth({execute:n,scope:r})}function maybeJsonSchema(e){return e===void 0?void 0:jsonSchema(e)}export{createExecutionNodeStep,createNodeHarnessTools};
1
+ import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{jsonSchema}from"ai";import{resolveRuntimeModelReference}from"#runtime/agent/resolve-model.js";import{dispatchDynamicModelEvent}from"#context/dynamic-model-lifecycle.js";import{createToolLoopHarness}from"#harness/tool-loop.js";import{AGENT_TOOL_DESCRIPTION,AGENT_TOOL_NAME}from"#runtime/framework-tools/agent.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{SUBAGENT_TOOL_INPUT_SCHEMA}from"#runtime/subagents/registry.js";import{findRegisteredRuntimeTool}from"#runtime/tools/registry.js";import{preserveFrameworkStateOnCompaction}from"#execution/compaction.js";import{createToolExecuteWithAuth}from"#execution/tool-auth.js";const log=createLogger(`execution.node-step`);function createExecutionNodeStep(e){let t=createRuntimeModelResolver(e.modelResolutionScope),n=e.node.turnAgent.dynamicModel===void 0?void 0:createRuntimeDynamicModelEventDispatcher(e.modelResolutionScope,e.node.turnAgent.dynamicModel),r=createNodeHarnessTools({node:e.node});return createToolLoopHarness({abortSignal:e.abortSignal,capabilities:e.capabilities,workflow:e.node.agent.workflowTool!==void 0,workflowMaxSubagents:e.workflowMaxSubagents,handleEvent:e.handleEvent,mode:e.mode,onCompaction:preserveFrameworkStateOnCompaction,dispatchDynamicModelEvent:n,resolveModel:t,runtimeIdentity:buildRuntimeIdentity(e.node),tools:r})}function buildRuntimeIdentity(e){let n=resolveInstalledPackageInfo(),r={agentId:e.turnAgent.id,agentName:e.agent.config?.name,eveVersion:n.version,modelId:e.turnAgent.dynamicModel===void 0?e.turnAgent.model.id:`dynamic:${e.turnAgent.model.id}`},i=process.env.VERCEL_GIT_COMMIT_SHA?.trim(),a=process.env.VERCEL_GIT_COMMIT_REF?.trim(),o=process.env.VERCEL_DEPLOYMENT_CREATED_AT?.trim();return i||a||o?{...r,build:{deployedAt:o||void 0,gitBranch:a||void 0,gitSha:i||void 0}}:r}function createRuntimeModelResolver(e){return t=>resolveRuntimeModelReference(t,e)}function createRuntimeDynamicModelEventDispatcher(e,t){return n=>dispatchDynamicModelEvent({ctx:n.ctx,dynamicModel:t,event:n.event,fallback:n.fallback,messages:n.messages,scope:e})}function createNodeHarnessTools(e){let t=new Map;for(let n of e.node.turnAgent.tools){let r=resolveHarnessToolDefinition({node:e.node,tool:n});r!==null&&t.set(n.name,r)}return e.node.nodeId===ROOT_RUNTIME_AGENT_NODE_ID&&!e.node.agent.disabledFrameworkTools.includes(AGENT_TOOL_NAME)&&!t.has(AGENT_TOOL_NAME)&&t.set(AGENT_TOOL_NAME,{description:AGENT_TOOL_DESCRIPTION,inputSchema:jsonSchema(SUBAGENT_TOOL_INPUT_SCHEMA),name:AGENT_TOOL_NAME,runtimeAction:{kind:`subagent-call`,nodeId:e.node.nodeId,subagentName:AGENT_TOOL_NAME}}),t}function resolveHarnessToolDefinition(e){if(e.tool.kind===`subagent`)return{description:e.tool.description??``,inputSchema:jsonSchema(e.tool.inputSchema??{}),name:e.tool.name,outputSchema:e.tool.outputSchema===void 0?void 0:jsonSchema(e.tool.outputSchema),runtimeAction:{kind:`subagent-call`,nodeId:e.tool.nodeId,subagentName:e.tool.name}};if(e.tool.kind===`remote`)return{description:e.tool.description??``,inputSchema:jsonSchema(e.tool.inputSchema??{}),name:e.tool.name,outputSchema:e.tool.outputSchema===void 0?void 0:jsonSchema(e.tool.outputSchema),runtimeAction:{kind:`remote-agent-call`,nodeId:e.tool.nodeId,remoteAgentName:e.tool.name,subagentName:e.tool.name}};let t=findRegisteredRuntimeTool(e.node.toolRegistry,e.tool.name);if(t===null)return log.warn(`declared tool is not registered — omitting from toolset`,{toolName:e.tool.name,nodeId:e.node.nodeId}),null;let r=t.definition,i=r.sourceId.startsWith(`eve:`),a=r.execute;return{approvalKey:r.approvalKey,description:r.description,execute:resolveAuthoredExecute({isFrameworkTool:i,rawExecute:a,scope:r.name}),inputSchema:r.inputStandardSchema??jsonSchema(r.inputSchema??{}),name:r.name,approval:r.approval,outputSchema:r.outputStandardSchema??maybeJsonSchema(r.outputSchema),toModelOutput:r.toModelOutput}}function resolveAuthoredExecute(e){let{isFrameworkTool:t,rawExecute:n,scope:r}=e;return n===void 0?void 0:t?n:createToolExecuteWithAuth({execute:n,scope:r})}function maybeJsonSchema(e){return e===void 0?void 0:jsonSchema(e)}export{createExecutionNodeStep,createNodeHarnessTools};
@@ -1,3 +1,4 @@
1
+ import type { CancelTurnResult } from "#channel/types.js";
1
2
  import type { HarnessSession } from "#harness/types.js";
2
3
  import type { RuntimeRemoteAgentCallActionRequest } from "#runtime/actions/types.js";
3
4
  import type { RuntimeSubagentRegistry } from "#runtime/subagents/registry.js";
@@ -9,6 +10,11 @@ export declare function startRemoteAgentSession(input: {
9
10
  readonly remote: ResolvedRuntimeRemoteAgentNode;
10
11
  readonly session: HarnessSession;
11
12
  }): Promise<string>;
13
+ export declare function cancelRemoteAgentTurn(input: {
14
+ readonly remote: ResolvedRuntimeRemoteAgentNode;
15
+ readonly sessionId: string;
16
+ }): Promise<CancelTurnResult>;
17
+ export declare function isRetryableRemoteAgentCancelError(error: unknown): boolean;
12
18
  export declare function resolveRemoteAgentForAction(input: {
13
19
  readonly nodeId: string;
14
20
  readonly registry: RuntimeSubagentRegistry["subagentsByNodeId"];
@@ -1 +1 @@
1
- import{createEveCallbackRoutePath}from"#protocol/routes.js";import{EVE_SESSION_ID_HEADER}from"#protocol/message.js";import{createWorkflowCallbackUrl}from"#execution/workflow-callback-url.js";import{formatSubagentInput}from"#execution/subagent-invocation.js";async function startRemoteAgentSession(n){let r=n.callbackToken??n.session.continuationToken;if(!r)throw Error(`Cannot dispatch remote agent without a parent continuation token.`);if(!n.callbackBaseUrl)throw Error(`Cannot dispatch remote agent without a callback base URL.`);let i=await resolveRemoteAgentRequestHeaders(n.remote),a=await fetch(createRemoteAgentSessionUrl(n.remote),{body:JSON.stringify({callback:{callId:n.action.callId,subagentName:n.action.remoteAgentName,token:r,url:createWorkflowCallbackUrl(n.callbackBaseUrl,createEveCallbackRoutePath(r))},message:formatRemoteAgentCallInputMessage({action:n.action,remote:n.remote}),mode:`task`,outputSchema:n.action.input.outputSchema??n.remote.outputSchema}),headers:{"content-type":`application/json`,...i},method:`POST`});if(!a.ok)throw Error(`Remote agent "${n.action.remoteAgentName}" create-session request failed with HTTP ${a.status}.`);let o=a.headers.get(EVE_SESSION_ID_HEADER);if(o!==null&&o.length>0)return o;try{let e=await a.json();if(typeof e.sessionId==`string`&&e.sessionId.length>0)return e.sessionId}catch{}throw Error(`Remote agent "${n.action.remoteAgentName}" create-session response did not include a session id.`)}function resolveRemoteAgentForAction(e){let t=e.registry.get(e.nodeId)?.definition;if(t?.kind!==`remote`)throw Error(`Missing remote agent "${e.remoteAgentName}" in runtime registry.`);return t}function createRemoteAgentSessionUrl(e){return new URL(e.path,`${trimTrailingSlash(e.url)}/`).toString()}async function resolveRemoteAgentRequestHeaders(e){let t={};return e.headers!==void 0&&Object.assign(t,typeof e.headers==`function`?await e.headers():e.headers),e.auth!==void 0&&Object.assign(t,(await e.auth()).headers),t}function formatRemoteAgentCallInputMessage(e){let t=typeof e.action.input.message==`string`?e.action.input.message:``;return formatSubagentInput({description:e.remote.description,message:t,name:e.action.remoteAgentName,type:`remote`}).message}function trimTrailingSlash(e){return e.endsWith(`/`)?e.slice(0,-1):e}export{resolveRemoteAgentForAction,startRemoteAgentSession};
1
+ import{createEveCallbackRoutePath,createEveCancelTurnRoutePath}from"#protocol/routes.js";import{EVE_SESSION_ID_HEADER}from"#protocol/message.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{createWorkflowCallbackUrl}from"#execution/workflow-callback-url.js";import{formatSubagentInput}from"#execution/subagent-invocation.js";var RemoteAgentCancelRequestError=class extends Error{retryable;constructor(e,t){super(e),this.name=`RemoteAgentCancelRequestError`,this.retryable=t.retryable}};async function startRemoteAgentSession(t){let r=t.callbackToken??t.session.continuationToken;if(!r)throw Error(`Cannot dispatch remote agent without a parent continuation token.`);if(!t.callbackBaseUrl)throw Error(`Cannot dispatch remote agent without a callback base URL.`);let a=await resolveRemoteAgentRequestHeaders(t.remote),o=await fetch(createRemoteAgentSessionUrl(t.remote),{body:JSON.stringify({callback:{callId:t.action.callId,subagentName:t.action.remoteAgentName,token:r,url:createWorkflowCallbackUrl(t.callbackBaseUrl,createEveCallbackRoutePath(r))},message:formatRemoteAgentCallInputMessage({action:t.action,remote:t.remote}),mode:`task`,outputSchema:t.action.input.outputSchema??t.remote.outputSchema}),headers:{"content-type":`application/json`,...a},method:`POST`});if(!o.ok)throw Error(`Remote agent "${t.action.remoteAgentName}" create-session request failed with HTTP ${o.status}.`);let s=o.headers.get(EVE_SESSION_ID_HEADER);if(s!==null&&s.length>0)return s;try{let e=await o.json();if(typeof e.sessionId==`string`&&e.sessionId.length>0)return e.sessionId}catch{}throw Error(`Remote agent "${t.action.remoteAgentName}" create-session response did not include a session id.`)}async function cancelRemoteAgentTurn(e){let t=await resolveRemoteAgentRequestHeaders(e.remote),n=await fetch(createRemoteAgentCancelTurnUrl(e.remote,e.sessionId),{headers:t,method:`POST`});if(!n.ok)throw new RemoteAgentCancelRequestError(`Remote agent "${e.remote.name}" cancel-turn request failed with HTTP ${n.status}.`,{retryable:isRetryableRemoteCancelStatus(n.status)});let i;try{i=await n.json()}catch{throw new RemoteAgentCancelRequestError(`Remote agent "${e.remote.name}" cancel-turn response was not valid JSON.`,{retryable:!1})}let a=CancelTurnResponseSchema.safeParse(i);if(!a.success||a.data.sessionId!==e.sessionId)throw new RemoteAgentCancelRequestError(`Remote agent "${e.remote.name}" cancel-turn response was invalid.`,{retryable:!1});return{status:a.data.status}}function isRetryableRemoteAgentCancelError(e){return!(e instanceof RemoteAgentCancelRequestError)||e.retryable}function resolveRemoteAgentForAction(e){let t=e.registry.get(e.nodeId)?.definition;if(t?.kind!==`remote`)throw Error(`Missing remote agent "${e.remoteAgentName}" in runtime registry.`);return t}function createRemoteAgentSessionUrl(e){return new URL(e.path,`${trimTrailingSlash(e.url)}/`).toString()}function createRemoteAgentCancelTurnUrl(e,n){return new URL(createEveCancelTurnRoutePath(n),`${trimTrailingSlash(e.url)}/`).toString()}function isRetryableRemoteCancelStatus(e){return e===408||e===425||e===429||e>=500}async function resolveRemoteAgentRequestHeaders(e){let t={};return e.headers!==void 0&&Object.assign(t,typeof e.headers==`function`?await e.headers():e.headers),e.auth!==void 0&&Object.assign(t,(await e.auth()).headers),t}function formatRemoteAgentCallInputMessage(e){let t=typeof e.action.input.message==`string`?e.action.input.message:``;return formatSubagentInput({description:e.remote.description,message:t,name:e.action.remoteAgentName,type:`remote`}).message}function trimTrailingSlash(e){return e.endsWith(`/`)?e.slice(0,-1):e}export{cancelRemoteAgentTurn,isRetryableRemoteAgentCancelError,resolveRemoteAgentForAction,startRemoteAgentSession};
@@ -1 +1 @@
1
- import{callAdapterEventHandler}from"#channel/adapter.js";import{encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState,isHarnessBetweenTurns,setHarnessEmissionState}from"#harness/emission.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession}from"#execution/session.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{clearPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{clearPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{clearAllProxyInputRequests,hasProxyInputRequests}from"#harness/proxy-input-requests.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{withContextScope}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{emitCancelledTurn}from"#harness/cancelled-turn-emission.js";async function settleCancelledTurnStep(r){"use step";let i=await readDurableSession(r.sessionState),a=await deserializeContext(r.serializedContext),o=a.require(ChannelKey),s=buildAdapterContext(o,a),c=a.require(BundleKey),l=hydrateDurableSession({compactionOverrides:{thresholdPercent:c.resolvedAgent.config.compaction?.thresholdPercent},durable:i,turnAgent:c.turnAgent}),u=getHarnessEmissionState(i.state);if(!(isHarnessBetweenTurns(l)&&hasProxyInputRequests(i.state))){let e=r.parentWritable.getWriter();try{let t=await withContextScope(a,l,async t=>({result:await emitCancelledTurn(async t=>{let n=await callAdapterEventHandler(o,t,s);setChannelContext(a,{...o,state:{...s.state}}),await e.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(n))),await dispatchStreamEventHooks({ctx:a,event:n,registry:c.hookRegistry})},u,t.continuationToken),session:t}));u=t.result,l=t.session}finally{e.releaseLock()}}let d=reconcileSessionContinuationToken(a,setHarnessEmissionState(clearAllProxyInputRequests(clearPendingWorkflowInterrupt(clearPendingRuntimeActionBatch(l))),u));return{serializedContext:serializeContext(a),sessionState:createDurableSessionState({session:d})}}export{settleCancelledTurnStep};
1
+ import{callAdapterEventHandler}from"#channel/adapter.js";import{encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState,isHarnessBetweenTurns,setHarnessEmissionState}from"#harness/emission.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{clearPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{hydrateDurableSession}from"#execution/session.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{clearPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{clearAllProxyInputRequests,hasProxyInputRequests}from"#harness/proxy-input-requests.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{withContextScope}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{emitCancelledTurn}from"#harness/cancelled-turn-emission.js";async function settleCancelledTurnStep(r){"use step";let i=await readDurableSession(r.sessionState),a=await deserializeContext(r.serializedContext),o=a.require(ChannelKey),s=buildAdapterContext(o,a),c=a.require(BundleKey),l=hydrateDurableSession({compactionOverrides:{thresholdPercent:c.resolvedAgent.config.compaction?.thresholdPercent},durable:i,turnAgent:c.turnAgent}),u=getHarnessEmissionState(i.state);if(!(isHarnessBetweenTurns(l)&&hasProxyInputRequests(i.state))){let e=r.parentWritable.getWriter();try{let t=await withContextScope(a,l,async t=>({result:await emitCancelledTurn(async t=>{let n=await callAdapterEventHandler(o,t,s);setChannelContext(a,{...o,state:{...s.state}}),await e.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(n))),await dispatchStreamEventHooks({ctx:a,event:n,registry:c.hookRegistry})},u,t.continuationToken),session:t}));u=t.result,l=t.session}finally{e.releaseLock()}}let d=reconcileSessionContinuationToken(a,setHarnessEmissionState(clearAllProxyInputRequests(clearPendingWorkflowInterrupt(clearPendingRuntimeActionBatch(l))),u));return{serializedContext:serializeContext(a),sessionState:createDurableSessionState({session:d})}}export{settleCancelledTurnStep};
@@ -1 +1 @@
1
- import{callAdapterEventHandler}from"#channel/adapter.js";import{ModeKey}from"#context/keys.js";import{encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession}from"#execution/session.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{upsertProxyInputRequests}from"#harness/proxy-input-requests.js";import{setChannelContext}from"#execution/channel-context.js";import{withContextScope}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{emitProxiedInputRequest}from"#execution/subagent-hitl-proxy.js";async function runProxySubagentEventStep(e){"use step";let t=await readDurableSession(e.sessionState);return emitProxiedSubagentEvent({ctx:await deserializeContext(e.serializedContext),durableSession:t,hookPayload:e.hookPayload,parentWritable:e.parentWritable})}async function emitProxiedSubagentEvent(i){let{ctx:a}=i,o=a.require(ChannelKey),s=a.require(BundleKey),c=hydrateDurableSession({compactionOverrides:{thresholdPercent:s.resolvedAgent.config.compaction?.thresholdPercent},durable:i.durableSession,turnAgent:s.turnAgent}),l=buildAdapterContext(o,a),u=i.parentWritable.getWriter(),d,f;try{let emit=async t=>{let r=await callAdapterEventHandler(o,t,l);await u.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(r)))},r=await withContextScope(a,c,async e=>{if(i.hookPayload.kind===`subagent-authorization-event`)return await emit(i.hookPayload.event),{result:void 0,session:e};let n=await emitProxiedInputRequest({emit,hookPayload:i.hookPayload,mode:a.require(ModeKey),session:e});return{result:n.entries,session:n.session}});d=r.result,f=r.session}finally{u.releaseLock()}setChannelContext(a,{...o,state:{...l.state}}),d!==void 0&&i.hookPayload.kind===`subagent-input-request`&&(f=upsertProxyInputRequests({entries:d,forChildContinuationToken:i.hookPayload.childContinuationToken,session:f}));let p=reconcileSessionContinuationToken(a,f);return{serializedContext:serializeContext(a),sessionState:createDurableSessionState({session:p})}}export{emitProxiedSubagentEvent,runProxySubagentEventStep};
1
+ import{callAdapterEventHandler}from"#channel/adapter.js";import{ModeKey}from"#context/keys.js";import{encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession}from"#execution/session.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{upsertProxyInputRequests}from"#harness/proxy-input-requests.js";import{setChannelContext}from"#execution/channel-context.js";import{withContextScope}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{emitProxiedInputRequest}from"#execution/subagent-hitl-proxy.js";async function runProxySubagentEventStep(e){"use step";let t=await readDurableSession(e.sessionState);return emitProxiedSubagentEvent({ctx:await deserializeContext(e.serializedContext),durableSession:t,hookPayload:e.hookPayload,parentWritable:e.parentWritable})}async function emitProxiedSubagentEvent(i){let{ctx:a}=i,o=a.require(ChannelKey),s=a.require(BundleKey),c=hydrateDurableSession({compactionOverrides:{thresholdPercent:s.resolvedAgent.config.compaction?.thresholdPercent},durable:i.durableSession,turnAgent:s.turnAgent}),l=buildAdapterContext(o,a),u=i.parentWritable.getWriter(),d,f;try{let emit=async t=>{let r=await callAdapterEventHandler(o,t,l);await u.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(r)))},r=await withContextScope(a,c,async e=>{if(i.hookPayload.kind===`subagent-authorization-event`)return await emit(i.hookPayload.event),{result:void 0,session:e};let n=await emitProxiedInputRequest({emit,hookPayload:i.hookPayload,mode:a.require(ModeKey),session:e});return{result:n.entries,session:n.session}});d=r.result,f=r.session}finally{u.releaseLock()}setChannelContext(a,{...o,state:{...l.state}}),d!==void 0&&i.hookPayload.kind===`subagent-input-request`&&(f=upsertProxyInputRequests({entries:d,forChildContinuationToken:i.hookPayload.childContinuationToken,session:f}));let p=reconcileSessionContinuationToken(a,f);return{serializedContext:serializeContext(a),sessionState:createDurableSessionState({session:p})}}export{emitProxiedSubagentEvent,runProxySubagentEventStep};
@@ -1,16 +1,3 @@
1
- /**
2
- * Derives the session-scoped cancel hook token. Stable for the session's
3
- * lifetime, so a cancel trigger can address it from the session id alone.
4
- */
5
- export declare function sessionCancelHookToken(sessionId: string): string;
6
- /**
7
- * Payload accepted by the session cancel hook. The optional `turnId`
8
- * guard scopes the cancel to the turn the caller observed; a mismatch is
9
- * consumed as a benign no-op. Omitting it cancels the current turn.
10
- */
11
- export interface TurnCancelPayload {
12
- readonly turnId?: string;
13
- }
14
1
  /**
15
2
  * Owns one turn's cancellation surface inside the turn workflow: the
16
3
  * session-scoped cancel hook and the durable `AbortController` whose
@@ -1 +1 @@
1
- import{createHook}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{TurnCancelledError}from"#harness/turn-cancellation.js";function sessionCancelHookToken(e){return`${e}:cancel`}async function createTurnCancellationControl(r){let i=createHook({token:sessionCancelHookToken(r.sessionId)}),a=i[Symbol.asyncIterator]();try{await claimHookOwnership(i)}catch(e){if(isHookConflictError(e))return;throw e}let o=new AbortController,s=consumeMatchingCancel(a,r.expectedTurnId).then(()=>(o.abort(new TurnCancelledError),`cancel`)),c=!1;return{signal:o.signal,requested:s,async dispose(){c||(c=!0,await disposeHook(i))}}}async function consumeMatchingCancel(e,t){for(;;){let n=await e.next();if(n.done)return await new Promise(()=>{});if(matchesActiveTurn(n.value,t))return}}function matchesActiveTurn(e,t){if(typeof e!=`object`||!e)return!0;let n=e.turnId;return n===void 0||n===t}export{createTurnCancellationControl,sessionCancelHookToken};
1
+ import{createHook}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{sessionCancelHookToken}from"#execution/turn-cancellation-token.js";import{TurnCancelledError}from"#harness/turn-cancellation.js";async function createTurnCancellationControl(r){let i=createHook({token:sessionCancelHookToken(r.sessionId)}),a=i[Symbol.asyncIterator]();try{await claimHookOwnership(i)}catch(e){if(isHookConflictError(e))return;throw e}let o=new AbortController,s=consumeMatchingCancel(a,r.expectedTurnId).then(()=>(o.abort(new TurnCancelledError),`cancel`)),c=!1;return{signal:o.signal,requested:s,async dispose(){c||(c=!0,await disposeHook(i))}}}async function consumeMatchingCancel(e,t){for(;;){let n=await e.next();if(n.done)return await new Promise(()=>{});if(matchesActiveTurn(n.value,t))return}}function matchesActiveTurn(e,t){if(typeof e!=`object`||!e)return!0;let n=e.turnId;return n===void 0||n===t}export{createTurnCancellationControl};
@@ -0,0 +1,9 @@
1
+ /** Derives the stable session-scoped cancellation hook token. */
2
+ export declare function sessionCancelHookToken(sessionId: string): string;
3
+ /**
4
+ * Payload accepted by the session cancel hook. A mismatched `turnId` is a
5
+ * benign no-op; omitting it targets whichever turn owns the hook.
6
+ */
7
+ export interface TurnCancelPayload {
8
+ readonly turnId?: string;
9
+ }
@@ -0,0 +1 @@
1
+ function sessionCancelHookToken(e){return`${e}:cancel`}export{sessionCancelHookToken};
@@ -1 +1 @@
1
- import{resolveRuntimeActionResultsForKeys}from"#harness/runtime-actions.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{turnStep}from"#execution/workflow-steps.js";import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{sendTurnControlStep}from"#execution/turn-control-protocol.js";import{dispatchWorkflowRuntimeActionsStep}from"#execution/dispatch-workflow-runtime-actions-step.js";import{migrateTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{runProxySubagentEventStep}from"#execution/subagent-event-proxy-step.js";import{createTurnCancellationControl}from"#execution/turn-cancellation-control.js";import{TurnExecutionCursor}from"#execution/turn-execution-cursor.js";import{activeTurnId}from"#harness/active-turn-id.js";const TASK_MODE_WAIT_ERROR_MESSAGE="Task mode cannot wait for follow-up input (`next: null`).";function canSettleCancelledTurnAsPark(e){return e.mode===`conversation`||e.stepInput.sessionState.continuationToken!==``}async function turnWorkflow(e){"use workflow";let t=migrateTurnWorkflowInput(e);return t.driverCapabilities?.turnInbox===!0?runTurnOwnedWorkflow(t):runLegacyTurnWorkflow(t)}async function runTurnOwnedWorkflow(e){let c=createHook({token:`${e.completionToken}:inbox`}),l=c[Symbol.asyncIterator](),u=new TurnExecutionCursor({controlToken:e.completionToken,parentWritable:e.stepInput.parentWritable,serializedContext:e.stepInput.serializedContext,sessionState:e.stepInput.sessionState}),d=0,nextDeliveryRequestId=()=>`${c.token}:delivery:${String(d++)}`,f=[],p=e.stepInput.input,m=!1,h;try{try{await claimHookOwnership(c),m=!0}catch(e){if(isHookConflictError(e))return;throw e}for(e.driverCapabilities?.cancelledTurnSettle===!0&&canSettleCancelledTurnAsPark(e)&&(h=await createTurnCancellationControl({expectedTurnId:activeTurnId(e.stepInput.sessionState.emissionState),sessionId:e.stepInput.sessionState.sessionId}));;){let i=await turnStep(u.createStepInput(p,h?.signal));if(i.action===`cancelled`){await h?.dispose(),await u.finish({sessionState:u.sessionState},{cancelled:!0,kind:`park`},f);return}if(i.action===`done`){await h?.dispose(),await u.finish(i,{kind:`done`,output:i.output??``,isError:i.isError,usage:i.usage},f);return}let o=i.action===`dispatch-workflow-runtime-actions`||i.action===`park`?i.pendingRuntimeActionKeys:void 0;if(o!==void 0){await u.adopt(i);let e=await(i.action===`dispatch-workflow-runtime-actions`?dispatchWorkflowRuntimeActionsStep:dispatchRuntimeActionsStep)({callbackBaseUrl:resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),parentContinuationToken:c.token,parentWritable:u.parentWritable,serializedContext:u.serializedContext,sessionState:u.sessionState});await u.adopt(e);let r=await waitForRuntimeActionResults({bufferedDeliveries:f,cancellation:h,cursor:u,inboxToken:c.token,initialResults:e.results,iterator:l,nextDeliveryRequestId,pendingActionKeys:o});if(r===`cancelled`){p=void 0;continue}p={kind:`runtime-action-result`,results:r};continue}if(i.action===`park`){if(!(i.hasPendingAuthorization||i.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);await h?.dispose(),await u.finish(i,{authorizationNames:i.authorizationNames,kind:`park`},f);return}await u.adopt(i),p=void 0}}catch(e){throw await u.send({error:normalizeSerializableError(e),kind:`turn-error`}),e}finally{h!==void 0&&await h.dispose(),m&&await disposeHook(c)}}async function waitForRuntimeActionResults(t){let n,r=[...t.initialResults];for(;;){let i=resolveRuntimeActionResultsForKeys({pendingKeys:t.pendingActionKeys,results:r});if(i!==void 0)return n!==void 0&&await t.cursor.send({kind:`turn-delivery-cancelled`,requestId:n}),i;t.cursor.sessionState.hasProxyInputRequests&&n===void 0&&(n=t.nextDeliveryRequestId(),await t.cursor.send({continuationToken:t.cursor.sessionState.continuationToken,inboxToken:t.inboxToken,kind:`turn-delivery-request`,requestId:n}));let a=t.iterator.next();a.catch(()=>{});let o=await(t.cancellation===void 0?a:Promise.race([a,t.cancellation.requested]));if(o===`cancel`)return n!==void 0&&await t.cursor.send({kind:`turn-delivery-cancelled`,requestId:n}),`cancelled`;if(o.done)throw Error(`Turn inbox closed before runtime actions completed.`);let s=o.value;if(s.kind===`runtime-action-result`){r.push(...s.results);continue}if(s.kind===`subagent-input-request`||s.kind===`subagent-authorization-event`){let e=await runProxySubagentEventStep({hookPayload:s,parentWritable:t.cursor.parentWritable,serializedContext:t.cursor.serializedContext,sessionState:t.cursor.sessionState});await t.cursor.adopt(e);continue}if(s.kind===`driver-delivery`&&s.requestId===n){await t.cursor.send({kind:`turn-delivery-accepted`,requestId:s.requestId}),n=void 0;let e=await routeDeliverToChildren({auth:s.delivery.auth,parentWritable:t.cursor.parentWritable,payloads:s.delivery.payloads,sessionState:t.cursor.sessionState});e!==void 0&&t.bufferedDeliveries.push({...s.delivery,payloads:[e]})}}}async function runLegacyTurnWorkflow(e){let t=e.stepInput;try{for(;;){let n=await turnStep(t);if(n.action===`done`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`done`,output:n.output??``,isError:n.isError,serializedContext:n.serializedContext,sessionState:n.sessionState,usage:n.usage},kind:`turn-result`}});return}if(n.action===`dispatch-workflow-runtime-actions`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`dispatch-workflow-runtime-actions`,pendingActionKeys:n.pendingRuntimeActionKeys,serializedContext:n.serializedContext,sessionState:n.sessionState},kind:`turn-result`}});return}if(n.action===`park`){let t=n.pendingRuntimeActionKeys;if(!(t!==void 0||n.hasPendingAuthorization||n.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);let r=t===void 0?{kind:`park`,serializedContext:n.serializedContext,sessionState:n.sessionState,authorizationNames:n.authorizationNames}:{kind:`dispatch-runtime-actions`,pendingActionKeys:t,serializedContext:n.serializedContext,sessionState:n.sessionState};await sendTurnControlStep({controlToken:e.completionToken,payload:{action:r,kind:`turn-result`}});return}t={input:void 0,parentWritable:t.parentWritable,serializedContext:n.serializedContext,sessionState:n.sessionState}}}catch(t){throw await sendTurnControlStep({controlToken:e.completionToken,payload:{error:normalizeSerializableError(t),kind:`turn-error`}}),t}}export{turnWorkflow};
1
+ import{resolveRuntimeActionResultsForKeys}from"#harness/runtime-actions.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{turnStep}from"#execution/workflow-steps.js";import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{sendTurnControlStep}from"#execution/turn-control-protocol.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{dispatchWorkflowRuntimeActionsStep}from"#execution/dispatch-workflow-runtime-actions-step.js";import{migrateTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{runProxySubagentEventStep}from"#execution/subagent-event-proxy-step.js";import{createTurnCancellationControl}from"#execution/turn-cancellation-control.js";import{TurnExecutionCursor}from"#execution/turn-execution-cursor.js";import{activeTurnId}from"#harness/active-turn-id.js";const TASK_MODE_WAIT_ERROR_MESSAGE="Task mode cannot wait for follow-up input (`next: null`).";function canSettleCancelledTurnAsPark(e){return e.mode===`conversation`||e.stepInput.sessionState.continuationToken!==``}async function turnWorkflow(e){"use workflow";let t=migrateTurnWorkflowInput(e);return t.driverCapabilities?.turnInbox===!0?runTurnOwnedWorkflow(t):runLegacyTurnWorkflow(t)}async function runTurnOwnedWorkflow(e){let c=createHook({token:`${e.completionToken}:inbox`}),l=c[Symbol.asyncIterator](),u=new TurnExecutionCursor({controlToken:e.completionToken,parentWritable:e.stepInput.parentWritable,serializedContext:e.stepInput.serializedContext,sessionState:e.stepInput.sessionState}),d=0,nextDeliveryRequestId=()=>`${c.token}:delivery:${String(d++)}`,f=[],p=e.stepInput.input,m=!1,h;try{try{await claimHookOwnership(c),m=!0}catch(e){if(isHookConflictError(e))return;throw e}for(e.driverCapabilities?.cancelledTurnSettle===!0&&canSettleCancelledTurnAsPark(e)&&(h=await createTurnCancellationControl({expectedTurnId:activeTurnId(e.stepInput.sessionState.emissionState),sessionId:e.stepInput.sessionState.sessionId}));;){let i=await turnStep(u.createStepInput(p,h?.signal));if(i.action===`cancelled`){await cancelDescendantTurnsStep({serializedContext:u.serializedContext,sessionState:u.sessionState}),await h?.dispose(),await u.finish({sessionState:u.sessionState},{cancelled:!0,kind:`park`},f);return}if(i.action===`done`){await h?.dispose(),await u.finish(i,{kind:`done`,output:i.output??``,isError:i.isError,usage:i.usage},f);return}let o=i.action===`dispatch-workflow-runtime-actions`||i.action===`park`?i.pendingRuntimeActionKeys:void 0;if(o!==void 0){await u.adopt(i);let e=await(i.action===`dispatch-workflow-runtime-actions`?dispatchWorkflowRuntimeActionsStep:dispatchRuntimeActionsStep)({callbackBaseUrl:resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),parentContinuationToken:c.token,parentWritable:u.parentWritable,serializedContext:u.serializedContext,sessionState:u.sessionState});await u.adopt(e);let r=await waitForRuntimeActionResults({bufferedDeliveries:f,cancellation:h,cursor:u,inboxToken:c.token,initialResults:e.results,iterator:l,nextDeliveryRequestId,pendingActionKeys:o});if(r===`cancelled`){p=void 0;continue}p={kind:`runtime-action-result`,results:r};continue}if(i.action===`park`){if(!(i.hasPendingAuthorization||i.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);await h?.dispose(),await u.finish(i,{authorizationNames:i.authorizationNames,kind:`park`},f);return}await u.adopt(i),p=void 0}}catch(e){throw await u.send({error:normalizeSerializableError(e),kind:`turn-error`}),e}finally{h!==void 0&&await h.dispose(),m&&await disposeHook(c)}}async function waitForRuntimeActionResults(t){let n,r=[...t.initialResults];for(;;){let i=resolveRuntimeActionResultsForKeys({pendingKeys:t.pendingActionKeys,results:r});if(i!==void 0)return n!==void 0&&await t.cursor.send({kind:`turn-delivery-cancelled`,requestId:n}),i;t.cursor.sessionState.hasProxyInputRequests&&n===void 0&&(n=t.nextDeliveryRequestId(),await t.cursor.send({continuationToken:t.cursor.sessionState.continuationToken,inboxToken:t.inboxToken,kind:`turn-delivery-request`,requestId:n}));let a=t.iterator.next();a.catch(()=>{});let o=await(t.cancellation===void 0?a:Promise.race([a,t.cancellation.requested]));if(o===`cancel`)return n!==void 0&&await t.cursor.send({kind:`turn-delivery-cancelled`,requestId:n}),`cancelled`;if(o.done)throw Error(`Turn inbox closed before runtime actions completed.`);let s=o.value;if(s.kind===`runtime-action-result`){r.push(...s.results);continue}if(s.kind===`subagent-input-request`||s.kind===`subagent-authorization-event`){let e=await runProxySubagentEventStep({hookPayload:s,parentWritable:t.cursor.parentWritable,serializedContext:t.cursor.serializedContext,sessionState:t.cursor.sessionState});await t.cursor.adopt(e);continue}if(s.kind===`driver-delivery`&&s.requestId===n){await t.cursor.send({kind:`turn-delivery-accepted`,requestId:s.requestId}),n=void 0;let e=await routeDeliverToChildren({auth:s.delivery.auth,parentWritable:t.cursor.parentWritable,payloads:s.delivery.payloads,sessionState:t.cursor.sessionState});e!==void 0&&t.bufferedDeliveries.push({...s.delivery,payloads:[e]})}}}async function runLegacyTurnWorkflow(e){let t=e.stepInput;try{for(;;){let n=await turnStep(t);if(n.action===`done`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`done`,output:n.output??``,isError:n.isError,serializedContext:n.serializedContext,sessionState:n.sessionState,usage:n.usage},kind:`turn-result`}});return}if(n.action===`dispatch-workflow-runtime-actions`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`dispatch-workflow-runtime-actions`,pendingActionKeys:n.pendingRuntimeActionKeys,serializedContext:n.serializedContext,sessionState:n.sessionState},kind:`turn-result`}});return}if(n.action===`park`){let t=n.pendingRuntimeActionKeys;if(!(t!==void 0||n.hasPendingAuthorization||n.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);let r=t===void 0?{kind:`park`,serializedContext:n.serializedContext,sessionState:n.sessionState,authorizationNames:n.authorizationNames}:{kind:`dispatch-runtime-actions`,pendingActionKeys:t,serializedContext:n.serializedContext,sessionState:n.sessionState};await sendTurnControlStep({controlToken:e.completionToken,payload:{action:r,kind:`turn-result`}});return}t={input:void 0,parentWritable:t.parentWritable,serializedContext:n.serializedContext,sessionState:n.sessionState}}}catch(t){throw await sendTurnControlStep({controlToken:e.completionToken,payload:{error:normalizeSerializableError(t),kind:`turn-error`}}),t}}export{turnWorkflow};
@@ -1,4 +1,4 @@
1
- import type { Runtime } from "#channel/types.js";
1
+ import type { CancelTurnInput, CancelTurnResult, Runtime } from "#channel/types.js";
2
2
  import { type Run, type StartOptionsWithoutDeploymentId, type WorkflowFunction, type WorkflowMetadata } from "#internal/workflow/runtime.js";
3
3
  import type { RuntimeCompiledArtifactsSource } from "#runtime/compiled-artifacts-source.js";
4
4
  export declare const LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE = "deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()";
@@ -40,6 +40,8 @@ export declare function createWorkflowRuntime(config: {
40
40
  readonly compiledArtifactsSource: RuntimeCompiledArtifactsSource;
41
41
  readonly nodeId?: string;
42
42
  }): Runtime;
43
+ /** Requests cancellation through a session's stable workflow hook. */
44
+ export declare function requestWorkflowTurnCancellation(input: CancelTurnInput): Promise<CancelTurnResult>;
43
45
  /**
44
46
  * Starts a workflow on the latest deployment when latest routing applies,
45
47
  * while preserving local/dev worlds that do not implement latest routing.