eve 0.30.7 → 0.31.0

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 (240) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +5 -6
  3. package/dist/src/acp/adapter.d.ts +10 -4
  4. package/dist/src/acp/adapter.js +1 -1
  5. package/dist/src/channel/adapter-context.d.ts +1 -1
  6. package/dist/src/channel/adapter.d.ts +2 -4
  7. package/dist/src/channel/adapter.js +1 -1
  8. package/dist/src/channel/channel-address.d.ts +58 -0
  9. package/dist/src/channel/channel-address.js +1 -0
  10. package/dist/src/channel/channel-operations.d.ts +72 -0
  11. package/dist/src/channel/channel-operations.js +1 -0
  12. package/dist/src/channel/compiled-channel.d.ts +10 -6
  13. package/dist/src/channel/cross-channel-receive.d.ts +13 -25
  14. package/dist/src/channel/cross-channel-receive.js +2 -2
  15. package/dist/src/channel/receive-target.d.ts +1 -2
  16. package/dist/src/channel/routes.d.ts +21 -149
  17. package/dist/src/channel/schedule.d.ts +1 -1
  18. package/dist/src/channel/schedule.js +1 -1
  19. package/dist/src/channel/send-input.d.ts +6 -0
  20. package/dist/src/channel/send-input.js +1 -0
  21. package/dist/src/channel/session.d.ts +44 -30
  22. package/dist/src/channel/session.js +1 -1
  23. package/dist/src/channel/types.d.ts +8 -35
  24. package/dist/src/chunks/{use-eve-agent-k-XHfrJT.js → use-eve-agent-CF5D6jSV.js} +361 -367
  25. package/dist/src/chunks/{use-eve-agent-BXMIf5fR.js → use-eve-agent-DbYZLG0h.js} +364 -368
  26. package/dist/src/cli/commands/agent-prompt/build-and-verify.md +1 -2
  27. package/dist/src/cli/commands/channel-add-conflicts.js +1 -1
  28. package/dist/src/cli/commands/info.d.ts +1 -1
  29. package/dist/src/cli/commands/info.js +1 -1
  30. package/dist/src/cli/commands/registry-metadata.d.ts +15 -0
  31. package/dist/src/cli/commands/registry-metadata.js +1 -0
  32. package/dist/src/cli/commands/registry-package.d.ts +46 -0
  33. package/dist/src/cli/commands/registry-package.js +1 -0
  34. package/dist/src/cli/commands/registry.d.ts +1 -1
  35. package/dist/src/cli/commands/registry.js +4 -4
  36. package/dist/src/cli/dev/tui/runner.d.ts +1 -1
  37. package/dist/src/cli/dev/tui/runner.js +1 -1
  38. package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
  39. package/dist/src/cli/dev/tui/terminal-renderer.js +2 -2
  40. package/dist/src/cli/dev/tui/tui.js +1 -1
  41. package/dist/src/cli/invoke/invoke.d.ts +1 -1
  42. package/dist/src/cli/invoke/invoke.js +1 -1
  43. package/dist/src/cli/invoke/result.d.ts +0 -11
  44. package/dist/src/cli/invoke/result.js +1 -1
  45. package/dist/src/client/client-error.d.ts +2 -0
  46. package/dist/src/client/client-error.js +1 -1
  47. package/dist/src/client/client.d.ts +7 -14
  48. package/dist/src/client/client.js +1 -1
  49. package/dist/src/client/eve-agent-store.d.ts +4 -4
  50. package/dist/src/client/eve-agent-store.js +1 -1
  51. package/dist/src/client/index.d.ts +3 -2
  52. package/dist/src/client/index.js +1 -1
  53. package/dist/src/client/message-reducer-types.d.ts +3 -0
  54. package/dist/src/client/message-reducer.js +1 -1
  55. package/dist/src/client/message-response.d.ts +2 -7
  56. package/dist/src/client/message-response.js +1 -1
  57. package/dist/src/client/open-stream.js +1 -1
  58. package/dist/src/client/session-controls.d.ts +29 -0
  59. package/dist/src/client/session-controls.js +1 -0
  60. package/dist/src/client/session-utils.d.ts +0 -20
  61. package/dist/src/client/session-utils.js +1 -1
  62. package/dist/src/client/session.d.ts +26 -90
  63. package/dist/src/client/session.js +1 -1
  64. package/dist/src/client/sessions.d.ts +20 -0
  65. package/dist/src/client/sessions.js +1 -0
  66. package/dist/src/client/types.d.ts +26 -47
  67. package/dist/src/compiler/extension-compatibility.d.ts +10 -10
  68. package/dist/src/compiler/extension-compatibility.js +1 -1
  69. package/dist/src/compiler/normalize-subagent.js +1 -1
  70. package/dist/src/evals/cli/eval-client.js +1 -1
  71. package/dist/src/evals/context.js +1 -1
  72. package/dist/src/evals/session.d.ts +7 -6
  73. package/dist/src/evals/session.js +1 -1
  74. package/dist/src/evals/types.d.ts +9 -9
  75. package/dist/src/execution/agent-handle-dispatch.js +1 -1
  76. package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
  77. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  78. package/dist/src/execution/remote-agent-dispatch.d.ts +1 -3
  79. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  80. package/dist/src/execution/runtime-context.js +1 -1
  81. package/dist/src/execution/runtime-errors.d.ts +1 -1
  82. package/dist/src/execution/session-command-token.d.ts +2 -0
  83. package/dist/src/execution/session-command-token.js +1 -1
  84. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  85. package/dist/src/execution/subagent-hitl-proxy.js +1 -1
  86. package/dist/src/execution/tool-auth.d.ts +1 -1
  87. package/dist/src/execution/tool-auth.js +1 -1
  88. package/dist/src/execution/turn-control-receiver.d.ts +2 -2
  89. package/dist/src/execution/turn-workflow.js +1 -1
  90. package/dist/src/execution/workflow-entry.js +1 -1
  91. package/dist/src/execution/workflow-runtime.js +1 -1
  92. package/dist/src/harness/cancelled-turn-emission.d.ts +1 -1
  93. package/dist/src/harness/cancelled-turn-emission.js +1 -1
  94. package/dist/src/harness/emission-state.d.ts +25 -0
  95. package/dist/src/harness/emission-state.js +1 -0
  96. package/dist/src/harness/emission.d.ts +5 -37
  97. package/dist/src/harness/emission.js +1 -1
  98. package/dist/src/harness/handles/prompt.d.ts +22 -3
  99. package/dist/src/harness/handles/prompt.js +1 -1
  100. package/dist/src/harness/handles/store.d.ts +0 -5
  101. package/dist/src/harness/handles/store.js +1 -1
  102. package/dist/src/harness/ordered-stream-emitter.d.ts +3 -2
  103. package/dist/src/harness/ordered-stream-emitter.js +1 -1
  104. package/dist/src/harness/runtime-actions.js +1 -1
  105. package/dist/src/harness/session-limit-enforcement.js +1 -1
  106. package/dist/src/harness/tool-loop.js +1 -1
  107. package/dist/src/harness/tools.d.ts +1 -1
  108. package/dist/src/harness/tools.js +1 -1
  109. package/dist/src/internal/application/package.js +1 -1
  110. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  111. package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
  112. package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.d.ts +15 -0
  113. package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.js +1 -0
  114. package/dist/src/internal/nitro/dev-runtime-source-snapshot.d.ts +14 -2
  115. package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
  116. package/dist/src/internal/nitro/host/dev-server-http.js +1 -1
  117. package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +2 -5
  118. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  119. package/dist/src/internal/nitro/routes/channel-route-context.d.ts +4 -3
  120. package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
  121. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  122. package/dist/src/protocol/cancel-turn.d.ts +9 -4
  123. package/dist/src/protocol/cancel-turn.js +1 -1
  124. package/dist/src/protocol/message.d.ts +27 -17
  125. package/dist/src/protocol/message.js +2 -2
  126. package/dist/src/protocol/reset-session.d.ts +1 -1
  127. package/dist/src/protocol/routes.d.ts +27 -47
  128. package/dist/src/protocol/routes.js +1 -1
  129. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +19 -21
  130. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  131. package/dist/src/public/channels/discord/discordChannel.d.ts +5 -4
  132. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  133. package/dist/src/public/channels/eve.d.ts +11 -10
  134. package/dist/src/public/channels/eve.js +1 -1
  135. package/dist/src/public/channels/github/dispatch.d.ts +8 -8
  136. package/dist/src/public/channels/github/dispatch.js +1 -1
  137. package/dist/src/public/channels/github/githubChannel.d.ts +4 -3
  138. package/dist/src/public/channels/github/githubChannel.js +1 -1
  139. package/dist/src/public/channels/github/pr-context.d.ts +1 -1
  140. package/dist/src/public/channels/index.d.ts +1 -1
  141. package/dist/src/public/channels/linear/linearChannel.d.ts +4 -3
  142. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  143. package/dist/src/public/channels/slack/index.d.ts +1 -1
  144. package/dist/src/public/channels/slack/interactions.d.ts +3 -4
  145. package/dist/src/public/channels/slack/interactions.js +1 -1
  146. package/dist/src/public/channels/slack/session-operations.d.ts +37 -0
  147. package/dist/src/public/channels/slack/session-operations.js +1 -0
  148. package/dist/src/public/channels/slack/slackChannel.d.ts +56 -74
  149. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  150. package/dist/src/public/channels/teams/teamsChannel.d.ts +4 -3
  151. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  152. package/dist/src/public/channels/telegram/telegramChannel.d.ts +5 -4
  153. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  154. package/dist/src/public/channels/twilio/twilioChannel.d.ts +4 -3
  155. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  156. package/dist/src/public/definitions/callback-context.d.ts +1 -2
  157. package/dist/src/public/definitions/channel.d.ts +22 -86
  158. package/dist/src/public/definitions/channel.js +1 -1
  159. package/dist/src/public/definitions/hook.d.ts +1 -0
  160. package/dist/src/public/definitions/remote-agent.js +1 -1
  161. package/dist/src/public/definitions/schedule.d.ts +16 -16
  162. package/dist/src/public/definitions/tool.d.ts +5 -5
  163. package/dist/src/public/schedules/index.d.ts +1 -1
  164. package/dist/src/react/use-eve-agent.d.ts +7 -4
  165. package/dist/src/react/use-eve-agent.js +1 -1
  166. package/dist/src/runtime/agent/bootstrap-model-utils.d.ts +11 -0
  167. package/dist/src/runtime/agent/bootstrap-model-utils.js +1 -1
  168. package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
  169. package/dist/src/runtime/agent/mock-model-fixtures.js +2 -2
  170. package/dist/src/runtime/prompt/compose.js +1 -1
  171. package/dist/src/runtime/subagents/dynamic-remote-agent-config.js +1 -1
  172. package/dist/src/runtime/types.d.ts +2 -2
  173. package/dist/src/services/inspect-application.d.ts +1 -1
  174. package/dist/src/services/inspect-application.js +1 -1
  175. package/dist/src/setup/channel-add-conflicts.js +1 -1
  176. package/dist/src/setup/integrations/linear/setup.js +1 -1
  177. package/dist/src/setup/scaffold/create/project.js +1 -1
  178. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  179. package/dist/src/setup/scaffold/create/web-template.js +29 -17
  180. package/dist/src/shared/async-iterable.d.ts +2 -0
  181. package/dist/src/shared/async-iterable.js +1 -0
  182. package/dist/src/shared/channel-definition.d.ts +7 -7
  183. package/dist/src/shared/schedule-definition.d.ts +2 -2
  184. package/dist/src/shared/tool-definition.d.ts +1 -1
  185. package/dist/src/svelte/index.js +1 -1
  186. package/dist/src/svelte/use-eve-agent.d.ts +8 -5
  187. package/dist/src/svelte/use-eve-agent.js +1 -1
  188. package/dist/src/vue/index.js +1 -1
  189. package/dist/src/vue/use-eve-agent.d.ts +8 -5
  190. package/dist/src/vue/use-eve-agent.js +1 -1
  191. package/docs/README.md +6 -6
  192. package/docs/channels/chat-sdk.mdx +5 -6
  193. package/docs/channels/custom.mdx +116 -144
  194. package/docs/channels/discord.mdx +1 -1
  195. package/docs/channels/eve.mdx +76 -30
  196. package/docs/channels/github.mdx +1 -1
  197. package/docs/channels/linear.mdx +10 -10
  198. package/docs/channels/overview.mdx +2 -2
  199. package/docs/channels/slack.mdx +46 -15
  200. package/docs/channels/telegram.mdx +1 -1
  201. package/docs/channels/twilio.mdx +1 -1
  202. package/docs/concepts/default-harness.md +11 -3
  203. package/docs/concepts/execution-model-and-durability.mdx +17 -5
  204. package/docs/concepts/sessions-runs-and-streaming.md +45 -16
  205. package/docs/evals/cases.mdx +3 -3
  206. package/docs/evals/targets.mdx +1 -1
  207. package/docs/guides/auth-and-route-protection.md +2 -1
  208. package/docs/guides/client/continuations.mdx +50 -77
  209. package/docs/guides/client/messages.mdx +29 -33
  210. package/docs/guides/client/output-schema.mdx +7 -14
  211. package/docs/guides/client/overview.mdx +40 -11
  212. package/docs/guides/client/streaming.mdx +18 -23
  213. package/docs/guides/frontend/nuxt.mdx +1 -1
  214. package/docs/guides/frontend/overview.mdx +40 -36
  215. package/docs/guides/frontend/sveltekit.mdx +1 -1
  216. package/docs/guides/frontend/use-eve-agent-svelte.mdx +19 -23
  217. package/docs/guides/frontend/use-eve-agent-vue.mdx +21 -25
  218. package/docs/guides/hooks.md +1 -1
  219. package/docs/guides/instrumentation.md +1 -1
  220. package/docs/install-integrations.mdx +4 -2
  221. package/docs/patterns/dynamic-scheduling.md +16 -15
  222. package/docs/reference/cli.md +4 -1
  223. package/docs/schedules.mdx +10 -11
  224. package/docs/subagents.mdx +1 -1
  225. package/docs/tools/human-in-the-loop.md +1 -1
  226. package/docs/tools/overview.mdx +26 -2
  227. package/docs/tutorial/ship-it.mdx +1 -1
  228. package/package.json +1 -1
  229. package/dist/src/channel/cancel.d.ts +0 -6
  230. package/dist/src/channel/cancel.js +0 -1
  231. package/dist/src/channel/clear-session.d.ts +0 -4
  232. package/dist/src/channel/clear-session.js +0 -1
  233. package/dist/src/channel/compact-session.d.ts +0 -4
  234. package/dist/src/channel/compact-session.js +0 -1
  235. package/dist/src/channel/reset-session.d.ts +0 -6
  236. package/dist/src/channel/reset-session.js +0 -1
  237. package/dist/src/channel/resolve-active-session.d.ts +0 -4
  238. package/dist/src/channel/resolve-active-session.js +0 -1
  239. package/dist/src/channel/send.d.ts +0 -6
  240. package/dist/src/channel/send.js +0 -1
@@ -1 +1 @@
1
- import{EVE_CLEAR_SESSION_ROUTE_PATH,EVE_COMPACT_SESSION_ROUTE_PATH,EVE_CREATE_SESSION_ROUTE_PATH,EVE_RESET_SESSION_ROUTE_PATH,createEveCancelTurnRoutePath,createEveContinueSessionRoutePath}from"#protocol/routes.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{advanceSession,createInitialSessionState}from"#client/session-utils.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{ClearResponseSchema}from"#protocol/clear-session.js";import{CompactResponseSchema}from"#protocol/compact-session.js";import{ResetResponseSchema}from"#protocol/reset-session.js";import{followStreamIterable}from"#client/open-stream.js";import{serializeOutputSchema}from"#shared/tool-schema.js";var ClientSession=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get state(){return this.#t}async snapshot(e){e?.signal?.throwIfAborted();let t=this.#t,n=t.sessionId;if(!n)throw Error(`Session has no session ID. Send a message first.`);let r=[];for await(let t of this.#a({follow:!1,sessionId:n,signal:e?.signal,startIndex:0}))r.push(t);e?.signal?.throwIfAborted();let i=r.at(-1),a=i?.type===`session.waiting`?i.data.continuationToken:i?.type===`session.completed`&&this.#e.preserveCompletedSessions?t.continuationToken:void 0;return{events:r,session:a===void 0?{sessionId:n,streamIndex:r.length}:{continuationToken:a,sessionId:n,streamIndex:r.length}}}async send(e){let t=normalizeSendTurnInput(e),n=this.#t,{continuationToken:r,sessionId:i}=await this.#n(t,n);if(this.#t===n){let e={...n,sessionId:i};r!==void 0&&(e.continuationToken=r),this.#t=e}return new MessageResponse({continuationToken:r,createStream:()=>this.#r(i,r,n,t),sessionId:i})}async cancel(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);let n=createClientUrl(this.#e.host,createEveCancelTurnRoutePath(t)),r=await this.#e.resolveHeaders();r.set(`content-type`,`application/json`);let a=await fetch(n,withRedirectPolicy({headers:r,method:`POST`,body:e?JSON.stringify(e):void 0},this.#e.redirect)),o=await a.text();if(!a.ok)throw new ClientError(a.status,o,a.headers);let s;try{s=JSON.parse(o)}catch{throw Error(`Cancel route returned invalid JSON (${a.status}).`)}let c=CancelTurnResponseSchema.safeParse(s);if(!c.success||c.data.sessionId!==t)throw Error(`Cancel route returned an invalid response (${a.status}).`);return{sessionId:c.data.sessionId,status:c.data.status}}async clear(){let t=this.#t,n=t.continuationToken;if(n===void 0){if(t.sessionId!==void 0)throw Error(`Session has no continuation token. Consume its event stream before clearing.`);return{status:`no_active_session`}}let r=createClientUrl(this.#e.host,EVE_CLEAR_SESSION_ROUTE_PATH),i=await this.#e.resolveHeaders();i.set(`content-type`,`application/json`);let a=await fetch(r,withRedirectPolicy({body:JSON.stringify({continuationToken:n}),headers:i,method:`POST`},this.#e.redirect)),o=await a.text();if(!a.ok)throw new ClientError(a.status,o,a.headers);let s;try{s=JSON.parse(o)}catch{throw Error(`Clear route returned invalid JSON (${a.status}).`)}let c=ClearResponseSchema.safeParse(s);if(!c.success||c.data.status===`accepted`&&t.sessionId!==void 0&&c.data.sessionId!==t.sessionId)throw Error(`Clear route returned an invalid response (${a.status}).`);return c.data.status===`accepted`?{sessionId:c.data.sessionId,status:`accepted`}:{status:`no_active_session`}}async compact(){let e=this.#t,n=e.continuationToken;if(n===void 0){if(e.sessionId!==void 0)throw Error(`Session has no continuation token. Consume its event stream before compacting.`);return{status:`no_active_session`}}let r=createClientUrl(this.#e.host,EVE_COMPACT_SESSION_ROUTE_PATH),i=await this.#e.resolveHeaders();i.set(`content-type`,`application/json`);let a=await fetch(r,withRedirectPolicy({body:JSON.stringify({continuationToken:n}),headers:i,method:`POST`},this.#e.redirect)),o=await a.text();if(!a.ok)throw new ClientError(a.status,o,a.headers);let s;try{s=JSON.parse(o)}catch{throw Error(`Compact route returned invalid JSON (${a.status}).`)}let c=CompactResponseSchema.safeParse(s);if(!c.success||c.data.status===`accepted`&&e.sessionId!==void 0&&c.data.sessionId!==e.sessionId)throw Error(`Compact route returned an invalid response (${a.status}).`);return c.data.status===`accepted`?{sessionId:c.data.sessionId,status:`accepted`}:{status:`no_active_session`}}async reset(){let e=this.#t,t=e.continuationToken;if(t===void 0){if(e.sessionId!==void 0)throw Error(`Session has no continuation token. Consume its event stream before resetting.`);return this.#t=createInitialSessionState(),{status:`no_active_session`}}let n=createClientUrl(this.#e.host,EVE_RESET_SESSION_ROUTE_PATH),i=await this.#e.resolveHeaders();i.set(`content-type`,`application/json`);let a=await fetch(n,withRedirectPolicy({body:JSON.stringify({continuationToken:t}),headers:i,method:`POST`},this.#e.redirect)),o=await a.text();if(!a.ok)throw new ClientError(a.status,o,a.headers);let s;try{s=JSON.parse(o)}catch{throw Error(`Reset route returned invalid JSON (${a.status}).`)}let c=ResetResponseSchema.safeParse(s);if(!c.success||c.data.status===`reset`&&e.sessionId!==void 0&&c.data.previousSessionId!==e.sessionId)throw Error(`Reset route returned an invalid response (${a.status}).`);return this.#t===e&&(this.#t=createInitialSessionState()),c.data.status===`reset`?{previousSessionId:c.data.previousSessionId,status:`reset`}:{status:`no_active_session`}}stream(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);if(e?.follow===!1&&(e.startIndex??this.#t.streamIndex)<0)throw Error(`stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.`);return this.#i(t,e)}async#n(e,t){let r=t.sessionId?createEveContinueSessionRoutePath(t.sessionId):EVE_CREATE_SESSION_ROUTE_PATH,i=createClientUrl(this.#e.host,r),s=await this.#e.resolveHeaders(e.headers);s.set(`content-type`,`application/json`);let c=createHandleMessageBody({input:e,outputSchema:serializeOutputSchema(e.outputSchema),session:t});if(c===null)throw Error(`Session.send requires a non-empty message, inputResponses, or both.`);let l=await postTurnWithRetry({body:JSON.stringify(c),headers:s,mustDeliver:(e.inputResponses?.length??0)>0,redirect:this.#e.redirect,signal:e.signal,url:i}),u=await l.json(),d=(typeof u.sessionId==`string`?u.sessionId:void 0)??l.headers.get(EVE_SESSION_ID_HEADER)?.trim()??t.sessionId;if(!d)throw Error(`Message route did not return a session id.`);return{continuationToken:typeof u.continuationToken==`string`?u.continuationToken:void 0,sessionId:d}}async*#r(e,t,n,r){let i=[];try{for await(let t of this.#a({headers:r.headers,streamReconnectPolicy:r.streamReconnectPolicy,sessionId:e,signal:r.signal,startIndex:n.sessionId===e?n.streamIndex:0}))if(i.push(t),yield t,isCurrentTurnBoundaryEvent(t))break}finally{this.#t=advanceSession({continuationToken:t,events:i,preserveCompletedSessions:this.#e.preserveCompletedSessions,sessionId:e,session:n})}}async*#i(e,t){let n=this.#t,r=t?.startIndex??n.streamIndex,i=[];try{for await(let n of this.#a({follow:t?.follow,sessionId:e,signal:t?.signal,startIndex:r,streamReconnectPolicy:t?.streamReconnectPolicy}))i.push(n),yield n}finally{r>=0&&(this.#t=advanceSession({continuationToken:n.continuationToken,events:i,preserveCompletedSessions:this.#e.preserveCompletedSessions,session:{...n,sessionId:e,streamIndex:r},sessionId:e}))}}#a(e){return followStreamIterable({follow:e.follow,host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(e.headers),redirect:this.#e.redirect,streamReconnectPolicy:e.streamReconnectPolicy,sessionId:e.sessionId,signal:e.signal,startIndex:e.startIndex})}};async function postTurnWithRetry(e){let t=e.mustDeliver?10:1,n,r,i;for(let a=0;a<t;a+=1){let o=await fetch(e.url,{body:e.body,headers:e.headers,method:`POST`,redirect:e.redirect,signal:e.signal??null});if(o.ok)return o;if(n=o.status,r=await o.text(),i=o.headers,!isRetryableDeliveryFailure(o.status,r))throw new ClientError(o.status,r,o.headers);a<t-1&&await sleep(200)}throw new ClientError(n??0,r??`Failed to deliver session turn.`,i)}function isRetryableDeliveryFailure(e,t){return e===500&&/target session was not found/i.test(t)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}function normalizeSendTurnInput(e){return typeof e==`string`?{message:e}:e}function createHandleMessageBody(e){let t={};return e.input.message!==void 0&&(t.message=e.input.message),e.input.inputResponses!==void 0&&e.input.inputResponses.length>0&&(t.inputResponses=e.input.inputResponses),e.input.clientContext!==void 0&&(t.clientContext=e.input.clientContext),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),e.session.continuationToken!==void 0&&(t.continuationToken=e.session.continuationToken),Object.keys(t).length===0||e.session.continuationToken===void 0&&t.message===void 0||e.session.continuationToken!==void 0&&t.message===void 0&&t.inputResponses===void 0?null:t}function withRedirectPolicy(e,t){return t===void 0?e:{...e,redirect:t}}export{ClientSession};
1
+ import{EVE_SESSION_ROUTE_PATH,createEveSessionRoutePath}from"#protocol/routes.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{followStreamIterable}from"#client/open-stream.js";import{cancelClientSession,clearClientSession,compactClientSession,resetClientSession}from"#client/session-controls.js";import{serializeOutputSchema}from"#shared/tool-schema.js";var ClientSession=class ClientSession{#e;#t;constructor(e,t){this.#e=e,this.#t=t}static async create(t,n){let r=await postTurn(t,EVE_SESSION_ROUTE_PATH,n,!0),i=await readSessionId(r),a=new ClientSession(t,{sessionId:i,streamIndex:0});return{response:a.#r(r,n,0),session:a}}get state(){return this.#t}async snapshot(e){e?.signal?.throwIfAborted();let t=[];for await(let n of this.#o({follow:!1,signal:e?.signal,startIndex:0}))t.push(n);return e?.signal?.throwIfAborted(),{events:t,session:{sessionId:this.#t.sessionId,streamIndex:t.length}}}async send(e,t={}){return await this.#n({...t,message:e})}async respond(e,t={}){if(e.length===0)throw Error(`ClientSession.respond() requires at least one input response.`);return await this.#n({...t,inputResponses:e})}async#n(e){let n=this.#t.streamIndex,r=await postTurn(this.#e,createEveSessionRoutePath(this.#t.sessionId),e,!1);if(await readSessionId(r,this.#t.sessionId)!==this.#t.sessionId)throw Error(`Message route returned a different session id.`);return this.#r(r,e,n)}async cancel(e){return await cancelClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}async clear(){return await clearClientSession({context:this.#e,sessionId:this.#t.sessionId})}async compact(){return await compactClientSession({context:this.#e,sessionId:this.#t.sessionId})}async reset(e){return await resetClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}stream(e){if(e?.follow===!1&&(e.startIndex??this.#t.streamIndex)<0)throw Error(`stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.`);return this.#a(e)}#r(e,t,n){return e.body?.cancel().catch(()=>{}),new MessageResponse({createStream:()=>this.#i(n,t),sessionId:this.#t.sessionId})}async*#i(e,t){let n=0;try{for await(let i of this.#o({headers:t.headers,signal:t.signal,startIndex:e,streamReconnectPolicy:t.streamReconnectPolicy}))if(n+=1,yield i,isCurrentTurnBoundaryEvent(i))break}finally{this.#t={sessionId:this.#t.sessionId,streamIndex:e+n}}}async*#a(e){let t=e?.startIndex??this.#t.streamIndex,n=0;try{for await(let r of this.#o({follow:e?.follow,signal:e?.signal,startIndex:t,streamReconnectPolicy:e?.streamReconnectPolicy}))n+=1,yield r}finally{t>=0&&(this.#t={sessionId:this.#t.sessionId,streamIndex:t+n})}}#o(e){return followStreamIterable({follow:e.follow,host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(e.headers),redirect:this.#e.redirect,sessionId:this.#t.sessionId,signal:e.signal,startIndex:e.startIndex,streamReconnectPolicy:e.streamReconnectPolicy})}};async function postTurn(e,t,n,r){let o=createMessageBody(n,r);if(o===null)throw Error(r?`Creating a session requires a non-empty message.`:`A session turn requires a non-empty message or inputResponses.`);let s=await e.resolveHeaders(n.headers);s.set(`content-type`,`application/json`);let c=await fetch(createClientUrl(e.host,t),{body:JSON.stringify(o),headers:s,method:`POST`,redirect:e.redirect,signal:n.signal??null});if(!c.ok){let e=await c.text();throw new ClientError(c.status,e,c.headers)}return c}async function readSessionId(e,t){let r=await e.json(),i=(typeof r.sessionId==`string`?r.sessionId:void 0)??e.headers.get(EVE_SESSION_ID_HEADER)?.trim()??t;if(!i)throw Error(`Message route did not return a session id.`);return i}function createMessageBody(e,t){let n={};e.message!==void 0&&(n.message=e.message),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses),e.clientContext!==void 0&&(n.clientContext=e.clientContext);let r=serializeOutputSchema(e.outputSchema);return r!==void 0&&(n.outputSchema=r),t&&n.message===void 0||n.message===void 0&&n.inputResponses===void 0?null:n}export{ClientSession};
@@ -0,0 +1,20 @@
1
+ import { ClientSession, type ClientSessionContext } from "#client/session.js";
2
+ import type { MessageResponse } from "#client/message-response.js";
3
+ import type { SendTurnInput } from "#client/types.js";
4
+ /** Result of explicitly creating an ID-addressed client session. */
5
+ export interface CreatedClientSession<TOutput = unknown> {
6
+ readonly response: MessageResponse<TOutput>;
7
+ readonly session: ClientSession;
8
+ }
9
+ /** Collection surface for explicitly creating or attaching ID-addressed sessions. */
10
+ export declare class ClientSessions {
11
+ #private;
12
+ /** @internal */
13
+ constructor(context: ClientSessionContext);
14
+ /** Creates a session immediately and returns its fixed handle plus first-turn response. */
15
+ create<TOutput = unknown>(input: SendTurnInput<TOutput>): Promise<CreatedClientSession<TOutput>>;
16
+ /** Attaches a fixed handle to a known session ID without performing I/O. */
17
+ attach(sessionId: string, options?: {
18
+ readonly streamIndex?: number;
19
+ }): ClientSession;
20
+ }
@@ -0,0 +1 @@
1
+ import{ClientSession}from"#client/session.js";var ClientSessions=class{#e;constructor(e){this.#e=e}async create(t){return await ClientSession.create(this.#e,t)}attach(t,n){if(t.length===0)throw Error(`sessionId must be a non-empty string.`);return new ClientSession(this.#e,{sessionId:t,streamIndex:n?.streamIndex??0})}};export{ClientSessions};
@@ -1,7 +1,7 @@
1
1
  import type { UserContent } from "ai";
2
2
  import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
3
3
  import type { MessageStreamEvent } from "#protocol/message.js";
4
- import type { CancelTurnStatus } from "#protocol/cancel-turn.js";
4
+ import type { CancelTurnResult } from "#protocol/cancel-turn.js";
5
5
  import type { ClearStatus } from "#protocol/clear-session.js";
6
6
  import type { CompactStatus } from "#protocol/compact-session.js";
7
7
  import type { ResetStatus } from "#protocol/reset-session.js";
@@ -70,31 +70,15 @@ export interface ClientOptions {
70
70
  * redirect.
71
71
  */
72
72
  readonly redirect?: ClientRedirectPolicy;
73
- /**
74
- * Keep a session's continuation token after a normal `session.completed`
75
- * boundary.
76
- *
77
- * By default, completed turns reset the client-side session so the next
78
- * `send()` starts a fresh server-side conversation. Interactive clients can
79
- * set this to preserve durable session state, including framework-managed
80
- * sandbox state, across follow-up prompts until they explicitly create a new
81
- * session.
82
- *
83
- * @default false
84
- */
85
- readonly preserveCompletedSessions?: boolean;
86
73
  }
87
74
  /**
88
- * Input payload for {@link ClientSession.send}. Pass a string as shorthand for
89
- * `{ message: string }`, or pass an object to include a message, HITL input
90
- * responses, one-turn client context, structured-output schema, abort signal,
91
- * and per-turn headers.
75
+ * Input object for creating a client session. The first message is required.
92
76
  */
93
- export type SendTurnInput<TOutput = unknown> = string | SendTurnPayload<TOutput>;
94
- /**
95
- * Object form accepted by {@link ClientSession.send}.
96
- */
97
- export interface SendTurnPayload<TOutput = unknown> {
77
+ export interface SendTurnInput<TOutput = unknown> extends SendTurnOptions<TOutput> {
78
+ readonly message: string | UserContent;
79
+ }
80
+ /** Options shared by message sends and HITL responses on a client session. */
81
+ export interface SendTurnOptions<TOutput = unknown> {
98
82
  /**
99
83
  * Ephemeral client/page context for the next model call only.
100
84
  *
@@ -104,14 +88,6 @@ export interface SendTurnPayload<TOutput = unknown> {
104
88
  * itself and is never persisted to durable session history.
105
89
  */
106
90
  readonly clientContext?: string | readonly string[] | JsonObject;
107
- /**
108
- * HITL responses resolving pending approvals or questions.
109
- */
110
- readonly inputResponses?: readonly InputResponse[];
111
- /**
112
- * Optional follow-up user message for the same turn.
113
- */
114
- readonly message?: string | UserContent;
115
91
  /**
116
92
  * Optional schema the harness must satisfy before this turn terminates.
117
93
  *
@@ -136,6 +112,16 @@ export interface SendTurnPayload<TOutput = unknown> {
136
112
  */
137
113
  readonly headers?: Readonly<Record<string, string>>;
138
114
  }
115
+ /** Options for answering pending HITL input requests on a client session. */
116
+ export type RespondTurnOptions<TOutput = unknown> = SendTurnOptions<TOutput>;
117
+ /** @internal Transport envelope used by stores and command adapters. */
118
+ export type SendTurnPayload<TOutput = unknown> = (SendTurnOptions<TOutput> & {
119
+ readonly inputResponses?: never;
120
+ readonly message: string | UserContent;
121
+ }) | (RespondTurnOptions<TOutput> & {
122
+ readonly inputResponses: readonly InputResponse[];
123
+ readonly message?: never;
124
+ });
139
125
  /** Retry and backoff settings for one kind of stream reconnection. */
140
126
  export interface StreamReconnectRetryPolicy {
141
127
  /** Initial delay before retrying, in milliseconds. */
@@ -186,19 +172,14 @@ export interface StreamOptions {
186
172
  readonly signal?: AbortSignal;
187
173
  }
188
174
  /** Result of requesting cancellation for a client session's active turn. */
189
- export interface CancelSessionResult {
190
- /** Session whose active turn was targeted. */
191
- readonly sessionId: string;
192
- /** Both outcomes are successful; `no_active_turn` means there was nothing left to cancel. */
193
- readonly status: CancelTurnStatus;
194
- }
175
+ export type CancelSessionResult = CancelTurnResult;
195
176
  /** Result of requesting a context clear for a client session. */
196
177
  export type ClearResult = {
197
178
  /** Session whose clear request was queued. */
198
179
  readonly sessionId: string;
199
180
  readonly status: Extract<ClearStatus, "accepted">;
200
181
  } | {
201
- /** The client had no continuation token or the token was already free. */
182
+ /** The fixed session ID was unknown or no longer active. */
202
183
  readonly status: Extract<ClearStatus, "no_active_session">;
203
184
  };
204
185
  /** Result of requesting context compaction for a client session. */
@@ -207,16 +188,16 @@ export type CompactResult = {
207
188
  readonly sessionId: string;
208
189
  readonly status: Extract<CompactStatus, "accepted">;
209
190
  } | {
210
- /** The client had no continuation token or the token was already free. */
191
+ /** The fixed session ID was unknown or no longer active. */
211
192
  readonly status: Extract<CompactStatus, "no_active_session">;
212
193
  };
213
194
  /** Result of terminally resetting a client session. */
214
195
  export type ResetResult = {
215
- /** The prior session was retired and its continuation token released. */
196
+ /** The prior session was terminally retired. */
216
197
  readonly previousSessionId: string;
217
198
  readonly status: Extract<ResetStatus, "reset">;
218
199
  } | {
219
- /** The client had no continuation token or the token was already free. */
200
+ /** The fixed session ID was unknown or no longer active. */
220
201
  readonly status: Extract<ResetStatus, "no_active_session">;
221
202
  };
222
203
  /**
@@ -266,12 +247,10 @@ export interface HealthResult {
266
247
  readonly workflowId: string;
267
248
  }
268
249
  /**
269
- * Serializable session cursor. Persist this value and pass it back to
270
- * {@link Client.session} to resume a conversation later.
250
+ * Serializable cursor for one fixed, ID-addressed client session.
271
251
  */
272
- export interface SessionState {
273
- readonly continuationToken?: string;
274
- readonly sessionId?: string;
252
+ export interface ClientSessionState {
253
+ readonly sessionId: string;
275
254
  readonly streamIndex: number;
276
255
  }
277
256
  /**
@@ -281,5 +260,5 @@ export interface SessionSnapshot {
281
260
  /** Events from the start of the session through the durable tail observed when the read opened. */
282
261
  readonly events: readonly MessageStreamEvent[];
283
262
  /** Session cursor advanced exactly past {@link events}. */
284
- readonly session: SessionState;
263
+ readonly session: ClientSessionState;
285
264
  }
@@ -11,13 +11,13 @@ declare const EXTENSION_CAPABILITY_CONTRACTS: {
11
11
  readonly dropped: {};
12
12
  };
13
13
  readonly tool: {
14
- readonly current: 6;
15
- readonly supported: readonly [1, 2, 3, 4, 5, 6];
14
+ readonly current: 7;
15
+ readonly supported: readonly [1, 2, 3, 4, 5, 6, 7];
16
16
  readonly dropped: {};
17
17
  };
18
18
  readonly dynamicTool: {
19
- readonly current: 9;
20
- readonly supported: readonly [1, 2, 3, 4, 5, 6, 7, 8, 9];
19
+ readonly current: 10;
20
+ readonly supported: readonly [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
21
21
  readonly dropped: {};
22
22
  };
23
23
  readonly connection: {
@@ -26,8 +26,8 @@ declare const EXTENSION_CAPABILITY_CONTRACTS: {
26
26
  readonly dropped: {};
27
27
  };
28
28
  readonly hook: {
29
- readonly current: 7;
30
- readonly supported: readonly [1, 2, 3, 4, 5, 6, 7];
29
+ readonly current: 8;
30
+ readonly supported: readonly [1, 2, 3, 4, 5, 6, 7, 8];
31
31
  readonly dropped: {};
32
32
  };
33
33
  readonly skill: {
@@ -36,8 +36,8 @@ declare const EXTENSION_CAPABILITY_CONTRACTS: {
36
36
  readonly dropped: {};
37
37
  };
38
38
  readonly dynamicSkill: {
39
- readonly current: 6;
40
- readonly supported: readonly [1, 2, 3, 4, 5, 6];
39
+ readonly current: 7;
40
+ readonly supported: readonly [1, 2, 3, 4, 5, 6, 7];
41
41
  readonly dropped: {};
42
42
  };
43
43
  readonly instructions: {
@@ -46,8 +46,8 @@ declare const EXTENSION_CAPABILITY_CONTRACTS: {
46
46
  readonly dropped: {};
47
47
  };
48
48
  readonly dynamicInstructions: {
49
- readonly current: 6;
50
- readonly supported: readonly [1, 2, 3, 4, 5, 6];
49
+ readonly current: 7;
50
+ readonly supported: readonly [1, 2, 3, 4, 5, 6, 7];
51
51
  readonly dropped: {};
52
52
  };
53
53
  readonly config: {
@@ -1 +1 @@
1
- import{readFile,writeFile}from"node:fs/promises";import{z}from"#compiled/zod/index.js";import{join}from"node:path";import{formatValidationError}from"#runtime/validation.js";const EXTENSION_COMPATIBILITY_MANIFEST_KIND=`eve-extension`,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION=1,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME=`_manifest.json`,EXTENSION_CAPABILITY_CONTRACTS={extension:{current:1,supported:[1],dropped:{}},tool:{current:6,supported:[1,2,3,4,5,6],dropped:{}},dynamicTool:{current:9,supported:[1,2,3,4,5,6,7,8,9],dropped:{}},connection:{current:2,supported:[1,2],dropped:{}},hook:{current:7,supported:[1,2,3,4,5,6,7],dropped:{}},skill:{current:1,supported:[1],dropped:{}},dynamicSkill:{current:6,supported:[1,2,3,4,5,6],dropped:{}},instructions:{current:1,supported:[1],dropped:{}},dynamicInstructions:{current:6,supported:[1,2,3,4,5,6],dropped:{}},config:{current:1,supported:[1],dropped:{}},state:{current:2,supported:[1,2],dropped:{}}},EXTENSION_CAPABILITY_VERSIONS=Object.fromEntries(Object.entries(EXTENSION_CAPABILITY_CONTRACTS).map(([e,t])=>[e,t.current])),EXTENSION_CAPABILITY_SUPPORT=Object.keys(EXTENSION_CAPABILITY_CONTRACTS).reduce((e,t)=>(e[t]=EXTENSION_CAPABILITY_CONTRACTS[t].supported,e),{}),extensionCompatibilityManifestSchema=z.object({kind:z.literal(EXTENSION_COMPATIBILITY_MANIFEST_KIND),formatVersion:z.literal(1),builtWithEve:z.string().min(1),requires:z.record(z.string(),z.number().int().positive())}).strict();function serializeExtensionCompatibilityManifest(e){return`${JSON.stringify(e,null,2)}\n`}function parseExtensionCompatibilityManifest(e,t){let n;try{n=JSON.parse(e)}catch(e){throw Error(`Extension compatibility manifest "${t}" is not valid JSON: ${e instanceof Error?e.message:String(e)}`)}let r=extensionCompatibilityManifestSchema.safeParse(n);if(!r.success)throw Error(`Extension compatibility manifest "${t}" is invalid. ${formatValidationError(r.error)}`);return r.data}async function readExtensionCompatibilityManifest(t){return parseExtensionCompatibilityManifest(await readFile(t,`utf8`),t)}async function writeExtensionCompatibilityManifest(e,n){await writeFile(join(e,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME),serializeExtensionCompatibilityManifest(n),`utf8`)}function findUnsupportedExtensionCapabilities(e,t=EXTENSION_CAPABILITY_SUPPORT){return Object.entries(e.requires).flatMap(([e,n])=>{let r=Object.hasOwn(t,e)?t[e]??[]:[];return r.includes(n)?[]:[{capability:e,requiredVersion:n,supportedVersions:r}]}).sort((e,t)=>e.capability.localeCompare(t.capability))}export{EXTENSION_CAPABILITY_SUPPORT,EXTENSION_CAPABILITY_VERSIONS,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION,EXTENSION_COMPATIBILITY_MANIFEST_KIND,findUnsupportedExtensionCapabilities,parseExtensionCompatibilityManifest,readExtensionCompatibilityManifest,serializeExtensionCompatibilityManifest,writeExtensionCompatibilityManifest};
1
+ import{readFile,writeFile}from"node:fs/promises";import{z}from"#compiled/zod/index.js";import{join}from"node:path";import{formatValidationError}from"#runtime/validation.js";const EXTENSION_COMPATIBILITY_MANIFEST_KIND=`eve-extension`,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION=1,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME=`_manifest.json`,EXTENSION_CAPABILITY_CONTRACTS={extension:{current:1,supported:[1],dropped:{}},tool:{current:7,supported:[1,2,3,4,5,6,7],dropped:{}},dynamicTool:{current:10,supported:[1,2,3,4,5,6,7,8,9,10],dropped:{}},connection:{current:2,supported:[1,2],dropped:{}},hook:{current:8,supported:[1,2,3,4,5,6,7,8],dropped:{}},skill:{current:1,supported:[1],dropped:{}},dynamicSkill:{current:7,supported:[1,2,3,4,5,6,7],dropped:{}},instructions:{current:1,supported:[1],dropped:{}},dynamicInstructions:{current:7,supported:[1,2,3,4,5,6,7],dropped:{}},config:{current:1,supported:[1],dropped:{}},state:{current:2,supported:[1,2],dropped:{}}},EXTENSION_CAPABILITY_VERSIONS=Object.fromEntries(Object.entries(EXTENSION_CAPABILITY_CONTRACTS).map(([e,t])=>[e,t.current])),EXTENSION_CAPABILITY_SUPPORT=Object.keys(EXTENSION_CAPABILITY_CONTRACTS).reduce((e,t)=>(e[t]=EXTENSION_CAPABILITY_CONTRACTS[t].supported,e),{}),extensionCompatibilityManifestSchema=z.object({kind:z.literal(EXTENSION_COMPATIBILITY_MANIFEST_KIND),formatVersion:z.literal(1),builtWithEve:z.string().min(1),requires:z.record(z.string(),z.number().int().positive())}).strict();function serializeExtensionCompatibilityManifest(e){return`${JSON.stringify(e,null,2)}\n`}function parseExtensionCompatibilityManifest(e,t){let n;try{n=JSON.parse(e)}catch(e){throw Error(`Extension compatibility manifest "${t}" is not valid JSON: ${e instanceof Error?e.message:String(e)}`)}let r=extensionCompatibilityManifestSchema.safeParse(n);if(!r.success)throw Error(`Extension compatibility manifest "${t}" is invalid. ${formatValidationError(r.error)}`);return r.data}async function readExtensionCompatibilityManifest(t){return parseExtensionCompatibilityManifest(await readFile(t,`utf8`),t)}async function writeExtensionCompatibilityManifest(e,n){await writeFile(join(e,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME),serializeExtensionCompatibilityManifest(n),`utf8`)}function findUnsupportedExtensionCapabilities(e,t=EXTENSION_CAPABILITY_SUPPORT){return Object.entries(e.requires).flatMap(([e,n])=>{let r=Object.hasOwn(t,e)?t[e]??[]:[];return r.includes(n)?[]:[{capability:e,requiredVersion:n,supportedVersions:r}]}).sort((e,t)=>e.capability.localeCompare(t.capability))}export{EXTENSION_CAPABILITY_SUPPORT,EXTENSION_CAPABILITY_VERSIONS,EXTENSION_COMPATIBILITY_MANIFEST_FILENAME,EXTENSION_COMPATIBILITY_MANIFEST_FORMAT_VERSION,EXTENSION_COMPATIBILITY_MANIFEST_KIND,findUnsupportedExtensionCapabilities,parseExtensionCompatibilityManifest,readExtensionCompatibilityManifest,serializeExtensionCompatibilityManifest,writeExtensionCompatibilityManifest};
@@ -1 +1 @@
1
- import{expectBoolean,expectFunction,expectObjectRecord,expectOnlyKnownKeys,expectString}from"#internal/authored-module.js";import{EVE_CREATE_SESSION_ROUTE_PATH}from"#protocol/routes.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{serializeOutputSchema}from"#shared/tool-schema.js";import{createCompiledSubagentNodeId}from"#compiler/manifest.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";import{isDynamicSentinel}from"#shared/dynamic-tool-definition.js";import{createPathDerivedSourceId}from"#discover/manifest.js";const ALLOWED_DYNAMIC_SUBAGENT_EVENTS=new Set([`session.started`,`turn.started`]);async function compileSubagentGraph(e){let t=[],n=[],r=[];for(let i of e.subagents){let a=await compileSubagentDefinition({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,externalDependencies:e.externalDependencies,parentNodeId:e.parentNodeId,source:i});if(a.kind===`remote`){r.push(a.node);continue}t.push(a.node,...a.descendants.nodes),n.push({childNodeId:a.node.nodeId,parentNodeId:e.parentNodeId},...a.descendants.edges)}return{edges:n,nodes:t,remoteAgents:r}}async function compileSubagentDefinition(e){let t=e.source.manifest.configModule;if(t===void 0)throw Error(`Subagent "${e.source.logicalPath}" is missing an agent config module.`);let n=createSubagentConfigModuleSourceRef(e.source,t),r=await loadModuleBackedDefinition({agentRoot:e.source.manifest.agentRoot,displayPath:n.logicalPath,externalDependencies:e.externalDependencies,kind:`subagent config`,source:t}),i=normalizeDynamicSubagentDefinition(r,`Expected the dynamic subagent config export "${t.exportName??`default`}" from "${n.logicalPath}" to match the public eve shape.`);if(i===void 0&&readAgentDefinitionKind(r)===`remote`)return{kind:`remote`,node:compileRemoteAgent({source:e.source,value:r})};let a=r;if(i!==void 0){let e={model:DEFAULT_AGENT_MODEL_ID};i.build!==void 0&&(e.build=i.build),a=e}return{kind:`local`,...await compileLocalSubagent({...e,agentConfigDefinition:a,dynamic:i?.definition})}}async function compileSubagent(e){let t=createCompiledSubagentNodeId(e.parentNodeId,e.source.sourceId),n=e.source.subagentId,r=await e.compileAgentNodeManifest({...e.source.manifest,appRoot:e.appRoot},e.context,{agentConfigDefinition:e.agentConfigDefinition,allowWorkflowConfig:!1,externalDependencies:e.externalDependencies}),i=r.config.description,a;if(e.dynamic!==void 0)a={dynamic:e.dynamic};else{if(!i)throw Error(`Local subagent "${e.source.logicalPath}" is missing a "description" field on its agent config. Add \`description\` to \`defineAgent({ ... })\` so the parent agent can decide when to delegate to this subagent.`);a={description:i}}let o=await compileSubagentGraph({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,externalDependencies:r.config.build?.externalDependencies,parentNodeId:t,subagents:e.source.manifest.subagents});return{descendants:o,node:{agent:{...r,remoteAgents:[...o.remoteAgents]},...a,entryPath:e.source.entryPath,logicalPath:e.source.logicalPath,name:n,nodeId:t,rootPath:e.source.rootPath,sourceId:e.source.sourceId,sourceKind:`module`}}}const compileLocalSubagent=compileSubagent;function compileRemoteAgent(e){let t=e.source.manifest.configModule;if(t===void 0)throw Error(`Remote agent "${e.source.logicalPath}" is missing a config module.`);assertRemoteAgentDefinitionHasNoLocalPackageEntries(e.source);let n=createSubagentConfigModuleSourceRef(e.source,t),r=normalizeRemoteAgentDefinition(e.value,`Expected the remote agent config export "${t.exportName??`default`}" from "${n.logicalPath}" to match the public eve shape.`),i={...n,description:r.description,entryPath:e.source.entryPath,name:e.source.subagentId,nodeId:e.source.sourceId,outputSchema:r.outputSchema,path:r.path,rootPath:e.source.rootPath};return r.url===void 0?i:{...i,url:r.url}}function normalizeDynamicSubagentDefinition(e,i){if(!isDynamicSentinel(e))return;let a=expectObjectRecord(e,i);if(Object.hasOwn(a,`fallback`))throw Error(`${i} Dynamic subagent definitions do not support "fallback". Return defineAgent(...) or defineRemoteAgent(...) from an event handler instead.`);expectOnlyKnownKeys(a,[`build`,`events`,`kind`],i);let s=a.build===void 0?void 0:normalizeAgentDefinition({build:a.build,model:DEFAULT_AGENT_MODEL_ID},i).build,c=expectObjectRecord(a.events,i),l=[];for(let[e,n]of Object.entries(c)){if(!ALLOWED_DYNAMIC_SUBAGENT_EVENTS.has(e))throw Error(`${i} Dynamic subagents support only "session.started" and "turn.started" handlers.`);expectFunction(n,i),l.push(e)}let u={definition:{eventNames:l}};return s!==void 0&&(u.build=s),u}function createSubagentConfigModuleSourceRef(e,t){let n=e.logicalPath===t.logicalPath?t.logicalPath:`${e.logicalPath}/${t.logicalPath}`,r={logicalPath:n,sourceId:createPathDerivedSourceId(n),sourceKind:`module`};return t.exportName!==void 0&&(r.exportName=t.exportName),r}function readAgentDefinitionKind(e){return typeof e!=`object`||!e?`local`:e.kind===`remote`?`remote`:`local`}function normalizeRemoteAgentDefinition(t,o){let c=expectObjectRecord(t,o);if(expectOnlyKnownKeys(c,[`auth`,`description`,`forwardPrincipal`,`headers`,`kind`,`outputSchema`,`path`,`url`],o),c.kind!==`remote`)throw Error(`${o} Expected "kind" to be "remote".`);return c.forwardPrincipal!==void 0&&expectBoolean(c.forwardPrincipal,`${o} Expected "forwardPrincipal" to be a boolean.`),{description:expectString(c.description,o),outputSchema:serializeOutputSchema(c.outputSchema),path:c.path===void 0?EVE_CREATE_SESSION_ROUTE_PATH:expectString(c.path,o),url:typeof c.url==`function`?void 0:expectString(c.url,o)}}function assertRemoteAgentDefinitionHasNoLocalPackageEntries(e){let t=e.manifest,n=[t.connections.length>0?`connections/`:void 0,t.hooks.length>0?`hooks/`:void 0,t.instructions.length>0?`instructions`:void 0,t.lib.length>0?`lib/`:void 0,t.sandbox===null?void 0:`sandbox/`,t.sandboxWorkspaces.length>0?`sandbox/workspace/`:void 0,t.schedules.length>0?`schedules/`:void 0,t.skills.length>0?`skills/`:void 0,t.subagents.length>0?`subagents/`:void 0,t.tools.length>0?`tools/`:void 0].filter(e=>e!==void 0);if(n.length!==0)throw Error(`Remote subagent definition "${e.logicalPath}" cannot include local package entries. Remove unsupported entries: ${n.join(`, `)}.`)}export{compileSubagentGraph};
1
+ import{expectBoolean,expectFunction,expectObjectRecord,expectOnlyKnownKeys,expectString}from"#internal/authored-module.js";import{EVE_SESSION_ROUTE_PATH}from"#protocol/routes.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{serializeOutputSchema}from"#shared/tool-schema.js";import{createCompiledSubagentNodeId}from"#compiler/manifest.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";import{isDynamicSentinel}from"#shared/dynamic-tool-definition.js";import{createPathDerivedSourceId}from"#discover/manifest.js";const ALLOWED_DYNAMIC_SUBAGENT_EVENTS=new Set([`session.started`,`turn.started`]);async function compileSubagentGraph(e){let t=[],n=[],r=[];for(let i of e.subagents){let a=await compileSubagentDefinition({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,externalDependencies:e.externalDependencies,parentNodeId:e.parentNodeId,source:i});if(a.kind===`remote`){r.push(a.node);continue}t.push(a.node,...a.descendants.nodes),n.push({childNodeId:a.node.nodeId,parentNodeId:e.parentNodeId},...a.descendants.edges)}return{edges:n,nodes:t,remoteAgents:r}}async function compileSubagentDefinition(e){let t=e.source.manifest.configModule;if(t===void 0)throw Error(`Subagent "${e.source.logicalPath}" is missing an agent config module.`);let n=createSubagentConfigModuleSourceRef(e.source,t),r=await loadModuleBackedDefinition({agentRoot:e.source.manifest.agentRoot,displayPath:n.logicalPath,externalDependencies:e.externalDependencies,kind:`subagent config`,source:t}),i=normalizeDynamicSubagentDefinition(r,`Expected the dynamic subagent config export "${t.exportName??`default`}" from "${n.logicalPath}" to match the public eve shape.`);if(i===void 0&&readAgentDefinitionKind(r)===`remote`)return{kind:`remote`,node:compileRemoteAgent({source:e.source,value:r})};let a=r;if(i!==void 0){let e={model:DEFAULT_AGENT_MODEL_ID};i.build!==void 0&&(e.build=i.build),a=e}return{kind:`local`,...await compileLocalSubagent({...e,agentConfigDefinition:a,dynamic:i?.definition})}}async function compileSubagent(e){let t=createCompiledSubagentNodeId(e.parentNodeId,e.source.sourceId),n=e.source.subagentId,r=await e.compileAgentNodeManifest({...e.source.manifest,appRoot:e.appRoot},e.context,{agentConfigDefinition:e.agentConfigDefinition,allowWorkflowConfig:!1,externalDependencies:e.externalDependencies}),i=r.config.description,a;if(e.dynamic!==void 0)a={dynamic:e.dynamic};else{if(!i)throw Error(`Local subagent "${e.source.logicalPath}" is missing a "description" field on its agent config. Add \`description\` to \`defineAgent({ ... })\` so the parent agent can decide when to delegate to this subagent.`);a={description:i}}let o=await compileSubagentGraph({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,externalDependencies:r.config.build?.externalDependencies,parentNodeId:t,subagents:e.source.manifest.subagents});return{descendants:o,node:{agent:{...r,remoteAgents:[...o.remoteAgents]},...a,entryPath:e.source.entryPath,logicalPath:e.source.logicalPath,name:n,nodeId:t,rootPath:e.source.rootPath,sourceId:e.source.sourceId,sourceKind:`module`}}}const compileLocalSubagent=compileSubagent;function compileRemoteAgent(e){let t=e.source.manifest.configModule;if(t===void 0)throw Error(`Remote agent "${e.source.logicalPath}" is missing a config module.`);assertRemoteAgentDefinitionHasNoLocalPackageEntries(e.source);let n=createSubagentConfigModuleSourceRef(e.source,t),r=normalizeRemoteAgentDefinition(e.value,`Expected the remote agent config export "${t.exportName??`default`}" from "${n.logicalPath}" to match the public eve shape.`),i={...n,description:r.description,entryPath:e.source.entryPath,name:e.source.subagentId,nodeId:e.source.sourceId,outputSchema:r.outputSchema,path:r.path,rootPath:e.source.rootPath};return r.url===void 0?i:{...i,url:r.url}}function normalizeDynamicSubagentDefinition(e,i){if(!isDynamicSentinel(e))return;let a=expectObjectRecord(e,i);if(Object.hasOwn(a,`fallback`))throw Error(`${i} Dynamic subagent definitions do not support "fallback". Return defineAgent(...) or defineRemoteAgent(...) from an event handler instead.`);expectOnlyKnownKeys(a,[`build`,`events`,`kind`],i);let s=a.build===void 0?void 0:normalizeAgentDefinition({build:a.build,model:DEFAULT_AGENT_MODEL_ID},i).build,c=expectObjectRecord(a.events,i),l=[];for(let[e,n]of Object.entries(c)){if(!ALLOWED_DYNAMIC_SUBAGENT_EVENTS.has(e))throw Error(`${i} Dynamic subagents support only "session.started" and "turn.started" handlers.`);expectFunction(n,i),l.push(e)}let u={definition:{eventNames:l}};return s!==void 0&&(u.build=s),u}function createSubagentConfigModuleSourceRef(e,t){let n=e.logicalPath===t.logicalPath?t.logicalPath:`${e.logicalPath}/${t.logicalPath}`,r={logicalPath:n,sourceId:createPathDerivedSourceId(n),sourceKind:`module`};return t.exportName!==void 0&&(r.exportName=t.exportName),r}function readAgentDefinitionKind(e){return typeof e!=`object`||!e?`local`:e.kind===`remote`?`remote`:`local`}function normalizeRemoteAgentDefinition(t,o){let c=expectObjectRecord(t,o);if(expectOnlyKnownKeys(c,[`auth`,`description`,`forwardPrincipal`,`headers`,`kind`,`outputSchema`,`path`,`url`],o),c.kind!==`remote`)throw Error(`${o} Expected "kind" to be "remote".`);return c.forwardPrincipal!==void 0&&expectBoolean(c.forwardPrincipal,`${o} Expected "forwardPrincipal" to be a boolean.`),{description:expectString(c.description,o),outputSchema:serializeOutputSchema(c.outputSchema),path:c.path===void 0?EVE_SESSION_ROUTE_PATH:expectString(c.path,o),url:typeof c.url==`function`?void 0:expectString(c.url,o)}}function assertRemoteAgentDefinitionHasNoLocalPackageEntries(e){let t=e.manifest,n=[t.connections.length>0?`connections/`:void 0,t.hooks.length>0?`hooks/`:void 0,t.instructions.length>0?`instructions`:void 0,t.lib.length>0?`lib/`:void 0,t.sandbox===null?void 0:`sandbox/`,t.sandboxWorkspaces.length>0?`sandbox/workspace/`:void 0,t.schedules.length>0?`schedules/`:void 0,t.skills.length>0?`skills/`:void 0,t.subagents.length>0?`subagents/`:void 0,t.tools.length>0?`tools/`:void 0].filter(e=>e!==void 0);if(n.length!==0)throw Error(`Remote subagent definition "${e.logicalPath}" cannot include local package entries. Remove unsupported entries: ${n.join(`, `)}.`)}export{compileSubagentGraph};
@@ -1 +1 @@
1
- import{resolveDevelopmentClientOptions}from"#services/dev-client/client-options.js";import{resolveVerifiedRemoteDevelopmentClient}from"#setup/verified-remote-client.js";import{Client}from"#client/client.js";function resolveEvalClientOptions(t){if(t.kind===`local`)return{host:t.url};let n={...resolveDevelopmentClientOptions(t.url),preserveCompletedSessions:!1},r=process.env.EVE_EVAL_AUTH_TOKEN?.trim();return r?{...n,auth:{bearer:r},redirect:`manual`}:n}async function createEvalClient(e,r={}){let i=resolveEvalClientOptions(e);if(e.kind===`local`||i.auth!==void 0||r.workspaceRoot===void 0)return new Client(i);let{options:a}=await resolveVerifiedRemoteDevelopmentClient({serverUrl:e.url,workspaceRoot:r.workspaceRoot,deps:r.deps});return new Client({...i,...a})}export{createEvalClient,resolveEvalClientOptions};
1
+ import{resolveDevelopmentClientOptions}from"#services/dev-client/client-options.js";import{resolveVerifiedRemoteDevelopmentClient}from"#setup/verified-remote-client.js";import{Client}from"#client/client.js";function resolveEvalClientOptions(t){if(t.kind===`local`)return{host:t.url};let n=resolveDevelopmentClientOptions(t.url),r=process.env.EVE_EVAL_AUTH_TOKEN?.trim();return r?{...n,auth:{bearer:r},redirect:`manual`}:n}async function createEvalClient(e,r={}){let i=resolveEvalClientOptions(e);if(e.kind===`local`||i.auth!==void 0||r.workspaceRoot===void 0)return new Client(i);let{options:a}=await resolveVerifiedRemoteDevelopmentClient({serverUrl:e.url,workspaceRoot:r.workspaceRoot,deps:r.deps});return new Client({...i,...a})}export{createEvalClient,resolveEvalClientOptions};
@@ -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},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:()=>evaluateAssertion(i,t)}))throw new EvalRequirementFailed;return t}function recordCheck(e,t,n){return e.recordValue({name:n.name,severity:n.severity,threshold:n.threshold,score:()=>evaluateAssertion(n,t)})}async function evaluateAssertion(e,t){return e.evaluate===void 0?{score:await e.score(t)}:await e.evaluate(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,t)=>primary().respond(e,t),respondAll:e=>primary().respondAll(e),send:(e,t)=>(a=typeof e==`string`?e:``,primary().send(e,t)),start:(e,t)=>(a=e,primary().start(e,t)),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:()=>evaluateAssertion(i,t)}))throw new EvalRequirementFailed;return t}function recordCheck(e,t,n){return e.recordValue({name:n.name,severity:n.severity,threshold:n.threshold,score:()=>evaluateAssertion(n,t)})}async function evaluateAssertion(e,t){return e.evaluate===void 0?{score:await e.score(t)}:await e.evaluate(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,6 +1,6 @@
1
1
  import type { Client } from "#client/client.js";
2
2
  import type { ClientSession } from "#client/session.js";
3
- import type { CancelSessionResult, SendTurnInput, SessionState } from "#client/types.js";
3
+ import type { CancelSessionResult, ClientSessionState, SendTurnInput, SendTurnOptions } from "#client/types.js";
4
4
  import type { MessageStreamEvent, 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";
@@ -19,21 +19,22 @@ export interface EvalSessionDriver extends EveEvalAssertions, EveEvalOutputAsser
19
19
  export declare class EvalSessionDriver implements EveEvalSession {
20
20
  #private;
21
21
  constructor(input: {
22
+ readonly client: Client;
22
23
  readonly collector: AssertionCollector;
23
- readonly session: ClientSession;
24
+ readonly session?: ClientSession;
24
25
  readonly signal?: AbortSignal;
25
26
  });
26
27
  get events(): readonly MessageStreamEvent[];
27
28
  get lastTurn(): EveEvalTurn | undefined;
28
29
  get pendingInputRequests(): readonly InputRequest[];
29
30
  get sessionId(): string | undefined;
30
- get state(): SessionState;
31
+ get state(): ClientSessionState | undefined;
31
32
  cancel(): Promise<CancelSessionResult>;
32
33
  requireInputRequest(filter?: EveEvalInputRequestMatchOptions): InputRequest;
33
- respond(...responses: InputResponse[]): Promise<EveEvalTurn>;
34
+ respond(responses: readonly InputResponse[], options?: SendTurnOptions): Promise<EveEvalTurn>;
34
35
  respondAll(optionId: string): Promise<EveEvalTurn>;
35
- send(input: SendTurnInput): Promise<EveEvalTurn>;
36
- start(input: SendTurnInput): Promise<EveEvalLiveTurn>;
36
+ send(message: SendTurnInput["message"], options?: SendTurnOptions): Promise<EveEvalTurn>;
37
+ start(message: string, options?: SendTurnOptions): Promise<EveEvalLiveTurn>;
37
38
  sendFile(text: string, filePath: string, mediaType?: string): Promise<EveEvalTurn>;
38
39
  readTurn(options?: {
39
40
  readonly startIndex?: number;
@@ -1 +1 @@
1
- import{readFile}from"node:fs/promises";import{basename,extname}from"node:path";import{isCurrentTurnBoundaryEvent,isTurnFailureEvent}from"#protocol/message.js";import{summarizeTurnEvents}from"#client/session-utils.js";import{createTextWithFileContent}from"#client/file-parts.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(n,r,i){let a=createTextWithFileContent({bytes:await readFile(r),filename:basename(r),mediaType:i??inferMediaType(r),text:n});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){let n=summarizeTurnEvents(t);return this.#o({data:extractCompletedResult(t),events:t,inputRequests:n.inputRequests,message:n.message,sessionId:e,status:n.status})}#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
+ import{readFile}from"node:fs/promises";import{basename,extname}from"node:path";import{isCurrentTurnBoundaryEvent,isTurnFailureEvent}from"#protocol/message.js";import{summarizeTurnEvents}from"#client/session-utils.js";import{createTextWithFileContent}from"#client/file-parts.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;#o=[];constructor(e){this.#e=e.client,this.#r=e.collector,this.#t=e.session,this.#n=e.signal,Object.assign(this,createScopedAssertions(this.#r,{timing:`snapshot`,select:()=>this.#u()}),createOutputAssertions(this.#r,{timing:`snapshot`,select:()=>this.#u()}))}get events(){return this.#i}get lastTurn(){return this.#a}get pendingInputRequests(){return this.#o}get sessionId(){return this.#t?.state.sessionId??this.#a?.sessionId}get state(){return this.#t?.state}async cancel(){if(this.#t===void 0)throw Error(`Eval session has not started.`);return await this.#t.cancel()}requireInputRequest(e={}){this.#o.length===0&&this.#d(`requireInputRequest`,`expected one pending input request, but the last turn did not park`);let t=this.#o.filter(t=>inputRequestMatches(t,e));return(this.#o.length!==1||t.length!==1)&&this.#d(`requireInputRequest`,`expected exactly one pending input request matching ${formatInputRequestFilter(e)}, found ${t.length} match(es) across ${this.#o.length} pending request(s)`),this.#r.recordOutcome({name:`requireInputRequest`,outcome:{score:1}}),t[0]}async respond(e,t={}){if(e.length===0)throw Error(`respond() requires at least one input response.`);return await(await this.#s({...t,inputResponses:e})).result()}async respondAll(e){let t=this.#o;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,t={}){return await(await this.#s({...t,message:e})).result()}async start(e,t={}){return await this.#s({...t,message:e})}async#s(e){let t=attachSignal(e,this.#n),n;if(this.#t===void 0){if(t.message===void 0)throw Error(`Eval session has not started.`);let e=await this.#e.sessions.create({...t,message:t.message});this.#t=e.session,n=e.response}else{let{inputResponses:e,message:r,...i}=t;n=e===void 0?await this.#t.send(r,i):await this.#t.respond(e,i)}return new EvalLiveTurn({events:n,record:e=>this.#l(n.sessionId,e),session:this,sessionId:n.sessionId})}async sendFile(n,r,i){let a=createTextWithFileContent({bytes:await readFile(r),filename:basename(r),mediaType:i??inferMediaType(r),text:n});return await this.send(a)}async readTurn(e){let t=this.sessionId;return await this.watchTurn(e,requireSessionId(t)).result()}watchTurn(e,t=requireSessionId(this.sessionId)){if(this.#t===void 0)throw Error(`Eval session has not started.`);return new EvalLiveTurn({events:this.#t.stream({signal:this.#n,startIndex:e?.startIndex}),record:e=>this.#l(t,e),session:this,sessionId:t})}snapshot(e){let t=this.sessionId;return{derived:deriveRunFacts(this.#i,{sessionId:t}),events:[...this.#i],primary:e,sessionId:t,state:this.#t?.state}}#c(e){this.#i.push(...e.events),this.#o=e.status===`waiting`?e.inputRequests:[];let t=deriveRunFacts(e.events,{sessionId:e.sessionId}),n=new EvalTurn({collector:this.#r,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.#a=n,n}#l(e,t){let n=summarizeTurnEvents(t);return this.#c({data:extractCompletedResult(t),events:t,inputRequests:n.inputRequests,message:n.message,sessionId:e,status:n.status})}#u(){let e=this.sessionId;return{derived:deriveRunFacts(this.#i,{sessionId:e}),events:[...this.#i],output:outputOf(this.#a),status:this.#a?.status??`completed`}}#d(e,t){throw this.#r.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({client:this.#e,collector:this.#n,signal:this.#t});return this.#r.push(e),e}#o(e,t){let n=new EvalSessionDriver({client:this.#e,collector:this.#n,session:this.#e.sessions.attach(e,{streamIndex:t?.startIndex??0}),signal:this.#t});return this.#r.push(n),n}};function attachSignal(e,t){return t===void 0?e:e.signal===void 0?{...e,signal:t}:e}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,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 { RuntimeIdentity, MessageStreamEvent } from "#protocol/message.js";
4
- import type { CancelSessionResult, SendTurnInput, SessionState } from "#client/types.js";
4
+ import type { CancelSessionResult, ClientSessionState, SendTurnInput, SendTurnOptions } 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";
@@ -73,7 +73,7 @@ export interface EveEvalSessionResult {
73
73
  readonly events: readonly MessageStreamEvent[];
74
74
  readonly primary: boolean;
75
75
  readonly sessionId?: string;
76
- readonly state: SessionState;
76
+ readonly state: ClientSessionState | undefined;
77
77
  }
78
78
  /**
79
79
  * Full result of executing one eval against an eve agent.
@@ -238,7 +238,7 @@ export interface EveEvalSessionDriver {
238
238
  /** Input requests left pending by the last parked turn. */
239
239
  readonly pendingInputRequests: readonly InputRequest[];
240
240
  /** Serializable cursor for resuming this session. */
241
- readonly state: SessionState;
241
+ readonly state: ClientSessionState | undefined;
242
242
  /** eve session id after the first successful send. */
243
243
  readonly sessionId: string | undefined;
244
244
  /** Request cooperative cancellation of this session's active turn. */
@@ -246,13 +246,13 @@ export interface EveEvalSessionDriver {
246
246
  /** Require exactly one pending input request matching `filter`, or abort dependent control flow. */
247
247
  requireInputRequest(filter?: EveEvalInputRequestMatchOptions): InputRequest;
248
248
  /** Resolve specific pending requests and run the resumed turn. */
249
- respond(...responses: InputResponse[]): Promise<EveEvalTurn>;
249
+ respond(responses: readonly InputResponse[], options?: SendTurnOptions): Promise<EveEvalTurn>;
250
250
  /** Resolve every pending request with the same option id. */
251
251
  respondAll(optionId: string): Promise<EveEvalTurn>;
252
252
  /** Send one turn through this session. */
253
- send(input: SendTurnInput): Promise<EveEvalTurn>;
254
- /** Start one turn and return as soon as its session is accepted. */
255
- start(input: SendTurnInput): Promise<EveEvalLiveTurn>;
253
+ send(message: SendTurnInput["message"], options?: SendTurnOptions): Promise<EveEvalTurn>;
254
+ /** Start one text turn and return as soon as its session is accepted. */
255
+ start(message: string, options?: SendTurnOptions): Promise<EveEvalLiveTurn>;
256
256
  /** Send one text turn with a local file attached as a data URL. */
257
257
  sendFile(text: string, filePath: string, mediaType?: string): Promise<EveEvalTurn>;
258
258
  }
@@ -376,8 +376,8 @@ export interface EveEvalTargetHandle extends EveEvalTarget {
376
376
  * Attach to a pre-existing session and consume one turn boundary.
377
377
  *
378
378
  * When that boundary is `session.waiting`, the attached session recovers
379
- * the current continuation token from the stream, so `session.send(...)`
380
- * and `session.respond(...)` continue the same durable session.
379
+ * the exact session ID, so `session.send(...)` and `session.respond(...)`
380
+ * continue the same durable session.
381
381
  */
382
382
  attachSession(sessionId: string, opts?: {
383
383
  readonly startIndex?: number;
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{isRuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{createEveCallbackRoutePath}from"#protocol/routes.js";import{continueRemoteAgentSession,isRetryableRemoteAgentContinueError,resolveRemoteAgentForAction}from"#execution/remote-agent-dispatch.js";import{AGENT_BUSY,AGENT_MISMATCH,AGENT_UNREACHABLE}from"#harness/agent-handle-errors.js";import{deriveAgentOperationId}from"#harness/handles/operation-id.js";import{prepareAgentContinuation,rejectAgentEffect}from"#harness/handles/transitions.js";import{normalizeRequestedOutputSchema}from"#execution/subagent-invocation.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{createWorkflowCallbackUrl}from"#execution/workflow-callback-url.js";import{err,ok}from"#shared/result.js";const log=createLogger(`execution.agent-handle-dispatch`);function isAgentHandleAction(e){return e.kind===`subagent-call`||e.kind===`remote-agent-call`}async function dispatchToAgentHandle(e){let{action:n,agentId:r,bundle:i}=e,a=n.kind===`remote-agent-call`?n.remoteAgentName:n.subagentName,o={callId:n.callId,id:deriveAgentOperationId({callId:n.callId,parentSessionId:e.currentSession.sessionId,parentTurnId:e.parentTurnId}),kind:`continue`,parentTurnId:e.parentTurnId,previousStatus:``},f=prepareAgentContinuation(e.currentSession,{agentId:r,invokedName:a,operation:o});switch(f.kind){case`unknown`:return{kind:`error`,result:createAgentErrorResult({action:n,code:AGENT_UNREACHABLE,message:`Agent with id "${r}" is no longer reachable.`}),session:e.currentSession};case`mismatch`:return{kind:`error`,result:createAgentErrorResult({action:n,code:AGENT_MISMATCH,message:`Agent "${r}" from the <agents> list does not belong to "${a}".`}),session:e.currentSession};case`busy`:return{kind:`error`,result:createAgentErrorResult({action:n,code:AGENT_BUSY,message:`Agent "${r}" is still working on its previous request. Wait for its result before continuing it.`}),session:e.currentSession};case`ready`:break}let{handle:p}=f,m=await deliverToAgentHandle({action:n,bundle:i,handle:p,parentToken:e.parentToken});if(!m.ok){let{cause:e,permanent:i}=m.error;return logError(log,`agent delivery failed`,e,{agentId:r,callId:n.callId,nodeId:p.identity.nodeId,permanent:i,subagentName:p.identity.name}),{kind:`error`,result:createAgentErrorResult({action:n,code:AGENT_UNREACHABLE,message:i?`Agent "${p.identity.name}" with id "${r}" is no longer reachable.`:`Agent "${p.identity.name}" with id "${r}" is temporarily unreachable. Try again.`}),session:rejectAgentEffect(f.session,{disposition:i?`dead`:`retryable`,operationId:o.id})}}return{address:p.address,callId:n.callId,kind:`called`,name:n.name,session:f.session,toolName:p.identity.name}}async function deliverToAgentHandle(e){let{action:t,bundle:s,handle:c}=e,{address:l,identity:u}=c;if(l.kind===`agent/remote`){if(l.continuationToken===void 0)return err({cause:Error(`Remote agent "${u.name}" returned no continuationToken at start; its deployment does not support continuations.`),permanent:!0});let n;try{n=resolveRemoteAgentForAction({nodeId:u.nodeId,remoteAgentName:u.name,registry:s.subagentRegistry.subagentsByNodeId})}catch(e){return err({cause:e,permanent:!0})}try{await continueRemoteAgentSession({callback:{callId:t.callId,subagentName:u.name,token:e.parentToken,url:createWorkflowCallbackUrl(l.callbackBaseUrl,createEveCallbackRoutePath(e.parentToken))},continuationToken:l.continuationToken,message:readSubagentMessage(t),outputSchema:normalizeRequestedOutputSchema(t.input.outputSchema),remote:{...n,url:l.url},sessionId:l.sessionId})}catch(e){return err({cause:e,permanent:!isRetryableRemoteAgentContinueError(e)})}return ok(void 0)}let d=createWorkflowRuntime({compiledArtifactsSource:s.compiledArtifactsSource,nodeId:u.nodeId});try{if((await d.dispatchSession({command:{caller:{callId:t.callId,replyTo:{kind:`hook`,token:e.parentToken},subagentName:u.name},kind:`send`,payload:{message:readSubagentMessage(t),outputSchema:normalizeRequestedOutputSchema(t.input.outputSchema)}},sessionId:l.sessionId})).status===`session_not_active`)return err({cause:Error(`Agent session "${l.sessionId}" is no longer active.`),permanent:!0})}catch(e){return err({cause:e,permanent:isRuntimeNoActiveSessionError(e)})}return ok(void 0)}function createAgentErrorResult(e){return{callId:e.action.callId,isError:!0,kind:`subagent-result`,origin:`dispatch`,output:{code:e.code,message:e.message},subagentName:e.action.kind===`remote-agent-call`?e.action.remoteAgentName:e.action.subagentName}}function readSubagentMessage(e){return typeof e.input.message==`string`?e.input.message:``}export{dispatchToAgentHandle,isAgentHandleAction};
1
+ import{createLogger,logError}from"#internal/logging.js";import{isRuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{createEveCallbackRoutePath}from"#protocol/routes.js";import{continueRemoteAgentSession,isRetryableRemoteAgentContinueError,resolveRemoteAgentForAction}from"#execution/remote-agent-dispatch.js";import{AGENT_BUSY,AGENT_MISMATCH,AGENT_UNREACHABLE}from"#harness/agent-handle-errors.js";import{deriveAgentOperationId}from"#harness/handles/operation-id.js";import{prepareAgentContinuation,rejectAgentEffect}from"#harness/handles/transitions.js";import{normalizeRequestedOutputSchema}from"#execution/subagent-invocation.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{createWorkflowCallbackUrl}from"#execution/workflow-callback-url.js";import{err,ok}from"#shared/result.js";const log=createLogger(`execution.agent-handle-dispatch`);function isAgentHandleAction(e){return e.kind===`subagent-call`||e.kind===`remote-agent-call`}async function dispatchToAgentHandle(e){let{action:n,agentId:r,bundle:i}=e,a=n.kind===`remote-agent-call`?n.remoteAgentName:n.subagentName,o={callId:n.callId,id:deriveAgentOperationId({callId:n.callId,parentSessionId:e.currentSession.sessionId,parentTurnId:e.parentTurnId}),kind:`continue`,parentTurnId:e.parentTurnId,previousStatus:``},f=prepareAgentContinuation(e.currentSession,{agentId:r,invokedName:a,operation:o});switch(f.kind){case`unknown`:return{kind:`error`,result:createAgentErrorResult({action:n,code:AGENT_UNREACHABLE,message:`Agent with id "${r}" is no longer reachable.`}),session:e.currentSession};case`mismatch`:return{kind:`error`,result:createAgentErrorResult({action:n,code:AGENT_MISMATCH,message:`Agent "${r}" from the <agents> list does not belong to "${a}".`}),session:e.currentSession};case`busy`:return{kind:`error`,result:createAgentErrorResult({action:n,code:AGENT_BUSY,message:`Agent "${r}" is still working on its previous request. Wait for its result before continuing it.`}),session:e.currentSession};case`ready`:break}let{handle:p}=f,m=await deliverToAgentHandle({action:n,bundle:i,handle:p,parentToken:e.parentToken});if(!m.ok){let{cause:e,permanent:i}=m.error;return logError(log,`agent delivery failed`,e,{agentId:r,callId:n.callId,nodeId:p.identity.nodeId,permanent:i,subagentName:p.identity.name}),{kind:`error`,result:createAgentErrorResult({action:n,code:AGENT_UNREACHABLE,message:i?`Agent "${p.identity.name}" with id "${r}" is no longer reachable.`:`Agent "${p.identity.name}" with id "${r}" is temporarily unreachable. Try again.`}),session:rejectAgentEffect(f.session,{disposition:i?`dead`:`retryable`,operationId:o.id})}}return{address:p.address,callId:n.callId,kind:`called`,name:n.name,session:f.session,toolName:p.identity.name}}async function deliverToAgentHandle(e){let{action:t,bundle:s,handle:c}=e,{address:l,identity:u}=c;if(l.kind===`agent/remote`){let n;try{n=resolveRemoteAgentForAction({nodeId:u.nodeId,remoteAgentName:u.name,registry:s.subagentRegistry.subagentsByNodeId})}catch(e){return err({cause:e,permanent:!0})}try{await continueRemoteAgentSession({callback:{callId:t.callId,subagentName:u.name,token:e.parentToken,url:createWorkflowCallbackUrl(l.callbackBaseUrl,createEveCallbackRoutePath(e.parentToken))},message:readSubagentMessage(t),outputSchema:normalizeRequestedOutputSchema(t.input.outputSchema),remote:{...n,url:l.url},sessionId:l.sessionId})}catch(e){return err({cause:e,permanent:!isRetryableRemoteAgentContinueError(e)})}return ok(void 0)}let d=createWorkflowRuntime({compiledArtifactsSource:s.compiledArtifactsSource,nodeId:u.nodeId});try{if((await d.dispatchSession({command:{caller:{callId:t.callId,replyTo:{kind:`hook`,token:e.parentToken},subagentName:u.name},kind:`send`,payload:{message:readSubagentMessage(t),outputSchema:normalizeRequestedOutputSchema(t.input.outputSchema)}},sessionId:l.sessionId})).status===`session_not_active`)return err({cause:Error(`Agent session "${l.sessionId}" is no longer active.`),permanent:!0})}catch(e){return err({cause:e,permanent:isRuntimeNoActiveSessionError(e)})}return ok(void 0)}function createAgentErrorResult(e){return{callId:e.action.callId,isError:!0,kind:`subagent-result`,origin:`dispatch`,output:{code:e.code,message:e.message},subagentName:e.action.kind===`remote-agent-call`?e.action.remoteAgentName:e.action.subagentName}}function readSubagentMessage(e){return typeof e.input.message==`string`?e.input.message:``}export{dispatchToAgentHandle,isAgentHandleAction};
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{cancelRemoteAgentTurn,isRetryableRemoteAgentCancelError,resolveRemoteAgentForAction}from"#execution/remote-agent-dispatch.js";import{requestWorkflowTurnCancellation}from"#execution/workflow-runtime.js";import{deserializeContext}from"#context/serialize.js";import{readDurableSession}from"#execution/durable-session-store.js";import{getAgentHandleStore}from"#harness/handles/store.js";import{getDynamicSubagentSelection}from"#context/dynamic-subagent-lifecycle.js";const log=createLogger(`execution.cancel-descendant-turns`);async function cancelDescendantTurnsStep(e){"use step";let r;try{r=(getAgentHandleStore((await readDurableSession(e.sessionState)).state)?.handles??[]).filter(e=>e.phase===`running`)}catch(n){logError(log,`failed to read pending descendants during cancellation`,n,{sessionId:e.sessionState.sessionId});return}if(r.length===0){log.warn(`no running agent handles found while cancelling descendants; nothing to cancel`,{sessionId:e.sessionState.sessionId});return}let i,getRemoteContext=()=>i??=deserializeContext(e.serializedContext).then(e=>({ctx:e,registry:e.require(BundleKey).subagentRegistry.subagentsByNodeId}));await Promise.all(r.map(e=>e.address.kind===`agent/remote`?cancelRemoteDescendant({handle:e,remoteContext:getRemoteContext()}):cancelLocalDescendant({handle:e})))}async function cancelLocalDescendant(e){let{handle:n}=e;try{let e=await requestCancellationWithRetry({request:()=>requestWorkflowTurnCancellation({sessionId:n.address.sessionId}),shouldRetryError:()=>!1});e.status!==`accepted`&&log.warn(`descendant cancel was never accepted; the child may run to completion`,{callId:n.operation.callId,childSessionId:n.address.sessionId,finalStatus:e.status,reason:e.reason,subagentName:n.identity.name})}catch(e){logError(log,`failed to cancel local descendant turn`,e,{callId:n.operation.callId,childSessionId:n.address.sessionId,subagentName:n.identity.name})}}async function cancelRemoteDescendant(e){let{handle:n}=e;if(n.address.kind!==`agent/remote`)return;let a=n.address.url;try{let{ctx:t,registry:o}=await e.remoteContext,s=getDynamicSubagentSelection(t,n.identity.nodeId),c={...await resolveRemoteAgentForAction({dynamicRemoteAgent:s?.kind===`remote`?s.remoteAgent:void 0,nodeId:n.identity.nodeId,remoteAgentName:n.identity.name,registry:o}),url:a},l=await requestCancellationWithRetry({request:()=>cancelRemoteAgentTurn({remote:c,sessionId:n.address.sessionId}),shouldRetryError:isRetryableRemoteAgentCancelError});l.status!==`accepted`&&log.warn(`remote descendant cancel was never accepted; the child may run to completion`,{callId:n.operation.callId,childSessionId:n.address.sessionId,finalStatus:l.status,reason:l.reason,remoteAgentName:n.identity.name})}catch(e){logError(log,`failed to cancel remote descendant turn`,e,{callId:n.operation.callId,childSessionId:n.address.sessionId,remoteAgentName:n.identity.name})}}async function requestCancellationWithRetry(e){let t=250,n={status:`no_active_turn`};for(let r=1;r<=8;r+=1){try{if(n=await e.request(),n.status===`accepted`||r===8)return n}catch(t){if(!e.shouldRetryError(t)||r===8)throw t}await new Promise(e=>setTimeout(e,t)),t=Math.min(t*2,1500)}return n}export{cancelDescendantTurnsStep};
1
+ import{createLogger,logError}from"#internal/logging.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{cancelRemoteAgentTurn,isRetryableRemoteAgentCancelError,resolveRemoteAgentForAction}from"#execution/remote-agent-dispatch.js";import{requestWorkflowTurnCancellation}from"#execution/workflow-runtime.js";import{deserializeContext}from"#context/serialize.js";import{readDurableSession}from"#execution/durable-session-store.js";import{getAgentHandleStore}from"#harness/handles/store.js";import{getDynamicSubagentSelection}from"#context/dynamic-subagent-lifecycle.js";const log=createLogger(`execution.cancel-descendant-turns`);async function cancelDescendantTurnsStep(e){"use step";let r;try{r=(getAgentHandleStore((await readDurableSession(e.sessionState)).state)?.handles??[]).filter(e=>e.phase===`running`)}catch(n){logError(log,`failed to read pending descendants during cancellation`,n,{sessionId:e.sessionState.sessionId});return}if(r.length===0){log.warn(`no running agent handles found while cancelling descendants; nothing to cancel`,{sessionId:e.sessionState.sessionId});return}let i,getRemoteContext=()=>i??=deserializeContext(e.serializedContext).then(e=>({ctx:e,registry:e.require(BundleKey).subagentRegistry.subagentsByNodeId}));await Promise.all(r.map(e=>e.address.kind===`agent/remote`?cancelRemoteDescendant({handle:e,remoteContext:getRemoteContext()}):cancelLocalDescendant({handle:e})))}async function cancelLocalDescendant(e){let{handle:n}=e;try{let e=await requestCancellationWithRetry({request:()=>requestWorkflowTurnCancellation({sessionId:n.address.sessionId}),shouldRetryError:()=>!1});e.status!==`accepted`&&log.warn(`descendant cancel was never accepted; the child may run to completion`,{callId:n.operation.callId,childSessionId:n.address.sessionId,finalStatus:e.status,subagentName:n.identity.name})}catch(e){logError(log,`failed to cancel local descendant turn`,e,{callId:n.operation.callId,childSessionId:n.address.sessionId,subagentName:n.identity.name})}}async function cancelRemoteDescendant(e){let{handle:n}=e;if(n.address.kind!==`agent/remote`)return;let a=n.address.url;try{let{ctx:t,registry:o}=await e.remoteContext,s=getDynamicSubagentSelection(t,n.identity.nodeId),c={...await resolveRemoteAgentForAction({dynamicRemoteAgent:s?.kind===`remote`?s.remoteAgent:void 0,nodeId:n.identity.nodeId,remoteAgentName:n.identity.name,registry:o}),url:a},l=await requestCancellationWithRetry({request:()=>cancelRemoteAgentTurn({remote:c,sessionId:n.address.sessionId}),shouldRetryError:isRetryableRemoteAgentCancelError});l.status!==`accepted`&&log.warn(`remote descendant cancel was never accepted; the child may run to completion`,{callId:n.operation.callId,childSessionId:n.address.sessionId,finalStatus:l.status,remoteAgentName:n.identity.name})}catch(e){logError(log,`failed to cancel remote descendant turn`,e,{callId:n.operation.callId,childSessionId:n.address.sessionId,remoteAgentName:n.identity.name})}}async function requestCancellationWithRetry(e){let t=250,n={status:`no_active_turn`};for(let r=1;r<=8;r+=1){try{if(n=await e.request(),n.status===`accepted`||r===8)return n}catch(t){if(!e.shouldRetryError(t)||r===8)throw t}await new Promise(e=>setTimeout(e,t)),t=Math.min(t*2,1500)}return n}export{cancelDescendantTurnsStep};
@@ -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,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{resolveRemoteAgentForAction,startRemoteAgentSession}from"#execution/remote-agent-dispatch.js";import{SUBAGENT_START_FAILED}from"#harness/agent-handle-errors.js";import{confirmAgentStarted,prepareAgentStart,rejectAgentEffect}from"#harness/handles/transitions.js";import{createWorkflowRuntime,workflowEntryReference}from"#execution/workflow-runtime.js";import{deserializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{getAgentHandleStore}from"#harness/handles/store.js";import{getDynamicSubagentSelection}from"#context/dynamic-subagent-lifecycle.js";import{hydrateDurableSession}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{dispatchToAgentHandle,isAgentHandleAction}from"#execution/agent-handle-dispatch.js";import{createAgentContinuationBundle}from"#execution/agent-continuation-bundle.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{createRecursiveAgentRootOnlyResult,createRemoteAgentStartFailureResult,createUnavailableDynamicSubagentResult,getSubagentName}from"#execution/dispatch-action-failures.js";import{mintStartOperation}from"#execution/dispatch-start-operation.js";import{buildSubagentRunInput}from"#execution/subagent-tool.js";import{readSessionTraceContext}from"#tracing/agent-trace-context-store.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),p=getPendingRuntimeActionBatch(s.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=resolveEffectiveAgentRuntime(h,m),_=hydrateDurableSession({compactionOverrides:{thresholdPercent:g.thresholdPercent},durable:s,turnAgent:g.turnAgent}),v=m.require(ChannelKey),y=m.get(AuthKey)??null,b=m.get(CapabilitiesKey),x=m.get(ChannelInstrumentationKey),S=m.get(InitiatorAuthKey)??null,C=buildAdapterContext(v,m),w=readSessionTraceContext(e.serializedContext,_.sessionId),T=h.resolvedAgent.config.experimental?.subagentPersistentSessions===!0;getAgentHandleStore(s.state);let E=planDispatch({actions:p.actions,bundle:h,ctx:m,session:_}),D=e.parentWritable.getWriter(),O=E.filter(e=>e.kind===`start`&&e.target.kind===`local`).length,k=_,A=[];try{for(let r of E){if(r.kind===`reject`){A.push(r.result);continue}let i;switch(r.kind){case`resume`:i=await dispatchToAgentHandle({action:r.action,agentId:r.agentId,bundle:createAgentContinuationBundle({action:r.action,bundle:h,dynamicRemoteAgent:r.dynamicRemoteAgent}),currentSession:k,parentToken:e.parentContinuationToken??_.continuationToken,parentTurnId:p.event.turnId});break;case`start`:i=await startSubagent({auth:y,batchEvent:p.event,bundle:h,callbackBaseUrl:e.callbackBaseUrl,capabilities:b,channelMetadata:x,currentSession:k,fanoutSize:O,initiatorAuth:S,parentContinuationToken:e.parentContinuationToken,parentTraceContext:w,persistentSessions:T,session:_,target:r.target});break}if(k=i.session,i.kind===`error`){A.push(i.result);continue}try{let e=await callAdapterEventHandler(v,createSubagentCalledEvent({callId:i.callId,childSessionId:i.address.sessionId,name:i.name,remote:i.address.kind===`agent/remote`?{url:i.address.url}:void 0,sequence:p.event.sequence,sessionId:_.sessionId,toolName:i.toolName,turnId:p.event.turnId,workflowId:workflowEntryReference.workflowId}),C);await D.write(encodeMessageStreamEvent(stampMessageStreamEvent(e)))}catch(e){logError(log,`subagent.called emission failed`,e,{callId:i.callId,childSessionId:i.address.sessionId,toolName:i.toolName})}}}finally{D.releaseLock()}return{results:A,sessionState:k===_?e.sessionState:createDurableSessionState({session:k})}}function planDispatch(e){let t=getAgentHandleStore(e.session.state)?.handles??[];return e.actions.map(n=>{let r=n.input.agentId,i=typeof r==`string`&&r.trim()!==``?r:void 0;if(i!==void 0&&isAgentHandleAction(n)){if(t.some(e=>e.identity.id===i)){let t=e.bundle.subagentRegistry.dynamicNodeIds?.has(n.nodeId)===!0?getDynamicSubagentSelection(e.ctx,n.nodeId):void 0;return{action:n,agentId:i,dynamicRemoteAgent:n.kind===`remote-agent-call`&&t?.kind===`remote`?t.remoteAgent:void 0,kind:`resume`}}log.warn(`unknown agentId on subagent call; starting a new agent`,{agentId:i,callId:n.callId})}return classifyFreshStart({action:n,bundle:e.bundle,ctx:e.ctx,session:e.session})})}function classifyFreshStart(e){let{action:t}=e,n=e.bundle.subagentRegistry.subagentsByNodeId,r=resolveSubagentDepth(e.session),i=e.session.rootSessionId!==void 0||r.currentDepth>0,a=(t.kind===`subagent-call`||t.kind===`remote-agent-call`)&&e.bundle.subagentRegistry.dynamicNodeIds?.has(t.nodeId)===!0,o=a?getDynamicSubagentSelection(e.ctx,t.nodeId):void 0;if(a&&(o===void 0||t.kind===`subagent-call`&&o.kind!==`subagent`||t.kind===`remote-agent-call`&&o.kind!==`remote`)){let e=getSubagentName(t);return log.warn(`dynamic subagent call blocked after availability changed`,{callId:t.callId,nodeId:t.nodeId,subagentName:e}),{kind:`reject`,result:createUnavailableDynamicSubagentResult(t)}}if(isRecursiveAgentAction(t,n)&&i)return log.warn(`recursive agent call blocked outside the root session`,{callId:t.callId,currentDepth:r.currentDepth,nodeId:t.nodeId,subagentName:t.subagentName}),{kind:`reject`,result:createRecursiveAgentRootOnlyResult(t)};switch(t.kind){case`subagent-call`:{let e=o?.kind===`subagent`?o.agentConfig:void 0,r=n.get(t.nodeId),i=e?.description??(r?.definition.kind===`subagent`?r.definition.description:void 0);return{kind:`start`,target:{action:t,dynamicSubagentAgentConfig:e,kind:`local`,source:i===void 0?{type:`runtime`}:{description:i,type:`local`}}}}case`remote-agent-call`:return{kind:`start`,target:{action:t,dynamicRemoteAgent:o?.kind===`remote`?o.remoteAgent:void 0,kind:`remote`}};default:throw Error(`Unsupported runtime action kind "${t.kind}" in workflow runtime.`)}}async function startSubagent(e){switch(e.target.kind){case`local`:return startLocalSubagent({action:e.target.action,auth:e.auth,batchEvent:e.batchEvent,bundle:e.bundle,capabilities:e.capabilities,channelMetadata:e.channelMetadata,currentSession:e.currentSession,dynamicSubagentAgentConfig:e.target.dynamicSubagentAgentConfig,fanoutSize:e.fanoutSize,initiatorAuth:e.initiatorAuth,parentContinuationToken:e.parentContinuationToken,parentTraceContext:e.parentTraceContext,persistentSessions:e.persistentSessions,session:e.session,source:e.target.source});case`remote`:return startRemoteSubagent({action:e.target.action,auth:e.auth,batchEvent:e.batchEvent,bundle:e.bundle,callbackBaseUrl:e.callbackBaseUrl,currentSession:e.currentSession,dynamicRemoteAgent:e.target.dynamicRemoteAgent,initiatorAuth:e.initiatorAuth,parentContinuationToken:e.parentContinuationToken,persistentSessions:e.persistentSessions,session:e.session});default:return e.target}}async function startLocalSubagent(e){let{action:n,source:r}=e,i=createWorkflowRuntime({compiledArtifactsSource:e.bundle.compiledArtifactsSource,dynamicSubagentAgentConfig:e.dynamicSubagentAgentConfig,nodeId:n.nodeId}),{childContinuationToken:a,runInput:o}=buildSubagentRunInput({action:n,auth:e.auth,batchEvent:e.batchEvent,capabilities:e.capabilities,channelMetadata:e.channelMetadata,fanoutSize:e.fanoutSize,initiatorAuth:e.initiatorAuth,parentContinuationToken:e.parentContinuationToken,parentTraceContext:e.parentTraceContext,persistentSessions:e.persistentSessions,session:e.session,source:r}),c=r.type===`runtime`?`agent/self`:`agent/local`,{identity:l,operation:u}=mintStartOperation({callId:n.callId,name:n.subagentName,nodeId:n.nodeId,parentSessionId:e.session.sessionId,parentTurnId:e.batchEvent.turnId}),d=prepareAgentStart(e.currentSession,{identity:l,operation:u,target:{continuationToken:a,kind:c}}),f;try{f=(await i.createSession(o)).sessionId}catch(e){return logError(log,`local subagent start failed`,e,{callId:n.callId,nodeId:n.nodeId,subagentName:n.subagentName}),{kind:`error`,result:{callId:n.callId,isError:!0,kind:`subagent-result`,origin:`dispatch`,output:{code:SUBAGENT_START_FAILED,message:toErrorMessage(e)},subagentName:n.subagentName},session:rejectAgentEffect(d,{disposition:`dead`,operationId:u.id})}}let p={continuationToken:a,kind:c,sessionId:f};return{address:p,callId:n.callId,kind:`called`,name:n.name,session:confirmAgentStarted(d,{address:p,operationId:u.id}),toolName:n.subagentName}}async function startRemoteSubagent(e){let{action:n}=e,r,i;try{if(e.callbackBaseUrl===void 0)throw Error(`Cannot dispatch remote agent without a callback base URL.`);r=e.callbackBaseUrl,i=resolveRemoteAgentForAction({dynamicRemoteAgent:e.dynamicRemoteAgent,nodeId:n.nodeId,remoteAgentName:n.remoteAgentName,registry:e.bundle.subagentRegistry.subagentsByNodeId})}catch(r){return logError(log,`remote agent start failed`,r,{remoteAgentName:n.remoteAgentName,nodeId:n.nodeId,callId:n.callId}),{kind:`error`,result:createRemoteAgentStartFailureResult({action:n,error:r}),session:e.currentSession}}let{identity:a,operation:o}=mintStartOperation({callId:n.callId,name:n.remoteAgentName,nodeId:n.nodeId,parentSessionId:e.session.sessionId,parentTurnId:e.batchEvent.turnId}),s=prepareAgentStart(e.currentSession,{identity:a,operation:o,target:{callbackBaseUrl:r,kind:`agent/remote`,url:i.url}});try{let t=await startRemoteAgentSession({action:n,auth:e.auth,callbackBaseUrl:r,callbackToken:e.parentContinuationToken,initiatorAuth:e.initiatorAuth,persistentSessions:e.persistentSessions,remote:i,session:e.session}),a={callbackBaseUrl:r,kind:`agent/remote`,sessionId:t.sessionId,url:i.url,...t.continuationToken===void 0?{}:{continuationToken:t.continuationToken}};return{address:a,callId:n.callId,kind:`called`,name:n.name,session:confirmAgentStarted(s,{address:a,operationId:o.id}),toolName:n.remoteAgentName}}catch(e){return logError(log,`remote agent start failed`,e,{remoteAgentName:n.remoteAgentName,nodeId:n.nodeId,callId:n.callId}),{kind:`error`,result:createRemoteAgentStartFailureResult({action:n,error:e}),session:rejectAgentEffect(s,{disposition:`dead`,operationId:o.id})}}}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,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{resolveRemoteAgentForAction,startRemoteAgentSession}from"#execution/remote-agent-dispatch.js";import{SUBAGENT_START_FAILED}from"#harness/agent-handle-errors.js";import{confirmAgentStarted,prepareAgentStart,rejectAgentEffect}from"#harness/handles/transitions.js";import{createWorkflowRuntime,workflowEntryReference}from"#execution/workflow-runtime.js";import{deserializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{getAgentHandleStore}from"#harness/handles/store.js";import{getDynamicSubagentSelection}from"#context/dynamic-subagent-lifecycle.js";import{hydrateDurableSession}from"#execution/session.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{dispatchToAgentHandle,isAgentHandleAction}from"#execution/agent-handle-dispatch.js";import{createAgentContinuationBundle}from"#execution/agent-continuation-bundle.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{createRecursiveAgentRootOnlyResult,createRemoteAgentStartFailureResult,createUnavailableDynamicSubagentResult,getSubagentName}from"#execution/dispatch-action-failures.js";import{mintStartOperation}from"#execution/dispatch-start-operation.js";import{buildSubagentRunInput}from"#execution/subagent-tool.js";import{readSessionTraceContext}from"#tracing/agent-trace-context-store.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),p=getPendingRuntimeActionBatch(s.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=resolveEffectiveAgentRuntime(h,m),_=hydrateDurableSession({compactionOverrides:{thresholdPercent:g.thresholdPercent},durable:s,turnAgent:g.turnAgent}),v=m.require(ChannelKey),y=m.get(AuthKey)??null,b=m.get(CapabilitiesKey),x=m.get(ChannelInstrumentationKey),S=m.get(InitiatorAuthKey)??null,C=buildAdapterContext(v,m),w=readSessionTraceContext(e.serializedContext,_.sessionId),T=h.resolvedAgent.config.experimental?.subagentPersistentSessions===!0;getAgentHandleStore(s.state);let E=planDispatch({actions:p.actions,bundle:h,ctx:m,session:_}),D=e.parentWritable.getWriter(),O=E.filter(e=>e.kind===`start`&&e.target.kind===`local`).length,k=_,A=[];try{for(let r of E){if(r.kind===`reject`){A.push(r.result);continue}let i;switch(r.kind){case`resume`:i=await dispatchToAgentHandle({action:r.action,agentId:r.agentId,bundle:createAgentContinuationBundle({action:r.action,bundle:h,dynamicRemoteAgent:r.dynamicRemoteAgent}),currentSession:k,parentToken:e.parentContinuationToken??_.continuationToken,parentTurnId:p.event.turnId});break;case`start`:i=await startSubagent({auth:y,batchEvent:p.event,bundle:h,callbackBaseUrl:e.callbackBaseUrl,capabilities:b,channelMetadata:x,currentSession:k,fanoutSize:O,initiatorAuth:S,parentContinuationToken:e.parentContinuationToken,parentTraceContext:w,persistentSessions:T,session:_,target:r.target});break}if(k=i.session,i.kind===`error`){A.push(i.result);continue}try{let e=await callAdapterEventHandler(v,createSubagentCalledEvent({callId:i.callId,childSessionId:i.address.sessionId,name:i.name,remote:i.address.kind===`agent/remote`?{url:i.address.url}:void 0,sequence:p.event.sequence,sessionId:_.sessionId,toolName:i.toolName,turnId:p.event.turnId,workflowId:workflowEntryReference.workflowId}),C);await D.write(encodeMessageStreamEvent(stampMessageStreamEvent(e)))}catch(e){logError(log,`subagent.called emission failed`,e,{callId:i.callId,childSessionId:i.address.sessionId,toolName:i.toolName})}}}finally{D.releaseLock()}return{results:A,sessionState:k===_?e.sessionState:createDurableSessionState({session:k})}}function planDispatch(e){let t=getAgentHandleStore(e.session.state)?.handles??[];return e.actions.map(n=>{let r=n.input.agentId,i=typeof r==`string`&&r.trim()!==``?r:void 0;if(i!==void 0&&isAgentHandleAction(n)){if(t.some(e=>e.identity.id===i)){let t=e.bundle.subagentRegistry.dynamicNodeIds?.has(n.nodeId)===!0?getDynamicSubagentSelection(e.ctx,n.nodeId):void 0;return{action:n,agentId:i,dynamicRemoteAgent:n.kind===`remote-agent-call`&&t?.kind===`remote`?t.remoteAgent:void 0,kind:`resume`}}log.warn(`unknown agentId on subagent call; starting a new agent`,{agentId:i,callId:n.callId})}return classifyFreshStart({action:n,bundle:e.bundle,ctx:e.ctx,session:e.session})})}function classifyFreshStart(e){let{action:t}=e,n=e.bundle.subagentRegistry.subagentsByNodeId,r=resolveSubagentDepth(e.session),i=e.session.rootSessionId!==void 0||r.currentDepth>0,a=(t.kind===`subagent-call`||t.kind===`remote-agent-call`)&&e.bundle.subagentRegistry.dynamicNodeIds?.has(t.nodeId)===!0,o=a?getDynamicSubagentSelection(e.ctx,t.nodeId):void 0;if(a&&(o===void 0||t.kind===`subagent-call`&&o.kind!==`subagent`||t.kind===`remote-agent-call`&&o.kind!==`remote`)){let e=getSubagentName(t);return log.warn(`dynamic subagent call blocked after availability changed`,{callId:t.callId,nodeId:t.nodeId,subagentName:e}),{kind:`reject`,result:createUnavailableDynamicSubagentResult(t)}}if(isRecursiveAgentAction(t,n)&&i)return log.warn(`recursive agent call blocked outside the root session`,{callId:t.callId,currentDepth:r.currentDepth,nodeId:t.nodeId,subagentName:t.subagentName}),{kind:`reject`,result:createRecursiveAgentRootOnlyResult(t)};switch(t.kind){case`subagent-call`:{let e=o?.kind===`subagent`?o.agentConfig:void 0,r=n.get(t.nodeId),i=e?.description??(r?.definition.kind===`subagent`?r.definition.description:void 0);return{kind:`start`,target:{action:t,dynamicSubagentAgentConfig:e,kind:`local`,source:i===void 0?{type:`runtime`}:{description:i,type:`local`}}}}case`remote-agent-call`:return{kind:`start`,target:{action:t,dynamicRemoteAgent:o?.kind===`remote`?o.remoteAgent:void 0,kind:`remote`}};default:throw Error(`Unsupported runtime action kind "${t.kind}" in workflow runtime.`)}}async function startSubagent(e){switch(e.target.kind){case`local`:return startLocalSubagent({action:e.target.action,auth:e.auth,batchEvent:e.batchEvent,bundle:e.bundle,capabilities:e.capabilities,channelMetadata:e.channelMetadata,currentSession:e.currentSession,dynamicSubagentAgentConfig:e.target.dynamicSubagentAgentConfig,fanoutSize:e.fanoutSize,initiatorAuth:e.initiatorAuth,parentContinuationToken:e.parentContinuationToken,parentTraceContext:e.parentTraceContext,persistentSessions:e.persistentSessions,session:e.session,source:e.target.source});case`remote`:return startRemoteSubagent({action:e.target.action,auth:e.auth,batchEvent:e.batchEvent,bundle:e.bundle,callbackBaseUrl:e.callbackBaseUrl,currentSession:e.currentSession,dynamicRemoteAgent:e.target.dynamicRemoteAgent,initiatorAuth:e.initiatorAuth,parentContinuationToken:e.parentContinuationToken,persistentSessions:e.persistentSessions,session:e.session});default:return e.target}}async function startLocalSubagent(e){let{action:n,source:r}=e,i=createWorkflowRuntime({compiledArtifactsSource:e.bundle.compiledArtifactsSource,dynamicSubagentAgentConfig:e.dynamicSubagentAgentConfig,nodeId:n.nodeId}),{childContinuationToken:a,runInput:o}=buildSubagentRunInput({action:n,auth:e.auth,batchEvent:e.batchEvent,capabilities:e.capabilities,channelMetadata:e.channelMetadata,fanoutSize:e.fanoutSize,initiatorAuth:e.initiatorAuth,parentContinuationToken:e.parentContinuationToken,parentTraceContext:e.parentTraceContext,persistentSessions:e.persistentSessions,session:e.session,source:r}),c=r.type===`runtime`?`agent/self`:`agent/local`,{identity:l,operation:u}=mintStartOperation({callId:n.callId,name:n.subagentName,nodeId:n.nodeId,parentSessionId:e.session.sessionId,parentTurnId:e.batchEvent.turnId}),d=prepareAgentStart(e.currentSession,{identity:l,operation:u,target:{continuationToken:a,kind:c}}),f;try{f=(await i.createSession(o)).sessionId}catch(e){return logError(log,`local subagent start failed`,e,{callId:n.callId,nodeId:n.nodeId,subagentName:n.subagentName}),{kind:`error`,result:{callId:n.callId,isError:!0,kind:`subagent-result`,origin:`dispatch`,output:{code:SUBAGENT_START_FAILED,message:toErrorMessage(e)},subagentName:n.subagentName},session:rejectAgentEffect(d,{disposition:`dead`,operationId:u.id})}}let p={continuationToken:a,kind:c,sessionId:f};return{address:p,callId:n.callId,kind:`called`,name:n.name,session:confirmAgentStarted(d,{address:p,operationId:u.id}),toolName:n.subagentName}}async function startRemoteSubagent(e){let{action:n}=e,r,i;try{if(e.callbackBaseUrl===void 0)throw Error(`Cannot dispatch remote agent without a callback base URL.`);r=e.callbackBaseUrl,i=resolveRemoteAgentForAction({dynamicRemoteAgent:e.dynamicRemoteAgent,nodeId:n.nodeId,remoteAgentName:n.remoteAgentName,registry:e.bundle.subagentRegistry.subagentsByNodeId})}catch(r){return logError(log,`remote agent start failed`,r,{remoteAgentName:n.remoteAgentName,nodeId:n.nodeId,callId:n.callId}),{kind:`error`,result:createRemoteAgentStartFailureResult({action:n,error:r}),session:e.currentSession}}let{identity:a,operation:o}=mintStartOperation({callId:n.callId,name:n.remoteAgentName,nodeId:n.nodeId,parentSessionId:e.session.sessionId,parentTurnId:e.batchEvent.turnId}),s=prepareAgentStart(e.currentSession,{identity:a,operation:o,target:{callbackBaseUrl:r,kind:`agent/remote`,url:i.url}});try{let t=await startRemoteAgentSession({action:n,auth:e.auth,callbackBaseUrl:r,callbackToken:e.parentContinuationToken,initiatorAuth:e.initiatorAuth,persistentSessions:e.persistentSessions,remote:i,session:e.session}),a={callbackBaseUrl:r,kind:`agent/remote`,sessionId:t.sessionId,url:i.url};return{address:a,callId:n.callId,kind:`called`,name:n.name,session:confirmAgentStarted(s,{address:a,operationId:o.id}),toolName:n.remoteAgentName}}catch(e){return logError(log,`remote agent start failed`,e,{remoteAgentName:n.remoteAgentName,nodeId:n.nodeId,callId:n.callId}),{kind:`error`,result:createRemoteAgentStartFailureResult({action:n,error:e}),session:rejectAgentEffect(s,{disposition:`dead`,operationId:o.id})}}}function isRecursiveAgentAction(e,t){return e.kind===`subagent-call`&&e.subagentName===`agent`&&!t.has(e.nodeId)}export{dispatchRuntimeActionsStep};
@@ -6,7 +6,6 @@ import type { DynamicRemoteAgentConfig } from "#runtime/subagents/dynamic-remote
6
6
  import type { ResolvedRuntimeRemoteAgentNode } from "#runtime/types.js";
7
7
  import type { JsonObject } from "#shared/json.js";
8
8
  type RemoteAgentSessionCoordinates = {
9
- readonly continuationToken?: string;
10
9
  readonly sessionId: string;
11
10
  };
12
11
  export declare function startRemoteAgentSession(input: {
@@ -26,7 +25,7 @@ export declare function startRemoteAgentSession(input: {
26
25
  readonly remote: ResolvedRuntimeRemoteAgentNode;
27
26
  readonly session: HarnessSession;
28
27
  }): Promise<RemoteAgentSessionCoordinates>;
29
- /** Continues one remote-agent session via agentId. */
28
+ /** Continues one remote-agent session by its immutable session ID. */
30
29
  export declare function continueRemoteAgentSession(input: {
31
30
  readonly callback: {
32
31
  readonly callId: string;
@@ -34,7 +33,6 @@ export declare function continueRemoteAgentSession(input: {
34
33
  readonly token: string;
35
34
  readonly url: string;
36
35
  };
37
- readonly continuationToken: string;
38
36
  readonly message: string;
39
37
  readonly outputSchema?: JsonObject;
40
38
  readonly remote: ResolvedRuntimeRemoteAgentNode;