eve 0.24.3 → 0.24.5

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 (214) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/src/channel/adapter.d.ts +4 -2
  3. package/dist/src/channel/adapter.js +1 -1
  4. package/dist/src/channel/session.d.ts +5 -1
  5. package/dist/src/channel/types.d.ts +20 -6
  6. package/dist/src/chunks/{use-eve-agent-dEGV09g_.js → use-eve-agent-8rerxDHY.js} +74 -10
  7. package/dist/src/chunks/{use-eve-agent-CFBTHlPx.js → use-eve-agent-DhgdHzDG.js} +74 -10
  8. package/dist/src/cli/commands/build.d.ts +14 -0
  9. package/dist/src/cli/commands/build.js +1 -0
  10. package/dist/src/cli/commands/channels.js +1 -1
  11. package/dist/src/cli/commands/link.d.ts +6 -5
  12. package/dist/src/cli/commands/link.js +1 -1
  13. package/dist/src/cli/dev/tui/runner.d.ts +2 -2
  14. package/dist/src/cli/dev/tui/runner.js +1 -1
  15. package/dist/src/cli/run.d.ts +3 -2
  16. package/dist/src/cli/run.js +1 -1
  17. package/dist/src/client/index.d.ts +2 -2
  18. package/dist/src/client/message-reducer.js +1 -1
  19. package/dist/src/client/ndjson.js +1 -1
  20. package/dist/src/client/open-stream.d.ts +3 -2
  21. package/dist/src/client/open-stream.js +1 -1
  22. package/dist/src/client/session-utils.js +1 -1
  23. package/dist/src/client/session.d.ts +19 -5
  24. package/dist/src/client/session.js +1 -1
  25. package/dist/src/client/types.d.ts +11 -2
  26. package/dist/src/compiled/.vendor-stamp.json +5 -5
  27. package/dist/src/compiled/@workflow/core/index.js +2 -2
  28. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +55 -0
  29. package/dist/src/compiled/@workflow/core/runtime/run-id-time.d.ts +9 -0
  30. package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +2 -0
  31. package/dist/src/compiled/@workflow/core/runtime/step-latency.d.ts +70 -4
  32. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +10 -1
  33. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  34. package/dist/src/compiled/@workflow/core/step/context-storage.d.ts +6 -0
  35. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +25 -0
  36. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  37. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  38. package/dist/src/compiled/@workflow/errors/index.d.ts +16 -0
  39. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  40. package/dist/src/compiled/@workflow/world/attributes.d.ts +7 -0
  41. package/dist/src/compiled/@workflow/world/events.d.ts +16 -0
  42. package/dist/src/compiled/@workflow/world/index.d.ts +1 -1
  43. package/dist/src/compiled/@workflow/world-local/index.js +3 -3
  44. package/dist/src/compiled/@workflow/world-vercel/index.js +16 -16
  45. package/dist/src/compiled/_chunks/workflow/attribute-changes-DXbmITuI.js +20 -0
  46. package/dist/src/compiled/_chunks/workflow/{dist-DpDDcpTl.js → dist-BYo8Gno2.js} +1 -1
  47. package/dist/src/compiled/_chunks/workflow/{dist-Blxnyb7-.js → dist-CSfKNxQW.js} +1 -1
  48. package/dist/src/compiled/_chunks/workflow/resume-hook-DvvgYsRt.js +1 -0
  49. package/dist/src/compiled/_chunks/workflow/run-BdvQmV5a.js +1 -0
  50. package/dist/src/compiled/_chunks/workflow/run-id-BdE0MZz9.js +1 -0
  51. package/dist/src/compiled/_chunks/workflow/sleep-DzxrwWTs.js +1 -0
  52. package/dist/src/discover/filesystem.js +1 -1
  53. package/dist/src/evals/assertions/run.d.ts +3 -3
  54. package/dist/src/evals/context.js +1 -1
  55. package/dist/src/evals/index.d.ts +2 -1
  56. package/dist/src/evals/match.d.ts +4 -0
  57. package/dist/src/evals/match.js +1 -1
  58. package/dist/src/evals/runner/derive-run-facts.js +1 -1
  59. package/dist/src/evals/session.d.ts +10 -2
  60. package/dist/src/evals/session.js +1 -1
  61. package/dist/src/evals/target.js +1 -1
  62. package/dist/src/evals/types.d.ts +52 -2
  63. package/dist/src/execution/cancel-descendant-turns-step.d.ts +6 -0
  64. package/dist/src/execution/cancel-descendant-turns-step.js +1 -0
  65. package/dist/src/execution/create-session-step.js +1 -1
  66. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  67. package/dist/src/execution/dispatch-workflow-runtime-actions-step.js +1 -1
  68. package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +1 -0
  69. package/dist/src/execution/durable-session-migrations/turn-workflow.js +1 -1
  70. package/dist/src/execution/next-driver-action.d.ts +7 -0
  71. package/dist/src/execution/node-step.js +1 -1
  72. package/dist/src/execution/remote-agent-dispatch.d.ts +6 -0
  73. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  74. package/dist/src/execution/settle-cancelled-turn-step.d.ts +16 -0
  75. package/dist/src/execution/settle-cancelled-turn-step.js +1 -0
  76. package/dist/src/execution/subagent-event-proxy-step.js +1 -1
  77. package/dist/src/execution/subagent-hitl-proxy.js +1 -1
  78. package/dist/src/execution/terminal-session-failure-step.d.ts +6 -0
  79. package/dist/src/execution/terminal-session-failure-step.js +1 -0
  80. package/dist/src/execution/turn-cancellation-control.d.ts +27 -0
  81. package/dist/src/execution/turn-cancellation-control.js +1 -0
  82. package/dist/src/execution/turn-cancellation-token.d.ts +9 -0
  83. package/dist/src/execution/turn-cancellation-token.js +1 -0
  84. package/dist/src/execution/turn-dispatch.d.ts +14 -1
  85. package/dist/src/execution/turn-dispatch.js +1 -1
  86. package/dist/src/execution/turn-execution-cursor.d.ts +2 -1
  87. package/dist/src/execution/turn-execution-cursor.js +1 -1
  88. package/dist/src/execution/turn-workflow.d.ts +9 -1
  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.d.ts +3 -1
  92. package/dist/src/execution/workflow-runtime.js +1 -1
  93. package/dist/src/execution/workflow-steps.d.ts +8 -6
  94. package/dist/src/execution/workflow-steps.js +1 -1
  95. package/dist/src/harness/active-turn-id.d.ts +11 -0
  96. package/dist/src/harness/active-turn-id.js +1 -0
  97. package/dist/src/harness/advertised-tools.js +1 -1
  98. package/dist/src/harness/cancelled-turn-emission.d.ts +11 -0
  99. package/dist/src/harness/cancelled-turn-emission.js +1 -0
  100. package/dist/src/harness/emission.d.ts +4 -2
  101. package/dist/src/harness/emission.js +1 -1
  102. package/dist/src/harness/execute-tool.d.ts +0 -1
  103. package/dist/src/harness/proxy-input-requests.d.ts +5 -0
  104. package/dist/src/harness/proxy-input-requests.js +1 -1
  105. package/dist/src/harness/runtime-actions.d.ts +16 -12
  106. package/dist/src/harness/runtime-actions.js +1 -1
  107. package/dist/src/harness/session-limit-enforcement.js +1 -1
  108. package/dist/src/harness/tool-loop.js +2 -2
  109. package/dist/src/internal/application/build-profile.d.ts +64 -0
  110. package/dist/src/internal/application/build-profile.js +1 -0
  111. package/dist/src/internal/application/compiled-artifacts.js +3 -2
  112. package/dist/src/internal/application/package.js +1 -1
  113. package/dist/src/internal/authored-module-loader.d.ts +10 -0
  114. package/dist/src/internal/authored-module-loader.js +3 -3
  115. package/dist/src/internal/authored-module-map-loader.js +1 -1
  116. package/dist/src/internal/bundler/nitro-rolldown.d.ts +18 -2
  117. package/dist/src/internal/bundler/nitro-rolldown.js +1 -1
  118. package/dist/src/internal/materialized-authored-modules.d.ts +2 -4
  119. package/dist/src/internal/materialized-authored-modules.js +1 -1
  120. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  121. package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
  122. package/dist/src/internal/nitro/host/build-application.js +1 -1
  123. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  124. package/dist/src/internal/nitro/host/types.d.ts +2 -0
  125. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  126. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +7 -1
  127. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  128. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  129. package/dist/src/internal/nitro/routes/channel-route-context.d.ts +3 -0
  130. package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
  131. package/dist/src/internal/nitro/routes/runtime-stack.js +1 -1
  132. package/dist/src/internal/nitro/routes/schedule-task.js +1 -1
  133. package/dist/src/internal/workflow/development-world-client.js +1 -1
  134. package/dist/src/internal/workflow/development-world-server.js +1 -1
  135. package/dist/src/internal/workflow/local-world-data-directory.d.ts +2 -0
  136. package/dist/src/internal/workflow/local-world-data-directory.js +1 -0
  137. package/dist/src/internal/workflow-bundle/builder-support.js +3 -3
  138. package/dist/src/internal/workflow-bundle/builder.js +2 -2
  139. package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
  140. package/dist/src/protocol/cancel-turn.d.ts +11 -0
  141. package/dist/src/protocol/cancel-turn.js +1 -0
  142. package/dist/src/protocol/message.d.ts +23 -3
  143. package/dist/src/protocol/message.js +2 -2
  144. package/dist/src/protocol/routes.d.ts +10 -0
  145. package/dist/src/protocol/routes.js +1 -1
  146. package/dist/src/public/channels/discord/discordChannel.d.ts +1 -0
  147. package/dist/src/public/channels/eve.d.ts +2 -1
  148. package/dist/src/public/channels/eve.js +2 -2
  149. package/dist/src/public/channels/github/githubChannel.d.ts +1 -0
  150. package/dist/src/public/channels/linear/api.d.ts +0 -1
  151. package/dist/src/public/channels/linear/api.js +17 -22
  152. package/dist/src/public/channels/linear/linearChannel.d.ts +1 -0
  153. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  154. package/dist/src/public/channels/slack/slackChannel.d.ts +1 -0
  155. package/dist/src/public/channels/teams/teamsChannel.d.ts +1 -0
  156. package/dist/src/public/channels/telegram/telegramChannel.d.ts +1 -0
  157. package/dist/src/public/channels/twilio/twilioChannel.d.ts +1 -0
  158. package/dist/src/public/definitions/channel.d.ts +25 -14
  159. package/dist/src/public/definitions/channel.js +1 -1
  160. package/dist/src/public/next/index.js +1 -1
  161. package/dist/src/public/next/resolve-eve-binary.d.ts +12 -0
  162. package/dist/src/public/next/resolve-eve-binary.js +1 -0
  163. package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
  164. package/dist/src/runtime/framework-tools/agent.d.ts +13 -0
  165. package/dist/src/runtime/framework-tools/agent.js +1 -0
  166. package/dist/src/runtime/framework-tools/index.d.ts +7 -2
  167. package/dist/src/runtime/framework-tools/index.js +1 -1
  168. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  169. package/dist/src/runtime/types.d.ts +2 -1
  170. package/dist/src/services/dev-client/runtime-artifacts.d.ts +2 -2
  171. package/dist/src/services/dev-client.d.ts +10 -18
  172. package/dist/src/services/dev-client.js +1 -1
  173. package/dist/src/setup/boxes/reconcile-host-framework-preset.d.ts +26 -0
  174. package/dist/src/setup/boxes/reconcile-host-framework-preset.js +1 -0
  175. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  176. package/dist/src/setup/index.js +1 -1
  177. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  178. package/dist/src/setup/scaffold/create/extension.js +0 -1
  179. package/dist/src/setup/scaffold/create/project.js +2 -4
  180. package/dist/src/setup/scaffold/index.d.ts +1 -1
  181. package/dist/src/setup/scaffold/index.js +1 -1
  182. package/dist/src/setup/scaffold/update/channels.d.ts +7 -1
  183. package/dist/src/setup/scaffold/update/channels.js +2 -2
  184. package/dist/src/setup/scaffold/update/connections.js +3 -3
  185. package/dist/src/setup/vercel-project-framework.d.ts +12 -0
  186. package/dist/src/setup/vercel-project-framework.js +1 -1
  187. package/dist/src/shared/continuation-token.d.ts +2 -0
  188. package/dist/src/shared/continuation-token.js +1 -0
  189. package/dist/src/svelte/index.js +1 -1
  190. package/dist/src/svelte/use-eve-agent.js +1 -1
  191. package/dist/src/vue/index.js +1 -1
  192. package/dist/src/vue/use-eve-agent.js +1 -1
  193. package/docs/channels/eve.mdx +11 -1
  194. package/docs/concepts/default-harness.md +2 -0
  195. package/docs/concepts/execution-model-and-durability.md +1 -1
  196. package/docs/concepts/sessions-runs-and-streaming.md +24 -4
  197. package/docs/evals/assertions.mdx +2 -2
  198. package/docs/evals/cases.mdx +31 -0
  199. package/docs/evals/overview.mdx +1 -1
  200. package/docs/evals/targets.mdx +2 -1
  201. package/docs/guides/client/continuations.mdx +16 -1
  202. package/docs/guides/client/streaming.mdx +31 -2
  203. package/docs/guides/deployment.md +1 -1
  204. package/docs/guides/frontend/overview.mdx +4 -2
  205. package/docs/guides/frontend/use-eve-agent-svelte.mdx +2 -2
  206. package/docs/guides/frontend/use-eve-agent-vue.mdx +2 -2
  207. package/docs/guides/remote-agents.md +2 -0
  208. package/docs/reference/cli.md +16 -3
  209. package/docs/subagents.mdx +10 -0
  210. package/package.json +6 -6
  211. package/dist/src/compiled/_chunks/workflow/attribute-changes-MGTOG_uX.js +0 -20
  212. package/dist/src/compiled/_chunks/workflow/resume-hook-DHP5ql3-.js +0 -1
  213. package/dist/src/compiled/_chunks/workflow/run-D8hv1ptT.js +0 -1
  214. package/dist/src/compiled/_chunks/workflow/sleep-uA9pS-PT.js +0 -1
@@ -105,7 +105,8 @@ export interface EveChannel extends Channel {
105
105
  /**
106
106
  * Builds the default eve HTTP channel: a {@link defineChannel} instance serving the
107
107
  * built-in `/eve/v1` routes (GET inspects the agent, POST creates a session, POST
108
- * delivers a follow-up, GET streams a session's NDJSON event feed). Every route
108
+ * delivers a follow-up, POST cancels the in-flight turn, GET streams a session's
109
+ * NDJSON event feed). Every route
109
110
  * runs {@link EveChannelInput.auth} via {@link routeAuth} before dispatching.
110
111
  * Default-export the result as your `agent/channels/eve.ts` channel; reach for
111
112
  * {@link defineChannel} directly only for a custom transport.
@@ -1,2 +1,2 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{hasInternalRefScheme}from"#internal/attachments/url-refs.js";import{EVE_INFO_ROUTE_PATH}from"#protocol/routes.js";import{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{isInputResponse}from"#runtime/input/types.js";import{parseJsonObject}from"#shared/json.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import"ai";import{parseSessionCallback}from"#channel/session-callback.js";import{readAgentInfoRouteResponse}from"#internal/nitro/routes/channel-route-context.js";import{routeAuth}from"#public/channels/auth.js";import{collectUploadPolicyViolations,formatUploadPolicyViolation,mergeUploadPolicy}from"#public/channels/upload-policy.js";const log=createLogger(`eve.channel`);function defaultEveAuth(e){return e.eve.caller}function eveChannel(e){let t=mergeUploadPolicy(e.uploadPolicy);return defineChannel({cors:normalizeEveCors(e.cors),routes:[GET(EVE_INFO_ROUTE_PATH,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=readAgentInfoRouteResponse(n);return i===void 0?Response.json({error:`Agent info route requires internal channel dispatch context.`,ok:!1},{status:500}):await i()}),POST(`/eve/v1/session`,async(n,{send:r})=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=i,o;try{o=await n.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof o!=`object`||!o)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let s=parseCreateBody(o);if(s instanceof Response)return s;let c=checkUploadPolicy(s,t);if(c!==null)return c;let l=await resolveOnMessage({auth:a,config:e,message:s.message,request:n});if(l instanceof Response)return l;if(!l.dispatch)return droppedMessageResponse();let u=`eve:${crypto.randomUUID()}`,d=await r(createSendPayload(s,mergeContext(s.context,l.context)),{auth:l.auth,callback:s.callback,continuationToken:u,mode:s.mode});return Response.json({continuationToken:d.continuationToken,ok:!0,sessionId:d.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:d.id},status:202})}),POST(`/eve/v1/session/:sessionId`,async(n,{send:r,getSession:i,params:a})=>{let o=await routeAuth(n,e.auth);if(o instanceof Response)return o;let s=o,c=a.sessionId;if(!c)return Response.json({error:`Missing session id.`,ok:!1},{status:400});try{i(c)}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}let l;try{l=await n.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof l!=`object`||!l)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let u=parseContinueBody(l);if(u instanceof Response)return u;let d=checkUploadPolicy(u,t);if(d!==null)return d;let f=u.context,p=s;if(u.message!==void 0){let t=await resolveOnMessage({auth:s,config:e,message:u.message,request:n,sessionId:c});if(t instanceof Response)return t;if(!t.dispatch)return droppedMessageResponse();f=mergeContext(u.context,t.context),p=t.auth}let m=await r({inputResponses:u.inputResponses,message:u.message,context:f,outputSchema:u.outputSchema},{auth:p,continuationToken:u.continuationToken});return Response.json({ok:!0,sessionId:m.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:m.id},status:200})}),GET(`/eve/v1/session/:sessionId/stream`,async(t,{getSession:n,params:r})=>{let l=await routeAuth(t,e.auth);if(l instanceof Response)return l;let u=r.sessionId;if(!u)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let d=parseStartIndex(t);if(d instanceof Response)return d;try{let e=serializeAsNdjson(await n(u).getEventStream({startIndex:d}));return new Response(e,{headers:{"cache-control":`no-store, no-transform`,"content-type":EVE_MESSAGE_STREAM_CONTENT_TYPE,"x-accel-buffering":`no`,[EVE_SESSION_ID_HEADER]:u,[EVE_STREAM_FORMAT_HEADER]:EVE_MESSAGE_STREAM_FORMAT,[EVE_STREAM_VERSION_HEADER]:EVE_MESSAGE_STREAM_VERSION}})}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}})],events:e.events})}function normalizeEveCors(e){if(e===void 0||e===!1)return!1;if(e===!0)return!0;let t={};return e.origin!==void 0&&(t.origin=normalizeEveCorsOrigin(e.origin)),e.methods!==void 0&&(t.methods=e.methods),e.allowedHeaders!==void 0&&(t.allowHeaders=e.allowedHeaders),e.exposedHeaders!==void 0&&(t.exposeHeaders=e.exposedHeaders),e.credentials!==void 0&&(t.credentials=e.credentials),e.maxAge!==void 0&&(t.maxAge=e.maxAge),e.preflightStatus!==void 0&&(t.preflight={statusCode:e.preflightStatus}),t}function normalizeEveCorsOrigin(e){return e===`*`||e===`null`?e:typeof e==`string`?[e]:e}async function resolveOnMessage(e){let n=e.config.onMessage??defaultOnMessage,r;try{r=await n({eve:e.sessionId===void 0?{caller:e.auth,request:e.request}:{caller:e.auth,request:e.request,sessionId:e.sessionId}},e.message)}catch(n){let r=logError(log,`onMessage handler failed`,n,{sessionId:e.sessionId});return Response.json({error:`onMessage handler failed.`,errorId:r,ok:!1},{status:500})}return r==null?{dispatch:!1}:r.context===void 0?{auth:r.auth,dispatch:!0}:{auth:r.auth,context:r.context,dispatch:!0}}function defaultOnMessage(e){return{auth:defaultEveAuth(e)}}function droppedMessageResponse(){return new Response(null,{headers:{"cache-control":`no-store`},status:204})}function parseCreateBody(e){let t=parseMessageField(e.message);if(t instanceof Response)return t;let n=parseClientContextField(e.clientContext);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseModeField(e.mode);if(i instanceof Response)return i;let a=parseOutputSchemaField(e.outputSchema);return a instanceof Response?a:t===void 0?Response.json({error:`Missing or empty 'message' field.`,ok:!1},{status:400}):{callback:r,message:t,mode:i,context:n,outputSchema:a}}function parseContinueBody(e){let t=typeof e.continuationToken==`string`&&e.continuationToken.length>0?e.continuationToken:void 0;if(t===void 0)return Response.json({error:`Missing or empty 'continuationToken' field.`,ok:!1},{status:400});let n=parseMessageField(e.message);if(n instanceof Response)return n;let r=parseInputResponses(e.inputResponses);if(r instanceof Response)return r;let i=parseClientContextField(e.clientContext);if(i instanceof Response)return i;let a=parseOutputSchemaField(e.outputSchema);return a instanceof Response?a:n===void 0&&r===void 0?Response.json({error:`Expected a non-empty 'message', a non-empty 'inputResponses' array, or both.`,ok:!1},{status:400}):{message:n,continuationToken:t,inputResponses:r,context:i,outputSchema:a}}function createSendPayload(e,t=e.context){if(t===void 0&&e.outputSchema===void 0)return e.message;let n={message:e.message};return t!==void 0&&(n.context=t),e.outputSchema!==void 0&&(n.outputSchema=e.outputSchema),n}function parseOutputSchemaField(e){if(e!==void 0)try{return parseJsonObject(e)}catch{return Response.json({error:`Expected 'outputSchema' to be a JSON-serializable object.`,ok:!1},{status:400})}}function parseCallbackField(e){if(e===void 0)return;let t=parseSessionCallback(e);return t.ok?t.callback:Response.json({error:t.message,ok:!1},{status:400})}function parseModeField(e){if(e!==void 0)return e===`conversation`||e===`task`?e:Response.json({error:`Expected 'mode' to be either 'conversation' or 'task'.`,ok:!1},{status:400})}function parseMessageField(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=parseMessagePart(n);if(e instanceof Response)return e;t.push(e)}return t}function parseMessagePart(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});if(hasInternalRefScheme(t.data))return Response.json({error:`File part 'data' must not use a framework-internal ref scheme.`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function checkUploadPolicy(e,t){if(!e.message)return null;let n=collectUploadPolicyViolations(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:formatUploadPolicyViolation(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function parseInputResponses(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(isInputResponse);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function mergeContext(e,t){return e===void 0?t:t===void 0?e:[...e,...t]}function parseClientContextField(e){if(e!==void 0){if(typeof e==`string`)return e.length>0?[toClientContextMessage(e)]:void 0;if(Array.isArray(e))return e.length===0?void 0:e.every(e=>typeof e==`string`&&e.length>0)?e.map(e=>toClientContextMessage(e)):Response.json({error:`Expected 'clientContext' array entries to be non-empty strings.`,ok:!1},{status:400});if(typeof e!=`object`||!e)return Response.json({error:`Expected 'clientContext' to be a string, string array, or JSON object.`,ok:!1},{status:400});try{let t=parseJsonObject(e);return[toClientContextMessage(JSON.stringify(t))]}catch{return Response.json({error:`Expected 'clientContext' to be a JSON-serializable object.`,ok:!1},{status:400})}}}function toClientContextMessage(e){return`Client context:
2
- ${e}`}function parseStartIndex(e){let t=new URL(e.url).searchParams.get(`startIndex`);if(t===null)return;let n=Number.parseInt(t,10);return!Number.isSafeInteger(n)||n<0?Response.json({error:`Expected startIndex to be a non-negative integer.`,ok:!1},{status:400}):n}function serializeAsNdjson(e){let t=new TextEncoder;return e.pipeThrough(new TransformStream({transform(e,n){n.enqueue(t.encode(`${JSON.stringify(e)}\n`))}}))}export{defaultEveAuth,eveChannel};
1
+ import{createLogger,logError}from"#internal/logging.js";import{hasInternalRefScheme}from"#internal/attachments/url-refs.js";import{EVE_CANCEL_TURN_ROUTE_PATTERN,EVE_INFO_ROUTE_PATH}from"#protocol/routes.js";import{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{isInputResponse}from"#runtime/input/types.js";import{parseJsonObject}from"#shared/json.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import"ai";import{parseSessionCallback}from"#channel/session-callback.js";import{readAgentInfoRouteResponse,readRouteAgent}from"#internal/nitro/routes/channel-route-context.js";import{routeAuth}from"#public/channels/auth.js";import{collectUploadPolicyViolations,formatUploadPolicyViolation,mergeUploadPolicy}from"#public/channels/upload-policy.js";const log=createLogger(`eve.channel`);function defaultEveAuth(e){return e.eve.caller}function eveChannel(e){let n=mergeUploadPolicy(e.uploadPolicy);return defineChannel({cors:normalizeEveCors(e.cors),routes:[GET(EVE_INFO_ROUTE_PATH,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=readAgentInfoRouteResponse(n);return i===void 0?Response.json({error:`Agent info route requires internal channel dispatch context.`,ok:!1},{status:500}):await i()}),POST(`/eve/v1/session`,async(t,{send:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=i,o;try{o=await t.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof o!=`object`||!o)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let s=parseCreateBody(o);if(s instanceof Response)return s;let c=checkUploadPolicy(s,n);if(c!==null)return c;let l=await resolveOnMessage({auth:a,config:e,message:s.message,request:t});if(l instanceof Response)return l;if(!l.dispatch)return droppedMessageResponse();let u=`eve:${crypto.randomUUID()}`,d=await r(createSendPayload(s,mergeContext(s.context,l.context)),{auth:l.auth,callback:s.callback,continuationToken:u,mode:s.mode});return Response.json({continuationToken:d.continuationToken,ok:!0,sessionId:d.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:d.id},status:202})}),POST(`/eve/v1/session/:sessionId`,async(t,{send:r,getSession:i,params:a})=>{let o=await routeAuth(t,e.auth);if(o instanceof Response)return o;let s=o,c=a.sessionId;if(!c)return Response.json({error:`Missing session id.`,ok:!1},{status:400});try{i(c)}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}let l;try{l=await t.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof l!=`object`||!l)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let u=parseContinueBody(l);if(u instanceof Response)return u;let d=checkUploadPolicy(u,n);if(d!==null)return d;let f=u.context,p=s;if(u.message!==void 0){let n=await resolveOnMessage({auth:s,config:e,message:u.message,request:t,sessionId:c});if(n instanceof Response)return n;if(!n.dispatch)return droppedMessageResponse();f=mergeContext(u.context,n.context),p=n.auth}let m=await r({inputResponses:u.inputResponses,message:u.message,context:f,outputSchema:u.outputSchema},{auth:p,continuationToken:u.continuationToken});return Response.json({ok:!0,sessionId:m.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:m.id},status:200})}),POST(EVE_CANCEL_TURN_ROUTE_PATTERN,async(n,r)=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=r.params.sessionId;if(!a)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let o=await parseCancelTurnBody(n);if(o instanceof Response)return o;let s;try{let e=readRouteAgent(r);if(e===void 0)throw Error(`Missing route agent.`);s=await e.cancelTurn({sessionId:a,turnId:o.turnId})}catch(e){let n=logError(log,`cancel-turn request failed`,e,{sessionId:a});return Response.json({error:`Failed to cancel the turn.`,errorId:n,ok:!1},{status:500})}return Response.json({ok:!0,sessionId:a,status:s.status},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:a},status:202})}),GET(`/eve/v1/session/:sessionId/stream`,async(t,{getSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let u=r.sessionId;if(!u)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let d=parseStartIndex(t);if(d instanceof Response)return d;try{let e=serializeAsNdjson(await n(u).getEventStream({startIndex:d}));return new Response(e,{headers:{"cache-control":`no-store, no-transform`,"content-type":EVE_MESSAGE_STREAM_CONTENT_TYPE,"x-accel-buffering":`no`,[EVE_SESSION_ID_HEADER]:u,[EVE_STREAM_FORMAT_HEADER]:EVE_MESSAGE_STREAM_FORMAT,[EVE_STREAM_VERSION_HEADER]:EVE_MESSAGE_STREAM_VERSION}})}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}})],events:e.events})}function normalizeEveCors(e){if(e===void 0||e===!1)return!1;if(e===!0)return!0;let t={};return e.origin!==void 0&&(t.origin=normalizeEveCorsOrigin(e.origin)),e.methods!==void 0&&(t.methods=e.methods),e.allowedHeaders!==void 0&&(t.allowHeaders=e.allowedHeaders),e.exposedHeaders!==void 0&&(t.exposeHeaders=e.exposedHeaders),e.credentials!==void 0&&(t.credentials=e.credentials),e.maxAge!==void 0&&(t.maxAge=e.maxAge),e.preflightStatus!==void 0&&(t.preflight={statusCode:e.preflightStatus}),t}function normalizeEveCorsOrigin(e){return e===`*`||e===`null`?e:typeof e==`string`?[e]:e}async function resolveOnMessage(e){let n=e.config.onMessage??defaultOnMessage,r;try{r=await n({eve:e.sessionId===void 0?{caller:e.auth,request:e.request}:{caller:e.auth,request:e.request,sessionId:e.sessionId}},e.message)}catch(n){let r=logError(log,`onMessage handler failed`,n,{sessionId:e.sessionId});return Response.json({error:`onMessage handler failed.`,errorId:r,ok:!1},{status:500})}return r==null?{dispatch:!1}:r.context===void 0?{auth:r.auth,dispatch:!0}:{auth:r.auth,context:r.context,dispatch:!0}}function defaultOnMessage(e){return{auth:defaultEveAuth(e)}}function droppedMessageResponse(){return new Response(null,{headers:{"cache-control":`no-store`},status:204})}function parseCreateBody(e){let t=parseMessageField(e.message);if(t instanceof Response)return t;let n=parseClientContextField(e.clientContext);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseModeField(e.mode);if(i instanceof Response)return i;let a=parseOutputSchemaField(e.outputSchema);return a instanceof Response?a:t===void 0?Response.json({error:`Missing or empty 'message' field.`,ok:!1},{status:400}):{callback:r,message:t,mode:i,context:n,outputSchema:a}}function parseContinueBody(e){let t=typeof e.continuationToken==`string`&&e.continuationToken.length>0?e.continuationToken:void 0;if(t===void 0)return Response.json({error:`Missing or empty 'continuationToken' field.`,ok:!1},{status:400});let n=parseMessageField(e.message);if(n instanceof Response)return n;let r=parseInputResponses(e.inputResponses);if(r instanceof Response)return r;let i=parseClientContextField(e.clientContext);if(i instanceof Response)return i;let a=parseOutputSchemaField(e.outputSchema);return a instanceof Response?a:n===void 0&&r===void 0?Response.json({error:`Expected a non-empty 'message', a non-empty 'inputResponses' array, or both.`,ok:!1},{status:400}):{message:n,continuationToken:t,inputResponses:r,context:i,outputSchema:a}}async function parseCancelTurnBody(e){let t;try{t=await e.text()}catch{return Response.json({error:`Unreadable request body.`,ok:!1},{status:400})}if(t.trim().length===0)return{};let n;try{n=JSON.parse(t)}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof n!=`object`||!n||Array.isArray(n))return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let r=n.turnId;return r===void 0?{}:typeof r!=`string`||r.length===0?Response.json({error:`Expected 'turnId' to be a non-empty string.`,ok:!1},{status:400}):{turnId:r}}function createSendPayload(e,t=e.context){if(t===void 0&&e.outputSchema===void 0)return e.message;let n={message:e.message};return t!==void 0&&(n.context=t),e.outputSchema!==void 0&&(n.outputSchema=e.outputSchema),n}function parseOutputSchemaField(e){if(e!==void 0)try{return parseJsonObject(e)}catch{return Response.json({error:`Expected 'outputSchema' to be a JSON-serializable object.`,ok:!1},{status:400})}}function parseCallbackField(e){if(e===void 0)return;let t=parseSessionCallback(e);return t.ok?t.callback:Response.json({error:t.message,ok:!1},{status:400})}function parseModeField(e){if(e!==void 0)return e===`conversation`||e===`task`?e:Response.json({error:`Expected 'mode' to be either 'conversation' or 'task'.`,ok:!1},{status:400})}function parseMessageField(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=parseMessagePart(n);if(e instanceof Response)return e;t.push(e)}return t}function parseMessagePart(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});if(hasInternalRefScheme(t.data))return Response.json({error:`File part 'data' must not use a framework-internal ref scheme.`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function checkUploadPolicy(e,t){if(!e.message)return null;let n=collectUploadPolicyViolations(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:formatUploadPolicyViolation(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function parseInputResponses(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(isInputResponse);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function mergeContext(e,t){return e===void 0?t:t===void 0?e:[...e,...t]}function parseClientContextField(e){if(e!==void 0){if(typeof e==`string`)return e.length>0?[toClientContextMessage(e)]:void 0;if(Array.isArray(e))return e.length===0?void 0:e.every(e=>typeof e==`string`&&e.length>0)?e.map(e=>toClientContextMessage(e)):Response.json({error:`Expected 'clientContext' array entries to be non-empty strings.`,ok:!1},{status:400});if(typeof e!=`object`||!e)return Response.json({error:`Expected 'clientContext' to be a string, string array, or JSON object.`,ok:!1},{status:400});try{let t=parseJsonObject(e);return[toClientContextMessage(JSON.stringify(t))]}catch{return Response.json({error:`Expected 'clientContext' to be a JSON-serializable object.`,ok:!1},{status:400})}}}function toClientContextMessage(e){return`Client context:
2
+ ${e}`}function parseStartIndex(e){let t=new URL(e.url).searchParams.get(`startIndex`);if(t===null)return;let n=Number(t);return!/^-?\d+$/.test(t)||!Number.isSafeInteger(n)?Response.json({error:`Expected startIndex to be an integer.`,ok:!1},{status:400}):n}function serializeAsNdjson(e){let t=new TextEncoder;return e.pipeThrough(new TransformStream({transform(e,n){n.enqueue(t.encode(`${JSON.stringify(e)}\n`))}}))}export{defaultEveAuth,eveChannel};
@@ -88,6 +88,7 @@ export interface GitHubChannelEvents {
88
88
  readonly "session.failed"?: GitHubSessionFailedHandler;
89
89
  readonly "session.waiting"?: GitHubEventHandler<"session.waiting">;
90
90
  readonly "turn.completed"?: GitHubEventHandler<"turn.completed">;
91
+ readonly "turn.cancelled"?: GitHubEventHandler<"turn.cancelled">;
91
92
  readonly "turn.failed"?: GitHubEventHandler<"turn.failed">;
92
93
  readonly "turn.started"?: GitHubEventHandler<"turn.started">;
93
94
  }
@@ -48,7 +48,6 @@ export interface LinearAgentSessionRecord {
48
48
  url?: string;
49
49
  } | null;
50
50
  issueId?: string | null;
51
- organizationId?: string;
52
51
  sourceCommentId?: string | null;
53
52
  status?: string;
54
53
  url?: string | null;
@@ -1,4 +1,15 @@
1
- import{isObject}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";import{resolveLinearAccessToken}from"#public/channels/linear/auth.js";var LinearApiError=class extends Error{body;queryName;status;constructor(e){super(`Linear GraphQL ${e.queryName} failed with HTTP ${e.status}.`),this.name=`LinearApiError`,this.body=e.body,this.queryName=e.queryName,this.status=e.status}};async function callLinearGraphQL(t){let r=t.api?.fetch??fetch,i=await resolveLinearAccessToken(t.credentials?.accessToken),a=await r(t.api?.apiBaseUrl??`https://api.linear.app/graphql`,{body:JSON.stringify({query:t.query,variables:t.variables??{}}),headers:{authorization:`Bearer ${i}`,"content-type":`application/json; charset=utf-8`},method:`POST`}),o=await parseResponseBody(a);if(!a.ok||hasGraphQLErrors(o)||!isObject(o)||!isObject(o.data))throw new LinearApiError({body:o,queryName:t.queryName,status:a.status});return o.data}async function createLinearAgentActivity(e){let n=(await callLinearGraphQL({api:e.api,credentials:e.credentials,query:`
1
+ import{isObject}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";import{resolveLinearAccessToken}from"#public/channels/linear/auth.js";const AGENT_SESSION_FIELDS=`
2
+ fragment AgentSessionFields on AgentSession {
3
+ id
4
+ appUser { id }
5
+ comment { id }
6
+ creator { id }
7
+ issue { id identifier title url }
8
+ sourceComment { id }
9
+ status
10
+ url
11
+ }
12
+ `;var LinearApiError=class extends Error{body;queryName;status;constructor(e){super(`Linear GraphQL ${e.queryName} failed with HTTP ${e.status}.`),this.name=`LinearApiError`,this.body=e.body,this.queryName=e.queryName,this.status=e.status}};async function callLinearGraphQL(t){let r=t.api?.fetch??fetch,i=await resolveLinearAccessToken(t.credentials?.accessToken),a=await r(t.api?.apiBaseUrl??`https://api.linear.app/graphql`,{body:JSON.stringify({query:t.query,variables:t.variables??{}}),headers:{authorization:`Bearer ${i}`,"content-type":`application/json; charset=utf-8`},method:`POST`}),o=await parseResponseBody(a);if(!a.ok||hasGraphQLErrors(o)||!isObject(o)||!isObject(o.data))throw new LinearApiError({body:o,queryName:t.queryName,status:a.status});return o.data}async function createLinearAgentActivity(e){let n=(await callLinearGraphQL({api:e.api,credentials:e.credentials,query:`
2
13
  mutation AgentActivityCreate($input: AgentActivityCreateInput!) {
3
14
  agentActivityCreate(input: $input) {
4
15
  success
@@ -16,37 +27,21 @@ import{isObject}from"#shared/guards.js";import{parseJsonObject}from"#shared/json
16
27
  agentSessionCreateOnIssue(input: $input) {
17
28
  success
18
29
  agentSession {
19
- id
20
- appUserId
21
- commentId
22
- creator { id }
23
- issue { id identifier title url }
24
- issueId
25
- organizationId
26
- sourceCommentId
27
- status
28
- url
30
+ ...AgentSessionFields
29
31
  }
30
32
  }
31
33
  }
34
+ ${AGENT_SESSION_FIELDS}
32
35
  `,queryName:`AgentSessionCreateOnIssue`,variables:{input:parseJsonObject({externalLink:e.externalLink,externalUrls:e.externalUrls,issueId:e.issueId})}})).agentSessionCreateOnIssue?.agentSession)}async function createLinearAgentSessionOnComment(e){return normalizeAgentSessionRecord((await callLinearGraphQL({api:e.api,credentials:e.credentials,query:`
33
36
  mutation AgentSessionCreateOnComment($input: AgentSessionCreateOnComment!) {
34
37
  agentSessionCreateOnComment(input: $input) {
35
38
  success
36
39
  agentSession {
37
- id
38
- appUserId
39
- commentId
40
- creator { id }
41
- issue { id identifier title url }
42
- issueId
43
- organizationId
44
- sourceCommentId
45
- status
46
- url
40
+ ...AgentSessionFields
47
41
  }
48
42
  }
49
43
  }
44
+ ${AGENT_SESSION_FIELDS}
50
45
  `,queryName:`AgentSessionCreateOnComment`,variables:{input:parseJsonObject({commentId:e.commentId,externalLink:e.externalLink,externalUrls:e.externalUrls})}})).agentSessionCreateOnComment?.agentSession)}async function listLinearAgentSessionActivities(e){let t=(await callLinearGraphQL({api:e.api,credentials:e.credentials,query:`
51
46
  query AgentSessionActivities($id: String!, $last: Int!) {
52
47
  agentSession(id: $id) {
@@ -66,4 +61,4 @@ import{isObject}from"#shared/guards.js";import{parseJsonObject}from"#shared/json
66
61
  }
67
62
  }
68
63
  }
69
- `,queryName:`AgentSessionActivities`,variables:{id:e.agentSessionId,last:e.last??20}})).agentSession?.activities?.nodes;return Array.isArray(t)?t.map(normalizeAgentActivityRecord).filter(notNull):[]}function normalizeAgentSessionRecord(t){if(!isObject(t)||typeof t.id!=`string`)throw Error(`linearChannel: Linear Agent Session response was malformed.`);let n=isObject(t.creator)?t.creator:void 0,r=normalizeIssue(t.issue),i={id:t.id};return typeof t.appUserId==`string`&&(i.appUserId=t.appUserId),(typeof t.commentId==`string`||t.commentId===null)&&(i.commentId=t.commentId),(typeof n?.id==`string`||n===void 0)&&(i.creatorId=typeof n?.id==`string`?n.id:null),r!==void 0&&(i.issue=r),(typeof t.issueId==`string`||t.issueId===null)&&(i.issueId=t.issueId),typeof t.organizationId==`string`&&(i.organizationId=t.organizationId),(typeof t.sourceCommentId==`string`||t.sourceCommentId===null)&&(i.sourceCommentId=t.sourceCommentId),typeof t.status==`string`&&(i.status=t.status),(typeof t.url==`string`||t.url===null)&&(i.url=t.url),i}function normalizeAgentActivityRecord(t){if(!isObject(t)||typeof t.id!=`string`||!isObject(t.content))return null;let n={};typeof t.content.body==`string`&&(n.body=t.content.body),typeof t.content.type==`string`&&(n.type=t.content.type),typeof t.content.__typename==`string`&&(n.__typename=t.content.__typename);let r={content:n,id:t.id};return typeof t.updatedAt==`string`&&(r.updatedAt=t.updatedAt),r}function normalizeIssue(t){if(t===null)return null;if(!isObject(t)||typeof t.id!=`string`)return;let n={id:t.id};return typeof t.identifier==`string`&&(n.identifier=t.identifier),typeof t.title==`string`&&(n.title=t.title),typeof t.url==`string`&&(n.url=t.url),n}async function parseResponseBody(e){let t=await e.text();if(!t)return null;try{return JSON.parse(t)}catch{return t}}function hasGraphQLErrors(t){return isObject(t)&&Array.isArray(t.errors)&&t.errors.length>0}function notNull(e){return e!==null}export{LinearApiError,callLinearGraphQL,createLinearAgentActivity,createLinearAgentSessionOnComment,createLinearAgentSessionOnIssue,listLinearAgentSessionActivities,updateLinearAgentSession};
64
+ `,queryName:`AgentSessionActivities`,variables:{id:e.agentSessionId,last:e.last??20}})).agentSession?.activities?.nodes;return Array.isArray(t)?t.map(normalizeAgentActivityRecord).filter(notNull):[]}function normalizeAgentSessionRecord(t){if(!isObject(t)||typeof t.id!=`string`)throw Error(`linearChannel: Linear Agent Session response was malformed.`);let n=normalizeIssue(t.issue),r={id:t.id},i=relationId(t.appUser);typeof i==`string`&&(r.appUserId=i);let a=relationId(t.comment);a!==void 0&&(r.commentId=a);let o=relationId(t.creator);o!==void 0&&(r.creatorId=o),n!==void 0&&(r.issue=n);let s=relationId(t.issue);s!==void 0&&(r.issueId=s);let c=relationId(t.sourceComment);return c!==void 0&&(r.sourceCommentId=c),typeof t.status==`string`&&(r.status=t.status),(typeof t.url==`string`||t.url===null)&&(r.url=t.url),r}function relationId(t){if(t===null)return null;if(isObject(t)&&typeof t.id==`string`)return t.id}function normalizeAgentActivityRecord(t){if(!isObject(t)||typeof t.id!=`string`||!isObject(t.content))return null;let n={};typeof t.content.body==`string`&&(n.body=t.content.body),typeof t.content.type==`string`&&(n.type=t.content.type),typeof t.content.__typename==`string`&&(n.__typename=t.content.__typename);let r={content:n,id:t.id};return typeof t.updatedAt==`string`&&(r.updatedAt=t.updatedAt),r}function normalizeIssue(t){if(t===null)return null;if(!isObject(t)||typeof t.id!=`string`)return;let n={id:t.id};return typeof t.identifier==`string`&&(n.identifier=t.identifier),typeof t.title==`string`&&(n.title=t.title),typeof t.url==`string`&&(n.url=t.url),n}async function parseResponseBody(e){let t=await e.text();if(!t)return null;try{return JSON.parse(t)}catch{return t}}function hasGraphQLErrors(t){return isObject(t)&&Array.isArray(t.errors)&&t.errors.length>0}function notNull(e){return e!==null}export{LinearApiError,callLinearGraphQL,createLinearAgentActivity,createLinearAgentSessionOnComment,createLinearAgentSessionOnIssue,listLinearAgentSessionActivities,updateLinearAgentSession};
@@ -102,6 +102,7 @@ export interface LinearChannelEvents {
102
102
  readonly "input.requested"?: LinearEventHandler<"input.requested">;
103
103
  readonly "turn.failed"?: LinearEventHandler<"turn.failed">;
104
104
  readonly "turn.completed"?: LinearEventHandler<"turn.completed">;
105
+ readonly "turn.cancelled"?: LinearEventHandler<"turn.cancelled">;
105
106
  readonly "session.failed"?: LinearSessionFailedHandler;
106
107
  readonly "session.completed"?: LinearEventHandler<"session.completed">;
107
108
  readonly "session.waiting"?: LinearEventHandler<"session.waiting">;
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{createLinearAgentActivity,createLinearAgentSessionOnComment,createLinearAgentSessionOnIssue,listLinearAgentSessionActivities,updateLinearAgentSession}from"#public/channels/linear/api.js";import{resolveLinearPromptInputResponses}from"#public/channels/linear/hitl.js";import{LINEAR_CHANNEL_DEFAULT_ROUTE}from"#public/channels/linear/constants.js";import{createDefaultEvents,defaultOnAgentSession}from"#public/channels/linear/defaults.js";import{formatLinearContextBlock,linearContinuationToken,messageFromLinearAgentSessionEvent,parseLinearWebhookEvent}from"#public/channels/linear/inbound.js";import{verifyLinearRequest}from"#public/channels/linear/verify.js";const log=createLogger(`linear.channel`);function linearChannel(e={}){let t=e.onAgentSession??defaultOnAgentSession,a={...createDefaultEvents({api:e.api,credentials:e.credentials}),...e.events};return defineChannel({kindHint:`linear`,state:initialLinearState(),metadata(e){return{agentSessionId:e.agentSessionId,commentId:e.commentId??null,issueId:e.issueId??null,issueIdentifier:e.issueIdentifier??null,organizationId:e.organizationId??null}},context(t,n){return rebuildLinearContext(t,n,e)},routes:[POST(e.route??LINEAR_CHANNEL_DEFAULT_ROUTE,async(n,{send:r,waitUntil:i})=>{let a=await verifyInbound(n,e.credentials);if(a===null)return new Response(`unauthorized`,{status:401});let o;try{o=parseLinearWebhookEvent({body:a,headers:n.headers})}catch(e){return log.warn(`inbound Linear body is not valid JSON`,{error:e}),jsonOk({ignored:!0,ok:!0})}return o===null?jsonOk({ignored:!0,ok:!0}):o.kind===`agent_session`?(i(dispatchAgentSession({config:e,event:o,onAgentSession:t,send:r})),jsonOk({ok:!0})):e.onDataWebhook===void 0?jsonOk({ignored:!0,ok:!0}):(i(Promise.resolve(e.onDataWebhook(o))),jsonOk({ok:!0}))})],async receive(t,{send:n}){let r=t.target,a=await resolveReceiveSession(r,e),o=readString(r.initialActivity);return o!==void 0&&await createLinearAgentActivity({api:e.api,credentials:e.credentials,activity:{agentSessionId:a.id,content:{body:o,type:`thought`}}}),n(t.message,{auth:t.auth,continuationToken:linearContinuationToken(a.id),state:stateFromAgentSession(a)})},events:a})}function rebuildLinearContext(e,t,n){return{linear:buildLinearHandle({agentSessionId:e.agentSessionId??``,config:n}),state:e}}function buildLinearHandle(e){return{agentSessionId:e.agentSessionId,createActivity(t,n){return createLinearAgentActivity({api:e.config.api,credentials:e.config.credentials,activity:{agentSessionId:e.agentSessionId,content:t,ephemeral:n?.ephemeral,signal:n?.signal,signalMetadata:n?.signalMetadata}})},listActivities(t){return listLinearAgentSessionActivities({api:e.config.api,credentials:e.config.credentials,agentSessionId:e.agentSessionId,last:t?.last})},updateSession(t){return updateLinearAgentSession({api:e.config.api,credentials:e.config.credentials,id:e.agentSessionId,update:t})}}}async function dispatchAgentSession(e){let{event:t}=e,n={delivery:t.delivery,linear:buildLinearHandle({agentSessionId:t.agentSession.id,config:e.config}),session:t.agentSession},r=await e.onAgentSession(n,t);if(r===null)return;let i=t.agentActivity?.body,a=t.action===`prompted`&&i!==void 0?await resolvePromptResponses({body:i,config:e.config,event:t}):[];await e.send({context:[formatLinearContextBlock(t),...t.previousComments,...r.context??[]],inputResponses:a,message:messageFromLinearAgentSessionEvent(t)},{auth:r.auth,continuationToken:linearContinuationToken(t.agentSession.id),state:stateFromAgentSession(t.agentSession)})}async function resolvePromptResponses(e){try{return resolveLinearPromptInputResponses({activities:await listLinearAgentSessionActivities({api:e.config.api,credentials:e.config.credentials,agentSessionId:e.event.agentSession.id,last:20}),body:e.body})}catch(e){return log.warn(`linear HITL activity lookup failed — treating prompt as a message`,{error:e}),[]}}async function resolveReceiveSession(e,t){if(hasString(e,`agentSessionId`))return{id:e.agentSessionId};if(hasString(e,`issueId`))return createLinearAgentSessionOnIssue({api:t.api,credentials:t.credentials,externalLink:readString(e.externalLink),externalUrls:readExternalUrls(e.externalUrls),issueId:e.issueId});if(hasString(e,`commentId`))return createLinearAgentSessionOnComment({api:t.api,credentials:t.credentials,commentId:e.commentId,externalLink:readString(e.externalLink),externalUrls:readExternalUrls(e.externalUrls)});throw Error(`linearChannel().receive requires target.agentSessionId, issueId, or commentId.`)}function stateFromAgentSession(e){return{agentSessionId:e.id,agentSessionUrl:e.url??null,commentId:e.commentId??null,issueId:e.issueId??e.issue?.id??null,issueIdentifier:e.issue?.identifier??null,issueTitle:e.issue?.title??null,issueUrl:e.issue?.url??null,organizationId:e.organizationId??null,pendingToolCallMessage:null,sourceCommentId:e.sourceCommentId??null}}function initialLinearState(){return{agentSessionId:null,agentSessionUrl:null,commentId:null,issueId:null,issueIdentifier:null,issueTitle:null,issueUrl:null,organizationId:null,pendingToolCallMessage:null,sourceCommentId:null}}async function verifyInbound(e,t){try{return await verifyLinearRequest(e,{webhookSecret:t?.webhookSecret,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`linear inbound verification failed`,{error:e}),null}}function hasString(e,t){return typeof e[t]==`string`&&e[t].length>0}function readString(e){return typeof e==`string`&&e.length>0?e:void 0}function readExternalUrls(e){if(!Array.isArray(e))return;let n=e.filter(e=>isObject(e)&&typeof e.label==`string`&&typeof e.url==`string`);return n.length>0?n:void 0}function jsonOk(e){return new Response(JSON.stringify(e),{headers:{"content-type":`application/json; charset=utf-8`},status:200})}export{linearChannel};
1
+ import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{createLinearAgentActivity,createLinearAgentSessionOnComment,createLinearAgentSessionOnIssue,listLinearAgentSessionActivities,updateLinearAgentSession}from"#public/channels/linear/api.js";import{resolveLinearPromptInputResponses}from"#public/channels/linear/hitl.js";import{LINEAR_CHANNEL_DEFAULT_ROUTE}from"#public/channels/linear/constants.js";import{createDefaultEvents,defaultOnAgentSession}from"#public/channels/linear/defaults.js";import{formatLinearContextBlock,linearContinuationToken,messageFromLinearAgentSessionEvent,parseLinearWebhookEvent}from"#public/channels/linear/inbound.js";import{verifyLinearRequest}from"#public/channels/linear/verify.js";const log=createLogger(`linear.channel`);function linearChannel(e={}){let t=e.onAgentSession??defaultOnAgentSession,a={...createDefaultEvents({api:e.api,credentials:e.credentials}),...e.events};return defineChannel({kindHint:`linear`,state:initialLinearState(),metadata(e){return{agentSessionId:e.agentSessionId,commentId:e.commentId??null,issueId:e.issueId??null,issueIdentifier:e.issueIdentifier??null,organizationId:e.organizationId??null}},context(t,n){return rebuildLinearContext(t,n,e)},routes:[POST(e.route??LINEAR_CHANNEL_DEFAULT_ROUTE,async(n,{send:r,waitUntil:i})=>{let a=await verifyInbound(n,e.credentials);if(a===null)return new Response(`unauthorized`,{status:401});let o;try{o=parseLinearWebhookEvent({body:a,headers:n.headers})}catch(e){return log.warn(`inbound Linear body is not valid JSON`,{error:e}),jsonOk({ignored:!0,ok:!0})}return o===null?jsonOk({ignored:!0,ok:!0}):o.kind===`agent_session`?(i(dispatchAgentSession({config:e,event:o,onAgentSession:t,send:r})),jsonOk({ok:!0})):e.onDataWebhook===void 0?jsonOk({ignored:!0,ok:!0}):(i(Promise.resolve(e.onDataWebhook(o))),jsonOk({ok:!0}))})],async receive(t,{send:n}){let r=t.target,a=await resolveReceiveSession(r,e),o=readString(r.initialActivity);return o!==void 0&&await createLinearAgentActivity({api:e.api,credentials:e.credentials,activity:{agentSessionId:a.id,content:{body:o,type:`thought`}}}),n(t.message,{auth:t.auth,continuationToken:linearContinuationToken(a.id),state:stateFromAgentSession(a)})},events:a})}function rebuildLinearContext(e,t,n){return{linear:buildLinearHandle({agentSessionId:e.agentSessionId??``,config:n}),state:e}}function buildLinearHandle(e){return{agentSessionId:e.agentSessionId,createActivity(t,n){return createLinearAgentActivity({api:e.config.api,credentials:e.config.credentials,activity:{agentSessionId:e.agentSessionId,content:t,ephemeral:n?.ephemeral,signal:n?.signal,signalMetadata:n?.signalMetadata}})},listActivities(t){return listLinearAgentSessionActivities({api:e.config.api,credentials:e.config.credentials,agentSessionId:e.agentSessionId,last:t?.last})},updateSession(t){return updateLinearAgentSession({api:e.config.api,credentials:e.config.credentials,id:e.agentSessionId,update:t})}}}async function dispatchAgentSession(e){let{event:t}=e,n={delivery:t.delivery,linear:buildLinearHandle({agentSessionId:t.agentSession.id,config:e.config}),session:t.agentSession},r=await e.onAgentSession(n,t);if(r===null)return;let i=t.agentActivity?.body,a=t.action===`prompted`&&i!==void 0?await resolvePromptResponses({body:i,config:e.config,event:t}):[];await e.send({context:[formatLinearContextBlock(t),...t.previousComments,...r.context??[]],inputResponses:a,message:messageFromLinearAgentSessionEvent(t)},{auth:r.auth,continuationToken:linearContinuationToken(t.agentSession.id),state:stateFromAgentSession(t.agentSession)})}async function resolvePromptResponses(e){try{return resolveLinearPromptInputResponses({activities:await listLinearAgentSessionActivities({api:e.config.api,credentials:e.config.credentials,agentSessionId:e.event.agentSession.id,last:20}),body:e.body})}catch(e){return log.warn(`linear HITL activity lookup failed — treating prompt as a message`,{error:e}),[]}}async function resolveReceiveSession(e,t){if(hasString(e,`agentSessionId`))return{id:e.agentSessionId};if(hasString(e,`issueId`))return createLinearAgentSessionOnIssue({api:t.api,credentials:t.credentials,externalLink:readString(e.externalLink),externalUrls:readExternalUrls(e.externalUrls),issueId:e.issueId});if(hasString(e,`commentId`))return createLinearAgentSessionOnComment({api:t.api,credentials:t.credentials,commentId:e.commentId,externalLink:readString(e.externalLink),externalUrls:readExternalUrls(e.externalUrls)});throw Error(`linearChannel().receive requires target.agentSessionId, issueId, or commentId.`)}function stateFromAgentSession(e){return{agentSessionId:e.id,agentSessionUrl:e.url??null,commentId:e.commentId??null,issueId:e.issueId??e.issue?.id??null,issueIdentifier:e.issue?.identifier??null,issueTitle:e.issue?.title??null,issueUrl:e.issue?.url??null,organizationId:`organizationId`in e?e.organizationId??null:null,pendingToolCallMessage:null,sourceCommentId:e.sourceCommentId??null}}function initialLinearState(){return{agentSessionId:null,agentSessionUrl:null,commentId:null,issueId:null,issueIdentifier:null,issueTitle:null,issueUrl:null,organizationId:null,pendingToolCallMessage:null,sourceCommentId:null}}async function verifyInbound(e,t){try{return await verifyLinearRequest(e,{webhookSecret:t?.webhookSecret,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`linear inbound verification failed`,{error:e}),null}}function hasString(e,t){return typeof e[t]==`string`&&e[t].length>0}function readString(e){return typeof e==`string`&&e.length>0?e:void 0}function readExternalUrls(e){if(!Array.isArray(e))return;let n=e.filter(e=>isObject(e)&&typeof e.label==`string`&&typeof e.url==`string`);return n.length>0?n:void 0}function jsonOk(e){return new Response(JSON.stringify(e),{headers:{"content-type":`application/json; charset=utf-8`},status:200})}export{linearChannel};
@@ -256,6 +256,7 @@ export interface SlackChannelEvents {
256
256
  readonly "input.requested"?: SlackEventHandler<"input.requested">;
257
257
  readonly "turn.failed"?: SlackEventHandler<"turn.failed">;
258
258
  readonly "turn.completed"?: SlackEventHandler<"turn.completed">;
259
+ readonly "turn.cancelled"?: SlackEventHandler<"turn.cancelled">;
259
260
  readonly "session.failed"?: SlackSessionFailedHandler;
260
261
  readonly "session.completed"?: SlackEventHandler<"session.completed">;
261
262
  readonly "session.waiting"?: SlackEventHandler<"session.waiting">;
@@ -99,6 +99,7 @@ export interface TeamsChannelEvents {
99
99
  readonly "input.requested"?: TeamsEventHandler<"input.requested">;
100
100
  readonly "turn.failed"?: TeamsEventHandler<"turn.failed">;
101
101
  readonly "turn.completed"?: TeamsEventHandler<"turn.completed">;
102
+ readonly "turn.cancelled"?: TeamsEventHandler<"turn.cancelled">;
102
103
  readonly "session.failed"?: TeamsSessionFailedHandler;
103
104
  readonly "session.completed"?: TeamsEventHandler<"session.completed">;
104
105
  readonly "session.waiting"?: TeamsEventHandler<"session.waiting">;
@@ -73,6 +73,7 @@ export interface TelegramChannelEvents {
73
73
  readonly "input.requested"?: TelegramEventHandler<"input.requested">;
74
74
  readonly "turn.failed"?: TelegramEventHandler<"turn.failed">;
75
75
  readonly "turn.completed"?: TelegramEventHandler<"turn.completed">;
76
+ readonly "turn.cancelled"?: TelegramEventHandler<"turn.cancelled">;
76
77
  readonly "session.failed"?: TelegramSessionFailedHandler;
77
78
  readonly "session.completed"?: TelegramEventHandler<"session.completed">;
78
79
  readonly "session.waiting"?: TelegramEventHandler<"session.waiting">;
@@ -94,6 +94,7 @@ export interface TwilioChannelEvents {
94
94
  readonly "input.requested"?: TwilioEventHandler<"input.requested">;
95
95
  readonly "turn.failed"?: TwilioEventHandler<"turn.failed">;
96
96
  readonly "turn.completed"?: TwilioEventHandler<"turn.completed">;
97
+ readonly "turn.cancelled"?: TwilioEventHandler<"turn.cancelled">;
97
98
  readonly "session.failed"?: TwilioSessionFailedHandler;
98
99
  readonly "session.completed"?: TwilioEventHandler<"session.completed">;
99
100
  readonly "session.waiting"?: TwilioEventHandler<"session.waiting">;
@@ -3,12 +3,12 @@ import { type ChannelCorsOptions } from "#channel/cors.js";
3
3
  import type { TypedReceiveTarget } from "#channel/receive-target.js";
4
4
  import type { RouteDefinition, SendFn } from "#channel/routes.js";
5
5
  import type { Session } from "#channel/session.js";
6
- import type { DeliverInput, GetEventStreamOptions, RunHandle, RunInput } from "#channel/types.js";
6
+ import type { CancelTurnInput, CancelTurnResult, DeliverInput, GetEventStreamOptions, RunHandle, RunInput } from "#channel/types.js";
7
7
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
8
8
  import type { SessionContext } from "#public/definitions/callback-context.js";
9
9
  import type { GenericChannelDefinition, GenericReceiveInput } from "#shared/channel-definition.js";
10
10
  declare const CHANNEL_METADATA_TYPE: unique symbol;
11
- export type { GetEventStreamOptions } from "#channel/types.js";
11
+ export type { CancelTurnInput, CancelTurnResult, GetEventStreamOptions } from "#channel/types.js";
12
12
  export type { Session, SessionHandle } from "#channel/session.js";
13
13
  export type { ChannelCors, ChannelCorsOptions } from "#channel/cors.js";
14
14
  export { GET, POST, PUT, PATCH, DELETE, WS } from "#channel/routes.js";
@@ -31,17 +31,16 @@ export type ChannelRouteMethod = ChannelMethod | "WEBSOCKET";
31
31
  * framework constructs this per request and passes it as the second
32
32
  * argument.
33
33
  *
34
- * Routes call into the agent to start new sessions (`agent.run`),
35
- * deliver follow-up messages to existing sessions (`agent.deliver`), or
36
- * read events from a previously-started session (`agent.getEventStream`).
34
+ * Routes call into the agent to start sessions, deliver follow-ups,
35
+ * cancel turns, and read events.
37
36
  */
38
37
  export interface RouteContext {
39
38
  /**
40
39
  * Handle to the agent that this route sends inbound requests to.
41
40
  * Conceptually the runtime + harness combined: routes call `run`,
42
- * `deliver`, and `getEventStream` to drive sessions of this agent
43
- * without knowing about the workflow runtime, the harness, or any
44
- * other execution-layer detail.
41
+ * `deliver`, `cancelTurn`, and `getEventStream` to drive sessions of
42
+ * this agent without knowing about the workflow runtime, the harness,
43
+ * or any other execution-layer detail.
45
44
  *
46
45
  * Every route speaks the same `RunInput` shape regardless of which
47
46
  * webhook it serves — `agent` is platform-agnostic.
@@ -78,8 +77,9 @@ export interface RouteContext {
78
77
  *
79
78
  * `Agent` is conceptually the workflow runtime plus the tool-loop harness:
80
79
  * routes call `run` to start a new session of the agent, `deliver` to
81
- * send a follow-up to a parked session, and `getEventStream` to read events
82
- * from a previously-started session. The framework's internal `Runtime`
80
+ * send a follow-up to a parked session, `cancelTurn` to stop in-flight work,
81
+ * and `getEventStream` to read events from a previously-started session.
82
+ * The framework's internal `Runtime`
83
83
  * interface (in `channel/types.ts`) is the underlying primitive — `Agent`
84
84
  * is the *public* shape exposed on `RouteContext` so route authors
85
85
  * speak in terms of the agent rather than the runtime.
@@ -91,6 +91,16 @@ export interface Agent {
91
91
  * with the same token resume the same session.
92
92
  */
93
93
  run(input: RunInput): Promise<RunHandle>;
94
+ /**
95
+ * Requests cancellation of a session's in-flight turn. A `turnId` limits
96
+ * the request to the turn the caller observed.
97
+ *
98
+ * `"accepted"` means a cancellation hook accepted the request; observe
99
+ * the event stream for `turn.cancelled` to confirm that it affected the
100
+ * current turn. `"no_active_turn"` means no cancellable hook was active.
101
+ * Both outcomes are successful.
102
+ */
103
+ cancelTurn(input: CancelTurnInput): Promise<CancelTurnResult>;
94
104
  /**
95
105
  * Sends a follow-up message to a session that is currently parked waiting
96
106
  * for input. Throws if no parked session exists for the supplied
@@ -105,10 +115,10 @@ export interface Agent {
105
115
  * existing session. Used by the framework's HTTP session-stream route and by
106
116
  * any user-authored route that exposes an event-streaming endpoint.
107
117
  *
108
- * Pass `options.startIndex` to skip events the caller has already
109
- * consumed the framework HTTP session-stream route uses this to forward
110
- * the `startIndex` query parameter so reconnecting clients resume from
111
- * the next unread event instead of replaying the session from the start.
118
+ * Nonnegative `options.startIndex` values skip events the caller has already
119
+ * consumed. Negative values read relative to the current tail (`-1` starts
120
+ * at the latest event). The framework HTTP session-stream route forwards
121
+ * the `startIndex` query parameter unchanged.
112
122
  */
113
123
  getEventStream(sessionId: string, options?: GetEventStreamOptions): Promise<ReadableStream<HandleMessageStreamEvent>>;
114
124
  }
@@ -172,6 +182,7 @@ export interface ChannelEvents<TCtx = void> {
172
182
  readonly "input.requested"?: ChannelEventHandler<"input.requested", TCtx>;
173
183
  readonly "turn.failed"?: ChannelEventHandler<"turn.failed", TCtx>;
174
184
  readonly "turn.completed"?: ChannelEventHandler<"turn.completed", TCtx>;
185
+ readonly "turn.cancelled"?: ChannelEventHandler<"turn.cancelled", TCtx>;
175
186
  readonly "session.failed"?: ChannelSessionFailedHandler<TCtx>;
176
187
  readonly "session.completed"?: ChannelEventHandler<"session.completed", TCtx>;
177
188
  readonly "session.waiting"?: ChannelEventHandler<"session.waiting", TCtx>;
@@ -1 +1 @@
1
- import{CHANNEL_SENTINEL}from"#channel/compiled-channel.js";import{defaultDeliverResult}from"#channel/adapter.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{normalizeChannelCors}from"#channel/cors.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";import{DELETE,GET,PATCH,POST,PUT,WS}from"#channel/routes.js";const DISABLED_ROUTE_SENTINEL_KIND=`eve:disabled-channel`;function disableRoute(){return{kind:DISABLED_ROUTE_SENTINEL_KIND}}function isDisabledRouteSentinel(e){return typeof e==`object`&&!!e&&e.kind===DISABLED_ROUTE_SENTINEL_KIND}function defineChannel(t){let n=buildAdapter(t),i=normalizeChannelCors(t.cors);return{__kind:CHANNEL_SENTINEL,routes:t.routes,adapter:n,cors:i,receive:t.receive}}function buildAdapter(e){let r=e.state!=null,a=e.context!=null,o=e.fetchFile!==void 0,s=e.metadata,c=r||a||s!==void 0,l={},u=!1,d=[`turn.started`,`actions.requested`,`action.result`,`message.completed`,`message.appended`,`reasoning.appended`,`reasoning.completed`,`input.requested`,`turn.failed`,`turn.completed`,`session.failed`,`session.completed`,`session.waiting`,`authorization.required`,`authorization.completed`],f=e.events;for(let e of d){let t=f?.[e];t&&(u=!0,l[e]=(r,i)=>{let a={...i,continuationToken:i.session?.continuationToken??``,setContinuationToken:e=>i.session?.setContinuationToken(e)};return e===`session.failed`?t(r,a):t(r,a,buildCallbackContext())})}return!c&&!u&&!o?{kind:e.kindHint??HTTP_ADAPTER_KIND}:{kind:e.kindHint??`defineChannel`,state:r?{...e.state}:{},fetchFile:e.fetchFile,instrumentation:s===void 0?void 0:{metadata(e){return s(e)}},createAdapterContext(t){let n=t.state,r=t.session;return{...a?e.context(n,r):{},state:n,ctx:t.ctx,session:r}},deliver(e){return defaultDeliverResult(e)},...l}}export{DELETE,GET,PATCH,POST,PUT,WS,defineChannel,disableRoute,isDisabledRouteSentinel};
1
+ import{CHANNEL_SENTINEL}from"#channel/compiled-channel.js";import{defaultDeliverResult}from"#channel/adapter.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{normalizeChannelCors}from"#channel/cors.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";import{DELETE,GET,PATCH,POST,PUT,WS}from"#channel/routes.js";const DISABLED_ROUTE_SENTINEL_KIND=`eve:disabled-channel`;function disableRoute(){return{kind:DISABLED_ROUTE_SENTINEL_KIND}}function isDisabledRouteSentinel(e){return typeof e==`object`&&!!e&&e.kind===DISABLED_ROUTE_SENTINEL_KIND}function defineChannel(t){let n=buildAdapter(t),i=normalizeChannelCors(t.cors);return{__kind:CHANNEL_SENTINEL,routes:t.routes,adapter:n,cors:i,receive:t.receive}}const eventTypes=Object.keys({"turn.started":null,"actions.requested":null,"action.result":null,"message.completed":null,"message.appended":null,"reasoning.appended":null,"reasoning.completed":null,"input.requested":null,"turn.failed":null,"turn.completed":null,"turn.cancelled":null,"session.failed":null,"session.completed":null,"session.waiting":null,"authorization.required":null,"authorization.completed":null});function buildAdapter(e){let r=e.state!=null,a=e.context!=null,o=e.fetchFile!==void 0,s=e.metadata,c=r||a||s!==void 0,l={},u=!1,d=e.events;for(let e of eventTypes){let t=d?.[e];t&&(u=!0,l[e]=(r,i)=>{let a={...i,continuationToken:i.session?.continuationToken??``,setContinuationToken:e=>i.session?.setContinuationToken(e)};return e===`session.failed`?t(r,a):t(r,a,buildCallbackContext())})}return!c&&!u&&!o?{kind:e.kindHint??HTTP_ADAPTER_KIND}:{kind:e.kindHint??`defineChannel`,state:r?{...e.state}:{},fetchFile:e.fetchFile,instrumentation:s===void 0?void 0:{metadata(e){return s(e)}},createAdapterContext(t){let n=t.state,r=t.session;return{...a?e.context(n,r):{},state:n,ctx:t.ctx,session:r}},deliver(e){return defaultDeliverResult(e)},...l}}export{DELETE,GET,PATCH,POST,PUT,WS,defineChannel,disableRoute,isDisabledRouteSentinel};
@@ -1 +1 @@
1
- import{resolveEveDestinationPrefix}from"./server.js";import{ensureEveVercelOutputConfig}from"./vercel-output-config.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{isAbsolute,join,relative,resolve}from"node:path";const EVE_NEXT_SERVICE_PREFIX=`/_eve_internal/eve`,EVE_NEXT_PRODUCTION_PORT_ENV=`EVE_NEXT_PRODUCTION_PORT`,AGENT_NAME_PATTERN=/^[a-z0-9][a-z0-9_-]*$/;function resolveApplicationRoot(e){return e===void 0||e.length===0?process.cwd():isAbsolute(e)?e:resolve(process.cwd(),e)}function resolveDevServerTimeout(e){if(e!==void 0){if(!Number.isFinite(e)||e<=0)throw Error(`eve Next.js development server timeout must be a positive number.`);return e}}function normalizeRoutePrefix(e){let t=(e.startsWith(`/`)?e:`/${e}`).replace(/\/+$/,``);if(t.length===0)throw Error(`eve Next.js service prefix cannot resolve to the root route.`);return t}function joinRoutePrefix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function createNamedAgentRoutePrefix(e){return joinRoutePrefix(`/eve/agents`,e)}function createNamedAgentServicePrefix(e,t){return joinRoutePrefix(e,t)}function createAgentRewriteSource(e){return joinRoutePrefix(e,`${EVE_ROUTE_PREFIX}/:path+`)}function normalizeOrigin(e){return new URL(e.trim()).origin}function readLocalProductionPort(e){let t=process.env[EVE_NEXT_PRODUCTION_PORT_ENV],n=t===void 0||t.trim().length===0?4274:Number.parseInt(t,10);if(t!==void 0&&t.trim().length>0&&String(n)!==t.trim())throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} must be an integer between 1 and 65535.`);let r=n+e;if(r<1||r>65535)throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} plus the eve agent count exceeds 65535.`);return r}function resolveProductionDestination(e){if(process.env.VERCEL)return{destinationPrefix:e.servicePrefix};let t=process.env.EVE_NEXT_PRODUCTION_ORIGIN;if(t!==void 0&&t.trim().length>0)return{destinationPrefix:joinRoutePrefix(normalizeOrigin(t),e.servicePrefix)};let n=`http://127.0.0.1:${String(readLocalProductionPort(e.localProductionPortOffset))}`;return{destinationPrefix:n,localServerOrigin:n}}function createEveRewriteRule(e){let t=createAgentRewriteSource(e.publicRoutePrefix);return{destination:joinRoutePrefix(e.destinationPrefix,`${EVE_ROUTE_PREFIX}/:path+`),source:t}}async function resolveExistingRewrites(e){return await e?.()}function mergeRewriteRules(e,t){return e===void 0?{beforeFiles:t}:isRewriteSections(e)?{...e,beforeFiles:[...t,...e.beforeFiles??[]]}:{afterFiles:e,beforeFiles:t}}function isRewriteSections(e){return!Array.isArray(e)}async function resolveNextConfig(e,t,n){return typeof e==`function`?await e(t,n):e}function assertValidAgentName(e){if(!AGENT_NAME_PATTERN.test(e))throw Error(`eve Next.js agent name ${JSON.stringify(e)} is invalid. Use lowercase letters, numbers, underscores, or hyphens, starting with a letter or number.`)}function quoteShellArg(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function toPosixPath(e){return e.replaceAll(`\\`,`/`)}function createDefaultBuildCommand(e){return`node ${quoteShellArg(toPosixPath(relative(e.agentRoot,join(e.nextRoot,`node_modules`,`eve`,`bin`,`eve.js`))))} build`}function normalizeAgentsConfig(e,t){let n=normalizeRoutePrefix(e.servicePrefix??`/_eve_internal/eve`),resolveBuildCommand=(n,r)=>r??e.eveBuildCommand??createDefaultBuildCommand({agentRoot:n,nextRoot:t});if(e.agents===void 0){let t=resolveApplicationRoot(e.eveRoot);return[{appRoot:t,buildCommand:resolveBuildCommand(t,void 0),localProductionPortOffset:0,publicRoutePrefix:``,servicePrefix:n}]}if(e.eveRoot!==void 0)throw Error(`withEve cannot combine eveRoot with agents. Use one configuration form.`);let r=Object.entries(e.agents);if(r.length===0)throw Error(`withEve agents must contain at least one named eve agent.`);return r.map(([e,t],r)=>{assertValidAgentName(e);let i=typeof t==`string`?{root:t}:t,a=resolveApplicationRoot(i.root);return{appRoot:a,buildCommand:resolveBuildCommand(a,i.buildCommand),localProductionPortOffset:r,name:e,publicRoutePrefix:createNamedAgentRoutePrefix(e),servicePrefix:normalizeRoutePrefix(i.servicePrefix??createNamedAgentServicePrefix(n,e))}})}function withEve(n,r={}){let i=process.cwd(),a=resolveDevServerTimeout(r.devServerTimeoutMs),o=normalizeAgentsConfig(r,i);return async function(r,s){let c=await resolveNextConfig(n,r,s),l=c.rewrites,u=await ensureEveVercelOutputConfig({agents:o.map(e=>({appRoot:e.appRoot,buildCommand:e.buildCommand,name:e.name,publicRoutePrefix:e.publicRoutePrefix,servicePrefix:e.servicePrefix})),nextRoot:i});if(process.env.VERCEL)return c;let d=new Map(u.agents.map(e=>[e.name,e])),f=o.map(e=>{let t=d.get(e.name),n=resolveProductionDestination({localProductionPortOffset:e.localProductionPortOffset,servicePrefix:t?.servicePrefix??e.servicePrefix});return{...e,productionDestination:n}});return{...c,async rewrites(){let[t,n]=await Promise.all([resolveExistingRewrites(l),Promise.all(f.map(async t=>createEveRewriteRule({destinationPrefix:await resolveEveDestinationPrefix({appRoot:t.appRoot,devServerTimeoutMs:a,logLabel:t.name,phase:r,productionDestinationPrefix:t.productionDestination.destinationPrefix,productionServerOrigin:t.productionDestination.localServerOrigin}),publicRoutePrefix:t.publicRoutePrefix})))]);return mergeRewriteRules(t,n)}}}}export{EVE_NEXT_SERVICE_PREFIX,withEve};
1
+ import{resolveEveBinaryPath}from"./resolve-eve-binary.js";import{resolveEveDestinationPrefix}from"./server.js";import{ensureEveVercelOutputConfig}from"./vercel-output-config.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{isAbsolute,relative,resolve}from"node:path";const EVE_NEXT_SERVICE_PREFIX=`/_eve_internal/eve`,EVE_NEXT_PRODUCTION_PORT_ENV=`EVE_NEXT_PRODUCTION_PORT`,AGENT_NAME_PATTERN=/^[a-z0-9][a-z0-9_-]*$/;function resolveApplicationRoot(e){return e===void 0||e.length===0?process.cwd():isAbsolute(e)?e:resolve(process.cwd(),e)}function resolveDevServerTimeout(e){if(e!==void 0){if(!Number.isFinite(e)||e<=0)throw Error(`eve Next.js development server timeout must be a positive number.`);return e}}function normalizeRoutePrefix(e){let t=(e.startsWith(`/`)?e:`/${e}`).replace(/\/+$/,``);if(t.length===0)throw Error(`eve Next.js service prefix cannot resolve to the root route.`);return t}function joinRoutePrefix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function createNamedAgentRoutePrefix(e){return joinRoutePrefix(`/eve/agents`,e)}function createNamedAgentServicePrefix(e,t){return joinRoutePrefix(e,t)}function createAgentRewriteSource(e){return joinRoutePrefix(e,`${EVE_ROUTE_PREFIX}/:path+`)}function normalizeOrigin(e){return new URL(e.trim()).origin}function readLocalProductionPort(e){let t=process.env[EVE_NEXT_PRODUCTION_PORT_ENV],n=t===void 0||t.trim().length===0?4274:Number.parseInt(t,10);if(t!==void 0&&t.trim().length>0&&String(n)!==t.trim())throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} must be an integer between 1 and 65535.`);let r=n+e;if(r<1||r>65535)throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} plus the eve agent count exceeds 65535.`);return r}function resolveProductionDestination(e){if(process.env.VERCEL)return{destinationPrefix:e.servicePrefix};let t=process.env.EVE_NEXT_PRODUCTION_ORIGIN;if(t!==void 0&&t.trim().length>0)return{destinationPrefix:joinRoutePrefix(normalizeOrigin(t),e.servicePrefix)};let n=`http://127.0.0.1:${String(readLocalProductionPort(e.localProductionPortOffset))}`;return{destinationPrefix:n,localServerOrigin:n}}function createEveRewriteRule(e){let t=createAgentRewriteSource(e.publicRoutePrefix);return{destination:joinRoutePrefix(e.destinationPrefix,`${EVE_ROUTE_PREFIX}/:path+`),source:t}}async function resolveExistingRewrites(e){return await e?.()}function mergeRewriteRules(e,t){return e===void 0?{beforeFiles:t}:isRewriteSections(e)?{...e,beforeFiles:[...t,...e.beforeFiles??[]]}:{afterFiles:e,beforeFiles:t}}function isRewriteSections(e){return!Array.isArray(e)}async function resolveNextConfig(e,t,n){return typeof e==`function`?await e(t,n):e}function assertValidAgentName(e){if(!AGENT_NAME_PATTERN.test(e))throw Error(`eve Next.js agent name ${JSON.stringify(e)} is invalid. Use lowercase letters, numbers, underscores, or hyphens, starting with a letter or number.`)}function quoteShellArg(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function toPosixPath(e){return e.replaceAll(`\\`,`/`)}function createDefaultBuildCommand(t){return`node ${quoteShellArg(toPosixPath(relative(t.agentRoot,resolveEveBinaryPath(t.nextRoot))))} build`}function normalizeAgentsConfig(e,t){let n=normalizeRoutePrefix(e.servicePrefix??`/_eve_internal/eve`),resolveBuildCommand=(n,r)=>r??e.eveBuildCommand??createDefaultBuildCommand({agentRoot:n,nextRoot:t});if(e.agents===void 0){let t=resolveApplicationRoot(e.eveRoot);return[{appRoot:t,buildCommand:resolveBuildCommand(t,void 0),localProductionPortOffset:0,publicRoutePrefix:``,servicePrefix:n}]}if(e.eveRoot!==void 0)throw Error(`withEve cannot combine eveRoot with agents. Use one configuration form.`);let r=Object.entries(e.agents);if(r.length===0)throw Error(`withEve agents must contain at least one named eve agent.`);return r.map(([e,t],r)=>{assertValidAgentName(e);let i=typeof t==`string`?{root:t}:t,a=resolveApplicationRoot(i.root);return{appRoot:a,buildCommand:resolveBuildCommand(a,i.buildCommand),localProductionPortOffset:r,name:e,publicRoutePrefix:createNamedAgentRoutePrefix(e),servicePrefix:normalizeRoutePrefix(i.servicePrefix??createNamedAgentServicePrefix(n,e))}})}function withEve(e,r={}){let i=process.cwd(),a=resolveDevServerTimeout(r.devServerTimeoutMs),o=normalizeAgentsConfig(r,i);return async function(r,s){let c=await resolveNextConfig(e,r,s),l=c.rewrites,u=await ensureEveVercelOutputConfig({agents:o.map(e=>({appRoot:e.appRoot,buildCommand:e.buildCommand,name:e.name,publicRoutePrefix:e.publicRoutePrefix,servicePrefix:e.servicePrefix})),nextRoot:i});if(process.env.VERCEL)return c;let d=new Map(u.agents.map(e=>[e.name,e])),f=o.map(e=>{let t=d.get(e.name),n=resolveProductionDestination({localProductionPortOffset:e.localProductionPortOffset,servicePrefix:t?.servicePrefix??e.servicePrefix});return{...e,productionDestination:n}});return{...c,async rewrites(){let[e,n]=await Promise.all([resolveExistingRewrites(l),Promise.all(f.map(async e=>createEveRewriteRule({destinationPrefix:await resolveEveDestinationPrefix({appRoot:e.appRoot,devServerTimeoutMs:a,logLabel:e.name,phase:r,productionDestinationPrefix:e.productionDestination.destinationPrefix,productionServerOrigin:e.productionDestination.localServerOrigin}),publicRoutePrefix:e.publicRoutePrefix})))]);return mergeRewriteRules(e,n)}}}}export{EVE_NEXT_SERVICE_PREFIX,withEve};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Resolves the absolute path to the installed eve binary from the app's
3
+ * perspective.
4
+ *
5
+ * Uses module resolution rather than assuming an app-local `node_modules/eve`:
6
+ * npm workspaces hoist eve to the workspace root, so the app-local path does
7
+ * not exist there, while pnpm symlinks it app-locally. eve does not export
8
+ * `./bin/eve.js`, but it does export `./package.json`, so we resolve that and
9
+ * derive the bin path from the package root. Falls back to the conventional
10
+ * app-local path when eve cannot be resolved (e.g. before install).
11
+ */
12
+ export declare function resolveEveBinaryPath(nextRoot: string): string;
@@ -0,0 +1 @@
1
+ import{createRequire}from"node:module";import{dirname,join}from"node:path";function resolveEveBinaryPath(e){try{return join(dirname(createRequire(join(e,`package.json`)).resolve(`eve/package.json`)),`bin`,`eve.js`)}catch{return join(e,`node_modules`,`eve`,`bin`,`eve.js`)}}export{resolveEveBinaryPath};
@@ -1,4 +1,4 @@
1
- import{z}from"#compiled/zod/index.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";import{MockLanguageModelV3}from"ai/test";import{FINAL_OUTPUT_TOOL_NAME}from"#runtime/framework-tools/final-output.js";import{BOOTSTRAP_RUNTIME_MODEL_ID,BOOTSTRAP_RUNTIME_SYSTEM_PROMPT}from"#runtime/agent/bootstrap.js";import{createBootstrapGenerateResult,createBootstrapStreamResult,estimateTokenCount,getLastUserPromptText,getPromptContentText,getPromptText}from"#runtime/agent/bootstrap-model-utils.js";import{createMockAuthoredToolInput,formatToolOutput,resolveMockFixtureToken,resolveWeatherCity}from"#runtime/agent/mock-model-fixtures.js";import{findRelevantSkill,getActivatedSkillIds,getAvailableSkills}from"#runtime/agent/mock-model-skill-selection.js";import{createJsonSchemaSample}from"#runtime/agent/mock-structured-output.js";const authoredRuntimeModelMocks=new Map,bootstrapWeatherPayloadSchema=z.object({city:z.string(),condition:z.string(),summary:z.string(),temperatureF:z.number().finite()}).strict();function shouldMockAuthoredRuntimeModels(){return process.env.NODE_ENV===`test`||process.env.EVE_MOCK_AUTHORED_MODELS===`1`}function createMockAuthoredRuntimeModel(e){let t=authoredRuntimeModelMocks.get(e.id);if(t!==void 0)return t;let r=new MockLanguageModelV3({modelId:e.id,provider:`eve-runtime-mock`,doGenerate:async t=>createMockModelResult(t,e.id),doStream:async t=>createBootstrapStreamResult(createMockModelResult(t,e.id))});return authoredRuntimeModelMocks.set(e.id,r),r}function createMockModelResult(e,t){let n=getLastAuthoredToolResult(e.prompt);if(n!==null){let r=createFollowUpToolCallResult({modelId:t,options:e,result:n});if(r!==null)return r}else{let n=createSkillLoadResult(e.prompt,t)??createAuthoredToolCallResult(e,t);if(n!==null)return n}let r=createFinalOutputResult(e,t);if(r!==null)return r;let i=n===null?createAssistantMessage(e.prompt):formatToolResultReply(n,e.prompt);return createBootstrapGenerateResult({inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(i),text:i})}function createFinalOutputResult(e,t){let n=getAvailableTools(e).find(e=>e.name===FINAL_OUTPUT_TOOL_NAME);if(n===void 0)return null;let i=createJsonSchemaSample(n.inputSchema);return createToolCallGenerateResult({input:i,inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(JSON.stringify(i)),toolCallId:createToolCallId(FINAL_OUTPUT_TOOL_NAME),toolName:FINAL_OUTPUT_TOOL_NAME})}function resolveMockAuthoredRuntimeModel(e){return!shouldMockAuthoredRuntimeModels()||e.id===BOOTSTRAP_RUNTIME_MODEL_ID?null:createMockAuthoredRuntimeModel(e)}function createSkillLoadResult(e,n){let r=getLastUserPromptText(e);if(r===null||getActivatedSkillIds(e).length>0)return null;let i=findRelevantSkill(getAvailableSkills(e),r);return i===null?null:createToolCallGenerateResult({input:{skill:i.name},inputTokens:estimateTokenCount(getPromptText(e)),modelId:n,outputTokens:estimateTokenCount(i.name),toolCallId:`call_load_skill`,toolName:LOAD_SKILL_TOOL_NAME})}function createAuthoredToolCallResult(e,t){let n=getLastUserPromptText(e.prompt);if(n===null)return null;let r=findRelevantTool(getAvailableTools(e),n);if(r===null)return null;let i=createMockAuthoredToolInput(r,n,resolveWeatherCity(n));return createToolCallGenerateResult({input:i,inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(Object.values(i).join(` `)),toolCallId:createToolCallId(r.name),toolName:r.name})}function createFollowUpToolCallResult(e){let t=findNextExplicitToolAfterResult({previousToolName:e.result.toolName,prompt:e.options.prompt,tools:getAvailableTools(e.options)});if(t===null)return null;let n=createFollowUpToolInput(e.result.output);return n===null?null:createToolCallGenerateResult({input:n,inputTokens:estimateTokenCount(getPromptText(e.options.prompt)),modelId:e.modelId,outputTokens:estimateTokenCount(Object.values(n).join(` `)),toolCallId:createToolCallId(t.name),toolName:t.name})}function createAssistantMessage(e){let t=getLastUserPromptText(e)??`Hello from eve`,n=getSystemPromptLabels(e),r=resolveSystemProbe(e),i=resolveMockFixtureToken(e);return i===null?n.length>0?r===null?`Bootstrap reply [${n.join(`, `)}]: ${t}`:`Bootstrap reply [${n.join(`, `)}; probe=${r}]: ${t}`:r===null?`Bootstrap reply: ${t}`:`Bootstrap reply [probe=${r}]: ${t}`:i}function formatToolResultReply(e,t){if(e.isError)return`Local weather tool failed: ${formatToolOutput(e.output)}`;if(isWeatherPayload(e.output))return`Used local weather tool for ${e.output.city}: ${e.output.condition}, ${e.output.temperatureF}F. ${e.output.summary}`;let n=getLastUserPromptText(t)??`Hello from eve`;return`Used ${e.toolName} for "${n}": ${formatToolOutput(e.output)}`}function createToolCallGenerateResult(e){return{content:[{input:JSON.stringify(e.input),toolCallId:e.toolCallId,toolName:e.toolName,type:`tool-call`}],finishReason:{raw:void 0,unified:`tool-calls`},response:{id:`bootstrap-response`,modelId:e.modelId,timestamp:new Date(`2026-03-16T00:00:00.000Z`)},usage:{inputTokens:{cacheRead:0,cacheWrite:0,noCache:e.inputTokens,total:e.inputTokens},outputTokens:{reasoning:0,text:e.outputTokens,total:e.outputTokens}},warnings:[]}}function getAvailableTools(e){return(e.tools??[]).flatMap(e=>e.type===`function`?[{description:e.description,inputSchema:`inputSchema`in e?e.inputSchema:void 0,name:e.name,outputSchema:`outputSchema`in e?e.outputSchema:void 0}]:[])}function getLastAuthoredToolResult(e){for(let n of[...e].reverse()){if(n.role===`user`)return null;if(!(n.role!==`tool`&&n.role!==`assistant`)){for(let e of[...n.content].reverse())if(!(typeof e==`string`||e.type!==`tool-result`)&&e.toolName!==LOAD_SKILL_TOOL_NAME)return{isError:e.output.type===`error-json`||e.output.type===`error-text`||e.output.type===`execution-denied`,output:e.output.type===`execution-denied`?{reason:e.output.reason??null,type:e.output.type}:e.output.value,toolCallId:e.toolCallId,toolName:e.toolName}}}return null}function findNextExplicitToolAfterResult(e){let t=getLastUserPromptText(e.prompt);if(t===null)return null;let n=normalizeText(t),r=n.indexOf(normalizeText(e.previousToolName));return r<0?null:e.tools.filter(t=>t.name!==e.previousToolName).flatMap(e=>{let t=n.indexOf(normalizeText(e.name),r+1);return t<0?[]:[{index:t,tool:e}]}).sort((e,t)=>e.index-t.index)[0]?.tool??null}function createFollowUpToolInput(e){return isRecord(e)&&typeof e.stepKey==`string`?{stepKey:e.stepKey}:null}function getSystemPromptLabels(e){let t=e.filter(e=>e.role===`system`);if(t.length===0)return[];let n=t.flatMap(e=>{let t=getPromptContentText(e.content);if(t.startsWith(`Available skills
1
+ import{z}from"#compiled/zod/index.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";import{MockLanguageModelV3}from"ai/test";import{FINAL_OUTPUT_TOOL_NAME}from"#runtime/framework-tools/final-output.js";import{BOOTSTRAP_RUNTIME_MODEL_ID,BOOTSTRAP_RUNTIME_SYSTEM_PROMPT}from"#runtime/agent/bootstrap.js";import{createBootstrapGenerateResult,createBootstrapStreamResult,estimateTokenCount,getLastUserPromptText,getPromptContentText,getPromptText}from"#runtime/agent/bootstrap-model-utils.js";import{createMockAuthoredToolInput,formatToolOutput,resolveMockFixtureToken,resolveWeatherCity}from"#runtime/agent/mock-model-fixtures.js";import{findRelevantSkill,getActivatedSkillIds,getAvailableSkills}from"#runtime/agent/mock-model-skill-selection.js";import{createJsonSchemaSample}from"#runtime/agent/mock-structured-output.js";const authoredRuntimeModelMocks=new Map,bootstrapWeatherPayloadSchema=z.object({city:z.string(),condition:z.string(),summary:z.string(),temperatureF:z.number().finite()}).strict();function shouldMockAuthoredRuntimeModels(){return process.env.NODE_ENV===`test`||process.env.EVE_MOCK_AUTHORED_MODELS===`1`}function createMockAuthoredRuntimeModel(e){let t=authoredRuntimeModelMocks.get(e.id);if(t!==void 0)return t;let r=new MockLanguageModelV3({modelId:e.id,provider:`eve-runtime-mock`,doGenerate:async t=>createMockModelResult(t,e.id),doStream:async t=>createBootstrapStreamResult(createMockModelResult(t,e.id))});return authoredRuntimeModelMocks.set(e.id,r),r}function createMockModelResult(e,t){let n=getLastAuthoredToolResult(e.prompt);if(n!==null){let r=createFollowUpToolCallResult({modelId:t,options:e,result:n});if(r!==null)return r}else{let n=createParallelAuthoredToolCallsResult(e,t)??createSubagentDelegationResult(e,t)??createSkillLoadResult(e.prompt,t)??createAuthoredToolCallResult(e,t);if(n!==null)return n}let r=createFinalOutputResult(e,t);if(r!==null)return r;let i=n===null?createAssistantMessage(e.prompt):formatToolResultReply(n,e.prompt);return createBootstrapGenerateResult({inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(i),text:i})}function createFinalOutputResult(e,t){let n=getAvailableTools(e).find(e=>e.name===FINAL_OUTPUT_TOOL_NAME);if(n===void 0)return null;let i=createJsonSchemaSample(n.inputSchema);return createToolCallGenerateResult({input:i,inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(JSON.stringify(i)),toolCallId:createToolCallId(FINAL_OUTPUT_TOOL_NAME),toolName:FINAL_OUTPUT_TOOL_NAME})}function resolveMockAuthoredRuntimeModel(e){return!shouldMockAuthoredRuntimeModels()||e.id===BOOTSTRAP_RUNTIME_MODEL_ID?null:createMockAuthoredRuntimeModel(e)}function createSkillLoadResult(e,n){let r=getLastUserPromptText(e);if(r===null||getActivatedSkillIds(e).length>0)return null;let i=findRelevantSkill(getAvailableSkills(e),r);return i===null?null:createToolCallGenerateResult({input:{skill:i.name},inputTokens:estimateTokenCount(getPromptText(e)),modelId:n,outputTokens:estimateTokenCount(i.name),toolCallId:`call_load_skill`,toolName:LOAD_SKILL_TOOL_NAME})}const SUBAGENT_TOOL_NAME=`agent`,SUBAGENT_DELEGATION_DIRECTIVE=/\bdelegate\s+to\s+a\s+subagent\s*:\s*(.+)$/iu,PARALLEL_AUTHORED_TOOLS_DIRECTIVE=/^call tools in parallel:\s*(.+)$/imu;function createParallelAuthoredToolCallsResult(e,t){let n=getLastUserPromptText(e.prompt);if(n===null)return null;let r=PARALLEL_AUTHORED_TOOLS_DIRECTIVE.exec(n)?.[1]?.split(`,`).map(e=>e.trim()).filter(Boolean);if(r===void 0||r.length<2||new Set(r).size!==r.length)return null;let i=new Map(getAvailableTools(e).map(e=>[e.name,e])),a=[];for(let e of r){let t=i.get(e);if(t===void 0)return null;a.push(t)}let o=resolveWeatherCity(n);return createToolCallsGenerateResult({calls:a.map(e=>({input:createMockAuthoredToolInput(e,n,o),toolCallId:createToolCallId(e.name),toolName:e.name})),inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(n)})}function createSubagentDelegationResult(e,t){let n=getLastUserPromptText(e.prompt);if(n===null)return null;let r=SUBAGENT_DELEGATION_DIRECTIVE.exec(n);if(r?.[1]===void 0||getAvailableTools(e).find(e=>e.name===SUBAGENT_TOOL_NAME)===void 0)return null;let i={message:r[1].trim()};return createToolCallGenerateResult({input:i,inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(i.message),toolCallId:createToolCallId(SUBAGENT_TOOL_NAME),toolName:SUBAGENT_TOOL_NAME})}function createAuthoredToolCallResult(e,t){let n=getLastUserPromptText(e.prompt);if(n===null)return null;let r=findRelevantTool(getAvailableTools(e),n);if(r===null)return null;let i=createMockAuthoredToolInput(r,n,resolveWeatherCity(n));return createToolCallGenerateResult({input:i,inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(Object.values(i).join(` `)),toolCallId:createToolCallId(r.name),toolName:r.name})}function createFollowUpToolCallResult(e){let t=findNextExplicitToolAfterResult({previousToolName:e.result.toolName,prompt:e.options.prompt,tools:getAvailableTools(e.options)});if(t===null)return null;let n=createFollowUpToolInput(e.result.output);return n===null?null:createToolCallGenerateResult({input:n,inputTokens:estimateTokenCount(getPromptText(e.options.prompt)),modelId:e.modelId,outputTokens:estimateTokenCount(Object.values(n).join(` `)),toolCallId:createToolCallId(t.name),toolName:t.name})}function createAssistantMessage(e){let t=getLastUserPromptText(e)??`Hello from eve`,n=getSystemPromptLabels(e),r=resolveSystemProbe(e),i=resolveMockFixtureToken(e);return i===null?n.length>0?r===null?`Bootstrap reply [${n.join(`, `)}]: ${t}`:`Bootstrap reply [${n.join(`, `)}; probe=${r}]: ${t}`:r===null?`Bootstrap reply: ${t}`:`Bootstrap reply [probe=${r}]: ${t}`:i}function formatToolResultReply(e,t){if(e.isError)return`Local weather tool failed: ${formatToolOutput(e.output)}`;if(isWeatherPayload(e.output))return`Used local weather tool for ${e.output.city}: ${e.output.condition}, ${e.output.temperatureF}F. ${e.output.summary}`;let n=getLastUserPromptText(t)??`Hello from eve`;return`Used ${e.toolName} for "${n}": ${formatToolOutput(e.output)}`}function createToolCallGenerateResult(e){return createToolCallsGenerateResult({calls:[{input:e.input,toolCallId:e.toolCallId,toolName:e.toolName}],inputTokens:e.inputTokens,modelId:e.modelId,outputTokens:e.outputTokens})}function createToolCallsGenerateResult(e){return{content:e.calls.map(e=>({input:JSON.stringify(e.input),toolCallId:e.toolCallId,toolName:e.toolName,type:`tool-call`})),finishReason:{raw:void 0,unified:`tool-calls`},response:{id:`bootstrap-response`,modelId:e.modelId,timestamp:new Date(`2026-03-16T00:00:00.000Z`)},usage:{inputTokens:{cacheRead:0,cacheWrite:0,noCache:e.inputTokens,total:e.inputTokens},outputTokens:{reasoning:0,text:e.outputTokens,total:e.outputTokens}},warnings:[]}}function getAvailableTools(e){return(e.tools??[]).flatMap(e=>e.type===`function`?[{description:e.description,inputSchema:`inputSchema`in e?e.inputSchema:void 0,name:e.name,outputSchema:`outputSchema`in e?e.outputSchema:void 0}]:[])}function getLastAuthoredToolResult(e){for(let n of[...e].reverse()){if(n.role===`user`)return null;if(!(n.role!==`tool`&&n.role!==`assistant`)){for(let e of[...n.content].reverse())if(!(typeof e==`string`||e.type!==`tool-result`)&&e.toolName!==LOAD_SKILL_TOOL_NAME)return{isError:e.output.type===`error-json`||e.output.type===`error-text`||e.output.type===`execution-denied`,output:e.output.type===`execution-denied`?{reason:e.output.reason??null,type:e.output.type}:e.output.value,toolCallId:e.toolCallId,toolName:e.toolName}}}return null}function findNextExplicitToolAfterResult(e){let t=getLastUserPromptText(e.prompt);if(t===null)return null;let n=normalizeText(t),r=n.indexOf(normalizeText(e.previousToolName));return r<0?null:e.tools.filter(t=>t.name!==e.previousToolName).flatMap(e=>{let t=n.indexOf(normalizeText(e.name),r+1);return t<0?[]:[{index:t,tool:e}]}).sort((e,t)=>e.index-t.index)[0]?.tool??null}function createFollowUpToolInput(e){return isRecord(e)&&typeof e.stepKey==`string`?{stepKey:e.stepKey}:null}function getSystemPromptLabels(e){let t=e.filter(e=>e.role===`system`);if(t.length===0)return[];let n=t.flatMap(e=>{let t=getPromptContentText(e.content);if(t.startsWith(`Available skills
2
2
  `))return[];let n=t.split(`
3
3
  `).map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of n){if(e===BOOTSTRAP_RUNTIME_SYSTEM_PROMPT||e===`Available skills`)continue;let t=/^System \((.+)\)$/.exec(e);if(t?.[1]){r.push(t[1]);continue}let n=/^Skill \((.+)\)$/.exec(e);n?.[1]&&r.push(n[1])}if(r.length>0)return r;let i=n.find(e=>e!==BOOTSTRAP_RUNTIME_SYSTEM_PROMPT&&e!==`Available skills`);return i===void 0?[]:[i]});return[...new Set(n)]}function findRelevantTool(e,n){let r=normalizeText(n),i=e.find(e=>e.name!==`agent`&&e.name!==LOAD_SKILL_TOOL_NAME&&r.includes(normalizeText(e.name)));return i===void 0?/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(r)?e.find(e=>/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(normalizeText(`${e.name} ${e.description??``}`)))??null:null:i}function normalizeText(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,` `).trim()}function createToolCallId(e){return`call_${e.toLowerCase().replace(/[^a-z0-9]+/gu,`_`).replace(/^_+|_+$/gu,``)||`tool`}`}function resolveSystemProbe(e){let t=e.filter(e=>e.role===`system`).map(e=>getPromptContentText(e.content)).join(`
4
4
  `);return/hmr-probe:\s*([^\n]+)/iu.exec(t)?.[1]?.trim()||null}function isWeatherPayload(e){return bootstrapWeatherPayloadSchema.safeParse(e).success}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{createMockAuthoredRuntimeModel,resolveMockAuthoredRuntimeModel,shouldMockAuthoredRuntimeModels};
@@ -0,0 +1,13 @@
1
+ import type { ResolvedToolDefinition } from "#runtime/types.js";
2
+ /**
3
+ * Stable model-visible name for the root-only agent delegation tool.
4
+ */
5
+ export declare const AGENT_TOOL_NAME = "agent";
6
+ /**
7
+ * Model-facing instructions for the root-only agent delegation tool.
8
+ */
9
+ export declare const AGENT_TOOL_DESCRIPTION: string;
10
+ /**
11
+ * Shared metadata for the root-only agent delegation tool.
12
+ */
13
+ export declare const AGENT_TOOL_DEFINITION: ResolvedToolDefinition;
@@ -0,0 +1 @@
1
+ import{SUBAGENT_TOOL_INPUT_SCHEMA}from"#runtime/subagents/registry.js";const AGENT_TOOL_NAME=`agent`,AGENT_TOOL_DESCRIPTION=[`Delegate a focused subtask to a fresh copy of yourself.`,`Use it to isolate complex work or split a large task into independent pieces.`,"Issue multiple `agent` calls in one response to run a small fixed set in parallel.","Each child has fresh history and state but shares your tools and sandbox, so include essential context in `message` and give parallel writers non-overlapping scopes."].join(` `),AGENT_TOOL_DEFINITION={description:AGENT_TOOL_DESCRIPTION,inputSchema:SUBAGENT_TOOL_INPUT_SCHEMA,logicalPath:`eve:framework/agent`,name:AGENT_TOOL_NAME,sourceId:`eve:agent-tool`,sourceKind:`module`};export{AGENT_TOOL_DEFINITION,AGENT_TOOL_DESCRIPTION,AGENT_TOOL_NAME};
@@ -8,12 +8,17 @@ import type { ResolvedToolDefinition } from "#runtime/types.js";
8
8
  * Returns framework-owned tool definitions registered in the tool registry
9
9
  * alongside authored tools during graph resolution.
10
10
  *
11
- * `connection_search` is no longer in this list it is registered as a
12
- * framework dynamic tool resolver in the graph resolution path.
11
+ * `connection_search` is no longer in this list. The graph resolution path
12
+ * registers it as a framework dynamic tool resolver.
13
13
  */
14
14
  export declare function getFrameworkToolDefinitions(_config?: {
15
15
  readonly hasConnections?: boolean;
16
16
  }): readonly ResolvedToolDefinition[];
17
+ /**
18
+ * Returns every static framework-owned tool definition, including tools such
19
+ * as `agent` that the runtime does not register in the tool registry.
20
+ */
21
+ export declare function getAllFrameworkToolDefinitions(): readonly ResolvedToolDefinition[];
17
22
  /**
18
23
  * Returns the names of every framework-provided tool the framework knows
19
24
  * about, regardless of whether the current agent gates any of them on
@@ -1 +1 @@
1
- import{ConnectionRegistryKey}from"#context/providers/connection-key.js";import{ReadFileStateKey}from"#runtime/framework-tools/file-state.js";import{TODO_TOOL_DEFINITION,TodoStateKey}from"#runtime/framework-tools/todo.js";import{ASK_QUESTION_TOOL_DEFINITION}from"#runtime/framework-tools/ask-question.js";import{WEB_SEARCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-search.js";import{BASH_TOOL_DEFINITION}from"#runtime/framework-tools/bash.js";import{GLOB_TOOL_DEFINITION}from"#runtime/framework-tools/glob.js";import{GREP_TOOL_DEFINITION}from"#runtime/framework-tools/grep.js";import{READ_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/read-file.js";import{SKILL_TOOL_DEFINITION}from"#runtime/framework-tools/skill.js";import{WEB_FETCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-fetch.js";import{WRITE_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/write-file.js";const ALL_FRAMEWORK_TOOLS=[ASK_QUESTION_TOOL_DEFINITION,BASH_TOOL_DEFINITION,GLOB_TOOL_DEFINITION,GREP_TOOL_DEFINITION,READ_FILE_TOOL_DEFINITION,WRITE_FILE_TOOL_DEFINITION,TODO_TOOL_DEFINITION,WEB_FETCH_TOOL_DEFINITION,WEB_SEARCH_TOOL_DEFINITION,SKILL_TOOL_DEFINITION];function getFrameworkToolDefinitions(e){return ALL_FRAMEWORK_TOOLS}function getAllFrameworkToolNames(){return new Set(ALL_FRAMEWORK_TOOLS.map(e=>e.name))}export{ConnectionRegistryKey,ReadFileStateKey,TodoStateKey,getAllFrameworkToolNames,getFrameworkToolDefinitions};
1
+ import{ConnectionRegistryKey}from"#context/providers/connection-key.js";import{ReadFileStateKey}from"#runtime/framework-tools/file-state.js";import{TODO_TOOL_DEFINITION,TodoStateKey}from"#runtime/framework-tools/todo.js";import{AGENT_TOOL_DEFINITION}from"#runtime/framework-tools/agent.js";import{ASK_QUESTION_TOOL_DEFINITION}from"#runtime/framework-tools/ask-question.js";import{WEB_SEARCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-search.js";import{BASH_TOOL_DEFINITION}from"#runtime/framework-tools/bash.js";import{GLOB_TOOL_DEFINITION}from"#runtime/framework-tools/glob.js";import{GREP_TOOL_DEFINITION}from"#runtime/framework-tools/grep.js";import{READ_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/read-file.js";import{SKILL_TOOL_DEFINITION}from"#runtime/framework-tools/skill.js";import{WEB_FETCH_TOOL_DEFINITION}from"#runtime/framework-tools/web-fetch.js";import{WRITE_FILE_TOOL_DEFINITION}from"#runtime/framework-tools/write-file.js";const REGISTERED_FRAMEWORK_TOOLS=[ASK_QUESTION_TOOL_DEFINITION,BASH_TOOL_DEFINITION,GLOB_TOOL_DEFINITION,GREP_TOOL_DEFINITION,READ_FILE_TOOL_DEFINITION,WRITE_FILE_TOOL_DEFINITION,TODO_TOOL_DEFINITION,WEB_FETCH_TOOL_DEFINITION,WEB_SEARCH_TOOL_DEFINITION,SKILL_TOOL_DEFINITION],ALL_FRAMEWORK_TOOLS=[...REGISTERED_FRAMEWORK_TOOLS,AGENT_TOOL_DEFINITION];function getFrameworkToolDefinitions(e){return REGISTERED_FRAMEWORK_TOOLS}function getAllFrameworkToolDefinitions(){return ALL_FRAMEWORK_TOOLS}function getAllFrameworkToolNames(){return new Set(ALL_FRAMEWORK_TOOLS.map(e=>e.name))}export{ConnectionRegistryKey,ReadFileStateKey,TodoStateKey,getAllFrameworkToolDefinitions,getAllFrameworkToolNames,getFrameworkToolDefinitions};
@@ -1 +1 @@
1
- import{expectObjectRecord}from"#internal/authored-module.js";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{createRuntimeToolRegistry}from"#runtime/tools/registry.js";import{createRuntimeSubagentRegistry}from"#runtime/subagents/registry.js";import{WORKFLOW_TOOL_NAME}from"#shared/workflow-sandbox.js";import{getAllFrameworkChannelNames,getFrameworkChannelDefinitions}from"#runtime/framework-channels/index.js";import{getAllFrameworkToolNames,getFrameworkToolDefinitions}from"#runtime/framework-tools/index.js";import{createConnectionSearchResolver}from"#runtime/framework-tools/connection-search-dynamic.js";import{resolveAgent}from"#runtime/resolve-agent.js";import{loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createResolvedRuntimeTurnAgent}from"#runtime/agent/bootstrap.js";import{createRuntimeHookRegistry}from"#runtime/hooks/registry.js";import{createRuntimeSandboxRegistry}from"#runtime/sandbox/registry.js";var ResolveRuntimeAgentGraphError=class extends Error{logicalPath;nodeId;sourceId;constructor(e,t={}){super(e),this.name=`ResolveRuntimeAgentGraphError`,t.logicalPath!==void 0&&(this.logicalPath=t.logicalPath),t.nodeId!==void 0&&(this.nodeId=t.nodeId),t.sourceId!==void 0&&(this.sourceId=t.sourceId)}};async function resolveRuntimeAgentGraph(e){let n=new Map,r=createChildNodeIdsByParentNodeId(e.manifest),i=new Map(e.manifest.subagents.map(e=>[e.nodeId,e]));return{nodesByNodeId:n,root:await resolveRuntimeAgentNode({childNodeIdsByParentNodeId:r,manifest:e.manifest,moduleMap:e.moduleMap,nodeId:ROOT_COMPILED_AGENT_NODE_ID,nodesByNodeId:n,subagentNodesById:i})}}async function resolveRuntimeAgentNode(e){let t=toRuntimeNodeId(e.nodeId);if(e.nodesByNodeId.has(t))throw new ResolveRuntimeAgentGraphError(`Found multiple runtime agent nodes for node id "${t}".`,{nodeId:t,sourceId:e.sourceId});let r=await resolveAgent({manifest:e.manifest,moduleMap:e.moduleMap,nodeId:e.nodeId}),a=r.connections.length>0,o=getFrameworkToolDefinitions({hasConnections:a}),s=new Set(o.map(e=>e.name)),c=getAllFrameworkToolNames(),l=new Set(r.tools.map(e=>e.name));for(let n of r.disabledFrameworkTools)if(!c.has(n))throw new ResolveRuntimeAgentGraphError(`agent/tools/${n}.ts exports disableTool() but "${n}" is not a framework tool. Rename the file to one of: ${[...c].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let u=new Set(r.disabledFrameworkTools),d=await createRuntimeToolRegistry({tools:[...o.filter(e=>!l.has(e.name)&&!u.has(e.name)),...r.tools]},{reservedToolNames:[WORKFLOW_TOOL_NAME,...s.has(LOAD_SKILL_TOOL_NAME)||l.has(LOAD_SKILL_TOOL_NAME)?[]:[LOAD_SKILL_TOOL_NAME]]}),f=new Set(r.channels.map(e=>e.name)),p=getAllFrameworkChannelNames();for(let n of r.disabledFrameworkChannels)if(!p.has(n))throw new ResolveRuntimeAgentGraphError(`agent/channels/${n}.ts exports disableRoute() but "${n}" is not a framework channel. Rename the file to one of: ${[...p].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let m=new Set(r.disabledFrameworkChannels),h=[...getFrameworkChannelDefinitions().filter(e=>!f.has(e.name)&&!m.has(e.name)),...r.channels],g=createRuntimeSandboxRegistry({authoredSandbox:r.sandbox,workspaceResourceRoot:r.workspaceResourceRoot}),_=createRuntimeSubagentRegistry({reservedToolNames:[LOAD_SKILL_TOOL_NAME,...d.preparedTools.map(e=>e.name)],subagents:await resolveRuntimeSubagents({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.manifest,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,parentNodeId:e.nodeId,subagentNodesById:e.subagentNodesById})}),v=a?{...r,dynamicToolResolvers:[...r.dynamicToolResolvers,createConnectionSearchResolver()]}:r,y={agent:v,channels:h,hookRegistry:createRuntimeHookRegistry(v.hooks),nodeId:t,sandboxRegistry:g,sourceId:e.sourceId,subagentRegistry:_,toolRegistry:d,turnAgent:createResolvedRuntimeTurnAgent({agent:v,nodeId:t,tools:[...d.preparedTools,..._.preparedTools]})};return e.nodesByNodeId.set(t,y),y}async function resolveRuntimeSubagents(e){let t=[],n=e.childNodeIdsByParentNodeId.get(e.parentNodeId)??[];for(let r of n){let n=e.subagentNodesById.get(r);if(n===void 0)throw new ResolveRuntimeAgentGraphError(`Missing compiled subagent node "${r}" while resolving runtime subagents.`,{nodeId:toRuntimeNodeId(e.parentNodeId),sourceId:r});t.push(await resolveRuntimeSubagent({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,sourceRef:n,subagentNodesById:e.subagentNodesById}))}for(let n of e.manifest.remoteAgents)t.push(await resolveRuntimeRemoteAgent({moduleMap:e.moduleMap,nodeScopeId:e.parentNodeId,sourceRef:n}));return t}async function resolveRuntimeSubagent(e){let t={description:e.sourceRef.description,kind:`subagent`,logicalPath:e.sourceRef.logicalPath,name:e.sourceRef.name,nodeId:toRuntimeNodeId(e.sourceRef.nodeId),sourceId:e.sourceRef.sourceId,sourceKind:`module`};return await resolveRuntimeAgentNode({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.sourceRef.agent,moduleMap:e.moduleMap,nodeId:e.sourceRef.nodeId,nodesByNodeId:e.nodesByNodeId,sourceId:e.sourceRef.sourceId,subagentNodesById:e.subagentNodesById}),t}async function resolveRuntimeRemoteAgent(t){let n=expectObjectRecord(await loadResolvedModuleExport({definition:t.sourceRef,kindLabel:`remote agent`,moduleMap:t.moduleMap,nodeId:t.nodeScopeId}),`Expected remote agent source "${t.sourceRef.logicalPath}" to export an object.`),r={description:t.sourceRef.description,kind:`remote`,logicalPath:t.sourceRef.logicalPath,name:t.sourceRef.name,nodeId:toRuntimeNodeId(t.sourceRef.nodeId),outputSchema:t.sourceRef.outputSchema,path:t.sourceRef.path,sourceId:t.sourceRef.sourceId,sourceKind:`module`,url:await resolveRemoteAgentUrl({bakedUrl:t.sourceRef.url,logicalPath:t.sourceRef.logicalPath,resolvedUrl:n.url})};typeof n.auth==`function`&&(r.auth=n.auth);let i=resolveRemoteAgentHeaders(n.headers);return i!==void 0&&(r.headers=i),r}async function resolveRemoteAgentUrl(e){if(typeof e.resolvedUrl==`function`){let t=await e.resolvedUrl();if(typeof t!=`string`||t.length===0)throw Error(`Remote agent "${e.logicalPath}" url function must return a non-empty string.`);return t}let t=e.bakedUrl??(typeof e.resolvedUrl==`string`?e.resolvedUrl:``);if(t.length===0)throw Error(`Remote agent "${e.logicalPath}" is missing a url.`);return t}function resolveRemoteAgentHeaders(e){if(e===void 0)return;if(typeof e==`function`)return e;if(typeof e!=`object`||!e||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}function createChildNodeIdsByParentNodeId(e){let t=new Map;for(let n of e.subagentEdges){let e=t.get(n.parentNodeId);if(e===void 0){t.set(n.parentNodeId,[n.childNodeId]);continue}e.push(n.childNodeId)}return t}function toRuntimeNodeId(e){return e===ROOT_COMPILED_AGENT_NODE_ID?ROOT_RUNTIME_AGENT_NODE_ID:e}export{resolveRuntimeAgentGraph};
1
+ import{expectObjectRecord}from"#internal/authored-module.js";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{createRuntimeSubagentRegistry}from"#runtime/subagents/registry.js";import{createRuntimeToolRegistry}from"#runtime/tools/registry.js";import{WORKFLOW_TOOL_NAME}from"#shared/workflow-sandbox.js";import{getAllFrameworkChannelNames,getFrameworkChannelDefinitions}from"#runtime/framework-channels/index.js";import{getAllFrameworkToolNames,getFrameworkToolDefinitions}from"#runtime/framework-tools/index.js";import{createConnectionSearchResolver}from"#runtime/framework-tools/connection-search-dynamic.js";import{resolveAgent}from"#runtime/resolve-agent.js";import{loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createResolvedRuntimeTurnAgent}from"#runtime/agent/bootstrap.js";import{createRuntimeHookRegistry}from"#runtime/hooks/registry.js";import{createRuntimeSandboxRegistry}from"#runtime/sandbox/registry.js";var ResolveRuntimeAgentGraphError=class extends Error{logicalPath;nodeId;sourceId;constructor(e,t={}){super(e),this.name=`ResolveRuntimeAgentGraphError`,t.logicalPath!==void 0&&(this.logicalPath=t.logicalPath),t.nodeId!==void 0&&(this.nodeId=t.nodeId),t.sourceId!==void 0&&(this.sourceId=t.sourceId)}};async function resolveRuntimeAgentGraph(e){let n=new Map,r=createChildNodeIdsByParentNodeId(e.manifest),i=new Map(e.manifest.subagents.map(e=>[e.nodeId,e]));return{nodesByNodeId:n,root:await resolveRuntimeAgentNode({childNodeIdsByParentNodeId:r,manifest:e.manifest,moduleMap:e.moduleMap,nodeId:ROOT_COMPILED_AGENT_NODE_ID,nodesByNodeId:n,subagentNodesById:i})}}async function resolveRuntimeAgentNode(e){let t=toRuntimeNodeId(e.nodeId);if(e.nodesByNodeId.has(t))throw new ResolveRuntimeAgentGraphError(`Found multiple runtime agent nodes for node id "${t}".`,{nodeId:t,sourceId:e.sourceId});let r=await resolveAgent({manifest:e.manifest,moduleMap:e.moduleMap,nodeId:e.nodeId}),a=r.connections.length>0,o=getFrameworkToolDefinitions({hasConnections:a}),s=new Set(o.map(e=>e.name)),c=getAllFrameworkToolNames(),l=new Set(r.tools.map(e=>e.name));for(let n of r.disabledFrameworkTools)if(!c.has(n))throw new ResolveRuntimeAgentGraphError(`agent/tools/${n}.ts exports disableTool() but "${n}" is not a framework tool. Rename the file to one of: ${[...c].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let u=new Set(r.disabledFrameworkTools),d=await createRuntimeToolRegistry({tools:[...o.filter(e=>!l.has(e.name)&&!u.has(e.name)),...r.tools]},{reservedToolNames:[WORKFLOW_TOOL_NAME,...s.has(LOAD_SKILL_TOOL_NAME)||l.has(LOAD_SKILL_TOOL_NAME)?[]:[LOAD_SKILL_TOOL_NAME]]}),f=new Set(r.channels.map(e=>e.name)),p=getAllFrameworkChannelNames();for(let n of r.disabledFrameworkChannels)if(!p.has(n))throw new ResolveRuntimeAgentGraphError(`agent/channels/${n}.ts exports disableRoute() but "${n}" is not a framework channel. Rename the file to one of: ${[...p].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let m=new Set(r.disabledFrameworkChannels),h=[...getFrameworkChannelDefinitions().filter(e=>!f.has(e.name)&&!m.has(e.name)),...r.channels],g=createRuntimeSandboxRegistry({authoredSandbox:r.sandbox,workspaceResourceRoot:r.workspaceResourceRoot}),_=createRuntimeSubagentRegistry({reservedToolNames:[LOAD_SKILL_TOOL_NAME,...d.preparedTools.map(e=>e.name)],subagents:await resolveRuntimeSubagents({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.manifest,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,parentNodeId:e.nodeId,subagentNodesById:e.subagentNodesById})}),v=a?{...r,dynamicToolResolvers:[...r.dynamicToolResolvers,createConnectionSearchResolver()]}:r,y={agent:v,channels:h,hookRegistry:createRuntimeHookRegistry(v.hooks),nodeId:t,sandboxRegistry:g,sourceId:e.sourceId,subagentRegistry:_,toolRegistry:d,turnAgent:createResolvedRuntimeTurnAgent({agent:v,nodeId:t,tools:[...d.preparedTools,..._.preparedTools]})};return e.nodesByNodeId.set(t,y),y}async function resolveRuntimeSubagents(e){let t=[],n=e.childNodeIdsByParentNodeId.get(e.parentNodeId)??[];for(let r of n){let n=e.subagentNodesById.get(r);if(n===void 0)throw new ResolveRuntimeAgentGraphError(`Missing compiled subagent node "${r}" while resolving runtime subagents.`,{nodeId:toRuntimeNodeId(e.parentNodeId),sourceId:r});t.push(await resolveRuntimeSubagent({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,sourceRef:n,subagentNodesById:e.subagentNodesById}))}for(let n of e.manifest.remoteAgents)t.push(await resolveRuntimeRemoteAgent({moduleMap:e.moduleMap,nodeScopeId:e.parentNodeId,sourceRef:n}));return t}async function resolveRuntimeSubagent(e){let t={description:e.sourceRef.description,kind:`subagent`,logicalPath:e.sourceRef.logicalPath,name:e.sourceRef.name,nodeId:toRuntimeNodeId(e.sourceRef.nodeId),sourceId:e.sourceRef.sourceId,sourceKind:`module`};return await resolveRuntimeAgentNode({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.sourceRef.agent,moduleMap:e.moduleMap,nodeId:e.sourceRef.nodeId,nodesByNodeId:e.nodesByNodeId,sourceId:e.sourceRef.sourceId,subagentNodesById:e.subagentNodesById}),t}async function resolveRuntimeRemoteAgent(t){let n=expectObjectRecord(await loadResolvedModuleExport({definition:t.sourceRef,kindLabel:`remote agent`,moduleMap:t.moduleMap,nodeId:t.nodeScopeId}),`Expected remote agent source "${t.sourceRef.logicalPath}" to export an object.`),r={description:t.sourceRef.description,kind:`remote`,logicalPath:t.sourceRef.logicalPath,name:t.sourceRef.name,nodeId:toRuntimeNodeId(t.sourceRef.nodeId),outputSchema:t.sourceRef.outputSchema,path:t.sourceRef.path,sourceId:t.sourceRef.sourceId,sourceKind:`module`,url:await resolveRemoteAgentUrl({bakedUrl:t.sourceRef.url,logicalPath:t.sourceRef.logicalPath,resolvedUrl:n.url})};typeof n.auth==`function`&&(r.auth=n.auth);let i=resolveRemoteAgentHeaders(n.headers);return i!==void 0&&(r.headers=i),r}async function resolveRemoteAgentUrl(e){if(typeof e.resolvedUrl==`function`){let t=await e.resolvedUrl();if(typeof t!=`string`||t.length===0)throw Error(`Remote agent "${e.logicalPath}" url function must return a non-empty string.`);return t}let t=e.bakedUrl??(typeof e.resolvedUrl==`string`?e.resolvedUrl:``);if(t.length===0)throw Error(`Remote agent "${e.logicalPath}" is missing a url.`);return t}function resolveRemoteAgentHeaders(e){if(e===void 0)return;if(typeof e==`function`)return e;if(typeof e!=`object`||!e||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}function createChildNodeIdsByParentNodeId(e){let t=new Map;for(let n of e.subagentEdges){let e=t.get(n.parentNodeId);if(e===void 0){t.set(n.parentNodeId,[n.childNodeId]);continue}e.push(n.childNodeId)}return t}function toRuntimeNodeId(e){return e===ROOT_COMPILED_AGENT_NODE_ID?ROOT_RUNTIME_AGENT_NODE_ID:e}export{resolveRuntimeAgentGraph};
@@ -120,7 +120,8 @@ export type ResolvedSandboxDefinition = ResolvedModuleSourceRef & {
120
120
  readonly onSession?: (input: SandboxSessionContext) => Promise<void> | void;
121
121
  };
122
122
  /**
123
- * Runtime-owned authored tool definition resolved from a compiled module map.
123
+ * Runtime-owned tool definition resolved from a compiled module map or
124
+ * declared by the framework catalog.
124
125
  * A tool without `execute` is surfaced to the client and never executed by eve.
125
126
  */
126
127
  export type ResolvedToolDefinition = Readonly<Optional<InternalToolDefinitionWithExecuteFn<unknown, unknown>, "execute">> & ResolvedModuleSourceRef & {
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Reads the dev server's runtime-artifacts revision — an opaque token that
3
3
  * changes whenever the authored-source watcher recompiles (HMR). Consumers
4
- * compare successive values to detect "the agent changed under me": the dev
5
- * client rotates an active session before the next turn or while idle.
4
+ * compare successive values to detect "the agent changed under me" and
5
+ * refresh the development UI before the next turn.
6
6
  *
7
7
  * Never throws: any transport failure, non-2xx response, or malformed body
8
8
  * resolves to `undefined`, so callers treat "unknown" and "unreachable" the