eve 0.79.1 → 0.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/src/channel/pending-authorization.d.ts +10 -0
  3. package/dist/src/channel/pending-authorization.js +1 -0
  4. package/dist/src/compiled/.vendor-stamp.json +7 -7
  5. package/dist/src/compiled/@chat-adapter/slack/api.d.ts +6 -0
  6. package/dist/src/compiled/@chat-adapter/slack/api.js +1 -1
  7. package/dist/src/compiled/@chat-adapter/slack/blocks.js +1 -1
  8. package/dist/src/compiled/@chat-adapter/slack/format.js +1 -1
  9. package/dist/src/compiled/@chat-adapter/slack/index.d.ts +14 -8
  10. package/dist/src/compiled/@chat-adapter/slack/index.js +33 -32
  11. package/dist/src/compiled/@chat-adapter/twilio/index.d.ts +37 -1
  12. package/dist/src/compiled/@chat-adapter/twilio/index.js +2 -2
  13. package/dist/src/compiled/@eve/tracing/index.js +1 -1
  14. package/dist/src/compiled/@eve/tracing/otel.js +1 -1
  15. package/dist/src/compiled/@linqapp/chat-sdk-adapter/index.js +1 -1
  16. package/dist/src/compiled/@photon-ai/chat-adapter-imessage/index.js +1 -1
  17. package/dist/src/compiled/@vercel/connect/index.js +5 -5
  18. package/dist/src/compiled/@vercel/connect/token.d.ts +11 -1
  19. package/dist/src/compiled/_chunks/node/chunk-NBSLXVG3-Bt7pDfyn.js +12 -0
  20. package/dist/src/compiled/_chunks/node/dist-BKsV21Vu.js +6 -0
  21. package/dist/src/compiled/_chunks/node/dist-CO_n_hUa.js +98 -0
  22. package/dist/src/compiled/_chunks/workflow/{mcp-C01bDEX-.js → mcp-Bwx_LQ4q.js} +4 -4
  23. package/dist/src/compiled/chat/index.js +1 -1
  24. package/dist/src/compiler/extension-compatibility.d.ts +18 -18
  25. package/dist/src/compiler/extension-compatibility.js +1 -1
  26. package/dist/src/compiler/manifest.d.ts +8 -4
  27. package/dist/src/compiler/manifest.js +1 -1
  28. package/dist/src/compiler/normalize-connection.js +1 -1
  29. package/dist/src/compiler/normalize-manifest.js +1 -1
  30. package/dist/src/context/schedule-collection-tools.js +1 -1
  31. package/dist/src/execution/catalog/connection-auth.d.ts +4 -2
  32. package/dist/src/execution/catalog/connection-auth.js +1 -1
  33. package/dist/src/execution/catalog/connection-entry.js +1 -1
  34. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  35. package/dist/src/execution/proxied-deliver-step.js +1 -1
  36. package/dist/src/execution/publish-session-events.d.ts +13 -3
  37. package/dist/src/execution/publish-session-events.js +1 -1
  38. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
  39. package/dist/src/execution/session/active-turn.d.ts +2 -1
  40. package/dist/src/execution/session/active-turn.js +1 -1
  41. package/dist/src/execution/session/entry.js +1 -1
  42. package/dist/src/execution/session/turn-step.js +1 -1
  43. package/dist/src/execution/session/turn.d.ts +1 -0
  44. package/dist/src/execution/session/turn.js +1 -1
  45. package/dist/src/execution/session-event-stream.js +1 -1
  46. package/dist/src/execution/stable-workflow-names.d.ts +2 -0
  47. package/dist/src/execution/stable-workflow-names.js +1 -1
  48. package/dist/src/execution/tasks/task-id-input.js +1 -1
  49. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  50. package/dist/src/execution/tools/workflow/apply-run-messages-step.d.ts +6 -2
  51. package/dist/src/execution/tools/workflow/apply-run-messages-step.js +1 -1
  52. package/dist/src/execution/tools/workflow/body.d.ts +10 -1
  53. package/dist/src/execution/tools/workflow/body.js +1 -1
  54. package/dist/src/execution/tools/workflow/owner-inbox.js +1 -1
  55. package/dist/src/execution/tools/workflow/serve.js +1 -1
  56. package/dist/src/execution/web-fetch/execute.js +1 -1
  57. package/dist/src/execution/workflow-runtime.d.ts +6 -0
  58. package/dist/src/execution/workflow-runtime.js +1 -1
  59. package/dist/src/extensions/git/extension/extension.d.ts +3 -1
  60. package/dist/src/extensions/git/extension/extension.js +1 -1
  61. package/dist/src/extensions/git/extension/lib/gh-tool.js +1 -1
  62. package/dist/src/extensions/git/extension/lib/github-shell.d.ts +14 -0
  63. package/dist/src/extensions/git/extension/lib/github-shell.js +1 -1
  64. package/dist/src/harness/action-result-helpers.js +1 -1
  65. package/dist/src/harness/attachment-staging.js +1 -1
  66. package/dist/src/harness/compaction/engine.js +3 -1
  67. package/dist/src/harness/compaction/prompt.d.ts +7 -0
  68. package/dist/src/harness/compaction/prompt.js +1 -1
  69. package/dist/src/harness/hitl/approvals.js +1 -1
  70. package/dist/src/harness/hitl/approved-calls.js +1 -1
  71. package/dist/src/harness/input-request-resolution.d.ts +2 -1
  72. package/dist/src/harness/input-request-resolution.js +1 -1
  73. package/dist/src/harness/model-call/call.js +1 -1
  74. package/dist/src/harness/model-call/errors.d.ts +2 -2
  75. package/dist/src/harness/model-call/recovery.d.ts +2 -3
  76. package/dist/src/instrumentation/native-events.js +1 -1
  77. package/dist/src/instrumentation/session-init.d.ts +2 -1
  78. package/dist/src/instrumentation/session-init.js +1 -1
  79. package/dist/src/internal/application/optional-package-import.d.ts +5 -0
  80. package/dist/src/internal/application/optional-package-import.js +1 -1
  81. package/dist/src/internal/application/stamped-package-version.js +1 -1
  82. package/dist/src/internal/authored-definition/connection.js +1 -1
  83. package/dist/src/internal/authored-definition/schedule-collection.js +1 -1
  84. package/dist/src/internal/nitro/host/application-route-registry.d.ts +7 -2
  85. package/dist/src/internal/nitro/host/application-route-registry.js +1 -1
  86. package/dist/src/internal/nitro/host/configure-nitro-routes.js +1 -1
  87. package/dist/src/internal/nitro/host/start-production-server.js +2 -2
  88. package/dist/src/internal/nitro/routes/channel-request-instrumentation.d.ts +3 -1
  89. package/dist/src/internal/nitro/routes/channel-request-instrumentation.js +1 -1
  90. package/dist/src/internal/nitro/routes/connection-events.d.ts +5 -0
  91. package/dist/src/internal/nitro/routes/connection-events.js +1 -0
  92. package/dist/src/internal/workflow-bundle/builder.js +1 -1
  93. package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.js +1 -1
  94. package/dist/src/protocol/message.d.ts +2 -0
  95. package/dist/src/protocol/message.js +1 -1
  96. package/dist/src/public/channels/slack/blocks.js +2 -2
  97. package/dist/src/public/channels/teams/authorization.d.ts +53 -0
  98. package/dist/src/public/channels/teams/authorization.js +1 -0
  99. package/dist/src/public/channels/teams/defaults.js +2 -2
  100. package/dist/src/public/channels/teams/hitl.d.ts +2 -1
  101. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  102. package/dist/src/public/channels/telegram/authorization-callback.js +1 -1
  103. package/dist/src/public/connections/index.d.ts +1 -0
  104. package/dist/src/public/definitions/connections/events.d.ts +43 -0
  105. package/dist/src/public/definitions/connections/events.js +1 -0
  106. package/dist/src/public/definitions/connections/mcp.d.ts +3 -0
  107. package/dist/src/public/next/index.js +1 -1
  108. package/dist/src/public/next/server.d.ts +11 -2
  109. package/dist/src/public/next/server.js +1 -1
  110. package/dist/src/public/schedules/subscription.d.ts +4 -3
  111. package/dist/src/runtime/connections/events/actions.d.ts +17 -0
  112. package/dist/src/runtime/connections/events/actions.js +1 -0
  113. package/dist/src/runtime/connections/events/delivery.d.ts +10 -0
  114. package/dist/src/runtime/connections/events/delivery.js +1 -0
  115. package/dist/src/runtime/connections/events/dispatch-step.d.ts +20 -0
  116. package/dist/src/runtime/connections/events/dispatch-step.js +1 -0
  117. package/dist/src/runtime/connections/events/lifecycle-step.d.ts +42 -0
  118. package/dist/src/runtime/connections/events/lifecycle-step.js +1 -0
  119. package/dist/src/runtime/connections/events/owner.d.ts +38 -0
  120. package/dist/src/runtime/connections/events/owner.js +1 -0
  121. package/dist/src/runtime/connections/events/path.d.ts +4 -0
  122. package/dist/src/runtime/connections/events/path.js +1 -0
  123. package/dist/src/runtime/connections/events/state.d.ts +37 -0
  124. package/dist/src/runtime/connections/events/state.js +1 -0
  125. package/dist/src/runtime/connections/events/workflow.d.ts +28 -0
  126. package/dist/src/runtime/connections/events/workflow.js +1 -0
  127. package/dist/src/runtime/connections/mcp-client.d.ts +4 -2
  128. package/dist/src/runtime/connections/mcp-client.js +1 -1
  129. package/dist/src/runtime/connections/openapi-client.js +1 -1
  130. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  131. package/dist/src/runtime/resolve-connection.js +1 -1
  132. package/dist/src/runtime/schedules/collection-client.d.ts +0 -2
  133. package/dist/src/runtime/schedules/collection-client.js +1 -1
  134. package/dist/src/runtime/types.d.ts +11 -0
  135. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  136. package/dist/src/setup/scaffold/create/project.js +2 -2
  137. package/dist/src/setup/scaffold/update/channels.js +1 -1
  138. package/dist/src/setup/scaffold/update/connections.js +2 -2
  139. package/dist/src/setup/scaffold/version-tokens.d.ts +1 -1
  140. package/dist/src/setup/scaffold/version-tokens.js +1 -1
  141. package/dist/src/shared/action-types.d.ts +1 -0
  142. package/dist/src/shared/action-types.js +1 -1
  143. package/dist/src/shared/agent-definition.d.ts +12 -4
  144. package/dist/src/shared/connection-events.d.ts +84 -0
  145. package/dist/src/shared/connection-events.js +1 -0
  146. package/dist/src/shared/connection-types.d.ts +10 -0
  147. package/dist/src/shared/validate-authorization.js +1 -1
  148. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  149. package/dist/src/tools/provided/no-reply.d.ts +5 -0
  150. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  151. package/dist/src/tools/signature.d.ts +4 -2
  152. package/dist/src/tools/signature.js +1 -1
  153. package/dist/src/tracing/eve/connection-events.d.ts +25 -0
  154. package/dist/src/tracing/eve/connection-events.js +1 -0
  155. package/dist/src/tracing/eve/install-instrumentation-runtime.js +1 -1
  156. package/dist/src/tracing/eve/mcp.d.ts +1 -0
  157. package/dist/src/tracing/eve/mcp.js +1 -1
  158. package/dist/src/tracing/eve/otel-declaration.d.ts +5 -0
  159. package/docs/agent-config.md +38 -13
  160. package/docs/channels/teams.mdx +6 -0
  161. package/docs/code-extension.mdx +28 -0
  162. package/docs/concepts/built-in-tools.md +3 -1
  163. package/docs/connections/mcp.mdx +105 -0
  164. package/docs/guides/hooks.md +4 -0
  165. package/docs/guides/instrumentation/instrumentation.mdx +2 -0
  166. package/docs/guides/instrumentation/otel.mdx +10 -0
  167. package/docs/sandbox/vercel.mdx +46 -0
  168. package/package.json +7 -7
  169. package/dist/src/compiled/_chunks/node/chunk-6QHBXN7B-gl4n6nmi.js +0 -12
  170. package/dist/src/compiled/_chunks/node/dist-DYDVZ-FS.js +0 -98
  171. package/dist/src/compiled/_chunks/node/dist-iEFkK9qw.js +0 -6
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{isLoopbackHostname}from"#shared/network-address.js";import{parseJsonObject}from"#shared/json.js";import{omitProvidedArgumentsFromSchema,resolveProvidedArguments}from"#runtime/connections/provided-arguments.js";import{passesToolFilter,resolveHeaders}from"#runtime/connections/mcp-client.js";import{HTTP_METHODS,operationDescription,operationName,uniqueName}from"#runtime/connections/openapi-operations.js";import{buildInputSchema,deref,derefSchema,isArray}from"#runtime/connections/openapi-schema.js";import{applySecurity,resolveSecurity}from"#runtime/connections/openapi-security.js";import{extractServerUrl,parseSpecDocument}from"#runtime/connections/openapi-spec.js";const log=createLogger(`runtime.connections.openapi-client`),SWAGGER_PARAMETER_SCHEMA_KEYS=[`default`,`enum`,`exclusiveMaximum`,`exclusiveMinimum`,`format`,`items`,`maximum`,`maxItems`,`maxLength`,`minimum`,`minItems`,`minLength`,`multipleOf`,`pattern`,`type`,`uniqueItems`];var OpenApiConnectionClient=class{#e;#t;#n;constructor(e){this.#n=e}async connect(){return this.#r()}async getToolMetadata(){return(await this.#r()).metadata}async executeTool(e,t,n){let r=await this.#r(),i=r.operations.get(e);if(i===void 0)throw Error(`Tool "${e}" not found in connection "${this.#n.connectionName}".`);return this.#f(i,r.baseUrl,isObject(t)?t:{},{abortSignal:n.abortSignal,callId:n.callId})}async close(){this.#e=void 0,this.#t=void 0}async#r(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#i();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#i(){let e=await this.#o(),t=this.#a(e),n=this.#s(e),r=this.#n.tools,i=r===void 0?n:n.filter(e=>passesToolFilter(e.toolName,r)),a=[],o=new Map,s=Object.keys(this.#n.toolCall?.providedArguments??{});for(let e of i){let t;try{t=parseJsonObject(omitProvidedArgumentsFromSchema(e.inputSchema,s))}catch(t){log.warn(`omitting OpenAPI operation with an invalid input schema`,{connectionName:this.#n.connectionName,error:t,toolName:e.toolName});continue}o.set(e.toolName,e),a.push({description:e.description,inputSchema:t,name:e.toolName})}return{metadata:a,operations:o,baseUrl:t}}#a(e){let t=this.#n.url,n=typeof t==`string`&&t.trim().length>0?t:extractServerUrl(e,this.#n.spec);if(n===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" has no base URL: set "baseUrl" or ensure the document declares an absolute "servers" entry or Swagger "host".`);return assertSecureUrl(n,this.#n.connectionName,`base`),n}async#o(){let e=this.#n.spec;if(e===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" is missing its "spec" source.`);if(typeof e!=`string`)return e;assertSecureUrl(e,this.#n.connectionName,`spec`);let t;try{t=await fetch(e,{headers:{accept:`application/json, application/yaml, text/yaml, */*`}})}catch(t){throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${e}": ${String(t)}`)}if(t.redirected&&assertSecureUrl(t.url,this.#n.connectionName,`spec`),!t.ok)throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${e}": HTTP ${t.status}.`);let n=await t.text(),r;try{r=parseSpecDocument(n)}catch(t){throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${e}" could not be parsed as JSON or YAML: ${String(t)}`)}if(!isObject(r))throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${e}" is not an OpenAPI document object.`);return r}#s(e){let t=e.paths;if(!isObject(t))return[];let n=[],r=new Set;for(let[i,a]of Object.entries(t)){if(!isObject(a))continue;let t=isArray(a.parameters)?a.parameters:[];for(let o of HTTP_METHODS){let s=a[o];if(!isObject(s))continue;let c=uniqueName(operationName(s,o,i),r),l=isArray(s.parameters)?s.parameters:[],u=[...t,...l],d=this.#c(e,u),f=this.#l(e,s.requestBody,u);n.push({toolName:c,method:o,pathTemplate:i,description:operationDescription(s),parameters:d,requestBody:f,inputSchema:buildInputSchema(d,f),security:resolveSecurity(e,s)})}}return n}#c(e,t){let n=[];for(let r of t){let t=isObject(r)?deref(e,r):r;if(!isObject(t))continue;let i=t.in;if(i!==`path`&&i!==`query`&&i!==`header`&&i!==`cookie`||typeof t.name!=`string`)continue;let a=this.#u(e,t);n.push({name:t.name,location:i,required:t.required===!0||i===`path`,schema:a,description:typeof t.description==`string`?t.description:void 0})}return n}#l(e,t,n=[]){if(isObject(t)){let n=deref(e,t);if(isObject(n)&&isObject(n.content)){let t=n.content,r=`application/json`in t?`application/json`:Object.keys(t)[0];if(r!==void 0){let i=t[r],a=isObject(i)&&isObject(i.schema)?derefSchema(e,i.schema):{};return{required:n.required===!0,contentType:r,schema:a}}}}return this.#d(e,n)}#u(e,t){if(isObject(t.schema))return derefSchema(e,t.schema);let n={};for(let e of SWAGGER_PARAMETER_SCHEMA_KEYS)t[e]!==void 0&&(n[e]=t[e]);return derefSchema(e,n)}#d(e,t){for(let n of t){let t=isObject(n)?deref(e,n):n;if(!isObject(t)||t.in!==`body`)continue;let r=isObject(t.schema)?derefSchema(e,t.schema):{};return{required:t.required===!0,contentType:`application/json`,schema:r}}}async#f(e,t,n,r){let i=await resolveProvidedArguments({args:n,callId:r.callId,connection:this.#n,toolName:e.toolName}),a=await resolveHeaders(this.#n),o=e.pathTemplate,s=new URLSearchParams,c=[];for(let t of e.parameters){let e=i[t.name];e!=null&&(t.location===`path`?o=o.replace(`{${t.name}}`,encodeURIComponent(String(e))):t.location===`query`?appendQuery(s,t.name,e):t.location===`cookie`?c.push(`${t.name}=${encodeURIComponent(String(e))}`):a[t.name]=String(e))}if(applySecurity(e.security,this.#n,a,s,c),c.length>0){let e=a.cookie??a.Cookie;delete a.Cookie,a.cookie=[e,...c].filter(e=>!!e).join(`; `)}let l=new URL(joinPath(t,o));l.search=s.toString();let u;e.requestBody!==void 0&&i.body!==void 0&&(u=JSON.stringify(i.body),a[`content-type`]=e.requestBody.contentType);let d=await fetch(l,{method:e.method.toUpperCase(),headers:a,body:u,signal:r?.abortSignal});return{status:d.status,statusText:d.statusText,body:await readResponseBody(d)}}};function appendQuery(e,t,n){if(isArray(n)){for(let r of n)e.append(t,String(r));return}e.append(t,String(n))}function joinPath(e,t){return`${e.endsWith(`/`)?e.slice(0,-1):e}${t.startsWith(`/`)?t:`/${t}`}`}function assertSecureUrl(e,t,n){let r;try{r=new URL(e)}catch{throw Error(`OpenAPI connection "${t}" has an invalid ${n} URL "${e}".`)}if(r.protocol!==`https:`&&!(r.protocol===`http:`&&isLoopbackHostname(r.hostname)))throw Error(`OpenAPI connection "${t}" must use https for its ${n} (got "${r.protocol}//${r.host}").`)}async function readResponseBody(e){let t=await e.text();if(t.length===0)return null;if((e.headers.get(`content-type`)??``).includes(`application/json`))try{return JSON.parse(t)}catch{return t}return t}export{OpenApiConnectionClient};
1
+ import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{isLoopbackHostname}from"#shared/network-address.js";import{parseJsonObject}from"#shared/json.js";import{resolveHeaders}from"#runtime/connections/mcp-client.js";import{omitProvidedArgumentsFromSchema,resolveProvidedArguments}from"#runtime/connections/provided-arguments.js";import{HTTP_METHODS,operationDescription,operationName,uniqueName}from"#runtime/connections/openapi-operations.js";import{buildInputSchema,deref,derefSchema,isArray}from"#runtime/connections/openapi-schema.js";import{applySecurity,resolveSecurity}from"#runtime/connections/openapi-security.js";import{extractServerUrl,parseSpecDocument}from"#runtime/connections/openapi-spec.js";const log=createLogger(`runtime.connections.openapi-client`),SWAGGER_PARAMETER_SCHEMA_KEYS=[`default`,`enum`,`exclusiveMaximum`,`exclusiveMinimum`,`format`,`items`,`maximum`,`maxItems`,`maxLength`,`minimum`,`minItems`,`minLength`,`multipleOf`,`pattern`,`type`,`uniqueItems`];var OpenApiConnectionClient=class{#e;#t;#n;constructor(e){this.#n=e}async connect(){return this.#r()}async getToolMetadata(){return(await this.#r()).metadata}async executeTool(e,t,n){let r=await this.#r(),i=r.operations.get(e);if(i===void 0)throw Error(`Tool "${e}" not found in connection "${this.#n.connectionName}".`);return this.#f(i,r.baseUrl,isObject(t)?t:{},{abortSignal:n.abortSignal,callId:n.callId})}async close(){this.#e=void 0,this.#t=void 0}async#r(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#i();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#i(){let e=await this.#o(),t=this.#a(e),n=this.#s(e),r=[],i=new Map,a=Object.keys(this.#n.toolCall?.providedArguments??{});for(let e of n){let t;try{t=parseJsonObject(omitProvidedArgumentsFromSchema(e.inputSchema,a))}catch(t){log.warn(`omitting OpenAPI operation with an invalid input schema`,{connectionName:this.#n.connectionName,error:t,toolName:e.toolName});continue}i.set(e.toolName,e),r.push({description:e.description,inputSchema:t,name:e.toolName})}return{metadata:r,operations:i,baseUrl:t}}#a(e){let t=this.#n.url,n=typeof t==`string`&&t.trim().length>0?t:extractServerUrl(e,this.#n.spec);if(n===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" has no base URL: set "baseUrl" or ensure the document declares an absolute "servers" entry or Swagger "host".`);return assertSecureUrl(n,this.#n.connectionName,`base`),n}async#o(){let e=this.#n.spec;if(e===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" is missing its "spec" source.`);if(typeof e!=`string`)return e;assertSecureUrl(e,this.#n.connectionName,`spec`);let t;try{t=await fetch(e,{headers:{accept:`application/json, application/yaml, text/yaml, */*`}})}catch(t){throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${e}": ${String(t)}`)}if(t.redirected&&assertSecureUrl(t.url,this.#n.connectionName,`spec`),!t.ok)throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${e}": HTTP ${t.status}.`);let n=await t.text(),r;try{r=parseSpecDocument(n)}catch(t){throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${e}" could not be parsed as JSON or YAML: ${String(t)}`)}if(!isObject(r))throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${e}" is not an OpenAPI document object.`);return r}#s(e){let t=e.paths;if(!isObject(t))return[];let n=[],r=new Set;for(let[i,a]of Object.entries(t)){if(!isObject(a))continue;let t=isArray(a.parameters)?a.parameters:[];for(let o of HTTP_METHODS){let s=a[o];if(!isObject(s))continue;let c=uniqueName(operationName(s,o,i),r),l=isArray(s.parameters)?s.parameters:[],u=[...t,...l],d=this.#c(e,u),f=this.#l(e,s.requestBody,u);n.push({toolName:c,method:o,pathTemplate:i,description:operationDescription(s),parameters:d,requestBody:f,inputSchema:buildInputSchema(d,f),security:resolveSecurity(e,s)})}}return n}#c(e,t){let n=[];for(let r of t){let t=isObject(r)?deref(e,r):r;if(!isObject(t))continue;let i=t.in;if(i!==`path`&&i!==`query`&&i!==`header`&&i!==`cookie`||typeof t.name!=`string`)continue;let a=this.#u(e,t);n.push({name:t.name,location:i,required:t.required===!0||i===`path`,schema:a,description:typeof t.description==`string`?t.description:void 0})}return n}#l(e,t,n=[]){if(isObject(t)){let n=deref(e,t);if(isObject(n)&&isObject(n.content)){let t=n.content,r=`application/json`in t?`application/json`:Object.keys(t)[0];if(r!==void 0){let i=t[r],a=isObject(i)&&isObject(i.schema)?derefSchema(e,i.schema):{};return{required:n.required===!0,contentType:r,schema:a}}}}return this.#d(e,n)}#u(e,t){if(isObject(t.schema))return derefSchema(e,t.schema);let n={};for(let e of SWAGGER_PARAMETER_SCHEMA_KEYS)t[e]!==void 0&&(n[e]=t[e]);return derefSchema(e,n)}#d(e,t){for(let n of t){let t=isObject(n)?deref(e,n):n;if(!isObject(t)||t.in!==`body`)continue;let r=isObject(t.schema)?derefSchema(e,t.schema):{};return{required:t.required===!0,contentType:`application/json`,schema:r}}}async#f(e,t,n,r){let i=await resolveProvidedArguments({args:n,callId:r.callId,connection:this.#n,toolName:e.toolName}),a=await resolveHeaders(this.#n),o=e.pathTemplate,s=new URLSearchParams,c=[];for(let t of e.parameters){let e=i[t.name];e!=null&&(t.location===`path`?o=o.replace(`{${t.name}}`,encodeURIComponent(String(e))):t.location===`query`?appendQuery(s,t.name,e):t.location===`cookie`?c.push(`${t.name}=${encodeURIComponent(String(e))}`):a[t.name]=String(e))}if(applySecurity(e.security,this.#n,a,s,c),c.length>0){let e=a.cookie??a.Cookie;delete a.Cookie,a.cookie=[e,...c].filter(e=>!!e).join(`; `)}let l=new URL(joinPath(t,o));l.search=s.toString();let u;e.requestBody!==void 0&&i.body!==void 0&&(u=JSON.stringify(i.body),a[`content-type`]=e.requestBody.contentType);let d=await fetch(l,{method:e.method.toUpperCase(),headers:a,body:u,signal:r?.abortSignal});return{status:d.status,statusText:d.statusText,body:await readResponseBody(d)}}};function appendQuery(e,t,n){if(isArray(n)){for(let r of n)e.append(t,String(r));return}e.append(t,String(n))}function joinPath(e,t){return`${e.endsWith(`/`)?e.slice(0,-1):e}${t.startsWith(`/`)?t:`/${t}`}`}function assertSecureUrl(e,t,n){let r;try{r=new URL(e)}catch{throw Error(`OpenAPI connection "${t}" has an invalid ${n} URL "${e}".`)}if(r.protocol!==`https:`&&!(r.protocol===`http:`&&isLoopbackHostname(r.hostname)))throw Error(`OpenAPI connection "${t}" must use https for its ${n} (got "${r.protocol}//${r.host}").`)}async function readResponseBody(e){let t=await e.text();if(t.length===0)return null;if((e.headers.get(`content-type`)??``).includes(`application/json`))try{return JSON.parse(t)}catch{return t}return t}export{OpenApiConnectionClient};
@@ -1 +1 @@
1
- import{contextStorage,loadContext}from"#context/container.js";import{AuthKey}from"#context/keys.js";import{ConnectionAuthorizationFailedError,ConnectionAuthorizationRequiredError,isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{consumeAuthorizationResult,createAuthorizationAttempt,requestAuthorization}from"#harness/authorization.js";import{supportsInteractiveAuthorization}from"#shared/connection-types.js";import{isAsyncIterable}from"#shared/async-iterable.js";import{evictCachedToken,readCachedToken,writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal,resolveConnectionPrincipalFromAuth}from"#runtime/connections/principal.js";const LOCAL_HTTP_VERCEL_CONNECT_HOSTNAMES=new Set([`127.0.0.1`,`[::1]`]);function createAuthorizationExecution(e={}){let t=new Set;async function complete(n){let r=n.instanceId??n.scope;!t.has(r)&&await(e.completeAuthorization??completeScopedAuthorization)(n)&&t.add(r)}function requireAuth(e,n){throw new ScopedAuthorizationRequiredError(e,t.has(e.instanceId??e.scope),n)}return{complete,isJustAuthorized(e){return t.has(e.instanceId??e.scope)},async getToken(e){await complete(e);try{return await resolveScopedToken(e)}catch(t){if(!isConnectionAuthorizationRequiredError(t))throw t;return requireAuth(e,t)}},async getResponderToken(e){try{return await resolveScopedToken(e)}catch(t){throw isConnectionAuthorizationRequiredError(t)?new ConnectionAuthorizationFailedError(e.scope,{message:`The approver of "${e.scope}" has no token for this provider, and an approved call doesn't start a sign-in.`,reason:`approver_authorization_required`,retryable:!1}):t}},requireAuth,async handleError(e,n){return n!==void 0&&isConnectionAuthorizationRequiredError(e)?await handleAuthorizationError(new ScopedAuthorizationRequiredError(n,t.has(n.instanceId??n.scope),e),{evictToken:!1}):await handleAuthorizationError(e)},run:executeWithAuthorization}}var ScopedAuthorizationRequiredError=class extends Error{scoped;justAuthorized;constructor(e,t,n){super(`Authorization required.`,{cause:n}),this.name=`ScopedAuthorizationRequiredError`,this.scoped=e,this.justAuthorized=t}};function isScopedAuthorizationRequiredError(e){return e instanceof Error&&e.name===`ScopedAuthorizationRequiredError`}async function handleAuthorizationError(e,t={evictToken:!0}){if(!isScopedAuthorizationRequiredError(e))throw e;let{scoped:n}=e;if(e.justAuthorized)throw new ConnectionAuthorizationFailedError(n.scope,{message:`Authorization for "${n.scope}" failed: the service rejected the token immediately after authorization.`,reason:`token_rejected_after_authorization`,retryable:!1});t.evictToken&&await evictScopedToken(n);let r=await startScopedAuthorization(n);if(r!==void 0)return r;throw supportsInteractiveAuthorization(n.authorization)?new ConnectionAuthorizationFailedError(n.scope,{message:`Authorization for "${n.scope}" requires sign-in, but no authorization callback URL could be minted for this run (missing session context).`,reason:`authorization_callback_unavailable`,retryable:!1}):e.cause??new ConnectionAuthorizationRequiredError(n.scope)}function executeWithAuthorization(e){try{let t=e();return isAsyncIterable(t)?handleIterable(t):Promise.resolve(t).catch(handleAuthorizationError)}catch(e){return handleAuthorizationError(e)}}async function*handleIterable(e){try{for await(let t of e)yield t}catch(e){yield await handleAuthorizationError(e)}}async function resolveScopedToken(e){let{scope:t,authorization:n,connection:r}=e,i=e.instanceId??t,a=contextStorage.getStore(),o=resolveScopedPrincipal(e,a);if(a===void 0)return await n.getToken({connection:r,principal:o});let s=principalKey(o),c=readCachedToken(a,i,s);if(c!==void 0)return c;let l=await n.getToken({connection:r,principal:o});return writeCachedToken(a,i,s,l),l}async function evictScopedToken(e){let{scope:t,authorization:n,connection:r}=e,i=e.instanceId??t,a=contextStorage.getStore();if(a===void 0)return;let o;try{o=resolveScopedPrincipal(e,a),evictCachedToken(a,i,principalKey(o))}catch{return}try{await n.evict?.({connection:r,principal:o})}catch{}}async function completeScopedAuthorization(e){let{scope:t,authorization:n,connection:r}=e;if(!supportsInteractiveAuthorization(n))return!1;let i=consumeAuthorizationResult(t,e.instanceId);if(i===void 0)return!1;let a=n,o=loadContext(),s=i.principal??resolveScopedPrincipal(e,o),c=await a.completeAuthorization({callbackUrl:i.hookUrl,connection:r,principal:s,resume:i.resume,callback:i.callback});return writeCachedToken(o,e.instanceId??t,principalKey(s),c),!0}async function startScopedAuthorization(e){let{scope:t,authorization:n,connection:r}=e;if(!supportsInteractiveAuthorization(n))return;let i=createAuthorizationAttempt(t);if(i===void 0)return;let a=n,o=resolveScopedPrincipal(e),s=e.boundResponder??contextStorage.getStore()?.get(AuthKey)??void 0,c=resolveAuthorizationCallbackUrl({authorization:n,callbackUrl:i.hookUrl}),{challenge:l,resume:u}=await a.startAuthorization({callbackUrl:c,connection:r,principal:o});return requestAuthorization([{attemptId:i.attemptId,challenge:stampChallengeDisplayName(l,n),grant:n.vercelConnect?.connector,hookUrl:c,instanceId:e.instanceId,name:t,principal:o,principalId:s?.principalId,requester:s,resume:u}])}function resolveScopedPrincipal(e,t){return e.boundResponder===void 0?resolveConnectionPrincipal(e.scope,e.authorization,t):resolveConnectionPrincipalFromAuth(e.scope,e.authorization,e.boundResponder,t)}function resolveAuthorizationCallbackUrl(e){if(e.authorization.vercelConnect===void 0)return e.callbackUrl;let t;try{t=new URL(e.callbackUrl)}catch{return e.callbackUrl}return t.protocol!==`http:`||!LOCAL_HTTP_VERCEL_CONNECT_HOSTNAMES.has(t.hostname)?e.callbackUrl:(t.hostname=`localhost`,t.toString())}function stampChallengeDisplayName(e,t){let n=t.displayName??e.displayName;return n===e.displayName?e:{...e,displayName:n}}export{completeScopedAuthorization,createAuthorizationExecution,evictScopedToken,handleAuthorizationError,resolveAuthorizationCallbackUrl,resolveScopedToken,stampChallengeDisplayName};
1
+ import{contextStorage,loadContext}from"#context/container.js";import{AuthKey}from"#context/keys.js";import{ConnectionAuthorizationFailedError,ConnectionAuthorizationRequiredError,isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{consumeAuthorizationResult,createAuthorizationAttempt,requestAuthorization}from"#harness/authorization.js";import{supportsInteractiveAuthorization}from"#shared/connection-types.js";import{isAsyncIterable}from"#shared/async-iterable.js";import{principalKey,resolveConnectionPrincipal,resolveConnectionPrincipalFromAuth}from"#runtime/connections/principal.js";import{evictCachedToken,readCachedToken,writeCachedToken}from"#runtime/connections/authorization-tokens.js";const LOCAL_HTTP_VERCEL_CONNECT_HOSTNAMES=new Set([`127.0.0.1`,`[::1]`]);function createAuthorizationExecution(e={}){let t=new Set;async function complete(n){let r=n.instanceId??n.scope;!t.has(r)&&await(e.completeAuthorization??completeScopedAuthorization)(n)&&t.add(r)}function requireAuth(e,n){throw new ScopedAuthorizationRequiredError(e,t.has(e.instanceId??e.scope),n)}return{complete,isJustAuthorized(e){return t.has(e.instanceId??e.scope)},async getToken(e){await complete(e);try{return await resolveScopedToken(e)}catch(t){if(!isConnectionAuthorizationRequiredError(t))throw t;return requireAuth(e,t)}},async getResponderToken(e){try{return await resolveScopedToken(e)}catch(t){throw isConnectionAuthorizationRequiredError(t)?new ConnectionAuthorizationFailedError(e.scope,{message:`The approver of "${e.scope}" has no token for this provider, and an approved call doesn't start a sign-in.`,reason:`approver_authorization_required`,retryable:!1}):t}},requireAuth,async handleError(e,n){return n!==void 0&&isConnectionAuthorizationRequiredError(e)?await handleAuthorizationError(new ScopedAuthorizationRequiredError(n,t.has(n.instanceId??n.scope),e),{evictToken:!1}):await handleAuthorizationError(e)},run:executeWithAuthorization}}var ScopedAuthorizationRequiredError=class extends Error{scoped;justAuthorized;constructor(e,t,n){super(`Authorization required.`,{cause:n}),this.name=`ScopedAuthorizationRequiredError`,this.scoped=e,this.justAuthorized=t}};function isScopedAuthorizationRequiredError(e){return e instanceof Error&&e.name===`ScopedAuthorizationRequiredError`}async function handleAuthorizationError(e,t={evictToken:!0}){if(!isScopedAuthorizationRequiredError(e))throw e;let{scoped:n}=e;if(e.justAuthorized)throw new ConnectionAuthorizationFailedError(n.scope,{message:`Authorization for "${n.scope}" failed: the service rejected the token immediately after authorization.`,reason:`token_rejected_after_authorization`,retryable:!1});t.evictToken&&await evictScopedToken(n);let r=await startScopedAuthorization(n);if(r!==void 0)return r;throw supportsInteractiveAuthorization(n.authorization)?new ConnectionAuthorizationFailedError(n.scope,{message:`Authorization for "${n.scope}" requires sign-in, but no authorization callback URL could be minted for this run (missing session context).`,reason:`authorization_callback_unavailable`,retryable:!1}):e.cause??new ConnectionAuthorizationRequiredError(n.scope)}function executeWithAuthorization(e){try{let t=e();return isAsyncIterable(t)?handleIterable(t):Promise.resolve(t).catch(handleAuthorizationError)}catch(e){return handleAuthorizationError(e)}}async function*handleIterable(e){try{for await(let t of e)yield t}catch(e){yield await handleAuthorizationError(e)}}async function resolveScopedToken(e){let{scope:t,authorization:n,connection:r}=e,i=e.instanceId??t,a=contextStorage.getStore(),o=resolveScopedPrincipal(e,a);if(a===void 0)return await n.getToken({connection:r,principal:o});let s=principalKey(o),c=readCachedToken(a,i,s);if(c!==void 0)return c;let l=await n.getToken({connection:r,principal:o});return writeCachedToken(a,i,s,l),l}async function evictScopedToken(e){let{scope:t,authorization:n,connection:r}=e,i=e.instanceId??t,a=contextStorage.getStore();if(a===void 0)return;let o;try{o=resolveScopedPrincipal(e,a),evictCachedToken(a,i,principalKey(o))}catch{return}try{await n.evict?.({connection:r,principal:o})}catch{}}async function completeScopedAuthorization(e){let{scope:t,authorization:n,connection:r}=e;if(!supportsInteractiveAuthorization(n))return!1;let i=consumeAuthorizationResult(t,e.instanceId);if(i===void 0)return!1;let a=n,o=loadContext(),s=i.principal??resolveScopedPrincipal(e,o),c=await a.completeAuthorization({callbackUrl:i.hookUrl,connection:r,principal:s,resume:i.resume,callback:i.callback});return writeCachedToken(o,e.instanceId??t,principalKey(s),c),!0}async function startScopedAuthorization(e){let{scope:t,authorization:n,connection:r}=e;if(!supportsInteractiveAuthorization(n))return;let i=createAuthorizationAttempt(t);if(i===void 0)return;let a=n,o=resolveScopedPrincipal(e),s=e.boundResponder??contextStorage.getStore()?.get(AuthKey)??void 0,c=resolveAuthorizationCallbackUrl({authorization:n,callbackUrl:i.hookUrl}),{challenge:l,resume:u}=await a.startAuthorization({callbackUrl:c,connection:r,principal:o});return requestAuthorization([{attemptId:i.attemptId,challenge:stampChallengeDisplayName(l,n),grant:n.vercelConnect?.connector,hookUrl:c,instanceId:e.instanceId,name:t,principal:o,principalId:s?.principalId,requester:s,resume:u}])}function resolveScopedPrincipal(e,t){return e.boundResponder===void 0?resolveConnectionPrincipal(e.scope,e.authorization,t):resolveConnectionPrincipalFromAuth(e.scope,e.authorization,e.boundResponder,t)}function resolveAuthorizationCallbackUrl(e){if(e.authorization.vercelConnect===void 0)return e.callbackUrl;let t;try{t=new URL(e.callbackUrl)}catch{return e.callbackUrl}return t.protocol!==`http:`||!LOCAL_HTTP_VERCEL_CONNECT_HOSTNAMES.has(t.hostname)?e.callbackUrl:(t.hostname=`localhost`,t.toString())}function stampChallengeDisplayName(e,t){let n=t.displayName??e.displayName;return n===e.displayName?e:{...e,displayName:n}}export{completeScopedAuthorization,createAuthorizationExecution,evictScopedToken,handleAuthorizationError,resolveAuthorizationCallbackUrl,resolveScopedToken,stampChallengeDisplayName};
@@ -1 +1 @@
1
- import{expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeMcpClientConnectionDefinition,normalizeOpenApiConnectionDefinition}from"#internal/authored-definition/connection.js";import{readStampedConnectionProtocol}from"#public/definitions/connections/protocol.js";import{connectionDefinitionKey,registerDefinitionSource}from"#internal/authored-definition/source-identity.js";import{normalizeAuthorizationSpec}from"#shared/validate-authorization.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createConnectionInstanceId}from"#runtime/connections/instance-identity.js";async function resolveConnectionDefinition(e,t,n){try{let r=await loadResolvedModuleExport({definition:e,kindLabel:`connection`,moduleMap:t,nodeId:n}),i=expectObjectRecord(r,`Expected the connection export "${e.exportName??`default`}" from "${e.logicalPath}" to return an object.`);registerDefinitionSource(i,{kind:`connection`,logicalPath:e.logicalPath,name:e.connectionName},connectionDefinitionKey(e.url,e.description));let a=i.auth!==void 0,o=i.headers!==void 0,s=e.protocol===`openapi`?i.operations:i.tools,c={connectionName:e.connectionName,description:e.description,exportName:e.exportName,logicalPath:e.logicalPath,instanceId:createConnectionInstanceId({connectionName:e.connectionName,instanceKey:typeof i.instanceKey==`string`?i.instanceKey:void 0,protocol:e.protocol,sourceId:e.sourceId,url:e.url}),protocol:e.protocol,sourceId:e.sourceId,sourceKind:`module`,url:e.url};if(a){if(typeof i.auth==`function`)c.authorization=i.auth;else try{c.authorization=normalizeAuthorizationSpec(i.auth,`Connection "${e.connectionName}" at "${e.logicalPath}":`)}catch(t){throw new ResolveAgentError(toErrorMessage(t),{logicalPath:e.logicalPath,sourceId:e.sourceId})}}if(e.protocol===`mcp`&&i.protocolVersionDiscovery!==void 0){if(typeof i.protocolVersionDiscovery!=`boolean`)throw Error(`"protocolVersionDiscovery" must be a boolean.`);c.protocolVersionDiscovery=i.protocolVersionDiscovery}if(e.protocol===`mcp`&&i.forwardPrincipal!==void 0){if(typeof i.forwardPrincipal!=`boolean`)throw Error(`"forwardPrincipal" must be a boolean.`);c.forwardPrincipal=i.forwardPrincipal}return o&&(c.headers=i.headers),i.toolCall!==void 0&&(c.toolCall=i.toolCall),s!==void 0&&(c.tools=s),e.protocol===`openapi`&&i.spec!==void 0&&(c.spec=i.spec),typeof i.approval==`function`&&(c.approval=i.approval),c}catch(t){throw t instanceof ResolveAgentError?t:new ResolveAgentError(`Failed to resolve connection "${e.connectionName}" from "${e.logicalPath}": ${toErrorMessage(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function resolveDynamicConnectionValue(e,t){let n=readStampedConnectionProtocol(e),r=`Dynamic connection "${t.connectionName}" from "${t.logicalPath}" must be created by defineMcpClientConnection() or defineOpenAPIConnection().`;if(n===void 0)throw Error(r);if(registerDefinitionSource(e,{kind:`connection`,logicalPath:t.logicalPath,name:t.connectionName}),n===`openapi`){let i=normalizeOpenApiConnectionDefinition(e,r);return assertAuthenticatedDynamicInstanceKey(i.auth,i.instanceKey,r),omitUndefined({approval:i.approval,authorization:i.auth,connectionName:t.connectionName,description:i.description,exportName:t.exportName,headers:i.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:i.instanceKey,protocol:n,sourceId:t.sourceId,url:i.baseUrl??``}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,spec:i.spec,toolCall:i.toolCall,tools:i.operations,url:i.baseUrl??``})}let i=normalizeMcpClientConnectionDefinition(e,r);return assertAuthenticatedDynamicInstanceKey(i.auth,i.instanceKey,r),omitUndefined({approval:i.approval,authorization:i.auth,connectionName:t.connectionName,description:i.description,exportName:t.exportName,headers:i.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:i.instanceKey,protocol:n,sourceId:t.sourceId,url:i.url}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,toolCall:i.toolCall,protocolVersionDiscovery:i.protocolVersionDiscovery,forwardPrincipal:i.forwardPrincipal,tools:i.tools,url:i.url})}function assertAuthenticatedDynamicInstanceKey(e,t,n){if(e!==void 0&&t===void 0)throw Error(`${n} Authenticated dynamic connections must set "instanceKey" to a stable, non-secret account or tenant identifier.`)}function omitUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}export{resolveConnectionDefinition,resolveDynamicConnectionValue};
1
+ import{expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeMcpClientConnectionDefinition,normalizeOpenApiConnectionDefinition}from"#internal/authored-definition/connection.js";import{readStampedConnectionProtocol}from"#public/definitions/connections/protocol.js";import{connectionDefinitionKey,registerDefinitionSource}from"#internal/authored-definition/source-identity.js";import{normalizeAuthorizationSpec}from"#shared/validate-authorization.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createConnectionInstanceId}from"#runtime/connections/instance-identity.js";async function resolveConnectionDefinition(e,t,n){try{let r=await loadResolvedModuleExport({definition:e,kindLabel:`connection`,moduleMap:t,nodeId:n}),i=expectObjectRecord(r,`Expected the connection export "${e.exportName??`default`}" from "${e.logicalPath}" to return an object.`);registerDefinitionSource(i,{kind:`connection`,logicalPath:e.logicalPath,name:e.connectionName},connectionDefinitionKey(e.url,e.description));let a=i.auth!==void 0,o=i.headers!==void 0,s=e.protocol===`openapi`?i.operations:i.tools,c={connectionName:e.connectionName,description:e.description,exportName:e.exportName,logicalPath:e.logicalPath,instanceId:createConnectionInstanceId({connectionName:e.connectionName,instanceKey:typeof i.instanceKey==`string`?i.instanceKey:void 0,protocol:e.protocol,sourceId:e.sourceId,url:e.url}),protocol:e.protocol,sourceId:e.sourceId,sourceKind:`module`,url:e.url};if(a){if(typeof i.auth==`function`)c.authorization=i.auth;else try{c.authorization=normalizeAuthorizationSpec(i.auth,`Connection "${e.connectionName}" at "${e.logicalPath}":`)}catch(t){throw new ResolveAgentError(toErrorMessage(t),{logicalPath:e.logicalPath,sourceId:e.sourceId})}}if(e.protocol===`mcp`&&i.protocolVersionDiscovery!==void 0){if(typeof i.protocolVersionDiscovery!=`boolean`)throw Error(`"protocolVersionDiscovery" must be a boolean.`);c.protocolVersionDiscovery=i.protocolVersionDiscovery}if(e.protocol===`mcp`&&i.forwardPrincipal!==void 0){if(typeof i.forwardPrincipal!=`boolean`)throw Error(`"forwardPrincipal" must be a boolean.`);c.forwardPrincipal=i.forwardPrincipal}if(e.experimental_events===!0){let t=normalizeMcpClientConnectionDefinition(i,`Connection "${e.connectionName}":`).experimental_events,n=typeof c.authorization==`object`?c.authorization:void 0;if(t===void 0||n?.vercelConnect?.experimental_events===void 0)throw new ResolveAgentError(`Connection "${e.connectionName}": experimental_events requires a static Connect auth provider with the events bridge.`,{logicalPath:e.logicalPath,sourceId:e.sourceId});c.experimental_events={callbacks:t,authorization:n,connector:n.vercelConnect.connector,backend:n.vercelConnect.experimental_events}}return o&&(c.headers=i.headers),i.toolCall!==void 0&&(c.toolCall=i.toolCall),s!==void 0&&(c.tools=s),e.protocol===`openapi`&&i.spec!==void 0&&(c.spec=i.spec),typeof i.approval==`function`&&(c.approval=i.approval),c}catch(t){throw t instanceof ResolveAgentError?t:new ResolveAgentError(`Failed to resolve connection "${e.connectionName}" from "${e.logicalPath}": ${toErrorMessage(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function resolveDynamicConnectionValue(e,t){let n=readStampedConnectionProtocol(e),r=`Dynamic connection "${t.connectionName}" from "${t.logicalPath}" must be created by defineMcpClientConnection() or defineOpenAPIConnection().`;if(n===void 0)throw Error(r);if(registerDefinitionSource(e,{kind:`connection`,logicalPath:t.logicalPath,name:t.connectionName}),n===`openapi`){let i=normalizeOpenApiConnectionDefinition(e,r);return assertAuthenticatedDynamicInstanceKey(i.auth,i.instanceKey,r),omitUndefined({approval:i.approval,authorization:i.auth,connectionName:t.connectionName,description:i.description,exportName:t.exportName,headers:i.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:i.instanceKey,protocol:n,sourceId:t.sourceId,url:i.baseUrl??``}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,spec:i.spec,toolCall:i.toolCall,tools:i.operations,url:i.baseUrl??``})}let i=normalizeMcpClientConnectionDefinition(e,r);if(i.experimental_events!==void 0)throw Error(`${r} experimental_events requires a statically authored connection so eve can mount its receiver at build time.`);return assertAuthenticatedDynamicInstanceKey(i.auth,i.instanceKey,r),omitUndefined({approval:i.approval,authorization:i.auth,connectionName:t.connectionName,description:i.description,exportName:t.exportName,headers:i.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:i.instanceKey,protocol:n,sourceId:t.sourceId,url:i.url}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,toolCall:i.toolCall,protocolVersionDiscovery:i.protocolVersionDiscovery,forwardPrincipal:i.forwardPrincipal,tools:i.tools,url:i.url})}function assertAuthenticatedDynamicInstanceKey(e,t,n){if(e!==void 0&&t===void 0)throw Error(`${n} Authenticated dynamic connections must set "instanceKey" to a stable, non-secret account or tenant identifier.`)}function omitUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}export{resolveConnectionDefinition,resolveDynamicConnectionValue};
@@ -1,5 +1,4 @@
1
1
  import type { StandardSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
2
- import type { SessionSchedule } from "#context/session-schedule.js";
3
2
  import type { ScheduleClient, ScheduleClientCreate, ScheduleClientUpdate, DynamicSchedulesDefinition, ScheduleEnvelope, ScheduleScopeContext } from "#public/schedules/subscription.js";
4
3
  export interface ScheduleBoundCallContext extends ScheduleScopeContext {
5
4
  readonly application: string;
@@ -26,4 +25,3 @@ export interface ScheduleCollectionClient<TInput, TPrepared> extends ScheduleCli
26
25
  update(name: string, patch: ScheduleClientUpdate<TInput>, approved?: PreparedScheduleUpdate): Promise<import("#public/schedules/subscription.js").ScheduleRecord>;
27
26
  }
28
27
  export declare function createScheduleCollectionClient<TPayload, TPrepared = TPayload>(definition: DynamicSchedulesDefinition<TPayload, StandardSchemaV1<unknown, TPayload>, TPrepared>, callContext: ScheduleBoundCallContext): ScheduleCollectionClient<TPayload, TPrepared>;
29
- export declare function assertScheduleManagementAllowed(schedule?: SessionSchedule): void;
@@ -1 +1 @@
1
- import{createHash,randomUUID}from"node:crypto";import{contextStorage,loadContext}from"#context/container.js";import{projectScheduleRecord}from"#runtime/schedules/record.js";import{createScheduleCollectionPayload,validateSchedulePayload}from"#runtime/schedules/payload.js";import{isDeepStrictEqual}from"node:util";import{readSessionSchedule}from"#context/session-schedule.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{resolveScheduleTiming,validateScheduleListLimit,validateScheduleName}from"#runtime/schedules/validation.js";import{dispatchScheduledOccurrence}from"#runtime/schedules/dispatch-occurrence.js";import{byPrincipal}from"#public/schedules/scope.js";function createScheduleCollectionClient(e,t){let n=t.operationId??randomUUID,contextFor=(e,n)=>{let r={...t,operation:e};return n!==void 0&&(r.name=n),r},resolveNamespace=async(r,i)=>{assertScheduleManagementAllowed(t.session.schedule);let a=contextFor(r,i),o=e.scope===void 0?byPrincipal(a):await e.scope({...a,operation:r});if(o===null)throw Error(`Schedule ${r} is not available in this context.`);return validateScope(o),{scope:o,provider:{abortSignal:t.abortSignal,collection:t.collection,namespace:deriveScheduleNamespace(t.application,t.collection,o),operationId:n(),target:{key:t.application,deliver:async({payload:n,occurrence:r})=>{await dispatchScheduledOccurrence({bundle:loadContext().require(BundleKey),collection:t.collection,definition:e,occurrence:{...r,collection:t.collection},payload:n})}}}}},prepareEnvelope=async(n,r,i,a)=>{let o=principalReference(t.session.auth.current);if(o===null)throw Error(`Writing a schedule payload requires an authenticated principal.`);let s=await validateSchedulePayload(e.inputSchema,n),c=e.preparePayload===void 0?s:await e.preparePayload(s,{...contextFor(i,a),operation:i,name:a});return createScheduleCollectionPayload({application:t.application,collection:t.collection,envelope:{version:3,payload:c,scope:r,principal:o}}).envelope},prepareUpdate=async(t,n)=>{let r=Object.keys(n).filter(e=>e!==`expression`&&e!==`payload`);if(r.length>0)throw Error(`Schedule update does not support: ${r.join(`, `)}.`);if(n.expression===void 0&&n.payload===void 0)throw Error(`Schedule update requires an expression or replacement payload.`);let i=validateScheduleName(t);n.expression!==void 0&&resolveScheduleTiming(n.expression);let{scope:a,provider:o}=await resolveNamespace(`update`,i);if(await e.provider.get(o,i)===null)throw Error(`Schedule was not found in the authorized scope.`);return{prepared:snapshotPreparedWrite({name:i,namespace:o.namespace,expression:n.expression,envelope:n.payload===void 0?void 0:await prepareEnvelope(n.payload,a,`update`,i)}),provider:o}},prepareCreation=async e=>{let t=validateScheduleName(e.name);resolveScheduleTiming(e.expression);let{scope:n,provider:r}=await resolveNamespace(`create`,t);return{prepared:snapshotPreparedWrite({displayName:t,expression:e.expression,envelope:await prepareEnvelope(e.payload,n,`create`,t)}),provider:r}};return{async prepareCreate(e){return(await prepareCreation(e)).prepared},async create(n,r){let{prepared:i,provider:a}=await prepareCreation(n);if(r!==void 0&&!isDeepStrictEqual(i,r))throw Error(`Schedule creation changed after approval. Request a new creation approval; no schedule was written.`);let o=`${i.displayName.slice(0,218)}--${randomUUID()}`,s=resolveScheduleTiming(n.expression),c=createScheduleCollectionPayload({application:t.application,collection:t.collection,envelope:i.envelope});return projectScheduleRecord(await e.provider.create(a,{expression:s,name:o,payload:c}))},async prepareUpdate(e,t){return(await prepareUpdate(e,t)).prepared},async update(n,r,i){let{prepared:a,provider:o}=await prepareUpdate(n,r);if(i!==void 0&&!isDeepStrictEqual(a,i))throw Error(`Schedule update changed after approval. Request a new update approval; no schedule was written.`);let s={expression:a.expression===void 0?void 0:resolveScheduleTiming(a.expression),payload:a.envelope===void 0?void 0:createScheduleCollectionPayload({application:t.application,collection:t.collection,envelope:a.envelope})};return projectScheduleRecord(await e.provider.update(o,a.name,s))},async delete(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`delete`,n);return await e.provider.delete(r,n)},async disable(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`disable`,n);return projectScheduleRecord(await e.provider.disable(r,n))},async enable(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`enable`,n);return projectScheduleRecord(await e.provider.enable(r,n))},async get(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`get`,n),i=await e.provider.get(r,n);return i===null?null:projectScheduleRecord(i)},async invoke(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`invoke`,n);await e.provider.invoke(r,n)},async list(t={}){let n=validateScheduleListLimit(t.limit),{provider:r}=await resolveNamespace(`list`),i={};t.cursor?.trim()&&(i.cursor=t.cursor.trim()),n!==void 0&&(i.limit=n);let a=await e.provider.list(r,i);return{...a,data:a.data.map(projectScheduleRecord)}}}}function snapshotPreparedWrite(e){let t=JSON.stringify(e);if(Buffer.byteLength(t)>65536)throw Error(`Prepared schedule write exceeds the 64 KB limit, including timing and payload.`);return JSON.parse(t)}function assertScheduleManagementAllowed(e){let t=contextStorage.getStore();if(e!==void 0||t!==void 0&&readSessionSchedule(t)!==void 0)throw Error(`Schedule management is unavailable during scheduled execution.`)}function principalReference(e){if(e===null||e.principalType===`anonymous`||e.principalType===`runtime`)return null;let t={type:e.principalType,authenticator:e.authenticator,principalId:e.principalId};return e.issuer!==void 0&&(t.issuer=e.issuer),e.subject!==void 0&&(t.subject=e.subject),t}function validateScope(e){let t=typeof e==`string`?[e]:e;if(t.length===0||t.some(e=>typeof e!=`string`||e.trim().length===0))throw Error(`Schedule scope must be a non-empty string or tuple of non-empty strings.`)}function deriveScheduleNamespace(e,t,n){if(e.trim().length===0)throw Error(`Schedule application must not be empty.`);return`eve-${createHash(`sha256`).update(JSON.stringify([`eve-schedule-namespace-v2`,e,t,n])).digest(`base64url`)}`}export{assertScheduleManagementAllowed,createScheduleCollectionClient};
1
+ import{createHash,randomUUID}from"node:crypto";import{loadContext}from"#context/container.js";import{projectScheduleRecord}from"#runtime/schedules/record.js";import{createScheduleCollectionPayload,validateSchedulePayload}from"#runtime/schedules/payload.js";import{isDeepStrictEqual}from"node:util";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{resolveScheduleTiming,validateScheduleListLimit,validateScheduleName}from"#runtime/schedules/validation.js";import{dispatchScheduledOccurrence}from"#runtime/schedules/dispatch-occurrence.js";import{byPrincipal}from"#public/schedules/scope.js";function createScheduleCollectionClient(e,t){let n=t.operationId??randomUUID,contextFor=(e,n)=>{let r={...t,operation:e};return n!==void 0&&(r.name=n),r},resolveNamespace=async(r,i)=>{let a=contextFor(r,i),o=e.scope===void 0?byPrincipal(a):await e.scope({...a,operation:r});if(o===null)throw Error(`Schedule ${r} is not available in this context.`);return validateScope(o),{scope:o,provider:{abortSignal:t.abortSignal,collection:t.collection,namespace:deriveScheduleNamespace(t.application,t.collection,o),operationId:n(),target:{key:t.application,deliver:async({payload:n,occurrence:r})=>{await dispatchScheduledOccurrence({bundle:loadContext().require(BundleKey),collection:t.collection,definition:e,occurrence:{...r,collection:t.collection},payload:n})}}}}},prepareEnvelope=async(n,r,i,a)=>{let o=principalReference(t.session.auth.current);if(o===null)throw Error(`Writing a schedule payload requires an authenticated principal.`);let s=await validateSchedulePayload(e.inputSchema,n),c=e.preparePayload===void 0?s:await e.preparePayload(s,{...contextFor(i,a),operation:i,name:a});return createScheduleCollectionPayload({application:t.application,collection:t.collection,envelope:{version:3,payload:c,scope:r,principal:o}}).envelope},prepareUpdate=async(t,n)=>{let r=Object.keys(n).filter(e=>e!==`expression`&&e!==`payload`);if(r.length>0)throw Error(`Schedule update does not support: ${r.join(`, `)}.`);if(n.expression===void 0&&n.payload===void 0)throw Error(`Schedule update requires an expression or replacement payload.`);let i=validateScheduleName(t);n.expression!==void 0&&resolveScheduleTiming(n.expression);let{scope:a,provider:o}=await resolveNamespace(`update`,i);if(await e.provider.get(o,i)===null)throw Error(`Schedule was not found in the authorized scope.`);return{prepared:snapshotPreparedWrite({name:i,namespace:o.namespace,expression:n.expression,envelope:n.payload===void 0?void 0:await prepareEnvelope(n.payload,a,`update`,i)}),provider:o}},prepareCreation=async e=>{let t=validateScheduleName(e.name);resolveScheduleTiming(e.expression);let{scope:n,provider:r}=await resolveNamespace(`create`,t);return{prepared:snapshotPreparedWrite({displayName:t,expression:e.expression,envelope:await prepareEnvelope(e.payload,n,`create`,t)}),provider:r}};return{async prepareCreate(e){return(await prepareCreation(e)).prepared},async create(n,r){let{prepared:i,provider:a}=await prepareCreation(n);if(r!==void 0&&!isDeepStrictEqual(i,r))throw Error(`Schedule creation changed after approval. Request a new creation approval; no schedule was written.`);let o=`${i.displayName.slice(0,218)}--${randomUUID()}`,s=resolveScheduleTiming(n.expression),c=createScheduleCollectionPayload({application:t.application,collection:t.collection,envelope:i.envelope});return projectScheduleRecord(await e.provider.create(a,{expression:s,name:o,payload:c}))},async prepareUpdate(e,t){return(await prepareUpdate(e,t)).prepared},async update(n,r,i){let{prepared:a,provider:o}=await prepareUpdate(n,r);if(i!==void 0&&!isDeepStrictEqual(a,i))throw Error(`Schedule update changed after approval. Request a new update approval; no schedule was written.`);let s={expression:a.expression===void 0?void 0:resolveScheduleTiming(a.expression),payload:a.envelope===void 0?void 0:createScheduleCollectionPayload({application:t.application,collection:t.collection,envelope:a.envelope})};return projectScheduleRecord(await e.provider.update(o,a.name,s))},async delete(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`delete`,n);return await e.provider.delete(r,n)},async disable(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`disable`,n);return projectScheduleRecord(await e.provider.disable(r,n))},async enable(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`enable`,n);return projectScheduleRecord(await e.provider.enable(r,n))},async get(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`get`,n),i=await e.provider.get(r,n);return i===null?null:projectScheduleRecord(i)},async invoke(t){let n=validateScheduleName(t),{provider:r}=await resolveNamespace(`invoke`,n);await e.provider.invoke(r,n)},async list(t={}){let n=validateScheduleListLimit(t.limit),{provider:r}=await resolveNamespace(`list`),i={};t.cursor?.trim()&&(i.cursor=t.cursor.trim()),n!==void 0&&(i.limit=n);let a=await e.provider.list(r,i);return{...a,data:a.data.map(projectScheduleRecord)}}}}function snapshotPreparedWrite(e){let t=JSON.stringify(e);if(Buffer.byteLength(t)>65536)throw Error(`Prepared schedule write exceeds the 64 KB limit, including timing and payload.`);return JSON.parse(t)}function principalReference(e){if(e===null||e.principalType===`anonymous`||e.principalType===`runtime`)return null;let t={type:e.principalType,authenticator:e.authenticator,principalId:e.principalId};return e.issuer!==void 0&&(t.issuer=e.issuer),e.subject!==void 0&&(t.subject=e.subject),t}function validateScope(e){let t=typeof e==`string`?[e]:e;if(t.length===0||t.some(e=>typeof e!=`string`||e.trim().length===0))throw Error(`Schedule scope must be a non-empty string or tuple of non-empty strings.`)}function deriveScheduleNamespace(e,t,n){if(e.trim().length===0)throw Error(`Schedule application must not be empty.`);return`eve-${createHash(`sha256`).update(JSON.stringify([`eve-schedule-namespace-v2`,e,t,n])).digest(`base64url`)}`}export{createScheduleCollectionClient};
@@ -1,3 +1,5 @@
1
+ import type { Experimental_ConnectionEvents } from "#public/definitions/connections/events.js";
2
+ import type { ConnectionEventsBackend } from "#shared/connection-events.js";
1
3
  import type { ChannelAdapter } from "#channel/adapter.js";
2
4
  import type { CompiledChannel } from "#channel/compiled-channel.js";
3
5
  import type { NormalizedChannelCorsOptions } from "#channel/cors.js";
@@ -76,7 +78,16 @@ export type ResolvedScheduleDefinition = Readonly<SourceRef & {
76
78
  * Both `authorization` and `headers` are optional — a connection to a
77
79
  * server that requires no authentication (e.g. localhost) may omit both.
78
80
  */
81
+ /** A connection's event watching, checked once when the connection resolves. */
82
+ export interface ResolvedConnectionEvents {
83
+ readonly callbacks: Experimental_ConnectionEvents;
84
+ /** The static Connect authorization every watch subscribes and runs under. */
85
+ readonly authorization: Readonly<AuthorizationDefinition>;
86
+ readonly connector: string;
87
+ readonly backend: ConnectionEventsBackend;
88
+ }
79
89
  export interface ResolvedConnectionDefinition extends ResolvedModuleSourceRef {
90
+ readonly experimental_events?: ResolvedConnectionEvents;
80
91
  readonly protocolVersionDiscovery?: boolean;
81
92
  /** MCP only: send the turn's principals in `eve-forwarded-principal`. */
82
93
  readonly forwardPrincipal?: boolean;
@@ -1 +1 @@
1
- import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{readFile}from"node:fs/promises";import{join}from"node:path";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(e){let t=e.packageManager??`pnpm`,n=join(e.projectRoot,`package.json`);if(!await pathExists(n))throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let r;try{r=JSON.parse(await readFile(n,`utf8`))}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Cannot add an eve agent because "${n}" is not valid JSON. No files were changed. Fix the file, then retry eve init. ${t}`)}let i=agentTemplateFiles(e.model,e.reasoning),a=[];for(let t of Object.keys(i))await pathExists(join(e.projectRoot,t))&&a.push(t);if(a.length===0&&await pathExists(join(e.projectRoot,`agent`))&&a.push(`agent/`),a.length>0)throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it already has: ${a.join(`, `)}.`);let o=resolveEvePackageContract(e.evePackage),s=resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.137`),c=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2.0`),l=resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.5.4`),u=[];for(let[t,n]of Object.entries(i)){let r=join(e.projectRoot,t);await writeTextFile(r,n),u.push(r)}let d={"@vercel/connect":c,ai:s,eve:formatEveDependencySpecifier(o.version),zod:l},f={};for(let[e,t]of Object.entries(d))hasDeclaredDependency(r,e)||(f[e]=t);let p={};Object.keys(f).length>0&&(p.dependencies=f),isPackageManagerWorkspaceMember(t,e.projectRoot)||(p.nodeEngineRequirement=o.nodeEngine);let m=await patchPackageJson(n,p),h=await patchWorkspaceRootPackageJson(t,e.projectRoot,{nodeEngineRequirement:o.nodeEngine}),g=h.nodeEngineOverride??m.nodeEngineOverride,_=await applyPackageManagerWorkspaceConfiguration({packageManager:t,projectRoot:e.projectRoot});return{filesWritten:u,dependenciesAdded:Object.keys(f).sort(),nodeEngineOverride:g,configurationFilesChanged:[...m.changed?[n]:[],...h.changed&&h.path!==void 0?[h.path]:[],..._.filesWritten]}}export{addAgentToProject};
1
+ import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{readFile}from"node:fs/promises";import{join}from"node:path";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(e){let t=e.packageManager??`pnpm`,n=join(e.projectRoot,`package.json`);if(!await pathExists(n))throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let r;try{r=JSON.parse(await readFile(n,`utf8`))}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Cannot add an eve agent because "${n}" is not valid JSON. No files were changed. Fix the file, then retry eve init. ${t}`)}let i=agentTemplateFiles(e.model,e.reasoning),a=[];for(let t of Object.keys(i))await pathExists(join(e.projectRoot,t))&&a.push(t);if(a.length===0&&await pathExists(join(e.projectRoot,`agent`))&&a.push(`agent/`),a.length>0)throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it already has: ${a.join(`, `)}.`);let o=resolveEvePackageContract(e.evePackage),s=resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.137`),c=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.5.2`),l=resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.5.4`),u=[];for(let[t,n]of Object.entries(i)){let r=join(e.projectRoot,t);await writeTextFile(r,n),u.push(r)}let d={"@vercel/connect":c,ai:s,eve:formatEveDependencySpecifier(o.version),zod:l},f={};for(let[e,t]of Object.entries(d))hasDeclaredDependency(r,e)||(f[e]=t);let p={};Object.keys(f).length>0&&(p.dependencies=f),isPackageManagerWorkspaceMember(t,e.projectRoot)||(p.nodeEngineRequirement=o.nodeEngine);let m=await patchPackageJson(n,p),h=await patchWorkspaceRootPackageJson(t,e.projectRoot,{nodeEngineRequirement:o.nodeEngine}),g=h.nodeEngineOverride??m.nodeEngineOverride,_=await applyPackageManagerWorkspaceConfiguration({packageManager:t,projectRoot:e.projectRoot});return{filesWritten:u,dependenciesAdded:Object.keys(f).sort(),nodeEngineOverride:g,configurationFilesChanged:[...m.changed?[n]:[],...h.changed&&h.path!==void 0?[h.path]:[],..._.filesWritten]}}export{addAgentToProject};
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_CHANNEL_TEMPLATES}from"./web-template.js";import{AGENT_INSTRUCTIONS_TEMPLATE}from"./instructions-template.js";import{SCAFFOLDED_AGENT_PATHS}from"./agent-paths.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.137`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.79.1`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{[SCAFFOLDED_AGENT_PATHS.config]:renderAgentTemplate(e,t),[SCAFFOLDED_AGENT_PATHS.channel]:WEB_CHANNEL_TEMPLATES.default,[SCAFFOLDED_AGENT_PATHS.instructions]:AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,t){let n=parseChatGptModelSelection(e);return n===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(n)}),\n${reasoningTemplateLine(t)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(t.model)!==void 0?renderAgentTemplate(t.model,t.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_CHANNEL_TEMPLATES}from"./web-template.js";import{AGENT_INSTRUCTIONS_TEMPLATE}from"./instructions-template.js";import{SCAFFOLDED_AGENT_PATHS}from"./agent-paths.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.137`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.80.0`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{[SCAFFOLDED_AGENT_PATHS.config]:renderAgentTemplate(e,t),[SCAFFOLDED_AGENT_PATHS.channel]:WEB_CHANNEL_TEMPLATES.default,[SCAFFOLDED_AGENT_PATHS.instructions]:AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,t){let n=parseChatGptModelSelection(e);return n===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(n)}),\n${reasoningTemplateLine(t)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(t.model)!==void 0?renderAgentTemplate(t.model,t.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -114,4 +114,4 @@ __EVE_INIT_REASONING__ modelOptions: {
114
114
  },
115
115
  },
116
116
  });
117
- `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate(e.includeRootOnlyPackageJsonFields)}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let n=await readdir(e),r=blockingCreateInPlaceEntries(n);if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(e){let t=resolve(e.targetDirectory??process.cwd(),e.projectName),n=e.projectName===`.`,r=e.overwriteExisting??!1,i=e.byokProvider??!1,a=e.packageManager??`pnpm`,o=resolveEvePackageContract(e.evePackage),s=pinnedNodeEngineMajor(o.nodeEngine),c=resolve(e.workspaceProbeDirectory??t),l=isPackageManagerWorkspaceMember(a,c);if(n)await assertCanCreateInPlace(t,r);else if(await pathExists(t))throw Error(`Cannot create project because "${t}" already exists.`);let u={appName:basename(t),model:e.model,reasoning:e.reasoning,eveVersion:o.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.137`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2.0`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.5.4`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,e.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:s,nodeEngine:s};await mkdir(t,{recursive:!0});for(let[a,o]of Object.entries(templateFiles({byokProvider:i,includeRootOnlyPackageJsonFields:!l}))){let i=`${t}/${a}`,s=await pathExists(i);await writeTextFile(i,renderTemplate(o,u),{force:n&&r}),s&&await e.onOverwriteFile?.(i)}return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:t,workspaceProbeRoot:c,onWorkspaceRootMutation:e.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(a,c,{nodeEngineRequirement:o.nodeEngine,onWorkspaceRootMutation:e.onWorkspaceRootMutation}),t}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
117
+ `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate(e.includeRootOnlyPackageJsonFields)}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let n=await readdir(e),r=blockingCreateInPlaceEntries(n);if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(e){let t=resolve(e.targetDirectory??process.cwd(),e.projectName),n=e.projectName===`.`,r=e.overwriteExisting??!1,i=e.byokProvider??!1,a=e.packageManager??`pnpm`,o=resolveEvePackageContract(e.evePackage),s=pinnedNodeEngineMajor(o.nodeEngine),c=resolve(e.workspaceProbeDirectory??t),l=isPackageManagerWorkspaceMember(a,c);if(n)await assertCanCreateInPlace(t,r);else if(await pathExists(t))throw Error(`Cannot create project because "${t}" already exists.`);let u={appName:basename(t),model:e.model,reasoning:e.reasoning,eveVersion:o.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.137`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.5.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.5.4`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,e.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:s,nodeEngine:s};await mkdir(t,{recursive:!0});for(let[a,o]of Object.entries(templateFiles({byokProvider:i,includeRootOnlyPackageJsonFields:!l}))){let i=`${t}/${a}`,s=await pathExists(i);await writeTextFile(i,renderTemplate(o,u),{force:n&&r}),s&&await e.onOverwriteFile?.(i)}return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:t,workspaceProbeRoot:c,onWorkspaceRootMutation:e.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(a,c,{nodeEngineRequirement:o.nodeEngine,onWorkspaceRootMutation:e.onWorkspaceRootMutation}),t}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
@@ -4,7 +4,7 @@ import { slackChannel } from "eve/channels/slack";
4
4
  export default slackChannel({
5
5
  credentials: connectSlackCredentials(${JSON.stringify(e)}),
6
6
  });
7
- `}const SLACK_ENV_EXAMPLE_VALUES={SLACK_BOT_TOKEN:``,SLACK_SIGNING_SECRET:``};function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let r=join(e,n);await pathExists(r)&&t.push(r)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=join(e.projectRoot,`app/page.tsx`),r=await pathExists(n);if(!e.force&&!e.skipDependencyMutation&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let i=resolveWebPackageVersions(e.webPackageVersions,e.webAuthentication),a=e.packageManager??`pnpm`,o=resolve(e.workspaceProbeDirectory??e.projectRoot),s=await patchWebPackageJson(e.projectRoot,a,o,i,e.onWorkspaceRootMutation,!e.skipDependencyMutation,e.webAuthentication),c=[],l=[],u=[],d=[],f=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?c.push(t):d.push(t)}let p=await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:e.projectRoot,workspaceProbeRoot:o,onWorkspaceRootMutation:e.onWorkspaceRootMutation});if(c.push(...p.filesWritten),d.push(...p.filesSkipped),!e.skipDependencyMutation){let t=WEB_CHANNEL_TEMPLATES[e.webAuthentication??`default`],n={...WEB_APP_TEMPLATE_FILES,...e.webAuthentication===`sign-in-with-vercel`?WEB_APP_SIGN_IN_WITH_VERCEL_TEMPLATE_FILES:{},[WEB_CHANNEL_PATH]:t};for(let[t,r]of Object.entries(n)){let n=join(e.projectRoot,t);if(t===WEB_CHANNEL_PATH&&!e.force&&await pathExists(n)){d.push(n);continue}let i=await pathExists(n);await writeTextFile(n,renderWebAppTemplate(r,f),{force:!0}),c.push(n),i&&l.push(n)}}u.push(...await findCompetingNextConfigFiles(e.projectRoot));let m=[...new Set(c)],h=[...new Set(d)].filter(e=>!m.includes(e)),g={kind:`web`,action:r?`overwritten`:`created`,filesWritten:m,filesSkipped:h,packageJsonUpdated:s.mutations};return l.length>0&&(g.filesOverwritten=l),u.length>0&&(g.competingNextConfigFiles=u),s.nodeEngineOverride!==void 0&&(g.nodeEngineOverride=s.nodeEngineOverride),g}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),n=await pathExists(t);if(!e.force&&n)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let r=e.slackCredentials??`vercel-connect`,i=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot),a,o=[],s=[t],c=[],l;if(r===`vercel-connect`){if(!e.skipDependencyMutation){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2.0`);o=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,t)}a=buildSlackConnectTemplate(e.slackConnectorUid??`slack/${i}`)}else{a=`import { slackChannel } from "eve/channels/slack";
7
+ `}const SLACK_ENV_EXAMPLE_VALUES={SLACK_BOT_TOKEN:``,SLACK_SIGNING_SECRET:``};function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let r=join(e,n);await pathExists(r)&&t.push(r)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=join(e.projectRoot,`app/page.tsx`),r=await pathExists(n);if(!e.force&&!e.skipDependencyMutation&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let i=resolveWebPackageVersions(e.webPackageVersions,e.webAuthentication),a=e.packageManager??`pnpm`,o=resolve(e.workspaceProbeDirectory??e.projectRoot),s=await patchWebPackageJson(e.projectRoot,a,o,i,e.onWorkspaceRootMutation,!e.skipDependencyMutation,e.webAuthentication),c=[],l=[],u=[],d=[],f=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?c.push(t):d.push(t)}let p=await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:e.projectRoot,workspaceProbeRoot:o,onWorkspaceRootMutation:e.onWorkspaceRootMutation});if(c.push(...p.filesWritten),d.push(...p.filesSkipped),!e.skipDependencyMutation){let t=WEB_CHANNEL_TEMPLATES[e.webAuthentication??`default`],n={...WEB_APP_TEMPLATE_FILES,...e.webAuthentication===`sign-in-with-vercel`?WEB_APP_SIGN_IN_WITH_VERCEL_TEMPLATE_FILES:{},[WEB_CHANNEL_PATH]:t};for(let[t,r]of Object.entries(n)){let n=join(e.projectRoot,t);if(t===WEB_CHANNEL_PATH&&!e.force&&await pathExists(n)){d.push(n);continue}let i=await pathExists(n);await writeTextFile(n,renderWebAppTemplate(r,f),{force:!0}),c.push(n),i&&l.push(n)}}u.push(...await findCompetingNextConfigFiles(e.projectRoot));let m=[...new Set(c)],h=[...new Set(d)].filter(e=>!m.includes(e)),g={kind:`web`,action:r?`overwritten`:`created`,filesWritten:m,filesSkipped:h,packageJsonUpdated:s.mutations};return l.length>0&&(g.filesOverwritten=l),u.length>0&&(g.competingNextConfigFiles=u),s.nodeEngineOverride!==void 0&&(g.nodeEngineOverride=s.nodeEngineOverride),g}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),n=await pathExists(t);if(!e.force&&n)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let r=e.slackCredentials??`vercel-connect`,i=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot),a,o=[],s=[t],c=[],l;if(r===`vercel-connect`){if(!e.skipDependencyMutation){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.5.2`);o=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,t)}a=buildSlackConnectTemplate(e.slackConnectorUid??`slack/${i}`)}else{a=`import { slackChannel } from "eve/channels/slack";
8
8
 
9
9
  export default slackChannel();
10
10
  `;let t=join(e.environmentRoot??e.projectRoot,`.env.example`);l={path:t,...await pathExists(t)?{content:await readFile(t,`utf8`)}:{}},(await appendEnv(t,SLACK_ENV_EXAMPLE_VALUES)).written.length>0?s.push(t):c.push(t)}try{await writeTextFile(t,a,{force:e.force})}catch(e){throw l!==void 0&&(l.content===void 0?await unlink(l.path):await writeFile(l.path,l.content,`utf8`)),e}let u={kind:`slack`,action:n?`overwritten`:`created`,filesWritten:s,filesSkipped:c,packageJsonUpdated:o,slackConnectorSlug:i};return n&&(u.filesOverwritten=[t]),u}async function listAuthoredChannels(e){let t=join(e,`channels`),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug,resolveVercelHostFrameworkPreset};
@@ -15,7 +15,7 @@ export default defineOpenAPIConnection({
15
15
  spec: "${e.spec}",
16
16
  ${i} description: "${t}",
17
17
  ${authBlock(n)}});
18
- `}function renderTemplate(e,t,n,r){return e===`mcp`?renderMcpTemplate(t,n,r):renderOpenApiTemplate(t,n,r)}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function ensureConnectDependency(e,t){if(!await pathExists(e))return[];let n=JSON.parse(await readFile(e,`utf8`));return(isJsonObject(n)&&isJsonObject(n.dependencies)?n.dependencies[CONNECT_PACKAGE_NAME]:void 0)===t?[]:(await patchPackageJson(e,{dependencies:{[CONNECT_PACKAGE_NAME]:t}}),[{path:e,dependencies:[CONNECT_PACKAGE_NAME],devDependencies:[],scripts:[]}])}async function ensureConnectionDependencies(e){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2.0`);return ensureConnectDependency(join(e.projectRoot,`package.json`),t)}function envKeyPresent(e,t){return RegExp(`^\\s*(?:export\\s+)?${t}\\s*=`,`m`).test(e)}async function seedEnvPlaceholders(e,t){if(t.length===0)return[];let n=``;await pathExists(e)&&(n=await readFile(e,`utf8`));let r=t.filter(e=>!envKeyPresent(n,e));if(r.length===0)return[];let i=`${n.length>0&&!n.endsWith(`
18
+ `}function renderTemplate(e,t,n,r){return e===`mcp`?renderMcpTemplate(t,n,r):renderOpenApiTemplate(t,n,r)}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function ensureConnectDependency(e,t){if(!await pathExists(e))return[];let n=JSON.parse(await readFile(e,`utf8`));return(isJsonObject(n)&&isJsonObject(n.dependencies)?n.dependencies[CONNECT_PACKAGE_NAME]:void 0)===t?[]:(await patchPackageJson(e,{dependencies:{[CONNECT_PACKAGE_NAME]:t}}),[{path:e,dependencies:[CONNECT_PACKAGE_NAME],devDependencies:[],scripts:[]}])}async function ensureConnectionDependencies(e){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.5.2`);return ensureConnectDependency(join(e.projectRoot,`package.json`),t)}function envKeyPresent(e,t){return RegExp(`^\\s*(?:export\\s+)?${t}\\s*=`,`m`).test(e)}async function seedEnvPlaceholders(e,t){if(t.length===0)return[];let n=``;await pathExists(e)&&(n=await readFile(e,`utf8`));let r=t.filter(e=>!envKeyPresent(n,e));if(r.length===0)return[];let i=`${n.length>0&&!n.endsWith(`
19
19
  `)?`
20
20
  `:``}${r.map(e=>`${e}=`).join(`
21
- `)}\n`;return await writeFile(e,n+i,`utf8`),r}async function ensureConnection(e){let t=e.slug??e.entry.slug,n=resolveAuth(e.entry),r=endpointForProtocol(e.entry,e.protocol);if(r===null)throw Error(`Connection "${t}" is missing a ${e.protocol===`mcp`?`mcp.url`:`openapi.spec`} endpoint for protocol "${e.protocol}".`);let i=join(e.projectRoot,USER_AUTHORED_CONNECTION_DIR,`${t}.ts`),a=envKeysForAuth(n),o=await pathExists(i);if(!e.force&&o)return{slug:t,protocol:e.protocol,action:`skipped`,filePath:i,filesWritten:[],filesSkipped:[i],packageJsonUpdated:[],envKeysAdded:[],envKeysRequired:a};let s=[];if(n.kind===`connect`){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2.0`);s.push(...await ensureConnectDependency(join(e.projectRoot,`package.json`),t))}await writeTextFile(i,renderTemplate(e.protocol,r,e.entry.description,n),{force:!0});let c=await seedEnvPlaceholders(join(e.projectRoot,`.env.local`),a),l={slug:t,protocol:e.protocol,action:o?`overwritten`:`created`,filePath:i,filesWritten:[i],filesSkipped:[],packageJsonUpdated:s,envKeysAdded:c,envKeysRequired:a};return o&&(l.filesOverwritten=[i]),l}async function listAuthoredConnections(e){let t=join(e,USER_AUTHORED_CONNECTION_DIR),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{ensureConnection,ensureConnectionDependencies,listAuthoredConnections};
21
+ `)}\n`;return await writeFile(e,n+i,`utf8`),r}async function ensureConnection(e){let t=e.slug??e.entry.slug,n=resolveAuth(e.entry),r=endpointForProtocol(e.entry,e.protocol);if(r===null)throw Error(`Connection "${t}" is missing a ${e.protocol===`mcp`?`mcp.url`:`openapi.spec`} endpoint for protocol "${e.protocol}".`);let i=join(e.projectRoot,USER_AUTHORED_CONNECTION_DIR,`${t}.ts`),a=envKeysForAuth(n),o=await pathExists(i);if(!e.force&&o)return{slug:t,protocol:e.protocol,action:`skipped`,filePath:i,filesWritten:[],filesSkipped:[i],packageJsonUpdated:[],envKeysAdded:[],envKeysRequired:a};let s=[];if(n.kind===`connect`){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.5.2`);s.push(...await ensureConnectDependency(join(e.projectRoot,`package.json`),t))}await writeTextFile(i,renderTemplate(e.protocol,r,e.entry.description,n),{force:!0});let c=await seedEnvPlaceholders(join(e.projectRoot,`.env.local`),a),l={slug:t,protocol:e.protocol,action:o?`overwritten`:`created`,filePath:i,filesWritten:[i],filesSkipped:[],packageJsonUpdated:s,envKeysAdded:c,envKeysRequired:a};return o&&(l.filesOverwritten=[i]),l}async function listAuthoredConnections(e){let t=join(e,USER_AUTHORED_CONNECTION_DIR),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{ensureConnection,ensureConnectionDependencies,listAuthoredConnections};
@@ -1,4 +1,4 @@
1
- export declare const DEFAULT_CONNECT_PACKAGE_VERSION = "2.2.0";
1
+ export declare const DEFAULT_CONNECT_PACKAGE_VERSION = "2.5.2";
2
2
  export declare const DEFAULT_MICROSANDBOX_PACKAGE_VERSION = "0.5.5";
3
3
  /**
4
4
  * Returns a scaffold version value, resolving a build-stamp token at the point
@@ -1 +1 @@
1
- import{existsSync,readFileSync,realpathSync}from"node:fs";import{dirname,join}from"node:path";import{fileURLToPath}from"node:url";function versionToken(e){return`__${e}_VERSION__`}function bareToken(e){return`__${e}__`}const NODE_ENGINE_TOKEN=bareToken(`NODE_ENGINE`),DEFAULT_CONNECT_PACKAGE_VERSION=`2.2.0`,DEFAULT_MICROSANDBOX_PACKAGE_VERSION=`0.5.5`,TOKEN_SOURCES={[versionToken(`EVE_PACKAGE`)]:{kind:`eve-version`},[versionToken(`EVE_PACKAGE_DEPENDENCY`)]:{kind:`eve-version`},[NODE_ENGINE_TOKEN]:{kind:`eve-node-engine`},[versionToken(`AI_SDK`)]:{kind:`catalog`,packageName:`ai`},[versionToken(`NEXT`)]:{kind:`catalog`,packageName:`next`},[versionToken(`REACT`)]:{kind:`catalog`,packageName:`react`},[versionToken(`REACT_DOM`)]:{kind:`catalog`,packageName:`react-dom`},[versionToken(`STREAMDOWN`)]:{kind:`catalog`,packageName:`streamdown`},[versionToken(`ZOD`)]:{kind:`catalog`,packageName:`zod`},[versionToken(`TYPESCRIPT`)]:{kind:`catalog`,packageName:`typescript`},[versionToken(`TYPES_REACT`)]:{kind:`catalog`,packageName:`@types/react`},[versionToken(`TYPES_REACT_DOM`)]:{kind:`catalog`,packageName:`@types/react-dom`}},resolvedTokens=new Map;function findEvePackageRoot(){let e=dirname(realpathSync(fileURLToPath(import.meta.url)));for(;;){let t=join(e,`package.json`);if(existsSync(t)&&JSON.parse(readFileSync(t,`utf8`)).name===`eve`)return e;let n=dirname(e);if(n===e)return;e=n}}function findWorkspaceManifest(e){let t=e;for(;;){let e=join(t,`pnpm-workspace.yaml`);if(existsSync(e))return e;let n=dirname(t);if(n===t)return;t=n}}function readCatalogVersion(e,t){let n=readFileSync(e,`utf8`).split(/\r?\n/),r=!1;for(let e of n){if(/^catalog:\s*$/.test(e)){r=!0;continue}if(!r)continue;if(/^\S/.test(e))break;let n=e.match(/^\s+(?:"([^"]+)"|([\w@/.-]+)):\s*"([^"]+)"/);if(n&&(n[1]??n[2])===t)return n[3]}}function resolveTokenFromDevTree(e){let t=TOKEN_SOURCES[e];if(t!==void 0)try{let e=findEvePackageRoot();if(e===void 0||!existsSync(join(e,`scripts/stamp-version-tokens.mjs`)))return;if(t.kind===`eve-version`){let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`));return typeof t.version==`string`?t.version:void 0}if(t.kind===`eve-node-engine`){let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`)).engines?.node;return typeof t==`string`?t:void 0}let n=findWorkspaceManifest(e);return n===void 0?void 0:readCatalogVersion(n,t.packageName)}catch{return}}function resolveVersionToken(e,t){if(!t.startsWith(`__`))return t;let n=resolvedTokens.get(t);if(n!==void 0)return n;let r=resolveTokenFromDevTree(t);if(r===void 0)throw Error(`Scaffold received unstamped version token (${e}=${t}). Build eve before using its dist entrypoint.`);return resolvedTokens.set(t,r),r}export{DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_MICROSANDBOX_PACKAGE_VERSION,resolveVersionToken};
1
+ import{existsSync,readFileSync,realpathSync}from"node:fs";import{dirname,join}from"node:path";import{fileURLToPath}from"node:url";function versionToken(e){return`__${e}_VERSION__`}function bareToken(e){return`__${e}__`}const NODE_ENGINE_TOKEN=bareToken(`NODE_ENGINE`),DEFAULT_CONNECT_PACKAGE_VERSION=`2.5.2`,DEFAULT_MICROSANDBOX_PACKAGE_VERSION=`0.5.5`,TOKEN_SOURCES={[versionToken(`EVE_PACKAGE`)]:{kind:`eve-version`},[versionToken(`EVE_PACKAGE_DEPENDENCY`)]:{kind:`eve-version`},[NODE_ENGINE_TOKEN]:{kind:`eve-node-engine`},[versionToken(`AI_SDK`)]:{kind:`catalog`,packageName:`ai`},[versionToken(`NEXT`)]:{kind:`catalog`,packageName:`next`},[versionToken(`REACT`)]:{kind:`catalog`,packageName:`react`},[versionToken(`REACT_DOM`)]:{kind:`catalog`,packageName:`react-dom`},[versionToken(`STREAMDOWN`)]:{kind:`catalog`,packageName:`streamdown`},[versionToken(`ZOD`)]:{kind:`catalog`,packageName:`zod`},[versionToken(`TYPESCRIPT`)]:{kind:`catalog`,packageName:`typescript`},[versionToken(`TYPES_REACT`)]:{kind:`catalog`,packageName:`@types/react`},[versionToken(`TYPES_REACT_DOM`)]:{kind:`catalog`,packageName:`@types/react-dom`}},resolvedTokens=new Map;function findEvePackageRoot(){let e=dirname(realpathSync(fileURLToPath(import.meta.url)));for(;;){let t=join(e,`package.json`);if(existsSync(t)&&JSON.parse(readFileSync(t,`utf8`)).name===`eve`)return e;let n=dirname(e);if(n===e)return;e=n}}function findWorkspaceManifest(e){let t=e;for(;;){let e=join(t,`pnpm-workspace.yaml`);if(existsSync(e))return e;let n=dirname(t);if(n===t)return;t=n}}function readCatalogVersion(e,t){let n=readFileSync(e,`utf8`).split(/\r?\n/),r=!1;for(let e of n){if(/^catalog:\s*$/.test(e)){r=!0;continue}if(!r)continue;if(/^\S/.test(e))break;let n=e.match(/^\s+(?:"([^"]+)"|([\w@/.-]+)):\s*"([^"]+)"/);if(n&&(n[1]??n[2])===t)return n[3]}}function resolveTokenFromDevTree(e){let t=TOKEN_SOURCES[e];if(t!==void 0)try{let e=findEvePackageRoot();if(e===void 0||!existsSync(join(e,`scripts/stamp-version-tokens.mjs`)))return;if(t.kind===`eve-version`){let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`));return typeof t.version==`string`?t.version:void 0}if(t.kind===`eve-node-engine`){let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`)).engines?.node;return typeof t==`string`?t:void 0}let n=findWorkspaceManifest(e);return n===void 0?void 0:readCatalogVersion(n,t.packageName)}catch{return}}function resolveVersionToken(e,t){if(!t.startsWith(`__`))return t;let n=resolvedTokens.get(t);if(n!==void 0)return n;let r=resolveTokenFromDevTree(t);if(r===void 0)throw Error(`Scaffold received unstamped version token (${e}=${t}). Build eve before using its dist entrypoint.`);return resolvedTokens.set(t,r),r}export{DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_MICROSANDBOX_PACKAGE_VERSION,resolveVersionToken};
@@ -170,6 +170,7 @@ export type RuntimeToolResultActionResult = z.infer<typeof runtimeToolResultActi
170
170
  */
171
171
  declare const runtimeToolResultActionResultSchema: z.ZodObject<{
172
172
  callId: z.ZodString;
173
+ errorName: z.ZodOptional<z.ZodString>;
173
174
  isError: z.ZodOptional<z.ZodBoolean>;
174
175
  kind: z.ZodLiteral<"tool-result">;
175
176
  output: z.ZodType<import("#shared/json.js").JsonValue, unknown, z.core.$ZodTypeInternals<import("#shared/json.js").JsonValue, unknown>>;
@@ -1 +1 @@
1
- import{z}from"#compiled/zod/index.js";import{jsonObjectSchema,jsonValueSchema}from"#shared/json-schemas.js";const runtimeToolCallActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`tool-call`),toolName:z.string()}).strict();z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict(),z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`workflow-tool-call`),toolName:z.string(),workflowId:z.string()}).strict(),z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict();const runtimeRemoteAgentDispatchRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),workflowToolCallEntrySchema=z.discriminatedUnion(`entryPoint`,[z.object({entryPoint:z.literal(`execute`)}).strict(),z.object({entryPoint:z.literal(`task`),taskId:z.string()}).strict(),z.object({entryPoint:z.literal(`serve`),taskId:z.string()}).strict(),z.object({entryPoint:z.literal(`receive`),taskId:z.string()}).strict()]),runtimeWorkflowTaskRequestSchema=z.object({callId:z.string(),entry:workflowToolCallEntrySchema,executeInput:jsonValueSchema.optional(),input:jsonObjectSchema,kind:z.literal(`workflow-task`),toolName:z.string(),workflowId:z.string()}).strict();z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`load-skill`),name:z.string()}).strict();const RUNTIME_WORKFLOW_TOOL_ACTION=Symbol.for(`eve:runtime-workflow-tool-action`);function markRuntimeWorkflowToolAction(e){return Object.defineProperty(e,RUNTIME_WORKFLOW_TOOL_ACTION,{value:!0}),e}function isRuntimeWorkflowToolAction(e){return e.kind===`workflow-tool-call`||e.kind===`tool-call`&&Reflect.get(e,RUNTIME_WORKFLOW_TOOL_ACTION)===!0}z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`tool-result`),output:jsonValueSchema,toolName:z.string()}).strict(),z.object({callId:z.string(),isError:z.literal(!0),kind:z.literal(`subagent-result`),origin:z.literal(`dispatch`),output:jsonValueSchema,subagentName:z.string()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`load-skill-result`),name:z.string(),output:jsonValueSchema}).strict();export{isRuntimeWorkflowToolAction,markRuntimeWorkflowToolAction,runtimeRemoteAgentDispatchRequestSchema,runtimeToolCallActionRequestSchema,runtimeWorkflowTaskRequestSchema};
1
+ import{z}from"#compiled/zod/index.js";import{jsonObjectSchema,jsonValueSchema}from"#shared/json-schemas.js";const runtimeToolCallActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`tool-call`),toolName:z.string()}).strict();z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict(),z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`workflow-tool-call`),toolName:z.string(),workflowId:z.string()}).strict(),z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict();const runtimeRemoteAgentDispatchRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),workflowToolCallEntrySchema=z.discriminatedUnion(`entryPoint`,[z.object({entryPoint:z.literal(`execute`)}).strict(),z.object({entryPoint:z.literal(`task`),taskId:z.string()}).strict(),z.object({entryPoint:z.literal(`serve`),taskId:z.string()}).strict(),z.object({entryPoint:z.literal(`receive`),taskId:z.string()}).strict()]),runtimeWorkflowTaskRequestSchema=z.object({callId:z.string(),entry:workflowToolCallEntrySchema,executeInput:jsonValueSchema.optional(),input:jsonObjectSchema,kind:z.literal(`workflow-task`),toolName:z.string(),workflowId:z.string()}).strict();z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`load-skill`),name:z.string()}).strict();const RUNTIME_WORKFLOW_TOOL_ACTION=Symbol.for(`eve:runtime-workflow-tool-action`);function markRuntimeWorkflowToolAction(e){return Object.defineProperty(e,RUNTIME_WORKFLOW_TOOL_ACTION,{value:!0}),e}function isRuntimeWorkflowToolAction(e){return e.kind===`workflow-tool-call`||e.kind===`tool-call`&&Reflect.get(e,RUNTIME_WORKFLOW_TOOL_ACTION)===!0}z.object({callId:z.string(),errorName:z.string().optional(),isError:z.boolean().optional(),kind:z.literal(`tool-result`),output:jsonValueSchema,toolName:z.string()}).strict(),z.object({callId:z.string(),isError:z.literal(!0),kind:z.literal(`subagent-result`),origin:z.literal(`dispatch`),output:jsonValueSchema,subagentName:z.string()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`load-skill-result`),name:z.string(),output:jsonValueSchema}).strict();export{isRuntimeWorkflowToolAction,markRuntimeWorkflowToolAction,runtimeRemoteAgentDispatchRequestSchema,runtimeToolCallActionRequestSchema,runtimeWorkflowTaskRequestSchema};
@@ -267,20 +267,28 @@ export interface AgentWorkflowDefinition {
267
267
  * Applied to every run that owns the session, including successors created
268
268
  * by deployment handoff.
269
269
  *
270
- * - `"default"`: same as omission. The Workflow SDK World decides.
270
+ * When omitted, eve uses the session's resolved OTel trace decision: full
271
+ * input and output capture keeps the World's default; dropped traces or
272
+ * either excluded content direction request `0`. Destination export filters
273
+ * and lifecycle-provider policies do not affect this choice.
274
+ *
275
+ * An explicit value overrides this automatic choice:
276
+ * - `"default"`: the Workflow SDK World decides, regardless of tracing.
271
277
  * On Vercel this follows your team's plan.
272
278
  * - `0`: the world deletes run payloads and stream chunks as soon as the run
273
279
  * completes or fails. Metadata such as run IDs, status, and timestamps may
274
280
  * persist up to the default period.
275
281
  *
276
- * The World you are using with the Workflow SDK might not support every
277
- * option. A World that does not recognize the value keeps the data.
282
+ * The World enforces deletion. Worlds older than spec version 4 reject `0`;
283
+ * spec version 4 Worlds without retention support keep the data. Run, step,
284
+ * and event metadata and attributes remain for the default period. Exported
285
+ * traces are not deleted.
278
286
  *
279
287
  * Note that with retention set to `0`, data deletion can race reads of a finished
280
288
  * run, so results and transcripts of completed sessions generally become
281
289
  * unreadable. Persist anything you need to keep from inside a tool.
282
290
  *
283
- * @default "default"
291
+ * @default Derived from the session's resolved trace policy.
284
292
  */
285
293
  readonly retention?: AgentWorkflowRetentionDefinition;
286
294
  /**
@@ -0,0 +1,84 @@
1
+ import type { ConnectionPrincipal } from "#shared/connection-types.js";
2
+ import type { Experimental_ConnectionEvent } from "#public/definitions/connections/events.js";
3
+ export type EventJson = string | number | boolean | null | readonly EventJson[] | EventJsonObject;
4
+ export type EventJsonObject = {
5
+ [key: string]: EventJson | undefined;
6
+ };
7
+ export interface ManagedEventSubscription {
8
+ id: string;
9
+ name: string;
10
+ arguments: EventJsonObject;
11
+ status: "pending" | "active" | "needs_auth" | "stopped" | "expired" | "failed";
12
+ expiresAt: string | null;
13
+ cleanupStatus?: "pending" | "complete" | "exhausted";
14
+ }
15
+ export type ManagedEventSubscribeInput = {
16
+ name: string;
17
+ arguments: EventJsonObject;
18
+ context?: EventJsonObject;
19
+ idempotencyKey: string;
20
+ /** Application lifetime in milliseconds, or null until explicitly stopped. */
21
+ ttlMs: number | null;
22
+ options?: {
23
+ signal?: AbortSignal;
24
+ timeout?: number;
25
+ maxTotalTimeout?: number;
26
+ };
27
+ };
28
+ export interface ConnectionEventsAdapter {
29
+ subscribe(input: ManagedEventSubscribeInput): Promise<ManagedEventSubscription>;
30
+ getSubscription(input: {
31
+ id: string;
32
+ options?: {
33
+ timeout?: number;
34
+ };
35
+ }): Promise<ManagedEventSubscription>;
36
+ unsubscribe(input: {
37
+ id: string;
38
+ options?: {
39
+ timeout?: number;
40
+ };
41
+ }): Promise<ManagedEventSubscription>;
42
+ }
43
+ export type ConnectionEventDelivery = {
44
+ version: 1;
45
+ deliveryId: string;
46
+ subscriptionId: string;
47
+ source: {
48
+ type: "mcp";
49
+ connectorId: string;
50
+ };
51
+ context: Record<string, unknown>;
52
+ } & ({
53
+ event: Experimental_ConnectionEvent;
54
+ } | {
55
+ control: {
56
+ type: "gap";
57
+ cursor: string | null;
58
+ truncated?: true;
59
+ };
60
+ } | {
61
+ control: {
62
+ type: "terminated";
63
+ error: {
64
+ code: number;
65
+ message: string;
66
+ data?: unknown;
67
+ };
68
+ };
69
+ });
70
+ export interface ConnectionEventsBackend {
71
+ createAdapter(input: {
72
+ principal: ConnectionPrincipal;
73
+ connection: {
74
+ url: string;
75
+ };
76
+ destination: {
77
+ path: string;
78
+ };
79
+ }): Promise<ConnectionEventsAdapter>;
80
+ verify(request: Request, options: {
81
+ path: string;
82
+ }): Promise<ConnectionEventDelivery>;
83
+ }
84
+ export declare function readConnectionEventsBackend(value: unknown): ConnectionEventsBackend | undefined;
@@ -0,0 +1 @@
1
+ function readConnectionEventsBackend(e){if(e!==void 0){if(typeof e!=`object`||!e||!(`createAdapter`in e)||typeof e.createAdapter!=`function`||!(`verify`in e)||typeof e.verify!=`function`)throw TypeError(`Connect experimental_events must provide createAdapter and verify methods.`);return e}}export{readConnectionEventsBackend};
@@ -1,3 +1,4 @@
1
+ import type { ConnectionEventsBackend } from "#shared/connection-events.js";
1
2
  /**
2
3
  * Protocol-agnostic interfaces for the connection system.
3
4
  *
@@ -225,6 +226,7 @@ interface AuthorizationDefinitionBase {
225
226
  * Connect side.
226
227
  */
227
228
  readonly vercelConnect?: {
229
+ readonly experimental_events?: ConnectionEventsBackend;
228
230
  readonly connector: string;
229
231
  };
230
232
  /**
@@ -405,9 +407,17 @@ export interface ConnectionToolExecuteOptions {
405
407
  }
406
408
  /** A live client for a single connection. */
407
409
  export interface ConnectionClient {
410
+ /** eve-owned event actions, separate from remote protocol tools and their filters. */
411
+ readonly eventActions?: ConnectionEventActionHandler;
408
412
  close(): Promise<void>;
409
413
  connect(): Promise<unknown>;
410
414
  executeTool(toolName: string, args: unknown, options: ConnectionToolExecuteOptions): Promise<unknown>;
411
415
  getToolMetadata(): Promise<readonly ConnectionToolMetadata[]>;
412
416
  }
417
+ export interface ConnectionEventActionHandler {
418
+ ownsName(name: string): boolean;
419
+ metadata(): Promise<readonly ConnectionToolMetadata[]>;
420
+ recoveryMetadata(): readonly ConnectionToolMetadata[];
421
+ execute(name: string, args: unknown, options: ConnectionToolExecuteOptions): Promise<unknown>;
422
+ }
413
423
  export {};
@@ -1 +1 @@
1
- import{extractVercelConnectMetadata}from"#shared/vercel-connect-metadata.js";function validateAuthorizationSpec(e,t=`auth`){if(typeof e!=`object`||!e)return`The "${t}" field must be an object with a "getToken" method.`;let n=e;if(typeof n.getToken!=`function`)return`The "${t}.getToken" field must be a function returning Promise<{ token }>.`;let r=n.startAuthorization!==void 0,i=n.completeAuthorization!==void 0,a=n.credentialOwner!==void 0,o=n.principalType!==void 0;if(a&&o)return`The "${t}" field must not provide both "credentialOwner" and "principalType".`;let s=a?`credentialOwner`:`principalType`,c=a?n.credentialOwner:n.principalType;if(c!==void 0&&c!==`app`&&c!==`user`)return`The "${t}.${s}" field must be "app" or "user".`;if(r!==i)return`The "${t}" field must provide either both "startAuthorization" and "completeAuthorization" (interactive OAuth) or neither (getToken-only). Got only "${r?`startAuthorization`:`completeAuthorization`}".`;if(r&&typeof n.startAuthorization!=`function`)return`The "${t}.startAuthorization" field must be a function when provided.`;if(i&&typeof n.completeAuthorization!=`function`)return`The "${t}.completeAuthorization" field must be a function when provided.`;if(r&&a)return`The "${t}.credentialOwner" field is only supported by getToken-only authorization. Interactive authorization is restricted to "principalType": "user" in v1.`;if(r&&n.principalType!==`user`)return`Interactive authorization (startAuthorization + completeAuthorization) is restricted to "principalType": "user" in v1. App-level credentials must use a getToken-only definition.`;if(n.displayName!==void 0&&(typeof n.displayName!=`string`||n.displayName.length===0))return`The "${t}.displayName" field must be a non-empty string when provided.`}function normalizeAuthorizationSpec(e,t,n=`auth`){let r=validateAuthorizationSpec(e,n);if(r!==void 0)throw Error(`${t} ${r}`);let i=e,a=extractVercelConnectMetadata(i.vercelConnect),o=i.displayName,s=typeof i.evict==`function`?i.evict:void 0;if(i.startAuthorization!==void 0&&i.completeAuthorization!==void 0){let e={completeAuthorization:i.completeAuthorization,getToken:i.getToken,principalType:`user`,startAuthorization:i.startAuthorization};return a!==void 0&&(e={...e,vercelConnect:a}),o!==void 0&&(e={...e,displayName:o}),s!==void 0&&(e={...e,evict:s}),e}let c={getToken:i.getToken,principalType:i.credentialOwner??i.principalType??`app`};return a!==void 0&&(c={...c,vercelConnect:a}),o!==void 0&&(c={...c,displayName:o}),s!==void 0&&(c={...c,evict:s}),c}export{normalizeAuthorizationSpec,validateAuthorizationSpec};
1
+ import{extractVercelConnectMetadata}from"#shared/vercel-connect-metadata.js";import{readConnectionEventsBackend}from"#shared/connection-events.js";function validateAuthorizationSpec(e,t=`auth`){if(typeof e!=`object`||!e)return`The "${t}" field must be an object with a "getToken" method.`;let n=e;if(typeof n.getToken!=`function`)return`The "${t}.getToken" field must be a function returning Promise<{ token }>.`;let r=n.startAuthorization!==void 0,i=n.completeAuthorization!==void 0,a=n.credentialOwner!==void 0,o=n.principalType!==void 0;if(a&&o)return`The "${t}" field must not provide both "credentialOwner" and "principalType".`;let s=a?`credentialOwner`:`principalType`,c=a?n.credentialOwner:n.principalType;if(c!==void 0&&c!==`app`&&c!==`user`)return`The "${t}.${s}" field must be "app" or "user".`;if(r!==i)return`The "${t}" field must provide either both "startAuthorization" and "completeAuthorization" (interactive OAuth) or neither (getToken-only). Got only "${r?`startAuthorization`:`completeAuthorization`}".`;if(r&&typeof n.startAuthorization!=`function`)return`The "${t}.startAuthorization" field must be a function when provided.`;if(i&&typeof n.completeAuthorization!=`function`)return`The "${t}.completeAuthorization" field must be a function when provided.`;if(r&&a)return`The "${t}.credentialOwner" field is only supported by getToken-only authorization. Interactive authorization is restricted to "principalType": "user" in v1.`;if(r&&n.principalType!==`user`)return`Interactive authorization (startAuthorization + completeAuthorization) is restricted to "principalType": "user" in v1. App-level credentials must use a getToken-only definition.`;if(n.displayName!==void 0&&(typeof n.displayName!=`string`||n.displayName.length===0))return`The "${t}.displayName" field must be a non-empty string when provided.`}function normalizeAuthorizationSpec(e,t,n=`auth`){let r=validateAuthorizationSpec(e,n);if(r!==void 0)throw Error(`${t} ${r}`);let i=e,a=extractVercelConnectMetadata(i.vercelConnect),o=readConnectionEventsBackend(i.vercelConnect?.experimental_events),s=a;o!==void 0&&a!==void 0&&(s={...a,experimental_events:o});let c=i.displayName,l=typeof i.evict==`function`?i.evict:void 0;if(i.startAuthorization!==void 0&&i.completeAuthorization!==void 0){let e={completeAuthorization:i.completeAuthorization,getToken:i.getToken,principalType:`user`,startAuthorization:i.startAuthorization};return s!==void 0&&(e={...e,vercelConnect:s}),c!==void 0&&(e={...e,displayName:c}),l!==void 0&&(e={...e,evict:l}),e}let u={getToken:i.getToken,principalType:i.credentialOwner??i.principalType??`app`};return s!==void 0&&(u={...u,vercelConnect:s}),c!==void 0&&(u={...u,displayName:c}),l!==void 0&&(u={...u,evict:l}),u}export{normalizeAuthorizationSpec,validateAuthorizationSpec};
@@ -1 +1 @@
1
- async function executeAskQuestionTool(e,t){"use workflow";return toAskQuestionOutput(await t.ask(toAskQuestionRequest(e)))}function toAskQuestionRequest(e){let t=e.options?.map(e=>({description:e.description,id:e.label,label:e.label}));return{allowFreeform:!0,display:t===void 0?`text`:`select`,prompt:e.question,...t!==void 0&&{options:t}}}function toAskQuestionOutput(e){switch(e.status){case`answered`:return{answer:e.optionId??e.text??``,status:`answered`};case`cancelled`:return{interrupted:!0};case`unavailable`:return{status:`unavailable`}}}executeAskQuestionTool.workflowId=`workflow//eve@0.79.1//executeAskQuestionTool`;export{executeAskQuestionTool,toAskQuestionOutput,toAskQuestionRequest};
1
+ async function executeAskQuestionTool(e,t){"use workflow";return toAskQuestionOutput(await t.ask(toAskQuestionRequest(e)))}function toAskQuestionRequest(e){let t=e.options?.map(e=>({description:e.description,id:e.label,label:e.label}));return{allowFreeform:!0,display:t===void 0?`text`:`select`,prompt:e.question,...t!==void 0&&{options:t}}}function toAskQuestionOutput(e){switch(e.status){case`answered`:return{answer:e.optionId??e.text??``,status:`answered`};case`cancelled`:return{interrupted:!0};case`unavailable`:return{status:`unavailable`}}}executeAskQuestionTool.workflowId=`workflow//eve@0.80.0//executeAskQuestionTool`;export{executeAskQuestionTool,toAskQuestionOutput,toAskQuestionRequest};
@@ -15,5 +15,10 @@ export interface NoReplyToolInput {
15
15
  *
16
16
  * A turn that ends with `no_reply` completes without a final message, so
17
17
  * channels and schedules post nothing. Only root sessions receive it.
18
+ * A root session also accepts a model call returning no text with
19
+ * `finishReason: "stop"` without retry. Delegated sessions still retry empty
20
+ * replies and report a failure if recovery is exhausted.
21
+ * This tool records an explicit choice to stay quiet and an optional reason
22
+ * instead of relying on blank model output.
18
23
  */
19
24
  export declare function noReply(): ToolDefinition<NoReplyToolInput, string>;
@@ -1 +1 @@
1
- import{sleep}from"#compiled/@workflow/core/index.js";async function executeSleepTool(e,t){"use workflow";let n=new Promise(e=>t.abortSignal.addEventListener(`abort`,()=>e(`interrupted`),{once:!0})),r=sleep(Math.ceil(e.seconds*1e3)).then(()=>`elapsed`);return await Promise.race([r,n])===`elapsed`?{waitedSeconds:e.seconds}:{interrupted:!0}}executeSleepTool.workflowId=`workflow//eve@0.79.1//executeSleepTool`;export{executeSleepTool};
1
+ import{sleep}from"#compiled/@workflow/core/index.js";async function executeSleepTool(e,t){"use workflow";if(t.abortSignal.aborted)return{interrupted:!0};let n=new Promise(e=>t.abortSignal.addEventListener(`abort`,()=>e(`interrupted`),{once:!0})),r=sleep(Math.ceil(e.seconds*1e3)).then(()=>`elapsed`);return await Promise.race([r,n])===`elapsed`?{waitedSeconds:e.seconds}:{interrupted:!0}}executeSleepTool.workflowId=`workflow//eve@0.80.0//executeSleepTool`;export{executeSleepTool};
@@ -7,8 +7,10 @@
7
7
  * as comments. Rendering is deterministic, so the same schemas always produce
8
8
  * the same text.
9
9
  */
10
- export declare function renderToolSignature(input: {
10
+ interface SignatureInput {
11
11
  readonly name: string;
12
12
  readonly inputSchema?: Record<string, unknown>;
13
13
  readonly outputSchema?: Record<string, unknown>;
14
- }): string;
14
+ }
15
+ export declare function renderToolSignature(input: SignatureInput): string;
16
+ export {};
@@ -1 +1 @@
1
- import{isObject}from"#shared/guards.js";const CONSTRAINT_KEYS=[`format`,`pattern`,`minimum`,`maximum`,`exclusiveMinimum`,`exclusiveMaximum`,`minLength`,`maxLength`,`minItems`,`maxItems`,`default`],IDENTIFIER=/^[A-Za-z_$][\w$]*$/u;function renderToolSignature(e){let t=e.inputSchema===void 0?`{}`:renderRoot(e.inputSchema),n=e.outputSchema===void 0?`unknown`:renderRoot(e.outputSchema),r=`${e.name}(input: ${t}): Promise<${n}>`;return r.length>4e3?`${r.slice(0,3997)}...`:r}function renderRoot(e){return renderType(e,{budget:{remaining:1e3},depth:0,refs:new Set,root:e})}function renderType(e,t){if(e===!0||!isObject(e)||t.depth>6||t.budget.remaining<=0)return`unknown`;if(--t.budget.remaining,typeof e.$ref==`string`){let n=resolveRef(e.$ref,t);return n===void 0?`unknown`:renderType(n,{...t,refs:new Set([...t.refs,e.$ref])})}if(`const`in e)return literal(e.const);if(Array.isArray(e.enum))return union(e.enum.map(literal));let n=Array.isArray(e.anyOf)?e.anyOf:Array.isArray(e.oneOf)?e.oneOf:void 0;if(n!==void 0)return union(n.map(e=>renderType(e,next(t))));if(Array.isArray(e.allOf))return e.allOf.map(e=>wrap(renderType(e,next(t)))).join(` & `);let r=(Array.isArray(e.type)?e.type:[e.type]).filter(e=>typeof e==`string`).map(n=>renderPrimitive(n,e,t));return r.length>0?union(r):isObject(e.properties)||e.additionalProperties!==void 0?renderObject(e,t):e.items===void 0?`unknown`:renderPrimitive(`array`,e,t)}function renderPrimitive(e,t,n){switch(e){case`string`:return`string`;case`number`:case`integer`:return`number`;case`boolean`:return`boolean`;case`null`:return`null`;case`array`:return`${wrap(renderType(t.items,next(n)))}[]`;case`object`:return renderObject(t,n);default:return`unknown`}}function renderObject(e,t){let n=isObject(e.properties)?e.properties:{},r=new Set(Array.isArray(e.required)?e.required.filter(e=>typeof e==`string`):[]),i=Object.entries(n).map(([e,n])=>{let i=IDENTIFIER.test(e)?e:JSON.stringify(e),a=r.has(e)?``:`?`,o=isObject(n)?propertyComment(n):``;return`${i}${a}: ${renderType(n,next(t))}${o}`}),a=e.additionalProperties;return isObject(a)&&i.push(`[key: string]: ${renderType(a,next(t))}`),i.length===0?a===!1?`{}`:`Record<string, unknown>`:`{ ${i.join(`; `)} }`}function propertyComment(e){let t=[],n=typeof e.description==`string`?e.description.replaceAll(/\s+/gu,` `).replace(/[\s.;,:]+$/u,``).trim():``;n.length>0&&t.push(truncate(n));for(let n of CONSTRAINT_KEYS)e[n]!==void 0&&t.push(`${n}: ${JSON.stringify(e[n])}`);return t.length===0?``:` /* ${t.join(`; `).replaceAll(`*/`,`* /`)} */`}function resolveRef(e,t){if(t.refs.has(e)||!e.startsWith(`#`))return;let n=t.root;for(let t of e.slice(1).split(`/`).filter(Boolean)){if(!isObject(n))return;n=n[t.replaceAll(`~1`,`/`).replaceAll(`~0`,`~`)]}return n}function next(e){return{...e,depth:e.depth+1}}function literal(e){return e===void 0?`undefined`:JSON.stringify(e)}function union(e){let t=[...new Set(e)];return t.length===0?`never`:t.join(` | `)}function wrap(e){return e.includes(` | `)||e.includes(` & `)?`(${e})`:e}function truncate(e){return e.length>120?`${e.slice(0,117)}...`:e}export{renderToolSignature};
1
+ import{isObject}from"#shared/guards.js";const MAX_SIGNATURE_LENGTH=4e3,CONSTRAINT_KEYS=[`format`,`pattern`,`minimum`,`maximum`,`exclusiveMinimum`,`exclusiveMaximum`,`minLength`,`maxLength`,`minItems`,`maxItems`,`default`],IDENTIFIER=/^[A-Za-z_$][\w$]*$/u;function renderToolSignature(e){let t=renderSignature(e,!0);if(t.length<=MAX_SIGNATURE_LENGTH)return t;let n=renderSignature(e,!1);return n.length>MAX_SIGNATURE_LENGTH?`${n.slice(0,3997)}...`:n}function renderSignature(e,t){let render=e=>renderType(e,{budget:{remaining:1e3},depth:0,descriptions:t,refs:new Set,root:e}),n=e.inputSchema===void 0?`{}`:render(e.inputSchema),r=e.outputSchema===void 0?`unknown`:render(e.outputSchema);return`${e.name}(input: ${n}): Promise<${r}>`}function renderType(e,t){if(e===!0||!isObject(e)||t.depth>6||t.budget.remaining<=0)return`unknown`;if(--t.budget.remaining,typeof e.$ref==`string`){let n=resolveRef(e.$ref,t);return n===void 0?`unknown`:renderType(n,{...t,refs:new Set([...t.refs,e.$ref])})}if(`const`in e)return literal(e.const);if(Array.isArray(e.enum))return union(e.enum.map(literal));let n=Array.isArray(e.anyOf)?e.anyOf:Array.isArray(e.oneOf)?e.oneOf:void 0;if(n!==void 0)return union(n.map(e=>renderType(e,next(t))));if(Array.isArray(e.allOf))return e.allOf.map(e=>wrap(renderType(e,next(t)))).join(` & `);let r=(Array.isArray(e.type)?e.type:[e.type]).filter(e=>typeof e==`string`).map(n=>renderPrimitive(n,e,t));return r.length>0?union(r):isObject(e.properties)||e.additionalProperties!==void 0?renderObject(e,t):e.items===void 0?`unknown`:renderPrimitive(`array`,e,t)}function renderPrimitive(e,t,n){switch(e){case`string`:return`string`;case`number`:case`integer`:return`number`;case`boolean`:return`boolean`;case`null`:return`null`;case`array`:return`${wrap(renderType(t.items,next(n)))}[]`;case`object`:return renderObject(t,n);default:return`unknown`}}function renderObject(e,t){let n=isObject(e.properties)?e.properties:{},r=new Set(Array.isArray(e.required)?e.required.filter(e=>typeof e==`string`):[]),i=Object.entries(n).map(([e,n])=>{let i=IDENTIFIER.test(e)?e:JSON.stringify(e),a=r.has(e)?``:`?`,o=isObject(n)?propertyComment(n,t.descriptions):``;return`${i}${a}: ${renderType(n,next(t))}${o}`}),a=e.additionalProperties;return isObject(a)&&i.push(`[key: string]: ${renderType(a,next(t))}`),i.length===0?a===!1?`{}`:`Record<string, unknown>`:`{ ${i.join(`; `)} }`}function propertyComment(e,t){let n=[],r=t&&typeof e.description==`string`?e.description.replaceAll(/\s+/gu,` `).replace(/[\s.;,:]+$/u,``).trim():``;r.length>0&&n.push(truncate(r));for(let t of CONSTRAINT_KEYS)e[t]!==void 0&&n.push(`${t}: ${JSON.stringify(e[t])}`);return n.length===0?``:` /* ${n.join(`; `).replaceAll(`*/`,`* /`)} */`}function resolveRef(e,t){if(t.refs.has(e)||!e.startsWith(`#`))return;let n=t.root;for(let t of e.slice(1).split(`/`).filter(Boolean)){if(!isObject(n))return;n=n[t.replaceAll(`~1`,`/`).replaceAll(`~0`,`~`)]}return n}function next(e){return{...e,depth:e.depth+1}}function literal(e){return e===void 0?`undefined`:JSON.stringify(e)}function union(e){let t=[...new Set(e)];return t.length===0?`never`:t.join(` | `)}function wrap(e){return e.includes(` | `)||e.includes(` & `)?`(${e})`:e}function truncate(e){return e.length>120?`${e.slice(0,117)}...`:e}export{renderToolSignature};
@@ -0,0 +1,25 @@
1
+ import { type SpanContext } from "#compiled/@opentelemetry/api/index.js";
2
+ import { type AlsContext } from "#context/container.js";
3
+ /** Only carry a validated W3C identity across durable steps, never baggage or content policy. */
4
+ export declare function connectionEventTraceContext(value: unknown): SpanContext | undefined;
5
+ export declare function connectionEventAttributes(input: {
6
+ connectionName: string;
7
+ sessionId?: string;
8
+ subscriptionId?: string;
9
+ deliveryId?: string;
10
+ bindingId?: string;
11
+ }): Record<string, string>;
12
+ /** Preserve diagnostic categories without logging SDK request objects or provider response bodies. */
13
+ export declare function connectionEventError(error: unknown): Error;
14
+ type EventOperation = "catalog" | "subscribe" | "get" | "unsubscribe" | "onEvent" | "onGap" | "onTerminated";
15
+ /** No model turn is needed to restore a session's trace policy in a durable event step. */
16
+ export declare function withConnectionEventSpan<T>(input: {
17
+ ctx: AlsContext;
18
+ connectionName: string;
19
+ operation: EventOperation;
20
+ subscriptionId?: string;
21
+ deliveryId?: string;
22
+ bindingId?: string;
23
+ requestTraceContext?: SpanContext;
24
+ }, execute: (reference?: SpanContext) => Promise<T>): Promise<T>;
25
+ export {};
@@ -0,0 +1 @@
1
+ import{createLogger,logError}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{SessionIdKey}from"#context/keys.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{formatTraceparent}from"#protocol/traceparent.js";import{ContextAgentTraceStateStore}from"#tracing/eve/agent-trace-context-store.js";import{resolveTracePolicy}from"#shared/trace-policy.js";import{ROOT_CONTEXT,context,trace}from"#compiled/@opentelemetry/api/index.js";import{markAgentTraceContext}from"#tracing/eve/agent-trace-context.js";import{activeTraceOperation,truncateTelemetryText,withErrorContent}from"#compiled/@eve/tracing/otel.js";import{otelTelemetry}from"#compiled/@eve/tracing/index.js";import{readInstrumentationSessionContext}from"#instrumentation/session-context.js";import{getInstrumentationRuntime}from"#instrumentation/runtime-global.js";import{withChannelAudience}from"#tracing/eve/channel-audience-context.js";import{eveOutputMapping}from"#tracing/eve/profile.js";const log=createLogger(`connection.events`);function connectionEventTraceContext(e){if(typeof e!=`object`||!e)return;let{traceId:t,spanId:n,traceFlags:r}=e;if(typeof t!=`string`||typeof n!=`string`||r!==0&&r!==1)return;let i={traceId:t,spanId:n,traceFlags:r};return formatTraceparent(i)===void 0?void 0:i}function connectionEventAttributes(e){let t={};for(let[n,r]of Object.entries({"agent.connection.name":e.connectionName,"agent.run.id":e.sessionId,"connect.subscription.id":e.subscriptionId,"connect.delivery.id":e.deliveryId,"eve.connection.event.binding.id":e.bindingId}))r!==void 0&&(t[n]=truncateTelemetryText(r,256));return t}function connectionEventError(e){let t=Error(`Connection event operation failed`);if(e instanceof Error&&[`Error`,`TypeError`,`RangeError`,`SyntaxError`,`AbortError`,`TimeoutError`,`MCPClientError`].includes(e.name)&&(t.name=e.name),typeof e!=`object`||!e)return t;let n=e,r=n.code,i=n.statusCode??n.status,a=typeof r==`number`&&Number.isFinite(r)||typeof r==`string`&&[`invalid_delivery`,`verification_unavailable`,`configuration_error`,`ETIMEDOUT`,`ECONNRESET`,`ECONNREFUSED`,`ENOTFOUND`,`EAI_AGAIN`].includes(r)?r:void 0;return a!==void 0&&Object.assign(t,{code:a}),typeof i==`number`&&Number.isInteger(i)&&i>=100&&i<=599&&Object.assign(t,{statusCode:i}),t}async function withConnectionEventSpan(e,t){return contextStorage.run(e.ctx,async()=>{let n=getInstrumentationRuntime(),r=otelTelemetry({tracerName:`eve.connection.events`,mapping:eveOutputMapping()}),i=n?.otelSettings,a=e.ctx.require(SessionIdKey),o=connectionEventAttributes({...e,sessionId:a}),run=async n=>{try{return await t(n)}catch(t){throw logError(log,`connection event operation failed`,connectionEventError(t),{...o,operation:e.operation}),t}};if(i===void 0)return r.suppressed(()=>run());let s=new ContextAgentTraceStateStore().get(`session`,a),c=readInstrumentationSessionContext(e.ctx),l=c.traceSeed?.decision??s?.decision??resolveTracePolicy(i.tracePolicy,{...c.conversation,agentName:e.ctx.require(BundleKey).resolvedAgent.config?.name??`eve`}),u=activeTraceOperation(),d=connectionEventTraceContext(e.requestTraceContext)??u?.reference??s?.context;if(l.action===`drop`||u?.capture.emit===!1||c.traceSeed!==void 0&&!(c.traceSeed.traceFlags&1)||s!==void 0&&!(s.context.traceFlags&1)||d!==void 0&&!(d.traceFlags&1))return r.suppressed(()=>run());let f=d===void 0?context.active():trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(d)),p=markAgentTraceContext(withErrorContent(withChannelAudience(f,c.audience),!1)),m=`agent.connection.event.${e.operation}`,h=r.startSpan({type:`step`,operationId:m,name:m,kind:e.operation.startsWith(`on`)?`CONSUMER`:`INTERNAL`,attributes:{...o,"operation.name":m,"resource.name":m}},{context:p});try{let t=await r.run({type:`step`,reference:h.reference,capture:{emit:!0,recordInputs:!1,recordOutputs:!1}},()=>run(connectionEventTraceContext(h.reference)),p);if([`subscribe`,`get`,`unsubscribe`].includes(e.operation)&&typeof t==`object`&&t){let e=t;typeof e.id==`string`&&h.setAttribute(`connect.subscription.id`,truncateTelemetryText(e.id,256)),typeof e.status==`string`&&[`pending`,`active`,`needs_auth`,`stopped`,`expired`,`failed`].includes(e.status)&&h.setAttribute(`connect.subscription.status`,e.status)}return h.setAttribute(`eve.connection.event.outcome`,`completed`),h.setStatus(`OK`),t}catch(e){throw h.setAttribute(`eve.connection.event.outcome`,`failed`),h.fail(void 0,`connection_event_error`),e}finally{h.end(),await n.forceFlush().catch(()=>log.warn(`flushing connection event traces failed`))}})}export{connectionEventAttributes,connectionEventError,connectionEventTraceContext,withConnectionEventSpan};