eve 0.54.4 → 0.55.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 (182) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/src/channel/adapter.d.ts +3 -2
  3. package/dist/src/channel/audience.d.ts +16 -0
  4. package/dist/src/channel/audience.js +1 -0
  5. package/dist/src/channel/conversation-context.d.ts +3 -0
  6. package/dist/src/channel/conversation-context.js +1 -0
  7. package/dist/src/channel/instrumentation.js +1 -1
  8. package/dist/src/channel/types.d.ts +9 -0
  9. package/dist/src/cli/commands/agent-prompt/scaffold.md +5 -4
  10. package/dist/src/cli/commands/init-target.js +2 -2
  11. package/dist/src/cli/commands/init.js +1 -1
  12. package/dist/src/cli/dev/environment.js +1 -1
  13. package/dist/src/cli/dev/tui/terminal-renderer.js +9 -9
  14. package/dist/src/compiled/.vendor-stamp.json +1 -1
  15. package/dist/src/compiler/extension-compatibility.d.ts +16 -16
  16. package/dist/src/compiler/extension-compatibility.js +1 -1
  17. package/dist/src/context/dynamic-resolve-context.js +1 -1
  18. package/dist/src/discover/filesystem.d.ts +3 -1
  19. package/dist/src/discover/filesystem.js +1 -1
  20. package/dist/src/discover/skills.js +1 -1
  21. package/dist/src/dynamic/definition.d.ts +6 -0
  22. package/dist/src/eve-channel/audience.d.ts +3 -0
  23. package/dist/src/eve-channel/audience.js +1 -0
  24. package/dist/src/eve-channel/index.js +1 -1
  25. package/dist/src/eve-channel/types.d.ts +14 -1
  26. package/dist/src/execution/activity-work.d.ts +2 -0
  27. package/dist/src/execution/activity-work.js +1 -1
  28. package/dist/src/execution/channel-context.js +1 -1
  29. package/dist/src/execution/coordination-dispatch-shared.d.ts +1 -0
  30. package/dist/src/execution/coordination-dispatch-shared.js +1 -1
  31. package/dist/src/execution/eve-workflow-attributes.js +1 -1
  32. package/dist/src/execution/runtime-context.js +1 -1
  33. package/dist/src/execution/scheduled-launch-delivery.d.ts +7 -0
  34. package/dist/src/execution/scheduled-launch-delivery.js +1 -0
  35. package/dist/src/execution/session-activity.js +1 -1
  36. package/dist/src/execution/tasks/child/steps.js +1 -1
  37. package/dist/src/execution/tasks/parent/delegate.d.ts +2 -0
  38. package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
  39. package/dist/src/execution/tools/sleep-workflow.js +1 -1
  40. package/dist/src/execution/tools/subagent/invoke-step.d.ts +2 -0
  41. package/dist/src/execution/tools/subagent/invoke-step.js +1 -1
  42. package/dist/src/execution/tools/subagent/start.d.ts +5 -0
  43. package/dist/src/execution/tools/subagent/start.js +1 -1
  44. package/dist/src/execution/wire/session-inbox-contract.d.ts +2 -2
  45. package/dist/src/execution/wire/session-inbox-contract.js +1 -1
  46. package/dist/src/execution/wire/session-inbox-encoder.d.ts +6 -2
  47. package/dist/src/execution/wire/session-inbox-encoder.js +1 -1
  48. package/dist/src/execution/wire/session-inbox-resume.js +1 -1
  49. package/dist/src/execution/wire/session-inbox-wire.js +1 -1
  50. package/dist/src/execution/wire/session-inbox-wire.v7.d.ts +342 -0
  51. package/dist/src/execution/wire/session-inbox-wire.v7.js +1 -0
  52. package/dist/src/execution/workflow-steps.js +1 -1
  53. package/dist/src/harness/action-presentation.d.ts +5 -0
  54. package/dist/src/harness/action-presentation.js +1 -1
  55. package/dist/src/harness/background-tools.d.ts +3 -1
  56. package/dist/src/harness/emission.js +1 -1
  57. package/dist/src/harness/step-hooks.js +1 -1
  58. package/dist/src/harness/tool-loop.js +1 -1
  59. package/dist/src/harness/tools.js +1 -1
  60. package/dist/src/harness/workflow-lifecycle.js +1 -1
  61. package/dist/src/instrumentation/channel-delivery.js +1 -1
  62. package/dist/src/instrumentation/content-policy.d.ts +2 -2
  63. package/dist/src/instrumentation/principal-summary.d.ts +3 -3
  64. package/dist/src/instrumentation/runtime-global.d.ts +4 -0
  65. package/dist/src/instrumentation/runtime-global.js +1 -0
  66. package/dist/src/instrumentation/runtime.d.ts +5 -9
  67. package/dist/src/instrumentation/runtime.js +1 -1
  68. package/dist/src/instrumentation/session-context.d.ts +1 -0
  69. package/dist/src/instrumentation/session-context.js +1 -1
  70. package/dist/src/instrumentation/session-init.d.ts +5 -0
  71. package/dist/src/instrumentation/session-init.js +1 -0
  72. package/dist/src/instrumentation/setup-context.js +1 -1
  73. package/dist/src/internal/application/dev-environment.d.ts +3 -0
  74. package/dist/src/internal/application/dev-environment.js +1 -1
  75. package/dist/src/internal/application/output-publication-journal.js +1 -1
  76. package/dist/src/internal/application/output-publication-lock.js +1 -1
  77. package/dist/src/internal/application/package.js +1 -1
  78. package/dist/src/internal/authored-definition/connection.js +1 -1
  79. package/dist/src/internal/instrumentation.d.ts +1 -12
  80. package/dist/src/internal/instrumentation.js +1 -1
  81. package/dist/src/internal/logging.js +1 -1
  82. package/dist/src/internal/nitro/host/build-application.js +1 -1
  83. package/dist/src/protocol/activity.d.ts +1 -0
  84. package/dist/src/protocol/activity.js +1 -1
  85. package/dist/src/public/channels/chat-sdk/audience.d.ts +8 -0
  86. package/dist/src/public/channels/chat-sdk/audience.js +1 -1
  87. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +0 -2
  88. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +1 -1
  89. package/dist/src/public/channels/discord/audience.js +1 -1
  90. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  91. package/dist/src/public/channels/discord/index.d.ts +0 -1
  92. package/dist/src/public/channels/index.d.ts +2 -3
  93. package/dist/src/public/channels/slack/activity-plan.js +1 -1
  94. package/dist/src/public/channels/slack/defaults.d.ts +2 -2
  95. package/dist/src/public/channels/slack/defaults.js +3 -3
  96. package/dist/src/public/channels/slack/hitl.d.ts +20 -4
  97. package/dist/src/public/channels/slack/hitl.js +2 -2
  98. package/dist/src/public/channels/slack/index.d.ts +1 -1
  99. package/dist/src/public/channels/slack/interactions.js +1 -1
  100. package/dist/src/public/channels/slack/private-approval-delivery.d.ts +11 -0
  101. package/dist/src/public/channels/slack/private-approval-delivery.js +1 -0
  102. package/dist/src/public/channels/slack/slackChannel.d.ts +27 -4
  103. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  104. package/dist/src/public/channels/teams/hitl.js +1 -1
  105. package/dist/src/public/channels/teams/index.d.ts +0 -1
  106. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  107. package/dist/src/public/channels/teams/verify.js +1 -1
  108. package/dist/src/public/channels/telegram/audience.d.ts +7 -0
  109. package/dist/src/public/channels/telegram/audience.js +1 -1
  110. package/dist/src/public/channels/telegram/index.d.ts +0 -1
  111. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  112. package/dist/src/public/channels/twilio/twilioChannel.d.ts +0 -2
  113. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  114. package/dist/src/public/definitions/channel.d.ts +2 -1
  115. package/dist/src/public/definitions/channel.js +1 -1
  116. package/dist/src/public/definitions/connections/mcp.d.ts +6 -0
  117. package/dist/src/public/definitions/workspace-agent.js +1 -1
  118. package/dist/src/public/models/openai/chatgpt/auth.js +1 -1
  119. package/dist/src/public/models/openai/chatgpt/codex-app-server.js +1 -1
  120. package/dist/src/public/models/openai/chatgpt/credential-store.js +1 -1
  121. package/dist/src/public/next/index.d.ts +6 -4
  122. package/dist/src/public/next/index.js +1 -1
  123. package/dist/src/public/next/server.js +1 -1
  124. package/dist/src/public/next/vercel-output-config.d.ts +1 -0
  125. package/dist/src/runtime/connections/mcp-client.js +1 -1
  126. package/dist/src/runtime/resolve-connection.js +1 -1
  127. package/dist/src/runtime/sessions/runtime-context-keys.js +1 -1
  128. package/dist/src/runtime/types.d.ts +1 -0
  129. package/dist/src/self-modification/agent.d.ts +7 -1
  130. package/dist/src/self-modification/agent.js +1 -1
  131. package/dist/src/self-modification/extension/instructions.js +6 -9
  132. package/dist/src/setup/flows/chatgpt-auth.js +1 -1
  133. package/dist/src/setup/flows/registry.js +1 -1
  134. package/dist/src/setup/provider-settings.js +1 -1
  135. package/dist/src/setup/scaffold/create/project.js +1 -1
  136. package/dist/src/shared/channel-audience.d.ts +0 -3
  137. package/dist/src/shared/channel-definition.d.ts +13 -4
  138. package/dist/src/shared/conversation-context.d.ts +47 -0
  139. package/dist/src/shared/conversation-context.js +1 -0
  140. package/dist/src/shared/forwarded-trace-policy.d.ts +2 -1
  141. package/dist/src/shared/forwarded-trace-policy.js +1 -1
  142. package/dist/src/shared/instrumentation-channel-kind.d.ts +3 -0
  143. package/dist/src/shared/instrumentation-channel-kind.js +1 -0
  144. package/dist/src/shared/instrumentation-content.d.ts +9 -4
  145. package/dist/src/shared/instrumentation-content.js +1 -1
  146. package/dist/src/shared/trace-policy.d.ts +7 -6
  147. package/dist/src/shared/trace-policy.js +1 -1
  148. package/dist/src/subagents/handle-dispatch.d.ts +2 -1
  149. package/dist/src/subagents/handle-dispatch.js +1 -1
  150. package/dist/src/subagents/remote-dispatch.js +1 -1
  151. package/dist/src/subagents/start-local.d.ts +1 -0
  152. package/dist/src/subagents/start-local.js +1 -1
  153. package/dist/src/subagents/start-remote.d.ts +2 -0
  154. package/dist/src/subagents/start-remote.js +1 -1
  155. package/dist/src/subagents/tool.d.ts +3 -0
  156. package/dist/src/subagents/tool.js +1 -1
  157. package/dist/src/tasks/session-index.d.ts +2 -0
  158. package/dist/src/tasks/session-index.js +1 -1
  159. package/dist/src/tracing/agent-invocation-coordinator.d.ts +3 -2
  160. package/dist/src/tracing/agent-invocation-coordinator.js +1 -1
  161. package/dist/src/tracing/agent-memory-instrumentation.d.ts +3 -1
  162. package/dist/src/tracing/agent-memory-instrumentation.js +1 -1
  163. package/dist/src/tracing/agent-otel-provider.d.ts +2 -0
  164. package/dist/src/tracing/agent-otel-provider.js +2 -2
  165. package/dist/src/tracing/agent-otel-session-context.d.ts +2 -0
  166. package/dist/src/tracing/agent-otel-session-context.js +1 -1
  167. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  168. package/dist/src/tracing/install-instrumentation-runtime.js +1 -1
  169. package/dist/src/tracing/local-instrumentation-runtime.d.ts +1 -1
  170. package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
  171. package/docs/channels/custom.mdx +22 -2
  172. package/docs/channels/eve.mdx +39 -0
  173. package/docs/channels/slack.mdx +47 -0
  174. package/docs/connections/mcp.mdx +14 -0
  175. package/docs/guides/frontend/nextjs.mdx +12 -10
  176. package/docs/guides/instrumentation-providers.md +10 -8
  177. package/docs/guides/instrumentation.md +2 -2
  178. package/docs/guides/remote-agents.md +1 -1
  179. package/docs/install-integrations.mdx +1 -1
  180. package/docs/reference/cli.md +9 -8
  181. package/docs/subagents/index.mdx +3 -1
  182. package/package.json +1 -1
@@ -6,7 +6,6 @@ import { type TwilioApiOptions, type TwilioApiResponse, type TwilioCredentials }
6
6
  import { type TwilioTextMessage, type TwilioVoiceCall, type TwilioVoiceTranscription } from "#public/channels/twilio/inbound.js";
7
7
  import { type TwilioAuthToken, type TwilioWebhookUrl } from "#public/channels/twilio/verify.js";
8
8
  import { type Channel } from "#public/definitions/channel.js";
9
- import type { ChannelAudience } from "#shared/channel-audience.js";
10
9
  type EventData<T extends UnstampedMessageStreamEvent["type"]> = Extract<UnstampedMessageStreamEvent, {
11
10
  type: T;
12
11
  }> extends {
@@ -36,7 +35,6 @@ export interface TwilioChannelState {
36
35
  }
37
36
  /** Per-session instrumentation snapshot for Twilio runtime telemetry. Reports the active phone-number pair and the most recent message and call SIDs. */
38
37
  export interface TwilioInstrumentationMetadata extends Record<string, unknown> {
39
- readonly audience: ChannelAudience;
40
38
  readonly from: string | null;
41
39
  readonly lastCallSid: string | null;
42
40
  readonly lastMessageSid: string | null;
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{readNonEmptyString}from"#shared/guards.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import"#public/channels/twilio/verify.js";import{callTwilioApi,sendTwilioMessage,twilioContinuationToken,updateTwilioCall}from"#public/channels/twilio/api.js";import{emptyTwilioResponse,gatherSpeechTwilioResponse,sayTwilioResponse}from"#public/channels/twilio/twiml.js";import{defaultEvents,defaultOnText,defaultOnVoice,defaultOnVoiceTranscription}from"#public/channels/twilio/defaults.js";import{formatTwilioContextBlock,parseTwilioTextMessage,parseTwilioVoiceCall,parseTwilioVoiceTranscription}from"#public/channels/twilio/inbound.js";import{buildTwilioActionUrl,buildTwilioRoutes,verifyTwilioInbound}from"#public/channels/twilio/routing.js";const log=createLogger(`twilio.channel`);function twilioChannel(e){assertAllowFromConfigured(e);let t=buildTwilioRoutes(e.route??`/eve/v1/twilio`),n=e.onText??defaultOnText,r=e.onVoice??defaultOnVoice,i=e.onVoiceTranscription??defaultOnVoiceTranscription,a={...defaultEvents,...e.events},o=handleTwilioMessages({config:e,onText:n}),s=handleTwilioVoice({config:e,onVoice:r,routes:t}),c=handleTwilioTranscription({config:e,onVoiceTranscription:i,routes:t});return defineChannel({kindHint:`twilio`,turnPolicy:e.turnPolicy,state:{from:null,to:null,lastCallSid:null,lastMessageSid:null},metadata(e){return{audience:`private`,from:e.from,lastCallSid:e.lastCallSid??null,lastMessageSid:e.lastMessageSid??null,to:e.to}},context(t,n){return rebuildTwilioContext(t,n,e)},routes:[GET(t.messages,o),POST(t.messages,o),GET(t.voice,s),POST(t.voice,s),GET(t.transcription,c),POST(t.transcription,c)],async receive(t,{from:n}){let r=readNonEmptyString(t.target.phoneNumber);if(!r)throw Error(`twilioChannel().receive requires target.phoneNumber.`);let i=readNonEmptyString(t.target.from)??e.messaging?.from??null;return n(twilioContinuationToken(r,i??void 0)).send(t.message,{auth:t.auth,state:{from:r,lastCallSid:null,lastMessageSid:null,to:i}})},events:a})}function handleTwilioMessages(e){return async(t,{from:n,waitUntil:r})=>{let i=await verifyTwilioInbound(t,e.config);if(i===null)return new Response(`unauthorized`,{status:401});let a=parseTwilioTextMessage(i.params);return a?await isAllowed(a.from,e.config.allowFrom)?(r(dispatchText({config:e.config,message:a,onText:e.onText,from:n})),emptyTwilioResponse()):new Response(`forbidden`,{status:403}):emptyTwilioResponse()}}function handleTwilioVoice(e){return async t=>{let n=await verifyTwilioInbound(t,e.config);if(n===null)return new Response(`unauthorized`,{status:401});let r=parseTwilioVoiceCall(n.params);if(!r)return sayTwilioResponse(`Missing caller information.`);if(!await isAllowed(r.from,e.config.allowFrom))return new Response(`forbidden`,{status:403});let i=await acceptVoiceCall({call:r,config:e.config,onVoice:e.onVoice});if(i===null)return new Response(`forbidden`,{status:403});let a=i??{};return gatherSpeechTwilioResponse({actionUrl:await buildTwilioActionUrl(t,e.config,e.routes.transcription),hints:a.hints??e.config.voice?.hints,language:a.language??e.config.voice?.language,profanityFilter:a.profanityFilter??e.config.voice?.profanityFilter,prompt:a.prompt??e.config.voice?.prompt??`Please say your message after the tone.`,speechModel:a.speechModel??e.config.voice?.speechModel,speechTimeout:a.speechTimeout??e.config.voice?.speechTimeout??`auto`,timeoutSeconds:a.timeoutSeconds??e.config.voice?.timeoutSeconds,voice:a.voice??e.config.voice?.voice})}}function handleTwilioTranscription(e){return async(t,{from:n,waitUntil:r})=>{let i=await verifyTwilioInbound(t,e.config);if(i===null)return new Response(`unauthorized`,{status:401});let a=parseTwilioVoiceTranscription(i.params);return a?await isAllowed(a.from,e.config.allowFrom)?(r(dispatchVoiceTranscription({config:e.config,onVoiceTranscription:e.onVoiceTranscription,from:n,transcription:a})),sayTwilioResponse(e.config.voice?.acknowledgement??`Thanks. I'll follow up by text.`)):new Response(`forbidden`,{status:403}):gatherSpeechTwilioResponse({actionUrl:await buildTwilioActionUrl(t,e.config,e.routes.transcription),language:e.config.voice?.language,prompt:e.config.voice?.prompt??`Please say your message after the tone.`,speechTimeout:e.config.voice?.speechTimeout??`auto`,timeoutSeconds:e.config.voice?.timeoutSeconds})}}function rebuildTwilioContext(e,t,n){return{state:e,twilio:buildTwilioHandle({callSid:e.lastCallSid??void 0,config:n,from:e.from??``,to:e.to??void 0})}}function buildTwilioHandle(e){let t=e.config.api,n=e.config.credentials,r=e.config.messaging?.from??e.to,i=e.config.messaging?.messagingServiceSid,a=e.config.messaging?.statusCallbackUrl;return{callSid:e.callSid,from:e.from,to:e.to,request(e,r){return callTwilioApi({apiBaseUrl:t?.apiBaseUrl,body:r,credentials:n,fetch:t?.fetch,path:e})},sendMessage(o,s){return sendTwilioMessage({apiBaseUrl:t?.apiBaseUrl,body:o,credentials:n,fetch:t?.fetch,from:s?.from??r,messagingServiceSid:s?.messagingServiceSid??i,statusCallbackUrl:s?.statusCallbackUrl??a,to:s?.to??e.from})},updateCall(e,r){return updateTwilioCall({apiBaseUrl:t?.apiBaseUrl,callSid:e,credentials:n,fetch:t?.fetch,twiml:r})}}}function assertAllowFromConfigured(e){if(e?.allowFrom===void 0)throw Error(`twilioChannel requires allowFrom. Use allowFrom: "*" to allow all numbers.`)}async function dispatchText(e){let{message:t}=e,n={twilio:buildTwilioHandle({callSid:void 0,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onText(n,t)}catch(e){log.error(`text handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({channel:`text`,from:t.from,messageSid:t.messageSid,to:t.to});try{await e.from(twilioContinuationToken(t.from,t.to)).send(t.body,{auth:r.auth,context:[i],state:{from:t.from,lastCallSid:null,lastMessageSid:t.messageSid??null,to:t.to??null},title:r.title})}catch(e){log.error(`text delivery failed`,{error:e})}}async function acceptVoiceCall(e){let{call:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})};try{return await e.onVoice(n,t)}catch(e){return log.error(`voice handler failed`,{error:e}),null}}async function dispatchVoiceTranscription(e){let{transcription:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onVoiceTranscription(n,t)}catch(e){log.error(`voice transcription handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({callSid:t.callSid,channel:`voice`,from:t.from,to:t.to});try{await e.from(twilioContinuationToken(t.from,t.to)).send(t.text,{auth:r.auth,context:[i],state:{from:t.from,lastCallSid:t.callSid??null,lastMessageSid:null,to:t.to??null},title:r.title})}catch(e){log.error(`voice transcription delivery failed`,{error:e})}}async function isAllowed(e,t){let n=typeof t==`function`?await t():t;return n===`*`?!0:typeof n==`string`?n===e:n.includes(e)}export{twilioChannel};
1
+ import{createLogger}from"#internal/logging.js";import{readNonEmptyString}from"#shared/guards.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import"#public/channels/twilio/verify.js";import{callTwilioApi,sendTwilioMessage,twilioContinuationToken,updateTwilioCall}from"#public/channels/twilio/api.js";import{emptyTwilioResponse,gatherSpeechTwilioResponse,sayTwilioResponse}from"#public/channels/twilio/twiml.js";import{defaultEvents,defaultOnText,defaultOnVoice,defaultOnVoiceTranscription}from"#public/channels/twilio/defaults.js";import{formatTwilioContextBlock,parseTwilioTextMessage,parseTwilioVoiceCall,parseTwilioVoiceTranscription}from"#public/channels/twilio/inbound.js";import{buildTwilioActionUrl,buildTwilioRoutes,verifyTwilioInbound}from"#public/channels/twilio/routing.js";const log=createLogger(`twilio.channel`);function twilioChannel(e){assertAllowFromConfigured(e);let t=buildTwilioRoutes(e.route??`/eve/v1/twilio`),n=e.onText??defaultOnText,r=e.onVoice??defaultOnVoice,i=e.onVoiceTranscription??defaultOnVoiceTranscription,a={...defaultEvents,...e.events},o=handleTwilioMessages({config:e,onText:n}),s=handleTwilioVoice({config:e,onVoice:r,routes:t}),c=handleTwilioTranscription({config:e,onVoiceTranscription:i,routes:t});return defineChannel({kindHint:`twilio`,turnPolicy:e.turnPolicy,state:{from:null,to:null,lastCallSid:null,lastMessageSid:null},metadata(e){return{from:e.from,lastCallSid:e.lastCallSid??null,lastMessageSid:e.lastMessageSid??null,to:e.to}},audience:()=>`private`,context(t,n){return rebuildTwilioContext(t,n,e)},routes:[GET(t.messages,o),POST(t.messages,o),GET(t.voice,s),POST(t.voice,s),GET(t.transcription,c),POST(t.transcription,c)],async receive(t,{from:n}){let r=readNonEmptyString(t.target.phoneNumber);if(!r)throw Error(`twilioChannel().receive requires target.phoneNumber.`);let i=readNonEmptyString(t.target.from)??e.messaging?.from??null;return n(twilioContinuationToken(r,i??void 0)).send(t.message,{auth:t.auth,state:{from:r,lastCallSid:null,lastMessageSid:null,to:i}})},events:a})}function handleTwilioMessages(e){return async(t,{from:n,waitUntil:r})=>{let i=await verifyTwilioInbound(t,e.config);if(i===null)return new Response(`unauthorized`,{status:401});let a=parseTwilioTextMessage(i.params);return a?await isAllowed(a.from,e.config.allowFrom)?(r(dispatchText({config:e.config,message:a,onText:e.onText,from:n})),emptyTwilioResponse()):new Response(`forbidden`,{status:403}):emptyTwilioResponse()}}function handleTwilioVoice(e){return async t=>{let n=await verifyTwilioInbound(t,e.config);if(n===null)return new Response(`unauthorized`,{status:401});let r=parseTwilioVoiceCall(n.params);if(!r)return sayTwilioResponse(`Missing caller information.`);if(!await isAllowed(r.from,e.config.allowFrom))return new Response(`forbidden`,{status:403});let i=await acceptVoiceCall({call:r,config:e.config,onVoice:e.onVoice});if(i===null)return new Response(`forbidden`,{status:403});let a=i??{};return gatherSpeechTwilioResponse({actionUrl:await buildTwilioActionUrl(t,e.config,e.routes.transcription),hints:a.hints??e.config.voice?.hints,language:a.language??e.config.voice?.language,profanityFilter:a.profanityFilter??e.config.voice?.profanityFilter,prompt:a.prompt??e.config.voice?.prompt??`Please say your message after the tone.`,speechModel:a.speechModel??e.config.voice?.speechModel,speechTimeout:a.speechTimeout??e.config.voice?.speechTimeout??`auto`,timeoutSeconds:a.timeoutSeconds??e.config.voice?.timeoutSeconds,voice:a.voice??e.config.voice?.voice})}}function handleTwilioTranscription(e){return async(t,{from:n,waitUntil:r})=>{let i=await verifyTwilioInbound(t,e.config);if(i===null)return new Response(`unauthorized`,{status:401});let a=parseTwilioVoiceTranscription(i.params);return a?await isAllowed(a.from,e.config.allowFrom)?(r(dispatchVoiceTranscription({config:e.config,onVoiceTranscription:e.onVoiceTranscription,from:n,transcription:a})),sayTwilioResponse(e.config.voice?.acknowledgement??`Thanks. I'll follow up by text.`)):new Response(`forbidden`,{status:403}):gatherSpeechTwilioResponse({actionUrl:await buildTwilioActionUrl(t,e.config,e.routes.transcription),language:e.config.voice?.language,prompt:e.config.voice?.prompt??`Please say your message after the tone.`,speechTimeout:e.config.voice?.speechTimeout??`auto`,timeoutSeconds:e.config.voice?.timeoutSeconds})}}function rebuildTwilioContext(e,t,n){return{state:e,twilio:buildTwilioHandle({callSid:e.lastCallSid??void 0,config:n,from:e.from??``,to:e.to??void 0})}}function buildTwilioHandle(e){let t=e.config.api,n=e.config.credentials,r=e.config.messaging?.from??e.to,i=e.config.messaging?.messagingServiceSid,a=e.config.messaging?.statusCallbackUrl;return{callSid:e.callSid,from:e.from,to:e.to,request(e,r){return callTwilioApi({apiBaseUrl:t?.apiBaseUrl,body:r,credentials:n,fetch:t?.fetch,path:e})},sendMessage(o,s){return sendTwilioMessage({apiBaseUrl:t?.apiBaseUrl,body:o,credentials:n,fetch:t?.fetch,from:s?.from??r,messagingServiceSid:s?.messagingServiceSid??i,statusCallbackUrl:s?.statusCallbackUrl??a,to:s?.to??e.from})},updateCall(e,r){return updateTwilioCall({apiBaseUrl:t?.apiBaseUrl,callSid:e,credentials:n,fetch:t?.fetch,twiml:r})}}}function assertAllowFromConfigured(e){if(e?.allowFrom===void 0)throw Error(`twilioChannel requires allowFrom. Use allowFrom: "*" to allow all numbers.`)}async function dispatchText(e){let{message:t}=e,n={twilio:buildTwilioHandle({callSid:void 0,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onText(n,t)}catch(e){log.error(`text handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({channel:`text`,from:t.from,messageSid:t.messageSid,to:t.to});try{await e.from(twilioContinuationToken(t.from,t.to)).send(t.body,{auth:r.auth,context:[i],state:{from:t.from,lastCallSid:null,lastMessageSid:t.messageSid??null,to:t.to??null},title:r.title})}catch(e){log.error(`text delivery failed`,{error:e})}}async function acceptVoiceCall(e){let{call:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})};try{return await e.onVoice(n,t)}catch(e){return log.error(`voice handler failed`,{error:e}),null}}async function dispatchVoiceTranscription(e){let{transcription:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onVoiceTranscription(n,t)}catch(e){log.error(`voice transcription handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({callSid:t.callSid,channel:`voice`,from:t.from,to:t.to});try{await e.from(twilioContinuationToken(t.from,t.to)).send(t.text,{auth:r.auth,context:[i],state:{from:t.from,lastCallSid:t.callSid??null,lastMessageSid:null,to:t.to??null},title:r.title})}catch(e){log.error(`voice transcription delivery failed`,{error:e})}}async function isAllowed(e,t){let n=typeof t==`function`?await t():t;return n===`*`?!0:typeof n==`string`?n===e:n.includes(e)}export{twilioChannel};
@@ -10,7 +10,8 @@ import type { GenericChannelDefinition, GenericReceiveInput } from "#shared/chan
10
10
  declare const CHANNEL_METADATA_TYPE: unique symbol;
11
11
  export type { CancelTurnResult, ClearSessionResult, CompactSessionResult, GetEventStreamOptions, ResetSessionResult, SessionCallback, TurnPolicy, } from "#channel/types.js";
12
12
  export type { Session, SessionHandle } from "#channel/session.js";
13
- export type { ChannelAudience, ChannelAudienceMetadata } from "#shared/channel-audience.js";
13
+ export type { ChannelAudience } from "#shared/channel-audience.js";
14
+ export type { AudienceInput, AudiencePrincipal, ConversationEnvironment, } from "#shared/conversation-context.js";
14
15
  export type { SessionRespondOptions, SessionSendOptions } from "#channel/session.js";
15
16
  export type { ChannelFrom, ChannelReceiveContext, ChannelResolveSession, ChannelRespondOptions, ChannelSendOptions, ChannelSource, };
16
17
  export type { ChannelCors, ChannelCorsOptions } from "#channel/cors.js";
@@ -1 +1 @@
1
- import{CHANNEL_SENTINEL}from"#channel/compiled-channel.js";import{defaultDeliverResult}from"#channel/adapter.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{normalizeChannelCors}from"#channel/cors.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";import{DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT,WS}from"#channel/routes.js";const DISABLED_ROUTE_SENTINEL_KIND=`eve:disabled-channel`;function disableRoute(){return{kind:DISABLED_ROUTE_SENTINEL_KIND}}function isDisabledRouteSentinel(e){return typeof e==`object`&&!!e&&e.kind===DISABLED_ROUTE_SENTINEL_KIND}function defineChannel(e){let t=buildAdapter(e),n=normalizeChannelCors(e.cors);return{__kind:CHANNEL_SENTINEL,routes:e.routes,adapter:t,cors:n,receive:e.receive,turnPolicy:e.turnPolicy}}const eventTypes=Object.keys({"approval.candidate":null,"approval.settled":null,"context.cleared":null,"compaction.requested":null,"compaction.completed":null,"turn.started":null,"actions.requested":null,"action.partial":null,"action.result":null,"message.completed":null,"message.appended":null,"reasoning.appended":null,"reasoning.completed":null,"input.requested":null,"turn.failed":null,"turn.completed":null,"turn.cancelled":null,"session.failed":null,"session.completed":null,"session.waiting":null,"authorization.required":null,"authorization.completed":null});function buildAdapter(e){let t=e.state!=null,n=e.context!=null,r=e.fetchFile!==void 0,i=e.metadata,a=t||n||i!==void 0,o={},s=!1,c=e.events;for(let e of eventTypes){let t=c?.[e];t&&(s=!0,o[e]=(n,r)=>{let{session:i,...a}=r,o={...a,continuation:i?.continuation===void 0?void 0:{token:i.continuation.token,rekey:e=>i.continuation?.rekey(e)}};if(e===`session.failed`)return t(n,o);let s=buildCallbackContext();return t(n,o,s)})}return!a&&!s&&!r?{kind:e.kindHint??HTTP_ADAPTER_KIND}:{kind:e.kindHint??`defineChannel`,state:t?{...e.state}:{},fetchFile:e.fetchFile,instrumentation:i===void 0?void 0:{metadata(e){return i(e)}},createAdapterContext(t){let r=t.state,i=t.session;return{...n?e.context(r,i):{},state:r,ctx:t.ctx,session:i}},deliver(t,n){return e.deliver===void 0?defaultDeliverResult(t):e.deliver(t,n)},...o}}export{DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT,WS,defineChannel,disableRoute,isDisabledRouteSentinel};
1
+ import{createMetadataAudienceProjector}from"#channel/audience.js";import{CHANNEL_SENTINEL}from"#channel/compiled-channel.js";import{defaultDeliverResult}from"#channel/adapter.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{normalizeChannelCors}from"#channel/cors.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";import{DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT,WS}from"#channel/routes.js";const DISABLED_ROUTE_SENTINEL_KIND=`eve:disabled-channel`;function disableRoute(){return{kind:DISABLED_ROUTE_SENTINEL_KIND}}function isDisabledRouteSentinel(e){return typeof e==`object`&&!!e&&e.kind===DISABLED_ROUTE_SENTINEL_KIND}function defineChannel(e){let t=buildAdapter(e),n=normalizeChannelCors(e.cors);return{__kind:CHANNEL_SENTINEL,routes:e.routes,adapter:t,cors:n,receive:e.receive,turnPolicy:e.turnPolicy}}const eventTypes=Object.keys({"approval.candidate":null,"approval.settled":null,"context.cleared":null,"compaction.requested":null,"compaction.completed":null,"turn.started":null,"actions.requested":null,"action.partial":null,"action.result":null,"message.completed":null,"message.appended":null,"reasoning.appended":null,"reasoning.completed":null,"input.requested":null,"turn.failed":null,"turn.completed":null,"turn.cancelled":null,"session.failed":null,"session.completed":null,"session.waiting":null,"authorization.required":null,"authorization.completed":null});function buildAdapter(e){let t=e.state!=null,n=e.context!=null,r=e.fetchFile!==void 0,i=e.metadata,a=i!==void 0,o=e.audience,s=t||n||a,c={},l=!1,u={kind:e.kindHint??`defineChannel`},d=e.events;for(let e of eventTypes){let t=d?.[e];t&&(l=!0,c[e]=(n,r)=>{let{session:i,...a}=r,o={...a,continuation:i?.continuation===void 0?void 0:{token:i.continuation.token,rekey:e=>i.continuation?.rekey(e)}};if(e===`session.failed`)return t(n,o);let s=buildCallbackContext();return t(n,o,s)})}return!s&&!l&&!r?{kind:e.kindHint??HTTP_ADAPTER_KIND,...o===void 0?void 0:{instrumentation:{audience:o}}}:{kind:e.kindHint??`defineChannel`,state:t?{...e.state}:{},fetchFile:e.fetchFile,instrumentation:i===void 0&&o===void 0?void 0:{...i===void 0?void 0:{metadata(e){let{audience:t,...n}=i(e);return n}},...o===void 0?i===void 0?void 0:{audience:createMetadataAudienceProjector(u,i)}:{audience:o}},createAdapterContext(t){let r=t.state,i=t.session;return{...n?e.context(r,i):{},state:r,ctx:t.ctx,session:i}},deliver(t,n){return e.deliver===void 0?defaultDeliverResult(t):e.deliver(t,n)},...c}}export{DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT,WS,defineChannel,disableRoute,isDisabledRouteSentinel};
@@ -20,6 +20,12 @@ export interface McpClientConnectionDefinition {
20
20
  * Must support Streamable HTTP or SSE transport.
21
21
  */
22
22
  readonly url: string;
23
+ /**
24
+ * Whether to discover the server's protocol before initialization.
25
+ * Defaults to enabled. Set to false for servers that require the older
26
+ * initialize handshake; that handshake still negotiates a supported version.
27
+ */
28
+ readonly protocolVersionDiscovery?: boolean;
23
29
  /**
24
30
  * Human-readable summary of the connection and its tools.
25
31
  *
@@ -1 +1 @@
1
- import{vercelOidc}from"#public/agents/auth.js";import{defineRemoteAgent}from"#public/definitions/remote-agent.js";const WORKSPACE_AGENT_NAME=Symbol.for(`eve.workspace-agent.name`);function defineWorkspaceAgent(e){let t=e.transport??defaultWorkspaceAgentTransport(e.name),n=defineRemoteAgent({auth:t.auth,description:e.description??``,forwardPrincipal:e.forwardPrincipal,headers:t.headers,outputSchema:e.outputSchema,url:t.url});return Object.defineProperty(n,WORKSPACE_AGENT_NAME,{value:e.name}),n}function workspaceSubagentName(e){return isBrandedWorkspaceSubagent(e)?e[WORKSPACE_AGENT_NAME]:void 0}function isBrandedWorkspaceSubagent(e){return typeof e==`object`&&!!e&&Reflect.has(e,WORKSPACE_AGENT_NAME)}function defaultWorkspaceAgentTransport(e){let t=vercelOidc();return{auth:async()=>(requireVercelWorkspaceEnvironment(),t()),url:()=>{requireVercelWorkspaceEnvironment();let t=process.env.VERCEL_ENV===`production`?process.env.VERCEL_PROJECT_PRODUCTION_URL:process.env.VERCEL_URL;if(t===void 0||t.length===0)throw Error(`The default workspace-agent transport requires VERCEL_URL, or VERCEL_PROJECT_PRODUCTION_URL in production.`);return`https://${t}/${e}`}}}function requireVercelWorkspaceEnvironment(){if(!process.env.VERCEL)throw Error(`No default workspace-agent transport is available in this environment. Provide transport to defineWorkspaceAgent().`)}export{defineWorkspaceAgent,workspaceSubagentName};
1
+ import{normalizePublicRoutePrefix}from"#shared/public-route-prefix.js";import{vercelOidc}from"#public/agents/auth.js";import{defineRemoteAgent}from"#public/definitions/remote-agent.js";const WORKSPACE_AGENT_NAME=Symbol.for(`eve.workspace-agent.name`);function defineWorkspaceAgent(e){let t=e.transport??defaultWorkspaceAgentTransport(e.name),n=defineRemoteAgent({auth:t.auth,description:e.description??``,forwardPrincipal:e.forwardPrincipal,headers:t.headers,outputSchema:e.outputSchema,url:t.url});return Object.defineProperty(n,WORKSPACE_AGENT_NAME,{value:e.name}),n}function workspaceSubagentName(e){return isBrandedWorkspaceSubagent(e)?e[WORKSPACE_AGENT_NAME]:void 0}function isBrandedWorkspaceSubagent(e){return typeof e==`object`&&!!e&&Reflect.has(e,WORKSPACE_AGENT_NAME)}function defaultWorkspaceAgentTransport(e){let t=vercelOidc();return{auth:async()=>(requireVercelWorkspaceEnvironment(),t()),url:()=>{requireVercelWorkspaceEnvironment();let t=process.env.VERCEL_ENV===`production`?process.env.VERCEL_PROJECT_PRODUCTION_URL:process.env.VERCEL_URL;if(t===void 0||t.length===0)throw Error(`The default workspace-agent transport requires VERCEL_URL, or VERCEL_PROJECT_PRODUCTION_URL in production.`);return`https://${t}${normalizePublicRoutePrefix(process.env.EVE_PUBLIC_ROUTE_PREFIX)?.startsWith(`/eve/agents/`)===!0?`/eve/agents/${e}`:`/${e}`}`}}}function requireVercelWorkspaceEnvironment(){if(!process.env.VERCEL)throw Error(`No default workspace-agent transport is available in this environment. Provide transport to defineWorkspaceAgent().`)}export{defineWorkspaceAgent,workspaceSubagentName};
@@ -1 +1 @@
1
- import{decodeJwt}from"#compiled/jose/index.js";import{isObject}from"#shared/guards.js";function readCodexJwtExpirationMs(e){let t=parseCodexJwtClaims(e);if(t!==void 0&&typeof t.exp==`number`)return t.exp*1e3}function extractCodexAccountIdFromToken(e){let t=parseCodexJwtClaims(e);if(t===void 0)return;let n=t[`https://api.openai.com/auth`],r=t.organizations;return readNonEmptyString$1(t.chatgpt_account_id)??readNonEmptyString$1(isObject(n)?n.chatgpt_account_id:void 0)??readNonEmptyString$1(Array.isArray(r)&&isObject(r[0])?r[0].id:void 0)}function extractCodexAccountLabelFromToken(e){let t=parseCodexJwtClaims(e);if(t===void 0)return;let n=t[`https://api.openai.com/auth`],r=readEmail(t.email)??readEmail(isObject(n)?n.email:void 0);if(r!==void 0)return r;let i=readNonEmptyString$1(t.sub);return i===void 0?void 0:readEmail(i.split(`|`).at(-1))}function readEmail(e){let t=readNonEmptyString$1(e);return t!==void 0&&/^[^@\s]+@[^@\s]+\.[^@\s]+$/u.test(t)?t:void 0}function readNonEmptyString$1(e){return typeof e==`string`&&e.trim()!==``?e:void 0}function parseCodexJwtClaims(e){if(e!==void 0)try{return decodeJwt(e)}catch{return}}export{extractCodexAccountIdFromToken,extractCodexAccountLabelFromToken,readCodexJwtExpirationMs};
1
+ import{isObject}from"#shared/guards.js";import{decodeJwt}from"#compiled/jose/index.js";function readCodexJwtExpirationMs(e){let t=parseCodexJwtClaims(e);if(t!==void 0&&typeof t.exp==`number`)return t.exp*1e3}function extractCodexAccountIdFromToken(e){let t=parseCodexJwtClaims(e);if(t===void 0)return;let n=t[`https://api.openai.com/auth`],r=t.organizations;return readNonEmptyString$1(t.chatgpt_account_id)??readNonEmptyString$1(isObject(n)?n.chatgpt_account_id:void 0)??readNonEmptyString$1(Array.isArray(r)&&isObject(r[0])?r[0].id:void 0)}function extractCodexAccountLabelFromToken(e){let t=parseCodexJwtClaims(e);if(t===void 0)return;let n=t[`https://api.openai.com/auth`],r=readEmail(t.email)??readEmail(isObject(n)?n.email:void 0);if(r!==void 0)return r;let i=readNonEmptyString$1(t.sub);return i===void 0?void 0:readEmail(i.split(`|`).at(-1))}function readEmail(e){let t=readNonEmptyString$1(e);return t!==void 0&&/^[^@\s]+@[^@\s]+\.[^@\s]+$/u.test(t)?t:void 0}function readNonEmptyString$1(e){return typeof e==`string`&&e.trim()!==``?e:void 0}function parseCodexJwtClaims(e){if(e!==void 0)try{return decodeJwt(e)}catch{return}}export{extractCodexAccountIdFromToken,extractCodexAccountLabelFromToken,readCodexJwtExpirationMs};
@@ -1 +1 @@
1
- import{extractCodexAccountIdFromToken,extractCodexAccountLabelFromToken,readCodexJwtExpirationMs}from"./auth.js";import{ChatGptSignInRequiredError}from"./oauth.js";import{ChatGptSignedOutError,isChatGptTokenFresh}from"./token.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{spawn}from"node:child_process";import{isErrnoCode,isObject}from"#shared/guards.js";import{createInterface}from"node:readline";var CodexBinaryNotFoundError=class extends Error{constructor(e){super("The `codex` CLI was not found.",{cause:e}),this.name=`CodexBinaryNotFoundError`}},CodexAppServerClient=class{#e;#t;#n;#r;constructor(e={}){this.#e=e.command??`codex`,this.#t=e.env,this.#n=e.spawnProcess??spawnCodexAppServer}async resolveToken(e){let t=await this.#i(e.forceRefresh);if(t.authMethod!==`chatgpt`||t.authToken===void 0)throw e.forceRefresh?new ChatGptSignInRequiredError:new ChatGptSignedOutError("ChatGPT subscription is not signed in to Codex. Run `codex login` or sign in from /model.");let n=tokenFromCodex(t.authToken);if(!e.forceRefresh&&!isChatGptTokenFresh(n,e.now())){if(t=await this.#i(!0),t.authMethod!==`chatgpt`||t.authToken===void 0)throw new ChatGptSignInRequiredError;n=tokenFromCodex(t.authToken)}return n}async#i(e){let t=await this.#a();try{return await t.getAuthStatus({refreshToken:e})}catch(e){throw t.exited&&(this.#r=void 0),e}}restart(){let e=this.#r;this.#r=void 0,e?.then(e=>e.close()).catch(()=>void 0)}#a(){return this.#r===void 0&&(this.#r=CodexAppServerConnection.start({command:this.#e,env:this.#t,spawnProcess:this.#n}).catch(e=>{throw this.#r=void 0,e})),this.#r}},CodexAppServerConnection=class CodexAppServerConnection{#e;#t;#n=new Map;#r=1;#i=!1;#a;constructor(e){this.#e=e,e.unref(),unrefStream(e.stdin),unrefStream(e.stdout),unrefStream(e.stderr),e.stderr.resume(),this.#t=createInterface({input:e.stdout}),this.#t.on(`line`,e=>this.#l(e)),e.once(`error`,e=>this.#u(e)),e.once(`exit`,(e,t)=>{let n=t===null?`code ${e??`unknown`}`:`signal ${t}`;this.#u(Error(`Codex app-server exited with ${n}.`))})}get exited(){return this.#i}close(){this.#e.kill(),this.#u(Error(`Codex app-server connection was restarted.`))}static async start(e){let t;try{t=e.spawnProcess(e.command,[`app-server`,`--stdio`],{env:e.env,stdio:[`pipe`,`pipe`,`pipe`]})}catch(e){throw appServerError(e)}let n=new CodexAppServerConnection(t);try{return await n.#o(`initialize`,{capabilities:null,clientInfo:{name:`eve`,title:`eve`,version:resolveInstalledPackageInfo().version}}),n.#s(`initialized`,{}),n}catch(e){throw t.kill(),e}}async getAuthStatus(e){let t=await this.#o(`getAuthStatus`,{includeToken:!0,refreshToken:e.refreshToken});if(!isObject(t))throw Error(`Codex app-server returned an invalid authentication response.`);return{...typeof t.authMethod==`string`&&{authMethod:t.authMethod},...typeof t.authToken==`string`&&{authToken:t.authToken},...typeof t.requiresOpenaiAuth==`boolean`&&{requiresOpenaiAuth:t.requiresOpenaiAuth}}}#o(e,t){if(this.#i)return Promise.reject(this.#a??Error(`Codex app-server is not running.`));let n=this.#r++,r=new Promise((e,t)=>{this.#n.set(n,{reject:t,resolve:e})});return this.#c({id:n,method:e,params:t}),r}#s(e,t){this.#c({method:e,params:t})}#c(e){this.#e.stdin.write(`${JSON.stringify(e)}\n`)}#l(e){let t;try{t=JSON.parse(e)}catch{return}if(typeof t.id!=`number`)return;let n=this.#n.get(t.id);if(n!==void 0){if(this.#n.delete(t.id),t.error!==void 0){n.reject(Error(t.error.message??`Codex app-server request failed (${t.error.code}).`));return}n.resolve(t.result)}}#u(e){if(!this.#i){this.#i=!0,this.#a=appServerError(e),this.#t.close();for(let e of this.#n.values())e.reject(this.#a);this.#n.clear()}}};function spawnCodexAppServer(e,t,n){return spawn(e,[...t],n)}function unrefStream(e){`unref`in e&&typeof e.unref==`function`&&e.unref()}function tokenFromCodex(e){let t=extractCodexAccountIdFromToken(e),n=extractCodexAccountLabelFromToken(e),r=readCodexJwtExpirationMs(e);return{token:e,...t!==void 0&&{accountId:t},...n!==void 0&&{accountLabel:n},...r!==void 0&&{expiresAt:r}}}function appServerError(e){if(isErrnoCode(e,`ENOENT`))return new CodexBinaryNotFoundError(e);let t=e instanceof Error?e.message:String(e);return Error(`Codex app-server is unavailable: ${t}`,{cause:e})}export{CodexAppServerClient,CodexBinaryNotFoundError};
1
+ import{extractCodexAccountIdFromToken,extractCodexAccountLabelFromToken,readCodexJwtExpirationMs}from"./auth.js";import{ChatGptSignInRequiredError}from"./oauth.js";import{ChatGptSignedOutError,isChatGptTokenFresh}from"./token.js";import{isErrnoCode,isObject}from"#shared/guards.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{spawn}from"node:child_process";import{createInterface}from"node:readline";var CodexBinaryNotFoundError=class extends Error{constructor(e){super("The `codex` CLI was not found.",{cause:e}),this.name=`CodexBinaryNotFoundError`}},CodexAppServerClient=class{#e;#t;#n;#r;constructor(e={}){this.#e=e.command??`codex`,this.#t=e.env,this.#n=e.spawnProcess??spawnCodexAppServer}async resolveToken(e){let t=await this.#i(e.forceRefresh);if(t.authMethod!==`chatgpt`||t.authToken===void 0)throw e.forceRefresh?new ChatGptSignInRequiredError:new ChatGptSignedOutError("ChatGPT subscription is not signed in to Codex. Run `codex login` or sign in from /model.");let n=tokenFromCodex(t.authToken);if(!e.forceRefresh&&!isChatGptTokenFresh(n,e.now())){if(t=await this.#i(!0),t.authMethod!==`chatgpt`||t.authToken===void 0)throw new ChatGptSignInRequiredError;n=tokenFromCodex(t.authToken)}return n}async#i(e){let t=await this.#a();try{return await t.getAuthStatus({refreshToken:e})}catch(e){throw t.exited&&(this.#r=void 0),e}}restart(){let e=this.#r;this.#r=void 0,e?.then(e=>e.close()).catch(()=>void 0)}#a(){return this.#r===void 0&&(this.#r=CodexAppServerConnection.start({command:this.#e,env:this.#t,spawnProcess:this.#n}).catch(e=>{throw this.#r=void 0,e})),this.#r}},CodexAppServerConnection=class CodexAppServerConnection{#e;#t;#n=new Map;#r=1;#i=!1;#a;constructor(e){this.#e=e,e.unref(),unrefStream(e.stdin),unrefStream(e.stdout),unrefStream(e.stderr),e.stderr.resume(),this.#t=createInterface({input:e.stdout}),this.#t.on(`line`,e=>this.#l(e)),e.once(`error`,e=>this.#u(e)),e.once(`exit`,(e,t)=>{let n=t===null?`code ${e??`unknown`}`:`signal ${t}`;this.#u(Error(`Codex app-server exited with ${n}.`))})}get exited(){return this.#i}close(){this.#e.kill(),this.#u(Error(`Codex app-server connection was restarted.`))}static async start(e){let t;try{t=e.spawnProcess(e.command,[`app-server`,`--stdio`],{env:e.env,stdio:[`pipe`,`pipe`,`pipe`]})}catch(e){throw appServerError(e)}let n=new CodexAppServerConnection(t);try{return await n.#o(`initialize`,{capabilities:null,clientInfo:{name:`eve`,title:`eve`,version:resolveInstalledPackageInfo().version}}),n.#s(`initialized`,{}),n}catch(e){throw t.kill(),e}}async getAuthStatus(e){let t=await this.#o(`getAuthStatus`,{includeToken:!0,refreshToken:e.refreshToken});if(!isObject(t))throw Error(`Codex app-server returned an invalid authentication response.`);return{...typeof t.authMethod==`string`&&{authMethod:t.authMethod},...typeof t.authToken==`string`&&{authToken:t.authToken},...typeof t.requiresOpenaiAuth==`boolean`&&{requiresOpenaiAuth:t.requiresOpenaiAuth}}}#o(e,t){if(this.#i)return Promise.reject(this.#a??Error(`Codex app-server is not running.`));let n=this.#r++,r=new Promise((e,t)=>{this.#n.set(n,{reject:t,resolve:e})});return this.#c({id:n,method:e,params:t}),r}#s(e,t){this.#c({method:e,params:t})}#c(e){this.#e.stdin.write(`${JSON.stringify(e)}\n`)}#l(e){let t;try{t=JSON.parse(e)}catch{return}if(typeof t.id!=`number`)return;let n=this.#n.get(t.id);if(n!==void 0){if(this.#n.delete(t.id),t.error!==void 0){n.reject(Error(t.error.message??`Codex app-server request failed (${t.error.code}).`));return}n.resolve(t.result)}}#u(e){if(!this.#i){this.#i=!0,this.#a=appServerError(e),this.#t.close();for(let e of this.#n.values())e.reject(this.#a);this.#n.clear()}}};function spawnCodexAppServer(e,t,n){return spawn(e,[...t],n)}function unrefStream(e){`unref`in e&&typeof e.unref==`function`&&e.unref()}function tokenFromCodex(e){let t=extractCodexAccountIdFromToken(e),n=extractCodexAccountLabelFromToken(e),r=readCodexJwtExpirationMs(e);return{token:e,...t!==void 0&&{accountId:t},...n!==void 0&&{accountLabel:n},...r!==void 0&&{expiresAt:r}}}function appServerError(e){if(isErrnoCode(e,`ENOENT`))return new CodexBinaryNotFoundError(e);let t=e instanceof Error?e.message:String(e);return Error(`Codex app-server is unavailable: ${t}`,{cause:e})}export{CodexAppServerClient,CodexBinaryNotFoundError};
@@ -1 +1 @@
1
- import{CHATGPT_LOGIN_HINT,ChatGptSignInRequiredError,requestChatGptTokens}from"./oauth.js";import{ChatGptSignedOutError,isChatGptTokenFresh}from"./token.js";import{randomUUID}from"node:crypto";import{mkdir,rm,stat}from"node:fs/promises";import{dirname,join}from"node:path";import{isErrnoCode,isObject}from"#shared/guards.js";import{homedir}from"node:os";import{setTimeout}from"node:timers/promises";import{secrets}from"#compiled/just-secrets/index.js";const SECRET_ID={service:`eve`,name:`chatgpt`},MAX_SECRET_BYTES=2560;var ChatGptInvalidStoredSessionError=class extends Error{constructor(){super(`The ChatGPT session in the OS secret store is invalid. Sign in again from /model to replace it.`)}};function createChatGptCredentialStore(e=join(homedir(),`.eve`,`auth`,`chatgpt.json`),t=secrets){let n;async function removeLegacyFile(){try{await rm(e,{force:!0})}catch{throw Error(`ChatGPT credentials are stored securely, but the old plaintext session could not be removed. Stop older eve processes, remove ~/.eve/auth/chatgpt.json, and retry.`)}}async function load(){let e;try{e=await t.get(SECRET_ID)}catch{throw secretStoreError()}if(e===null){n=void 0;return}let r;try{if(Buffer.byteLength(e)>MAX_SECRET_BYTES)throw Error();r=JSON.parse(e)}catch{throw new ChatGptInvalidStoredSessionError}if(!isObject(r)||typeof r.sessionId!=`string`||!r.sessionId||typeof r.refreshToken!=`string`||!r.refreshToken)throw new ChatGptInvalidStoredSessionError;let i={refreshToken:r.refreshToken,...typeof r.accountId==`string`&&{accountId:r.accountId},...typeof r.accountLabel==`string`&&{accountLabel:r.accountLabel}},a=n?.sessionId===r.sessionId?{...i,accessToken:n.credentials.accessToken,expiresAt:n.credentials.expiresAt}:i;return await removeLegacyFile(),{sessionId:r.sessionId,credentials:a}}let r={async read(){return(await load())?.credentials},async resolveToken(e){let t=await r.read();if(!t)throw e.forceRefresh?new ChatGptSignInRequiredError:new ChatGptSignedOutError(`ChatGPT subscription is not signed in. ${CHATGPT_LOGIN_HINT}`);let n=tokenFromCredentials(t)?.token;(e.forceRefresh||!isChatGptTokenFresh(tokenFromCredentials(t),e.now()))&&(t=await r.update(async t=>{if(!t)throw new ChatGptSignInRequiredError;return`accessToken`in t&&isChatGptTokenFresh(tokenFromCredentials(t),e.now())&&(!e.forceRefresh||t.accessToken!==n)?t:requestChatGptTokens({grant_type:`refresh_token`,refresh_token:t.refreshToken},{fetch:e.fetch,previous:t,now:e.now})}));let i=tokenFromCredentials(t);if(!i)throw Error(`ChatGPT access token is unavailable. ${CHATGPT_LOGIN_HINT}`);return i},async update(r,i){await mkdir(dirname(e),{recursive:!0,mode:448});let a=`${e}.lock`,o=Date.now()+35e3;for(;;)try{await mkdir(a,{mode:448});break}catch(e){if(!isErrnoCode(e,`EEXIST`))throw e;let t=await stat(a).catch(e=>{if(!isErrnoCode(e,`ENOENT`))throw e});if(t&&Date.now()-t.mtimeMs>6e5){await rm(a,{recursive:!0,force:!0});continue}if(Date.now()>=o)throw Error(`Another eve process is updating the ChatGPT session. Retry shortly.`);await setTimeout(100)}try{let e=i?.replace?void 0:await load(),a=await r(e?.credentials),o=e?.sessionId??randomUUID(),s=JSON.stringify({sessionId:o,refreshToken:a.refreshToken,...a.accountId&&{accountId:a.accountId},...a.accountLabel&&{accountLabel:a.accountLabel}});if(Buffer.byteLength(s)>MAX_SECRET_BYTES)throw Error(`The ChatGPT refresh session exceeds the OS secret store's 2,560-byte limit. Use an API-key model instead.`);try{await t.set({...SECRET_ID,value:s})}catch{throw secretStoreError()}return n={sessionId:o,credentials:a},await removeLegacyFile(),a}finally{await rm(a,{recursive:!0,force:!0})}}};return r}let defaultStore;function getDefaultChatGptCredentialStore(){return defaultStore??=createChatGptCredentialStore()}function tokenFromCredentials(e){if(`accessToken`in e)return{token:e.accessToken,expiresAt:e.expiresAt,...e.accountId&&{accountId:e.accountId},...e.accountLabel&&{accountLabel:e.accountLabel}}}function secretStoreError(){let e=process.platform===`linux`?`Install libsecret-tools and start or unlock a Secret Service keyring with a session D-Bus. Headless sessions may need an API-key model.`:process.platform===`win32`?`Allow Windows PowerShell and Credential Manager access in your user session.`:`Unlock your login keychain and allow credential access.`;return Error(`Could not access ChatGPT credentials in the OS secret store. ${e} Retry from /model.`)}export{ChatGptInvalidStoredSessionError,createChatGptCredentialStore,getDefaultChatGptCredentialStore};
1
+ import{CHATGPT_LOGIN_HINT,ChatGptSignInRequiredError,requestChatGptTokens}from"./oauth.js";import{ChatGptSignedOutError,isChatGptTokenFresh}from"./token.js";import{randomUUID}from"node:crypto";import{mkdir,rm,stat}from"node:fs/promises";import{isErrnoCode,isObject}from"#shared/guards.js";import{dirname,join}from"node:path";import{homedir}from"node:os";import{setTimeout}from"node:timers/promises";import{secrets}from"#compiled/just-secrets/index.js";const SECRET_ID={service:`eve`,name:`chatgpt`},MAX_SECRET_BYTES=2560;var ChatGptInvalidStoredSessionError=class extends Error{constructor(){super(`The ChatGPT session in the OS secret store is invalid. Sign in again from /model to replace it.`)}};function createChatGptCredentialStore(e=join(homedir(),`.eve`,`auth`,`chatgpt.json`),t=secrets){let n;async function removeLegacyFile(){try{await rm(e,{force:!0})}catch{throw Error(`ChatGPT credentials are stored securely, but the old plaintext session could not be removed. Stop older eve processes, remove ~/.eve/auth/chatgpt.json, and retry.`)}}async function load(){let e;try{e=await t.get(SECRET_ID)}catch{throw secretStoreError()}if(e===null){n=void 0;return}let r;try{if(Buffer.byteLength(e)>MAX_SECRET_BYTES)throw Error();r=JSON.parse(e)}catch{throw new ChatGptInvalidStoredSessionError}if(!isObject(r)||typeof r.sessionId!=`string`||!r.sessionId||typeof r.refreshToken!=`string`||!r.refreshToken)throw new ChatGptInvalidStoredSessionError;let i={refreshToken:r.refreshToken,...typeof r.accountId==`string`&&{accountId:r.accountId},...typeof r.accountLabel==`string`&&{accountLabel:r.accountLabel}},a=n?.sessionId===r.sessionId?{...i,accessToken:n.credentials.accessToken,expiresAt:n.credentials.expiresAt}:i;return await removeLegacyFile(),{sessionId:r.sessionId,credentials:a}}let r={async read(){return(await load())?.credentials},async resolveToken(e){let t=await r.read();if(!t)throw e.forceRefresh?new ChatGptSignInRequiredError:new ChatGptSignedOutError(`ChatGPT subscription is not signed in. ${CHATGPT_LOGIN_HINT}`);let n=tokenFromCredentials(t)?.token;(e.forceRefresh||!isChatGptTokenFresh(tokenFromCredentials(t),e.now()))&&(t=await r.update(async t=>{if(!t)throw new ChatGptSignInRequiredError;return`accessToken`in t&&isChatGptTokenFresh(tokenFromCredentials(t),e.now())&&(!e.forceRefresh||t.accessToken!==n)?t:requestChatGptTokens({grant_type:`refresh_token`,refresh_token:t.refreshToken},{fetch:e.fetch,previous:t,now:e.now})}));let i=tokenFromCredentials(t);if(!i)throw Error(`ChatGPT access token is unavailable. ${CHATGPT_LOGIN_HINT}`);return i},async update(r,i){await mkdir(dirname(e),{recursive:!0,mode:448});let a=`${e}.lock`,o=Date.now()+35e3;for(;;)try{await mkdir(a,{mode:448});break}catch(e){if(!isErrnoCode(e,`EEXIST`))throw e;let t=await stat(a).catch(e=>{if(!isErrnoCode(e,`ENOENT`))throw e});if(t&&Date.now()-t.mtimeMs>6e5){await rm(a,{recursive:!0,force:!0});continue}if(Date.now()>=o)throw Error(`Another eve process is updating the ChatGPT session. Retry shortly.`);await setTimeout(100)}try{let e=i?.replace?void 0:await load(),a=await r(e?.credentials),o=e?.sessionId??randomUUID(),s=JSON.stringify({sessionId:o,refreshToken:a.refreshToken,...a.accountId&&{accountId:a.accountId},...a.accountLabel&&{accountLabel:a.accountLabel}});if(Buffer.byteLength(s)>MAX_SECRET_BYTES)throw Error(`The ChatGPT refresh session exceeds the OS secret store's 2,560-byte limit. Use an API-key model instead.`);try{await t.set({...SECRET_ID,value:s})}catch{throw secretStoreError()}return n={sessionId:o,credentials:a},await removeLegacyFile(),a}finally{await rm(a,{recursive:!0,force:!0})}}};return r}let defaultStore;function getDefaultChatGptCredentialStore(){return defaultStore??=createChatGptCredentialStore()}function tokenFromCredentials(e){if(`accessToken`in e)return{token:e.accessToken,expiresAt:e.expiresAt,...e.accountId&&{accountId:e.accountId},...e.accountLabel&&{accountLabel:e.accountLabel}}}function secretStoreError(){let e=process.platform===`linux`?`Install libsecret-tools and start or unlock a Secret Service keyring with a session D-Bus. Headless sessions may need an API-key model.`:process.platform===`win32`?`Allow Windows PowerShell and Credential Manager access in your user session.`:`Unlock your login keychain and allow credential access.`;return Error(`Could not access ChatGPT credentials in the OS secret store. ${e} Retry from /model.`)}export{ChatGptInvalidStoredSessionError,createChatGptCredentialStore,getDefaultChatGptCredentialStore};
@@ -77,15 +77,17 @@ export interface WithEveOptions {
77
77
  readonly devServerTimeoutMs?: number;
78
78
  /**
79
79
  * Path to the eve application root, relative to `process.cwd()` unless
80
- * absolute. Defaults to the Next.js app root.
80
+ * absolute. Defaults to the Next.js app root when it is not an eve workspace.
81
81
  */
82
82
  readonly eveRoot?: string;
83
83
  /**
84
84
  * Named eve agents to mount under `/eve/agents/<name>/eve/v1/*`.
85
85
  *
86
- * Use this when one Next.js app needs to talk to multiple eve agents. When
87
- * set, do not also set {@link eveRoot}; the single-agent form remains the
88
- * shorthand for one unnamed agent mounted at `/eve/v1/*`.
86
+ * Use this when one Next.js app needs to talk to multiple eve agents outside
87
+ * a project-level `agents/` workspace. When unset, withEve discovers that
88
+ * workspace's members automatically. Do not combine with {@link eveRoot};
89
+ * the single-agent form remains the shorthand for one unnamed agent mounted
90
+ * at `/eve/v1/*`.
89
91
  */
90
92
  readonly agents?: WithEveAgentsConfig;
91
93
  /**
@@ -1 +1 @@
1
- import{resolveEveDestinationPrefix}from"./server.js";import{ensureEveVercelOutputConfig}from"./vercel-output-config.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{isAbsolute,resolve}from"node:path";import{assertValidPublicAgentName}from"#internal/agent-name.js";import{quoteVercelShellArgument,toVercelRelativePath}from"#internal/vercel/build-command.js";import{resolveEveBinaryPath}from"#shared/resolve-eve-binary.js";const EVE_NEXT_SERVICE_PREFIX=`/_eve_internal/eve`,EVE_NEXT_PRODUCTION_PORT_ENV=`EVE_NEXT_PRODUCTION_PORT`;function resolveApplicationRoot(e){return e===void 0||e.length===0?process.cwd():isAbsolute(e)?e:resolve(process.cwd(),e)}function resolveDevServerTimeout(e){if(e!==void 0){if(!Number.isFinite(e)||e<=0)throw Error(`eve Next.js development server timeout must be a positive number.`);return e}}function normalizeRoutePrefix(e){let t=(e.startsWith(`/`)?e:`/${e}`).replace(/\/+$/,``);if(t.length===0)throw Error(`eve Next.js service prefix cannot resolve to the root route.`);return t}function joinRoutePrefix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function createNamedAgentRoutePrefix(e){return joinRoutePrefix(`/eve/agents`,e)}function createNamedAgentServicePrefix(e,t){return joinRoutePrefix(e,t)}function createAgentRewriteSource(e){return joinRoutePrefix(e,`${EVE_ROUTE_PREFIX}/:path+`)}function normalizeOrigin(e){return new URL(e.trim()).origin}function readLocalProductionPort(e){let t=process.env[EVE_NEXT_PRODUCTION_PORT_ENV],n=t===void 0||t.trim().length===0?4274:Number.parseInt(t,10);if(t!==void 0&&t.trim().length>0&&String(n)!==t.trim())throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} must be an integer between 1 and 65535.`);let r=n+e;if(r<1||r>65535)throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} plus the eve agent count exceeds 65535.`);return r}function resolveProductionDestination(e){if(process.env.VERCEL)return{destinationPrefix:e.servicePrefix};let t=process.env.EVE_NEXT_PRODUCTION_ORIGIN;if(t!==void 0&&t.trim().length>0)return{destinationPrefix:joinRoutePrefix(normalizeOrigin(t),e.servicePrefix)};let n=`http://127.0.0.1:${String(readLocalProductionPort(e.localProductionPortOffset))}`;return{destinationPrefix:n,localServerOrigin:n}}function createEveRewriteRule(e){let t=createAgentRewriteSource(e.publicRoutePrefix);return{destination:joinRoutePrefix(e.destinationPrefix,`${EVE_ROUTE_PREFIX}/:path+`),source:t}}async function resolveExistingRewrites(e){return await e?.()}function mergeRewriteRules(e,t){return e===void 0?{beforeFiles:t}:isRewriteSections(e)?{...e,beforeFiles:[...t,...e.beforeFiles??[]]}:{afterFiles:e,beforeFiles:t}}function isRewriteSections(e){return!Array.isArray(e)}async function resolveNextConfig(e,t,n){return typeof e==`function`?await e(t,n):e}function assertValidAgentName(e){assertValidPublicAgentName(e,`eve Next.js agent name`)}function createDefaultBuildCommand(e){let t=toVercelRelativePath(e.agentRoot,resolveEveBinaryPath(e.agentRoot));return`node ${quoteVercelShellArgument(t)} build`}function normalizeAgentsConfig(e){let t=normalizeRoutePrefix(e.servicePrefix??`/_eve_internal/eve`),resolveBuildCommand=(t,n)=>n??e.eveBuildCommand??createDefaultBuildCommand({agentRoot:t});if(e.agents===void 0){let n=resolveApplicationRoot(e.eveRoot);return[{appRoot:n,buildCommand:resolveBuildCommand(n,void 0),localProductionPortOffset:0,publicRoutePrefix:``,servicePrefix:t}]}if(e.eveRoot!==void 0)throw Error(`withEve cannot combine eveRoot with agents. Use one configuration form.`);let n=Object.entries(e.agents);if(n.length===0)throw Error(`withEve agents must contain at least one named eve agent.`);return n.map(([e,n],r)=>{assertValidAgentName(e);let i=typeof n==`string`?{root:n}:n,a=resolveApplicationRoot(i.root);return{appRoot:a,buildCommand:resolveBuildCommand(a,i.buildCommand),localProductionPortOffset:r,name:e,publicRoutePrefix:createNamedAgentRoutePrefix(e),servicePrefix:normalizeRoutePrefix(i.servicePrefix??createNamedAgentServicePrefix(t,e))}})}function withEve(e,t={}){let n=process.cwd(),r=resolveDevServerTimeout(t.devServerTimeoutMs),i=normalizeAgentsConfig(t);return async function(t,a){let o=await resolveNextConfig(e,t,a),s=o.rewrites,c=await ensureEveVercelOutputConfig({agents:i.map(e=>({appRoot:e.appRoot,buildCommand:e.buildCommand,name:e.name,publicRoutePrefix:e.publicRoutePrefix,servicePrefix:e.servicePrefix})),nextRoot:n});if(process.env.VERCEL)return o;let l=new Map(c.agents.map(e=>[e.name,e])),u=i.map(e=>{let t=l.get(e.name),n=resolveProductionDestination({localProductionPortOffset:e.localProductionPortOffset,servicePrefix:t?.servicePrefix??e.servicePrefix});return{...e,productionDestination:n}});return{...o,async rewrites(){let[e,n]=await Promise.all([resolveExistingRewrites(s),Promise.all(u.map(async e=>createEveRewriteRule({destinationPrefix:await resolveEveDestinationPrefix({appRoot:e.appRoot,devServerTimeoutMs:r,logLabel:e.name,phase:t,productionDestinationPrefix:e.productionDestination.destinationPrefix,productionServerOrigin:e.productionDestination.localServerOrigin}),publicRoutePrefix:e.publicRoutePrefix})))]);return mergeRewriteRules(e,n)}}}}export{EVE_NEXT_SERVICE_PREFIX,withEve};
1
+ import{resolveEveDestinationPrefix}from"./server.js";import{ensureEveVercelOutputConfig}from"./vercel-output-config.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{isAbsolute,resolve}from"node:path";import{findEveProjectContext}from"#internal/project-context.js";import{assertValidPublicAgentName}from"#internal/agent-name.js";import{quoteVercelShellArgument,toVercelRelativePath}from"#internal/vercel/build-command.js";import{resolveEveBinaryPath}from"#shared/resolve-eve-binary.js";const EVE_NEXT_SERVICE_PREFIX=`/_eve_internal/eve`,EVE_NEXT_PRODUCTION_PORT_ENV=`EVE_NEXT_PRODUCTION_PORT`;function resolveApplicationRoot(e){return e===void 0||e.length===0?process.cwd():isAbsolute(e)?e:resolve(process.cwd(),e)}function resolveDevServerTimeout(e){if(e!==void 0){if(!Number.isFinite(e)||e<=0)throw Error(`eve Next.js development server timeout must be a positive number.`);return e}}function normalizeRoutePrefix(e){let t=(e.startsWith(`/`)?e:`/${e}`).replace(/\/+$/,``);if(t.length===0)throw Error(`eve Next.js service prefix cannot resolve to the root route.`);return t}function joinRoutePrefix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function createNamedAgentRoutePrefix(e){return joinRoutePrefix(`/eve/agents`,e)}function createNamedAgentServicePrefix(e,t){return joinRoutePrefix(e,t)}function createAgentRewriteSource(e){return joinRoutePrefix(e,`${EVE_ROUTE_PREFIX}/:path+`)}function normalizeOrigin(e){return new URL(e.trim()).origin}function readLocalProductionPort(e){let t=process.env[EVE_NEXT_PRODUCTION_PORT_ENV],n=t===void 0||t.trim().length===0?4274:Number.parseInt(t,10);if(t!==void 0&&t.trim().length>0&&String(n)!==t.trim())throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} must be an integer between 1 and 65535.`);let r=n+e;if(r<1||r>65535)throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} plus the eve agent count exceeds 65535.`);return r}function resolveProductionDestination(e){if(process.env.VERCEL)return{destinationPrefix:e.servicePrefix};let t=process.env.EVE_NEXT_PRODUCTION_ORIGIN;if(t!==void 0&&t.trim().length>0)return{destinationPrefix:joinRoutePrefix(normalizeOrigin(t),e.servicePrefix)};let n=`http://127.0.0.1:${String(readLocalProductionPort(e.localProductionPortOffset))}`;return{destinationPrefix:n,localServerOrigin:n}}function createEveRewriteRule(e){let t=createAgentRewriteSource(e.publicRoutePrefix);return{destination:joinRoutePrefix(e.destinationPrefix,`${EVE_ROUTE_PREFIX}/:path+`),source:t}}async function resolveExistingRewrites(e){return await e?.()}function mergeRewriteRules(e,t){return e===void 0?{beforeFiles:t}:isRewriteSections(e)?{...e,beforeFiles:[...t,...e.beforeFiles??[]]}:{afterFiles:e,beforeFiles:t}}function isRewriteSections(e){return!Array.isArray(e)}async function resolveNextConfig(e,t,n){return typeof e==`function`?await e(t,n):e}function assertValidAgentName(e){assertValidPublicAgentName(e,`eve Next.js agent name`)}function assertValidWithEveOptions(e){if(e.agents===void 0)return;if(e.eveRoot!==void 0)throw Error(`withEve cannot combine eveRoot with agents. Use one configuration form.`);let t=Object.keys(e.agents);if(t.length===0)throw Error(`withEve agents must contain at least one named eve agent.`);for(let e of t)assertValidAgentName(e)}function createDefaultBuildCommand(e){let t=toVercelRelativePath(e.agentRoot,resolveEveBinaryPath(e.agentRoot));return`node ${quoteVercelShellArgument(t)} build`}async function normalizeAgentsConfig(e,t){let n=normalizeRoutePrefix(e.servicePrefix??`/_eve_internal/eve`),resolveBuildCommand=(t,n)=>n??e.eveBuildCommand??createDefaultBuildCommand({agentRoot:t});if(e.agents===void 0){if(e.eveRoot===void 0){let e=await findEveProjectContext(t);if(e?.kind===`workspace`&&e.workspace.root===t&&e.workspace.members.length>0)return e.workspace.members.map((e,t)=>({appRoot:e.appRoot,buildCommand:resolveBuildCommand(e.appRoot,void 0),localProductionPortOffset:t,name:e.name,publicRoutePrefix:createNamedAgentRoutePrefix(e.name),servicePrefix:createNamedAgentServicePrefix(n,e.name),workspaceMember:!0}))}let r=resolveApplicationRoot(e.eveRoot);return[{appRoot:r,buildCommand:resolveBuildCommand(r,void 0),localProductionPortOffset:0,publicRoutePrefix:``,servicePrefix:n}]}let r=Object.entries(e.agents);if(r.length===0)throw Error(`withEve agents must contain at least one named eve agent.`);return r.map(([e,t],r)=>{assertValidAgentName(e);let i=typeof t==`string`?{root:t}:t,a=resolveApplicationRoot(i.root);return{appRoot:a,buildCommand:resolveBuildCommand(a,i.buildCommand),localProductionPortOffset:r,name:e,publicRoutePrefix:createNamedAgentRoutePrefix(e),servicePrefix:normalizeRoutePrefix(i.servicePrefix??createNamedAgentServicePrefix(n,e))}})}function withEve(e,t={}){let n=process.cwd(),r=resolveDevServerTimeout(t.devServerTimeoutMs);return assertValidWithEveOptions(t),async function(i,a){let[o,s]=await Promise.all([normalizeAgentsConfig(t,n),resolveNextConfig(e,i,a)]),c=s.rewrites,l=await ensureEveVercelOutputConfig({agents:o.map(e=>{let t={appRoot:e.appRoot,buildCommand:e.buildCommand,name:e.name,publicRoutePrefix:e.publicRoutePrefix,servicePrefix:e.servicePrefix};return e.workspaceMember===!0&&(t.workspaceMember=!0),t}),nextRoot:n});if(process.env.VERCEL)return s;let u=new Map(l.agents.map(e=>[e.name,e])),d=o.map(e=>{let t=u.get(e.name),n=resolveProductionDestination({localProductionPortOffset:e.localProductionPortOffset,servicePrefix:t?.servicePrefix??e.servicePrefix});return{...e,productionDestination:n}});return{...s,async rewrites(){let[e,t]=await Promise.all([resolveExistingRewrites(c),Promise.all(d.map(async e=>createEveRewriteRule({destinationPrefix:await resolveEveDestinationPrefix({appRoot:e.appRoot,devServerTimeoutMs:r,logLabel:e.name,phase:i,productionDestinationPrefix:e.productionDestination.destinationPrefix,productionServerOrigin:e.productionDestination.localServerOrigin}),publicRoutePrefix:e.publicRoutePrefix})))]);return mergeRewriteRules(e,t)}}}}export{EVE_NEXT_SERVICE_PREFIX,withEve};
@@ -1,2 +1,2 @@
1
1
  import{mkdir,open,readFile,rm,stat,writeFile}from"node:fs/promises";import{join}from"node:path";import{resolvePackageRoot}from"#internal/application/package.js";import{existsSync}from"node:fs";import{spawn}from"node:child_process";import{readDevelopmentRuntimeArtifactsRevision}from"#services/dev-client/runtime-artifacts.js";const DEFAULT_SERVER_READY_TIMEOUT_MS=18e4,ANSI_ESCAPE_PATTERN=RegExp(`\x1B\\[[0-?]*[ -/]*[@-~]`,`g`),SERVER_URL_CANDIDATE_PATTERN=/https?:\/\/[^\s"'<>]+/g,globalStateSymbol=Symbol.for(`eve.next.state`);function getGlobalState(){let e=globalThis;return e[globalStateSymbol]??={servers:new Map},e[globalStateSymbol]}function normalizeOrigin(e){return new URL(e).origin}function readEveBaseUrlEnvironment(){let e=process.env.EVE_BASE_URL;if(e!==void 0&&e.trim().length!==0)return normalizeOrigin(e)}function isNodeErrorWithCode(e,t){return e instanceof Error&&`code`in e&&e.code===t}function delay(e){return new Promise(t=>setTimeout(t,e))}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function resolveEveCacheDirectory(e){return join(e,`.eve`)}function resolveEveDevServerRegistryPath(e){return join(resolveEveCacheDirectory(e),`next-dev-server.json`)}function resolveEveDevServerLockPath(e){return join(resolveEveCacheDirectory(e),`next-dev-server.lock`)}function normalizeDevServerRegistry(e){if(isRecord(e)&&typeof e.appRoot==`string`&&typeof e.origin==`string`&&typeof e.updatedAt==`string`&&(e.pid===null||typeof e.pid==`number`))try{return{appRoot:e.appRoot,origin:normalizeOrigin(e.origin),pid:e.pid,updatedAt:e.updatedAt}}catch{return}}async function readUsableEveDevServerRegistry(e){try{let t=normalizeDevServerRegistry(JSON.parse(await readFile(resolveEveDevServerRegistryPath(e),`utf8`)));return t===void 0||t.appRoot!==e||await readDevelopmentRuntimeArtifactsRevision({serverUrl:t.origin,timeoutMs:1e3})===void 0?void 0:t.origin}catch(e){if(isNodeErrorWithCode(e,`ENOENT`))return;throw e}}async function writeEveDevServerRegistry(e,t){await mkdir(resolveEveCacheDirectory(e),{recursive:!0}),await writeFile(resolveEveDevServerRegistryPath(e),`${JSON.stringify({appRoot:e,origin:t.origin,pid:t.process?.pid??null,updatedAt:new Date().toISOString()},null,2)}\n`)}async function removeStaleEveDevServerLock(e){try{let t=await stat(e);Date.now()-t.mtimeMs>3e4&&await rm(e,{force:!0})}catch(e){if(!isNodeErrorWithCode(e,`ENOENT`))throw e}}async function acquireEveDevServerLock(e,t){let n=resolveEveCacheDirectory(e),r=resolveEveDevServerLockPath(e),i=Date.now()+t;for(await mkdir(n,{recursive:!0});;)try{let e=await open(r,`wx`);return await e.writeFile(`${String(process.pid)}\n`),await e.close(),async()=>{await rm(r,{force:!0})}}catch(n){if(!isNodeErrorWithCode(n,`EEXIST`))throw n;if(await readUsableEveDevServerRegistry(e)!==void 0)return async()=>{};if(await removeStaleEveDevServerLock(r),Date.now()>i)throw Error(`Timed out after ${t}ms waiting for another Next.js process to start eve.`);await delay(100)}}function createEveBinaryPath(){return join(resolvePackageRoot(),`bin`,`eve.js`)}function isLoopbackHostname(e){return e===`localhost`||e===`::1`||e===`[::1]`||/^127(?:\.\d{1,3}){3}$/.test(e)}function parseLocalServerOrigin(e){let t=URL.parse(e);if(!(t===null||t.protocol!==`http:`&&t.protocol!==`https:`||!isLoopbackHostname(t.hostname)||t.port.length===0))return t.origin}function findLocalServerOrigin(e){for(let t of e.matchAll(SERVER_URL_CANDIDATE_PATTERN)){let e=t[0],n=parseLocalServerOrigin(e);if(n!==void 0)return n}}function formatEveDevOutputLine(e,t){let n=e.replace(/\r$/,``),r=n.replace(ANSI_ESCAPE_PATTERN,``).trim();if(r.length===0||/^☰eve\b/.test(r)||r===`CONFIGURATION_FIELD_CONFLICT`||r.startsWith(`[CONFIGURATION_FIELD_CONFLICT]`))return;let i=t===void 0?`[eve:dev]`:`[eve:dev:${t}]`,a=/server listening at\s+(https?:\/\/[^\s]+)/i.exec(n);return a===null?`${i} ${n}`:`${i} server listening at ${a[1]}`}function createEveDevOutputWriter(e){let t=``,writeLine=t=>{let n=formatEveDevOutputLine(t,e.logLabel);n!==void 0&&e.stream.write(`${n}\n`)};return{flush(){t.length!==0&&(writeLine(t),t=``)},write(e){t+=e.toString(`utf8`);let n=t.split(`
2
- `);t=n.pop()??``;for(let e of n)writeLine(e)}}}function startServerProcess(e){return new Promise((t,n)=>{let r=spawn(e.command,e.args,{cwd:e.cwd,env:{...process.env,...e.env},stdio:[`ignore`,`pipe`,`pipe`]}),i=createEveDevOutputWriter({logLabel:e.logLabel,stream:process.stderr}),a=createEveDevOutputWriter({logLabel:e.logLabel,stream:process.stdout}),o=setTimeout(()=>{r.kill(),n(Error(`Timed out after ${e.timeoutMs??DEFAULT_SERVER_READY_TIMEOUT_MS}ms waiting for eve to print its server URL.`))},e.timeoutMs??DEFAULT_SERVER_READY_TIMEOUT_MS),cleanup=()=>{clearTimeout(o),r.off(`error`,handleError),r.off(`exit`,handleEarlyExit)},flushOutput=()=>{a.flush(),i.flush()},handleError=e=>{flushOutput(),cleanup(),n(e)},handleEarlyExit=(e,t)=>{flushOutput(),cleanup(),n(Error(`eve server process exited before printing its server URL (code ${String(e)}, signal ${String(t)}).`))},handleOutput=e=>{let n=findLocalServerOrigin(e.toString(`utf8`));n!==void 0&&(cleanup(),t({origin:n,process:r}))};r.once(`error`,handleError),r.once(`exit`,handleEarlyExit),r.stdout.on(`data`,e=>{a.write(e),handleOutput(e)}),r.stderr.on(`data`,e=>{i.write(e),handleOutput(e)})})}function installProcessShutdown(e){let t=e.process;if(t===void 0)return e;let close=()=>{t.killed||t.kill()};return process.once(`beforeExit`,close),process.once(`exit`,close),e}function startEveDevServer(e,t,n){return startServerProcess({args:[createEveBinaryPath(),`dev`,`--no-ui`,`--port`,`0`],command:process.execPath,cwd:e,logLabel:n,timeoutMs:t}).then(e=>installProcessShutdown(e))}function startEveProductionServer(e){let t=new URL(e.origin),n=t.port,r=join(e.appRoot,`.output`,`server`,`index.mjs`);if(existsSync(r))return startServerProcess({args:[r],command:process.execPath,cwd:e.appRoot,env:{HOST:t.hostname,NITRO_HOST:t.hostname,NITRO_PORT:n,PORT:n}}).then(installProcessShutdown)}async function resolveSharedEveDevServer(e,t,n){let r=await readUsableEveDevServerRegistry(e);if(r!==void 0)return{origin:r};let i=await acquireEveDevServerLock(e,t);try{let r=await readUsableEveDevServerRegistry(e);if(r!==void 0)return{origin:r};let i=await startEveDevServer(e,t,n);return await writeEveDevServerRegistry(e,i),i}finally{await i()}}async function resolveEveDestinationPrefix(e){let t=getGlobalState();if(process.env.NODE_ENV===`production`){if(e.phase===`phase-production-build`)return e.productionDestinationPrefix;let n=`production:${e.appRoot}`,r=t.servers.get(n);return r===void 0&&(r=process.env.VERCEL||e.productionServerOrigin===void 0?void 0:startEveProductionServer({appRoot:e.appRoot,origin:e.productionServerOrigin}),r!==void 0&&(r=r.catch(e=>{throw t.servers.delete(n),e}),t.servers.set(n,r))),r===void 0?e.productionDestinationPrefix:(await r).origin}let n=readEveBaseUrlEnvironment();if(n!==void 0)return n;if(process.env.NODE_ENV!==`development`)return e.productionDestinationPrefix;let r=`dev:${e.appRoot}`,i=t.servers.get(r);return i===void 0&&(i=resolveSharedEveDevServer(e.appRoot,e.devServerTimeoutMs??18e4,e.logLabel).catch(e=>{throw t.servers.delete(r),e}),t.servers.set(r,i)),(await i).origin}export{resolveEveDestinationPrefix};
2
+ `);t=n.pop()??``;for(let e of n)writeLine(e)}}}function startServerProcess(e){return new Promise((t,n)=>{let r=spawn(e.command,e.args,{cwd:e.cwd,env:{...process.env,...e.env},stdio:[`ignore`,`pipe`,`pipe`]}),i=createEveDevOutputWriter({logLabel:e.logLabel,stream:process.stderr}),a=createEveDevOutputWriter({logLabel:e.logLabel,stream:process.stdout}),o=setTimeout(()=>{r.kill(),n(Error(`Timed out after ${e.timeoutMs??DEFAULT_SERVER_READY_TIMEOUT_MS}ms waiting for eve to print its server URL.`))},e.timeoutMs??DEFAULT_SERVER_READY_TIMEOUT_MS),cleanup=()=>{clearTimeout(o),r.off(`error`,handleError),r.off(`exit`,handleEarlyExit)},flushOutput=()=>{a.flush(),i.flush()},handleError=e=>{flushOutput(),cleanup(),n(e)},handleEarlyExit=(e,t)=>{flushOutput(),cleanup(),n(Error(`eve server process exited before printing its server URL (code ${String(e)}, signal ${String(t)}).`))},handleOutput=e=>{let n=findLocalServerOrigin(e.toString(`utf8`));n!==void 0&&(cleanup(),t({origin:n,process:r}))};r.once(`error`,handleError),r.once(`exit`,handleEarlyExit),r.stdout.on(`data`,e=>{a.write(e),handleOutput(e)}),r.stderr.on(`data`,e=>{i.write(e),handleOutput(e)})})}function installProcessShutdown(e){let t=e.process;if(t===void 0)return e;let close=()=>{t.killed||t.kill()};return process.once(`beforeExit`,close),process.once(`exit`,close),e}function startEveDevServer(e,t,n){return startServerProcess({args:[createEveBinaryPath(),`dev`,`--no-ui`,`--port`,`0`],command:process.execPath,cwd:e,logLabel:n,timeoutMs:t}).then(e=>installProcessShutdown(e))}function startEveProductionServer(e){let t=new URL(e.origin),n=t.port,r=join(e.appRoot,`.output`,`server`,`index.mjs`);if(!existsSync(r))throw Error(`eve production output is missing at ${r}. Run eve build from ${e.appRoot} before starting Next.js.`);return startServerProcess({args:[r],command:process.execPath,cwd:e.appRoot,env:{HOST:t.hostname,NITRO_HOST:t.hostname,NITRO_PORT:n,PORT:n}}).then(installProcessShutdown)}async function resolveSharedEveDevServer(e,t,n){let r=await readUsableEveDevServerRegistry(e);if(r!==void 0)return{origin:r};let i=await acquireEveDevServerLock(e,t);try{let r=await readUsableEveDevServerRegistry(e);if(r!==void 0)return{origin:r};let i=await startEveDevServer(e,t,n);return await writeEveDevServerRegistry(e,i),i}finally{await i()}}async function resolveEveDestinationPrefix(e){let t=getGlobalState();if(process.env.NODE_ENV===`production`){if(e.phase===`phase-production-build`)return e.productionDestinationPrefix;let n=`production:${e.appRoot}`,r=t.servers.get(n);return r===void 0&&(r=process.env.VERCEL||e.productionServerOrigin===void 0?void 0:startEveProductionServer({appRoot:e.appRoot,origin:e.productionServerOrigin}),r!==void 0&&(r=r.catch(e=>{throw t.servers.delete(n),e}),t.servers.set(n,r))),r===void 0?e.productionDestinationPrefix:(await r).origin}let n=readEveBaseUrlEnvironment();if(n!==void 0)return n;if(process.env.NODE_ENV!==`development`)return e.productionDestinationPrefix;let r=`dev:${e.appRoot}`,i=t.servers.get(r);return i===void 0&&(i=resolveSharedEveDevServer(e.appRoot,e.devServerTimeoutMs??18e4,e.logLabel).catch(e=>{throw t.servers.delete(r),e}),t.servers.set(r,i)),(await i).origin}export{resolveEveDestinationPrefix};
@@ -7,6 +7,7 @@ export interface EnsureVercelOutputConfigAgentInput {
7
7
  readonly name?: string;
8
8
  readonly publicRoutePrefix: string;
9
9
  readonly servicePrefix: string;
10
+ readonly workspaceMember?: boolean;
10
11
  }
11
12
  export interface EnsureVercelOutputConfigAgentResult {
12
13
  readonly name?: string;
@@ -1 +1 @@
1
- import{isObject}from"#shared/guards.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{evictScopedToken,resolveScopedToken}from"#runtime/connections/scoped-authorization.js";import{ConnectionAuthorizationRequiredError}from"#connections/errors.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{createMCPClient}from"#compiled/@ai-sdk/mcp/index.js";import{omitProvidedArgumentsFromSchema,resolveProvidedArguments}from"#runtime/connections/provided-arguments.js";var McpConnectionClient=class{#e;#t;#n;#r;#i;constructor(e){this.#i=e}async connect(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#a();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#a(){let e=await resolveHeaders(this.#i),t=this.#i.url;try{return await createMCPClient({transport:{type:`http`,url:t,headers:e}})}catch(n){if(!isMcpHttpFallbackRetryableError(n))throw n;return await createMCPClient({transport:{type:`sse`,url:t,headers:e}})}}async getToolMetadata(){return(await this.#o()).metadata}async getTools(){return(await this.#o()).tools}async executeTool(e,t,n){try{let{tools:r}=await this.#o(),i=r[e];if(i?.execute===void 0)throw Error(`Tool "${e}" not found in connection "${this.#i.connectionName}".`);let a=await resolveProvidedArguments({args:t,callId:n.callId,connection:this.#i,toolName:e});return await i.execute(a,{abortSignal:n.abortSignal})}catch(e){return await this.#l(e)}}async#o(){if(this.#r!==void 0)return this.#r;if(this.#n!==void 0)return this.#n;this.#n=this.#s();try{return this.#r=await this.#n,this.#r}catch(e){throw this.#n=void 0,e}}async#s(){try{return await this.#c()}catch(e){return await this.#l(e)}}async#c(){let e=await this.connect(),t=await e.listTools(),n=this.#i.tools,r=n===void 0?t.tools:t.tools.filter(e=>passesToolFilter(e.name,n)),i=Object.keys(this.#i.toolCall?.providedArguments??{}),a=r.map(e=>({...e,inputSchema:omitProvidedArgumentsFromSchema(e.inputSchema,i)})),o=e.toolsFromDefinitions({tools:a});return{metadata:a.map(e=>({annotations:e.annotations,description:e.description??``,inputSchema:e.inputSchema??{},name:e.name,outputSchema:`outputSchema`in e&&e.outputSchema!==void 0?e.outputSchema:void 0})),tools:o}}async close(){this.#t!==void 0&&(await this.#t.close(),this.#t=void 0),this.#e=void 0,this.#n=void 0,this.#r=void 0}async#l(e){throw isMcpAuthRequiredError(e)?(await this.#u(),await this.close(),new ConnectionAuthorizationRequiredError(this.#i.connectionName,{message:`Connection "${this.#i.connectionName}" requires authorization (the server rejected the token).`})):e}async#u(){let e=await resolveConnectionAuthorization(this.#i);e!==void 0&&await evictScopedToken({authorization:e,connection:{url:this.#i.url},instanceId:this.#i.instanceId,scope:this.#i.connectionName})}};function isMcpAuthRequiredError(e){return readHttpStatus(e)===401}function isMcpHttpFallbackRetryableError(e){let t=readHttpStatus(e);return t===400||t===404||t===405}function readHttpStatus(e){for(let t of walkErrorChain(e)){if(!isObject(t))continue;let e=readStatusField(t);if(e!==void 0)return e;let n=t.response;if(isObject(n)){let e=readStatusField(n);if(e!==void 0)return e}if(typeof t.message==`string`){let e=/\bHTTP\s+(\d{3})\b/u.exec(t.message);if(e?.[1]!==void 0)return Number(e[1])}}}function readStatusField(e){if(typeof e.status==`number`)return e.status;if(typeof e.statusCode==`number`)return e.statusCode}function*walkErrorChain(e){let t=e,n=new Set;for(;t!=null&&!n.has(t);){if(n.add(t),yield t,!isObject(t)||!(`cause`in t))return;t=t.cause}}function passesToolFilter(e,t){return t===void 0?!0:`allow`in t?t.allow.includes(e):!t.block.includes(e)}async function resolveHeaders(e){let t={},n,getCallbackContext=()=>n??=buildCallbackContext(),r=await resolveConnectionAuthorization(e,typeof e.authorization==`function`?getCallbackContext():void 0);if(r!==void 0&&(t.Authorization=`Bearer ${(await resolveToken(e,r)).token}`),e.headers!==void 0){let n=await resolveHeadersDefinition(e.headers,getCallbackContext);for(let[i,a]of Object.entries(n)){if(r!==void 0&&i.toLowerCase()===`authorization`)throw Error(`Connection "${e.connectionName}" headers must not include an "Authorization" key when "authorization" is also provided.`);t[i]=a}}return t}async function resolveToken(e,t){return await resolveScopedToken({authorization:t,connection:{url:e.url},instanceId:e.instanceId,scope:e.connectionName})}async function resolveHeadersDefinition(e,t){if(typeof e==`function`)return{...await e(t())};let n={},r=Object.entries(e);for(let[e,i]of r)n[e]=await resolveHeaderValue(i,t);return n}async function resolveHeaderValue(e,t){return typeof e==`function`?await e(t()):await e}export{McpConnectionClient,isMcpAuthRequiredError,passesToolFilter,resolveHeaders};
1
+ import{isObject}from"#shared/guards.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{evictScopedToken,resolveScopedToken}from"#runtime/connections/scoped-authorization.js";import{ConnectionAuthorizationRequiredError}from"#connections/errors.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{createMCPClient}from"#compiled/@ai-sdk/mcp/index.js";import{omitProvidedArgumentsFromSchema,resolveProvidedArguments}from"#runtime/connections/provided-arguments.js";var McpConnectionClient=class{#e;#t;#n;#r;#i;constructor(e){this.#i=e}async connect(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#a();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#a(){let e=await resolveHeaders(this.#i),t=this.#i.url;try{return await createMCPClient({protocolVersionDiscovery:this.#i.protocolVersionDiscovery,transport:{type:`http`,url:t,headers:e}})}catch(n){if(!isMcpHttpFallbackRetryableError(n))throw n;return await createMCPClient({protocolVersionDiscovery:this.#i.protocolVersionDiscovery,transport:{type:`sse`,url:t,headers:e}})}}async getToolMetadata(){return(await this.#o()).metadata}async getTools(){return(await this.#o()).tools}async executeTool(e,t,n){try{let{tools:r}=await this.#o(),i=r[e];if(i?.execute===void 0)throw Error(`Tool "${e}" not found in connection "${this.#i.connectionName}".`);let a=await resolveProvidedArguments({args:t,callId:n.callId,connection:this.#i,toolName:e});return await i.execute(a,{abortSignal:n.abortSignal})}catch(e){return await this.#l(e)}}async#o(){if(this.#r!==void 0)return this.#r;if(this.#n!==void 0)return this.#n;this.#n=this.#s();try{return this.#r=await this.#n,this.#r}catch(e){throw this.#n=void 0,e}}async#s(){try{return await this.#c()}catch(e){return await this.#l(e)}}async#c(){let e=await this.connect(),t=await e.listTools(),n=this.#i.tools,r=n===void 0?t.tools:t.tools.filter(e=>passesToolFilter(e.name,n)),i=Object.keys(this.#i.toolCall?.providedArguments??{}),a=r.map(e=>({...e,inputSchema:omitProvidedArgumentsFromSchema(e.inputSchema,i)})),o=e.toolsFromDefinitions({tools:a});return{metadata:a.map(e=>({annotations:e.annotations,description:e.description??``,inputSchema:e.inputSchema??{},name:e.name,outputSchema:`outputSchema`in e&&e.outputSchema!==void 0?e.outputSchema:void 0})),tools:o}}async close(){this.#t!==void 0&&(await this.#t.close(),this.#t=void 0),this.#e=void 0,this.#n=void 0,this.#r=void 0}async#l(e){throw isMcpAuthRequiredError(e)?(await this.#u(),await this.close(),new ConnectionAuthorizationRequiredError(this.#i.connectionName,{message:`Connection "${this.#i.connectionName}" requires authorization (the server rejected the token).`})):e}async#u(){let e=await resolveConnectionAuthorization(this.#i);e!==void 0&&await evictScopedToken({authorization:e,connection:{url:this.#i.url},instanceId:this.#i.instanceId,scope:this.#i.connectionName})}};function isMcpAuthRequiredError(e){return readHttpStatus(e)===401}function isMcpHttpFallbackRetryableError(e){let t=readHttpStatus(e);return t===400||t===404||t===405}function readHttpStatus(e){for(let t of walkErrorChain(e)){if(!isObject(t))continue;let e=readStatusField(t);if(e!==void 0)return e;let n=t.response;if(isObject(n)){let e=readStatusField(n);if(e!==void 0)return e}if(typeof t.message==`string`){let e=/\bHTTP\s+(\d{3})\b/u.exec(t.message);if(e?.[1]!==void 0)return Number(e[1])}}}function readStatusField(e){if(typeof e.status==`number`)return e.status;if(typeof e.statusCode==`number`)return e.statusCode}function*walkErrorChain(e){let t=e,n=new Set;for(;t!=null&&!n.has(t);){if(n.add(t),yield t,!isObject(t)||!(`cause`in t))return;t=t.cause}}function passesToolFilter(e,t){return t===void 0?!0:`allow`in t?t.allow.includes(e):!t.block.includes(e)}async function resolveHeaders(e){let t={},n,getCallbackContext=()=>n??=buildCallbackContext(),r=await resolveConnectionAuthorization(e,typeof e.authorization==`function`?getCallbackContext():void 0);if(r!==void 0&&(t.Authorization=`Bearer ${(await resolveToken(e,r)).token}`),e.headers!==void 0){let n=await resolveHeadersDefinition(e.headers,getCallbackContext);for(let[i,a]of Object.entries(n)){if(r!==void 0&&i.toLowerCase()===`authorization`)throw Error(`Connection "${e.connectionName}" headers must not include an "Authorization" key when "authorization" is also provided.`);t[i]=a}}return t}async function resolveToken(e,t){return await resolveScopedToken({authorization:t,connection:{url:e.url},instanceId:e.instanceId,scope:e.connectionName})}async function resolveHeadersDefinition(e,t){if(typeof e==`function`)return{...await e(t())};let n={},r=Object.entries(e);for(let[e,i]of r)n[e]=await resolveHeaderValue(i,t);return n}async function resolveHeaderValue(e,t){return typeof e==`function`?await e(t()):await e}export{McpConnectionClient,isMcpAuthRequiredError,passesToolFilter,resolveHeaders};
@@ -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{registerDefinitionSource,stampDefinitionKey}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.`),a={kind:`connection`,logicalPath:e.logicalPath,name:e.connectionName},o=`connection-source:${e.sourceId}`;stampDefinitionKey(i,o),registerDefinitionSource(o,a),registerDefinitionSource(`connection:${e.url}`,a);let s=i.auth!==void 0,c=i.headers!==void 0,l=e.protocol===`openapi`?i.operations:i.tools,u={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(s){if(typeof i.auth==`function`)u.authorization=i.auth;else try{u.authorization=normalizeAuthorizationSpec(i.auth,`Connection "${e.connectionName}" at "${e.logicalPath}":`)}catch(t){throw new ResolveAgentError(toErrorMessage(t),{logicalPath:e.logicalPath,sourceId:e.sourceId})}}return c&&(u.headers=i.headers),i.toolCall!==void 0&&(u.toolCall=i.toolCall),l!==void 0&&(u.tools=l),e.protocol===`openapi`&&i.spec!==void 0&&(u.spec=i.spec),typeof i.approval==`function`&&(u.approval=i.approval),u}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);let i={kind:`connection`,logicalPath:t.logicalPath,name:t.connectionName},a=`dynamic-connection-source:${t.sourceId}:${t.connectionName}`;if(stampDefinitionKey(e,a),registerDefinitionSource(a,i),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 o=normalizeMcpClientConnectionDefinition(e,r);return assertAuthenticatedDynamicInstanceKey(o.auth,o.instanceKey,r),omitUndefined({approval:o.approval,authorization:o.auth,connectionName:t.connectionName,description:o.description,exportName:t.exportName,headers:o.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:o.instanceKey,protocol:n,sourceId:t.sourceId,url:o.url}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,toolCall:o.toolCall,tools:o.tools,url:o.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{registerDefinitionSource,stampDefinitionKey}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.`),a={kind:`connection`,logicalPath:e.logicalPath,name:e.connectionName},o=`connection-source:${e.sourceId}`;stampDefinitionKey(i,o),registerDefinitionSource(o,a),registerDefinitionSource(`connection:${e.url}`,a);let s=i.auth!==void 0,c=i.headers!==void 0,l=e.protocol===`openapi`?i.operations:i.tools,u={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(s){if(typeof i.auth==`function`)u.authorization=i.auth;else try{u.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.`);u.protocolVersionDiscovery=i.protocolVersionDiscovery}return c&&(u.headers=i.headers),i.toolCall!==void 0&&(u.toolCall=i.toolCall),l!==void 0&&(u.tools=l),e.protocol===`openapi`&&i.spec!==void 0&&(u.spec=i.spec),typeof i.approval==`function`&&(u.approval=i.approval),u}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);let i={kind:`connection`,logicalPath:t.logicalPath,name:t.connectionName},a=`dynamic-connection-source:${t.sourceId}:${t.connectionName}`;if(stampDefinitionKey(e,a),registerDefinitionSource(a,i),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 o=normalizeMcpClientConnectionDefinition(e,r);return assertAuthenticatedDynamicInstanceKey(o.auth,o.instanceKey,r),omitUndefined({approval:o.approval,authorization:o.auth,connectionName:t.connectionName,description:o.description,exportName:t.exportName,headers:o.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:o.instanceKey,protocol:n,sourceId:t.sourceId,url:o.url}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,toolCall:o.toolCall,protocolVersionDiscovery:o.protocolVersionDiscovery,tools:o.tools,url:o.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 +1 @@
1
- import{getAdapterKind}from"#channel/adapter.js";import{ContextKey}from"#context/key.js";import{CHANNEL_CONTEXT_KEY_NAME}from"#context/key-names.js";import{buildChannelInstrumentationProjection}from"#channel/instrumentation.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{resolveDurableCompiledArtifactsSource,serializeDurableCompiledArtifactsSource}from"#runtime/durable-compiled-artifacts-source.js";import{deserializeRuntimeAdapter}from"#runtime/channels/registry.js";const ChannelKey=new ContextKey(CHANNEL_CONTEXT_KEY_NAME,{codec:{serialize(e){let t=buildChannelInstrumentationProjection({adapter:e});return{kind:getAdapterKind(e),state:e.state?{...e.state}:{},audience:t.metadata.audience}},deserialize(e,t){let n=t.get(BundleKey);if(n===void 0)throw Error(`Cannot deserialize "eve.channel" before "eve.bundle". The runtime bundle must be present in context.`);return deserializeRuntimeAdapter(n.adapterRegistry,e)}}}),BundleKey=new ContextKey(`eve.bundle`,{codec:{serialize:e=>({nodeId:e.nodeId,source:serializeDurableCompiledArtifactsSource(e.compiledArtifactsSource)}),deserialize:e=>{let{source:t,nodeId:n}=e;return getCompiledRuntimeAgentBundle({compiledArtifactsSource:resolveDurableCompiledArtifactsSource(t),nodeId:n})}}});export{BundleKey,ChannelKey};
1
+ import{getAdapterKind}from"#channel/adapter.js";import{ContextKey}from"#context/key.js";import{CHANNEL_CONTEXT_KEY_NAME}from"#context/key-names.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{resolveDurableCompiledArtifactsSource,serializeDurableCompiledArtifactsSource}from"#runtime/durable-compiled-artifacts-source.js";import{deserializeRuntimeAdapter}from"#runtime/channels/registry.js";const ChannelKey=new ContextKey(CHANNEL_CONTEXT_KEY_NAME,{codec:{serialize(e){return{kind:getAdapterKind(e),state:e.state?{...e.state}:{}}},deserialize(e,t){let n=t.get(BundleKey);if(n===void 0)throw Error(`Cannot deserialize "eve.channel" before "eve.bundle". The runtime bundle must be present in context.`);return deserializeRuntimeAdapter(n.adapterRegistry,e)}}}),BundleKey=new ContextKey(`eve.bundle`,{codec:{serialize:e=>({nodeId:e.nodeId,source:serializeDurableCompiledArtifactsSource(e.compiledArtifactsSource)}),deserialize:e=>{let{source:t,nodeId:n}=e;return getCompiledRuntimeAgentBundle({compiledArtifactsSource:resolveDurableCompiledArtifactsSource(t),nodeId:n})}}});export{BundleKey,ChannelKey};
@@ -78,6 +78,7 @@ export type ResolvedScheduleDefinition = Readonly<SourceRef & {
78
78
  * server that requires no authentication (e.g. localhost) may omit both.
79
79
  */
80
80
  export interface ResolvedConnectionDefinition extends ResolvedModuleSourceRef {
81
+ readonly protocolVersionDiscovery?: boolean;
81
82
  readonly approval?: Approval;
82
83
  readonly authorization?: Readonly<AuthorizationDefinition> | ConnectionAuthResolver;
83
84
  readonly connectionName: string;
@@ -1,4 +1,4 @@
1
- import { type AgentStaticModelDefinition } from "#public/index.js";
1
+ import { type AgentReasoningDefinition, type AgentStaticModelDefinition } from "#public/index.js";
2
2
  import { type SelfModificationConfig } from "./config.js";
3
3
  /** Default model used by the self-modification subagent. */
4
4
  export declare const DEFAULT_SELF_MODIFICATION_MODEL = "anthropic/claude-sonnet-5";
@@ -12,14 +12,20 @@ export interface SelfModificationAgentOptions {
12
12
  * @default "anthropic/claude-sonnet-5"
13
13
  */
14
14
  readonly model?: AgentStaticModelDefinition;
15
+ /**
16
+ * Reasoning effort used by the self-modification subagent.
17
+ */
18
+ readonly reasoning?: AgentReasoningDefinition;
15
19
  }
16
20
  /** Defines the environment-aware self-modification dynamic subagent. */
17
21
  export declare function defineSelfModificationAgent(options?: SelfModificationAgentOptions): import("#dynamic/definition.js").DynamicSentinel<import("#public/index.js").DefinedAgent<{
18
22
  description: string;
19
23
  model: AgentStaticModelDefinition;
24
+ reasoning: AgentReasoningDefinition | undefined;
20
25
  }> | null>;
21
26
  declare const _default: import("#dynamic/definition.js").DynamicSentinel<import("#public/index.js").DefinedAgent<{
22
27
  description: string;
23
28
  model: AgentStaticModelDefinition;
29
+ reasoning: AgentReasoningDefinition | undefined;
24
30
  }> | null>;
25
31
  export default _default;
@@ -1 +1 @@
1
- import{resolveSelfModificationConfig}from"./config.js";import{hasGitHubCredential}from"./credentials.js";import{resolveSelfModificationMode}from"./mode.js";import{defineAgent,defineDynamic}from"#public/index.js";const DEFAULT_SELF_MODIFICATION_MODEL=`anthropic/claude-sonnet-5`;function renderDescription(e){return e.filter(e=>e.length>0).join(` `)}function defineSelfModificationAgent(e={}){let t=e.model??`anthropic/claude-sonnet-5`,n=resolveSelfModificationConfig(e.config),resolve=async(e,r)=>{let i=resolveSelfModificationMode(n),a=renderDescription([`Delegate here when the user asks to change this eve agent or its authored source.`,`If the requested change references a tool or skill, include the exact identifier. Do not infer source paths; let the child resolve the appropriate file under /source. Delegate the requested change and existing constraints without adding unrequested features, implementation steps, or reporting requirements.`,`Treat requests for persistent changes to future behavior or capabilities as source-modification requests, even when the requester does not mention files or source code. Infer persistence from the request and conversation rather than waiting for phrases such as “modify your source.” For example, asking the agent to stop always doing something, add a capability, or change future responses calls for inspecting and editing the authored source instead of providing a one-turn workaround.`,i===`local`?`Delegate questions about which integrations, channels, connections, or capabilities are available to add: the subagent searches the eve registry and reports exact item addresses instead of guessing them.`:`Delegate requests to add integrations, channels, connections, or capabilities: the subagent searches the official eve registry and can install source changes into the draft proposal. Setup may require non-secret answers or an external action, and secret binding remains separate.`,i===`local`?`Delegate requests to investigate, diagnose, or optimize the agent's behavior from local traces to this subagent: it can inspect the invoking session's trace and make persistent source changes when warranted.`:``,`Resolve short follow-ups such as “yes” or “do it” against the preceding conversation. If whether the requested change should persist is genuinely ambiguous, ask one concise clarifying question.`,i===`local`?`Source edits do not affect the caller’s current turn. After this subagent reports changes, do not invoke edited tools or attempt runtime verification until a new user turn.`:`Source edits do not affect the caller’s current turn. The subagent can publish only a draft pull request, and changes become effective only after review, merge, and redeployment.`]);if(i===`local`)return defineAgent({description:a,model:t});if(i!==`deployed`||n.deployed===void 0||n.deployed.credentials.kind===`pat`&&!hasGitHubCredential())return null;try{if(!await n.deployed.authorize({channel:r.channel,principal:r.session.auth.current}))return null}catch{return null}return defineAgent({description:a,model:t})};return defineDynamic({events:{"session.started":resolve,"turn.started":resolve}})}var agent_default=defineSelfModificationAgent();export{DEFAULT_SELF_MODIFICATION_MODEL,agent_default as default,defineSelfModificationAgent};
1
+ import{resolveSelfModificationConfig}from"./config.js";import{hasGitHubCredential}from"./credentials.js";import{resolveSelfModificationMode}from"./mode.js";import{defineAgent,defineDynamic}from"#public/index.js";const DEFAULT_SELF_MODIFICATION_MODEL=`anthropic/claude-sonnet-5`;function renderDescription(e){return e.filter(e=>e.length>0).join(` `)}function defineSelfModificationAgent(e={}){let t=e.model??`anthropic/claude-sonnet-5`,n=e.reasoning,r=resolveSelfModificationConfig(e.config),resolve=async(e,i)=>{let a=resolveSelfModificationMode(r),o=renderDescription([`Delegate here when the user asks to change this eve agent or its authored source.`,`If the requested change references a tool or skill, include the exact identifier. Do not infer source paths; let the child resolve the appropriate file under /source. Delegate the requested change and existing constraints without adding unrequested features, implementation steps, or reporting requirements.`,`Treat requests for persistent changes to future behavior or capabilities as source-modification requests, even when the requester does not mention files or source code. Infer persistence from the request and conversation rather than waiting for phrases such as “modify your source.” For example, asking the agent to stop always doing something, add a capability, or change future responses calls for inspecting and editing the authored source instead of providing a one-turn workaround.`,`Treat questions phrased as whether you can install, add, enable, or connect to a named product or service as requests to extend this eve agent and delegate immediately. Do not assume they refer to device software, ask what kind of installation they mean, or deny them because you lack access to the user's device. The subagent determines whether the request maps to an integration, channel, connection, or other capability, then checks registry availability and any required setup.`,a===`local`?`Delegate questions about which integrations, channels, connections, or capabilities are available to add: the subagent searches the eve registry and reports exact item addresses instead of guessing them.`:`Delegate requests to add integrations, channels, connections, or capabilities: the subagent searches the official eve registry and can install source changes into the draft proposal. Setup may require non-secret answers or an external action, and secret binding remains separate.`,a===`local`?`Delegate requests to investigate, diagnose, or optimize the agent's behavior from local traces to this subagent: it can inspect the invoking session's trace and make persistent source changes when warranted.`:``,`Resolve short follow-ups such as “yes” or “do it” against the preceding conversation. If whether the requested change should persist is genuinely ambiguous, ask one concise clarifying question.`,a===`local`?`Source edits do not affect the caller’s current turn. After this subagent reports changes, do not invoke edited tools or attempt runtime verification until a new user turn.`:`Source edits do not affect the caller’s current turn. The subagent can publish only a draft pull request, and changes become effective only after review, merge, and redeployment.`]);if(a===`local`)return defineAgent({description:o,model:t,reasoning:n});if(a!==`deployed`||r.deployed===void 0||r.deployed.credentials.kind===`pat`&&!hasGitHubCredential())return null;try{if(!await r.deployed.authorize({channel:i.channel,principal:i.session.auth.current}))return null}catch{return null}return defineAgent({description:o,model:t,reasoning:n})};return defineDynamic({events:{"session.started":resolve,"turn.started":resolve}})}var agent_default=defineSelfModificationAgent();export{DEFAULT_SELF_MODIFICATION_MODEL,agent_default as default,defineSelfModificationAgent};
@@ -10,7 +10,11 @@ Resolve named tools by filename under /source/tools before searching contents. T
10
10
 
11
11
  Use selfmod__edit_file for localized changes; include only the unique matching text. For a complete rewrite, use read_file then write_file; do not encode the whole old file as one replacement. If tool arguments fail argument parsing, retry the same tool with corrected encoding.
12
12
 
13
- Once paths are known, batch independent file reads and edits to different files. Never edit the same file concurrently.`,`## Add integrations
13
+ Once paths are known, batch independent file reads and edits to different files. Never edit the same file concurrently.`,`## Add model-callable actions
14
+
15
+ When the requester wants this agent to gain a reusable action or capability that it can invoke in future turns, implement it as an authored eve tool under /source/tools. This applies even when the request describes the action without using the word “tool.” Follow the path-derived naming and defineTool conventions in the mounted eve tools documentation and existing source.
16
+
17
+ Do not substitute a loose Python, shell, or JavaScript file for a model-callable tool. A support script is acceptable only when an authored eve tool invokes it as an implementation detail, or when the requester explicitly asks for a standalone script instead of an agent capability.`,`## Add integrations
14
18
 
15
19
  Before adding a new eve-managed channel, connection, extension, instrumentation, or memory integration, call selfmod__search_registry alongside source discovery. If an item fulfills the requirement, install it with selfmod__registry_add using its exact address. If no matching item fulfills the requirement, or if the developer asks for a custom implementation, write the integration yourself.
16
20
 
@@ -18,14 +22,7 @@ Modifying the behavior of an existing skill or tool does not require a registry
18
22
 
19
23
  Registry installation is outside the source sandbox.`,`## Consult documentation
20
24
 
21
- The eve framework documentation is mounted read-only at /eve-docs. Prefer source and existing local patterns. Before reading docs, identify the specific unresolved API question. Search the relevant file for its heading or term, then read only the bounded surrounding section. Do not concatenate wildcard files or read a full page when a section answers the question. Stop when the question is resolved.`,t===`local`?`## Local environment
22
-
23
- The selfmod__registry_add tool will complete installation for items that need no setup. In the local dev TUI, a \`needs-terminal\` result from the tool call automatically opens the existing setup panel for the user to complete setup there. In headless development, relay the terminal command the tool names.
24
-
25
- Local eve dev logs are available read-only at /logs.
26
- Local trace segments are mounted read-only at /traces when available. Inspect other traces only when the user asks about another session or broader behavior.
27
-
28
- The application package.json is not mounted. Do not search outside /source for application files. You cannot run host binaries such as git, node, pnpm, or tsc. Use existing imports and selfmod__registry_add for supported registry installations.`:"## Deployed environment\n\nThe selfmod__registry_add tool may return `completed`, `input-required`, `external-action-required`, `cancelled`, or `failed`. Supply only non-secret structured answers when continuing an `input-required` setup; set `installed: true` so the continuation does not reinstall source. Never request, accept, or repeat secret values. External authorization and secret binding are incomplete follow-up boundaries, not evidence that an integration is active.\n\nThe configured target branch is checked out as a disposable workspace under /workspace/repository. Make ordinary changes through /source, which is the writable view of the configured application's agent/ directory. Publication validates the final repository snapshot, including registry, manifest, and lockfile changes. Never modify Git refs, access GitHub directly, or use shell commands to write files. The sandbox has no reusable GitHub credential after checkout.\n\nComplete all edits and registry installations before publication, and call publish by itself. Before publication, review and summarize the complete intended scope. Call publish once with a concise title and summary. A successful result is only a draft pull request. Return its URL and changed paths, and state that merge and deployment have not occurred.",t===`local`?localTraceGuidance(e):``,`## Work efficiently
25
+ The eve framework documentation is mounted read-only at /eve-docs. Prefer source and existing local patterns. Before reading docs, identify the specific unresolved API question. Search the relevant file for its heading or term, then read only the bounded surrounding section. Do not concatenate wildcard files or read a full page when a section answers the question. Stop when the question is resolved.`,t===`local`?"## Local environment\n\nThe selfmod__registry_add tool will complete installation for items that need no setup. In the local dev TUI, a `needs-terminal` result from the tool call automatically opens the existing setup panel for the user to complete setup there. In headless development, if a `needs-terminal` result includes `nextCommand`, present that exact value as the only shell command in your response. Never infer, construct, or rewrite a command: installing an item uses `eve add <item>`; `eve registry add` configures registry namespace mappings and does not install items.\n\nLocal eve dev logs are available read-only at /logs.\nLocal trace segments are mounted read-only at /traces when available. Inspect other traces only when the user asks about another session or broader behavior.\n\nThe application package.json is not mounted. Do not search outside /source for application files. You cannot run host binaries such as git, node, pnpm, or tsc. Use existing imports and selfmod__registry_add for supported registry installations.":"## Deployed environment\n\nThe selfmod__registry_add tool may return `completed`, `input-required`, `external-action-required`, `cancelled`, or `failed`. Supply only non-secret structured answers when continuing an `input-required` setup; set `installed: true` so the continuation does not reinstall source. Never request, accept, or repeat secret values. External authorization and secret binding are incomplete follow-up boundaries, not evidence that an integration is active.\n\nThe configured target branch is checked out as a disposable workspace under /workspace/repository. Make ordinary changes through /source, which is the writable view of the configured application's agent/ directory. Publication validates the final repository snapshot, including registry, manifest, and lockfile changes. Never modify Git refs, access GitHub directly, or use shell commands to write files. The sandbox has no reusable GitHub credential after checkout.\n\nComplete all edits and registry installations before publication, and call publish by itself. Before publication, review and summarize the complete intended scope. Call publish once with a concise title and summary. A successful result is only a draft pull request. Return its URL and changed paths, and state that merge and deployment have not occurred.",t===`local`?localTraceGuidance(e):``,`## Work efficiently
29
26
 
30
27
  Skip task lists for simple work - only use them for complex actions. Never spend a turn only reporting status or updating the task list - batch them with other calls.
31
28
 
@@ -1 +1 @@
1
- import{createHash,randomBytes}from"node:crypto";import{createServer}from"node:http";import{spawn}from"node:child_process";import{WizardCancelledError}from"#setup/step.js";import{createProcessOutputBuffer}from"#setup/primitives/process-output.js";import{isErrnoCode,isObject}from"#shared/guards.js";import{setTimeout as setTimeout$1}from"node:timers/promises";import{getDefaultCodexTokenBroker}from"#public/models/openai/chatgpt/token-broker.js";import{ChatGptInvalidStoredSessionError,getDefaultChatGptCredentialStore}from"#public/models/openai/chatgpt/credential-store.js";import{CHATGPT_CLIENT_ID,CHATGPT_ISSUER,readChatGptAuthResponse,requestChatGptTokens}from"#public/models/openai/chatgpt/oauth.js";import{openUrl}from"#setup/primitives/open-url.js";const REDIRECT_URI=`http://localhost:1455/auth/callback`;async function ensureChatGptAuth(e={}){let t=e.broker??getDefaultCodexTokenBroker(),n=e.store??getDefaultChatGptCredentialStore();e.signal?.throwIfAborted();let r=await t.refreshState();if(r.kind===`ready`)return;let i=t.credentialOwner();if(i===void 0)throw Error(`ChatGPT credential owner could not be resolved.`);if(i===`codex`){if(r.kind===`unavailable`)throw Error(r.reason);try{let n=e.log??(e=>process.stdout.write(`${e}\n`));await(e.codexLogin??(e=>loginWithCodex(e,n)))(e.signal),await assertChatGptAuthReady(t,`Codex login completed without a usable ChatGPT session.`);return}catch(e){if(!isErrnoCode(e,`ENOENT`))throw e;let n=await t.refreshState();if(t.credentialOwner()!==`eve`)throw e;if(n.kind===`ready`)return;if(n.kind===`unavailable`)throw Error(n.reason)}}try{await n.read()}catch(e){if(!(e instanceof ChatGptInvalidStoredSessionError))throw e}await signInWithOwnedCredentials(e,t,n)}async function signInWithOwnedCredentials(e,t,n){let r=new AbortController,cancel=()=>r.abort(new WizardCancelledError);process.once(`SIGINT`,cancel);let i=setTimeout(()=>r.abort(Error(`ChatGPT sign-in timed out. Retry from /model.`)),3e5),a=AbortSignal.any([r.signal,...e.signal?[e.signal]:[]]),o=e.log??(e=>process.stdout.write(`${e}\n`)),s=e.open??openUrl;try{let r=e.headless??!!(process.env.SSH_CONNECTION||process.env.SSH_TTY)?await deviceLogin({...e,signal:a,log:o,open:s}):await browserLogin({...e,signal:a,log:o,open:s});a.throwIfAborted(),await n.update(async()=>(a.throwIfAborted(),r),{replace:!0}),await assertChatGptAuthReady(t,`ChatGPT sign-in could not be verified. Retry from /model.`),o(`ChatGPT subscription connected.`)}catch(e){throw a.throwIfAborted(),e}finally{clearTimeout(i),process.removeListener(`SIGINT`,cancel)}}async function assertChatGptAuthReady(e,t){if((await e.refreshState()).kind!==`ready`)throw Error(t)}async function loginWithCodex(e,t){let n=spawn(`codex`,[`login`],{stdio:[`ignore`,`pipe`,`pipe`],...e!==void 0&&{signal:e}}),r=createProcessOutputBuffer(({text:e})=>t(e));n.stdout.on(`data`,e=>r.write(`stdout`,e)),n.stderr.on(`data`,e=>r.write(`stderr`,e));try{await new Promise((e,t)=>{n.once(`error`,t),n.once(`close`,(n,r)=>{n===0?e():t(Error(`codex login failed (${r??n??`unknown`}).`))})})}finally{r.flush()}}async function browserLogin(e){let t=randomBytes(32).toString(`base64url`),n=randomBytes(32).toString(`base64url`),r=new URL(`${CHATGPT_ISSUER}/oauth/authorize`);r.search=new URLSearchParams({response_type:`code`,client_id:CHATGPT_CLIENT_ID,redirect_uri:REDIRECT_URI,scope:`openid profile email offline_access`,code_challenge:createHash(`sha256`).update(t).digest(`base64url`),code_challenge_method:`S256`,id_token_add_organizations:`true`,codex_cli_simplified_flow:`true`,state:n,originator:`eve`}).toString();let i=Promise.withResolvers();i.promise.catch(()=>{});let a=createServer({requestTimeout:1e4,headersTimeout:1e4,maxHeaderSize:8192},(e,t)=>{let r=URL.parse(e.url??``,REDIRECT_URI);if(t.setHeader(`content-type`,`text/plain; charset=utf-8`),t.setHeader(`cache-control`,`no-store`),e.method!==`GET`||r?.pathname!==`/auth/callback`){t.writeHead(404).end(`Not found.`);return}if(r.searchParams.get(`state`)!==n){t.writeHead(400).end(`This sign-in belongs to another attempt. Return to eve and use its sign-in link.`);return}if(r.searchParams.has(`error`)){t.writeHead(400).end(`ChatGPT sign-in was declined. Return to eve to retry.`),i.reject(Error(`ChatGPT sign-in was declined. Retry from /model.`));return}let a=r.searchParams.get(`code`);if(!a){t.writeHead(400).end(`Missing authorization code.`);return}t.end(`Authorization received. Return to eve to finish connecting your ChatGPT subscription.`),i.resolve(a)});a.maxConnections=10;let abort=()=>i.reject(e.signal.reason);e.signal.addEventListener(`abort`,abort,{once:!0});try{e.signal.throwIfAborted();try{await new Promise((e,t)=>{a.once(`error`,t),a.listen(1455,`127.0.0.1`,e)})}catch(t){if(!isErrnoCode(t,`EADDRINUSE`))throw Error(`Could not start ChatGPT sign-in on localhost:1455. Free the port and retry from /model.`);return e.log(`Local sign-in port is in use. Continuing with a device code.`),await deviceLogin(e)}e.signal.throwIfAborted(),e.log(`Sign in to ChatGPT in your browser:\n${r.href}\nWaiting for sign-in. Press Ctrl+C to cancel.`),e.open(r.href);let n=await i.promise;return await requestChatGptTokens({grant_type:`authorization_code`,code:n,code_verifier:t,redirect_uri:REDIRECT_URI},e)}finally{e.signal.removeEventListener(`abort`,abort),a.closeAllConnections(),await new Promise(e=>a.close(()=>e()))}}async function deviceLogin(e){let t=await deviceRequest(`usercode`,{client_id:CHATGPT_CLIENT_ID},e);if(!t.ok)throw Error(`ChatGPT device sign-in is unavailable (HTTP ${t.status}). Enable device code authorization in ChatGPT Settings > Security, then retry from /model.`);let n=await readChatGptAuthResponse(t);if(!isObject(n)||typeof n.device_auth_id!=`string`||!n.device_auth_id||typeof n.user_code!=`string`||!/^[A-Z0-9-]{4,32}$/iu.test(n.user_code))throw Error(`ChatGPT returned an invalid device code. Retry from /model.`);let r=Math.min(30,Math.max(1,Number(n.interval)||5))*1e3,i=`${CHATGPT_ISSUER}/codex/device`;for(e.log(`Open ${i} and enter code: ${n.user_code}\nIf prompted, enable device code authorization in ChatGPT Settings > Security.\nWaiting for sign-in. Press Ctrl+C to cancel.`),e.open(i);;){await setTimeout$1(r+1e3,void 0,{signal:e.signal});let t=await deviceRequest(`token`,{device_auth_id:n.device_auth_id,user_code:n.user_code},e);if(t.status===403||t.status===404)continue;if(!t.ok)throw Error(`ChatGPT device sign-in failed (HTTP ${t.status}). Retry from /model.`);let i=await readChatGptAuthResponse(t);if(!isObject(i)||typeof i.authorization_code!=`string`||!i.authorization_code||typeof i.code_verifier!=`string`||!i.code_verifier)throw Error(`ChatGPT returned an invalid device authorization. Retry from /model.`);return requestChatGptTokens({grant_type:`authorization_code`,code:i.authorization_code,code_verifier:i.code_verifier,redirect_uri:`${CHATGPT_ISSUER}/deviceauth/callback`},e)}}async function deviceRequest(e,t,n){try{return await(n.fetch??fetch)(`${CHATGPT_ISSUER}/api/accounts/deviceauth/${e}`,{method:`POST`,headers:{"content-type":`application/json`,"user-agent":`eve`},body:JSON.stringify(t),redirect:`error`,signal:AbortSignal.any([n.signal,AbortSignal.timeout(3e4)])})}catch{throw n.signal.throwIfAborted(),Error(`Could not reach ChatGPT device sign-in. Check your connection and retry from /model.`)}}export{ensureChatGptAuth};
1
+ import{createHash,randomBytes}from"node:crypto";import{isErrnoCode,isObject}from"#shared/guards.js";import{createServer}from"node:http";import{spawn}from"node:child_process";import{WizardCancelledError}from"#setup/step.js";import{createProcessOutputBuffer}from"#setup/primitives/process-output.js";import{setTimeout as setTimeout$1}from"node:timers/promises";import{getDefaultCodexTokenBroker}from"#public/models/openai/chatgpt/token-broker.js";import{ChatGptInvalidStoredSessionError,getDefaultChatGptCredentialStore}from"#public/models/openai/chatgpt/credential-store.js";import{CHATGPT_CLIENT_ID,CHATGPT_ISSUER,readChatGptAuthResponse,requestChatGptTokens}from"#public/models/openai/chatgpt/oauth.js";import{openUrl}from"#setup/primitives/open-url.js";const REDIRECT_URI=`http://localhost:1455/auth/callback`;async function ensureChatGptAuth(e={}){let t=e.broker??getDefaultCodexTokenBroker(),n=e.store??getDefaultChatGptCredentialStore();e.signal?.throwIfAborted();let r=await t.refreshState();if(r.kind===`ready`)return;let i=t.credentialOwner();if(i===void 0)throw Error(`ChatGPT credential owner could not be resolved.`);if(i===`codex`){if(r.kind===`unavailable`)throw Error(r.reason);try{let n=e.log??(e=>process.stdout.write(`${e}\n`));await(e.codexLogin??(e=>loginWithCodex(e,n)))(e.signal),await assertChatGptAuthReady(t,`Codex login completed without a usable ChatGPT session.`);return}catch(e){if(!isErrnoCode(e,`ENOENT`))throw e;let n=await t.refreshState();if(t.credentialOwner()!==`eve`)throw e;if(n.kind===`ready`)return;if(n.kind===`unavailable`)throw Error(n.reason)}}try{await n.read()}catch(e){if(!(e instanceof ChatGptInvalidStoredSessionError))throw e}await signInWithOwnedCredentials(e,t,n)}async function signInWithOwnedCredentials(e,t,n){let r=new AbortController,cancel=()=>r.abort(new WizardCancelledError);process.once(`SIGINT`,cancel);let i=setTimeout(()=>r.abort(Error(`ChatGPT sign-in timed out. Retry from /model.`)),3e5),a=AbortSignal.any([r.signal,...e.signal?[e.signal]:[]]),o=e.log??(e=>process.stdout.write(`${e}\n`)),s=e.open??openUrl;try{let r=e.headless??!!(process.env.SSH_CONNECTION||process.env.SSH_TTY)?await deviceLogin({...e,signal:a,log:o,open:s}):await browserLogin({...e,signal:a,log:o,open:s});a.throwIfAborted(),await n.update(async()=>(a.throwIfAborted(),r),{replace:!0}),await assertChatGptAuthReady(t,`ChatGPT sign-in could not be verified. Retry from /model.`),o(`ChatGPT subscription connected.`)}catch(e){throw a.throwIfAborted(),e}finally{clearTimeout(i),process.removeListener(`SIGINT`,cancel)}}async function assertChatGptAuthReady(e,t){if((await e.refreshState()).kind!==`ready`)throw Error(t)}async function loginWithCodex(e,t){let n=spawn(`codex`,[`login`],{stdio:[`ignore`,`pipe`,`pipe`],...e!==void 0&&{signal:e}}),r=createProcessOutputBuffer(({text:e})=>t(e));n.stdout.on(`data`,e=>r.write(`stdout`,e)),n.stderr.on(`data`,e=>r.write(`stderr`,e));try{await new Promise((e,t)=>{n.once(`error`,t),n.once(`close`,(n,r)=>{n===0?e():t(Error(`codex login failed (${r??n??`unknown`}).`))})})}finally{r.flush()}}async function browserLogin(e){let t=randomBytes(32).toString(`base64url`),n=randomBytes(32).toString(`base64url`),r=new URL(`${CHATGPT_ISSUER}/oauth/authorize`);r.search=new URLSearchParams({response_type:`code`,client_id:CHATGPT_CLIENT_ID,redirect_uri:REDIRECT_URI,scope:`openid profile email offline_access`,code_challenge:createHash(`sha256`).update(t).digest(`base64url`),code_challenge_method:`S256`,id_token_add_organizations:`true`,codex_cli_simplified_flow:`true`,state:n,originator:`eve`}).toString();let i=Promise.withResolvers();i.promise.catch(()=>{});let a=createServer({requestTimeout:1e4,headersTimeout:1e4,maxHeaderSize:8192},(e,t)=>{let r=URL.parse(e.url??``,REDIRECT_URI);if(t.setHeader(`content-type`,`text/plain; charset=utf-8`),t.setHeader(`cache-control`,`no-store`),e.method!==`GET`||r?.pathname!==`/auth/callback`){t.writeHead(404).end(`Not found.`);return}if(r.searchParams.get(`state`)!==n){t.writeHead(400).end(`This sign-in belongs to another attempt. Return to eve and use its sign-in link.`);return}if(r.searchParams.has(`error`)){t.writeHead(400).end(`ChatGPT sign-in was declined. Return to eve to retry.`),i.reject(Error(`ChatGPT sign-in was declined. Retry from /model.`));return}let a=r.searchParams.get(`code`);if(!a){t.writeHead(400).end(`Missing authorization code.`);return}t.end(`Authorization received. Return to eve to finish connecting your ChatGPT subscription.`),i.resolve(a)});a.maxConnections=10;let abort=()=>i.reject(e.signal.reason);e.signal.addEventListener(`abort`,abort,{once:!0});try{e.signal.throwIfAborted();try{await new Promise((e,t)=>{a.once(`error`,t),a.listen(1455,`127.0.0.1`,e)})}catch(t){if(!isErrnoCode(t,`EADDRINUSE`))throw Error(`Could not start ChatGPT sign-in on localhost:1455. Free the port and retry from /model.`);return e.log(`Local sign-in port is in use. Continuing with a device code.`),await deviceLogin(e)}e.signal.throwIfAborted(),e.log(`Sign in to ChatGPT in your browser:\n${r.href}\nWaiting for sign-in. Press Ctrl+C to cancel.`),e.open(r.href);let n=await i.promise;return await requestChatGptTokens({grant_type:`authorization_code`,code:n,code_verifier:t,redirect_uri:REDIRECT_URI},e)}finally{e.signal.removeEventListener(`abort`,abort),a.closeAllConnections(),await new Promise(e=>a.close(()=>e()))}}async function deviceLogin(e){let t=await deviceRequest(`usercode`,{client_id:CHATGPT_CLIENT_ID},e);if(!t.ok)throw Error(`ChatGPT device sign-in is unavailable (HTTP ${t.status}). Enable device code authorization in ChatGPT Settings > Security, then retry from /model.`);let n=await readChatGptAuthResponse(t);if(!isObject(n)||typeof n.device_auth_id!=`string`||!n.device_auth_id||typeof n.user_code!=`string`||!/^[A-Z0-9-]{4,32}$/iu.test(n.user_code))throw Error(`ChatGPT returned an invalid device code. Retry from /model.`);let r=Math.min(30,Math.max(1,Number(n.interval)||5))*1e3,i=`${CHATGPT_ISSUER}/codex/device`;for(e.log(`Open ${i} and enter code: ${n.user_code}\nIf prompted, enable device code authorization in ChatGPT Settings > Security.\nWaiting for sign-in. Press Ctrl+C to cancel.`),e.open(i);;){await setTimeout$1(r+1e3,void 0,{signal:e.signal});let t=await deviceRequest(`token`,{device_auth_id:n.device_auth_id,user_code:n.user_code},e);if(t.status===403||t.status===404)continue;if(!t.ok)throw Error(`ChatGPT device sign-in failed (HTTP ${t.status}). Retry from /model.`);let i=await readChatGptAuthResponse(t);if(!isObject(i)||typeof i.authorization_code!=`string`||!i.authorization_code||typeof i.code_verifier!=`string`||!i.code_verifier)throw Error(`ChatGPT returned an invalid device authorization. Retry from /model.`);return requestChatGptTokens({grant_type:`authorization_code`,code:i.authorization_code,code_verifier:i.code_verifier,redirect_uri:`${CHATGPT_ISSUER}/deviceauth/callback`},e)}}async function deviceRequest(e,t,n){try{return await(n.fetch??fetch)(`${CHATGPT_ISSUER}/api/accounts/deviceauth/${e}`,{method:`POST`,headers:{"content-type":`application/json`,"user-agent":`eve`},body:JSON.stringify(t),redirect:`error`,signal:AbortSignal.any([n.signal,AbortSignal.timeout(3e4)])})}catch{throw n.signal.throwIfAborted(),Error(`Could not reach ChatGPT device sign-in. Check your connection and retry from /model.`)}}export{ensureChatGptAuth};
@@ -1,2 +1,2 @@
1
- import{createRegistrySession}from"./registry-session.js";import{PlannerNavigationError}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{withSpinner}from"#setup/with-spinner.js";const PLANNER_STEPS=[`Channels`,`Integrations`,`Review`];var RegistryFlowFailedError=class extends Error{completed;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.name=`RegistryFlowFailedError`,this.completed=t}};const SECTIONS={channels:{title:`Where should people reach your agent?`,description:`You can add more later with /add.`,featured:[`channel/web`,`channel/slack`,`channel/github`,`channel/linear-agent`,`channel/photon-imessage`],includes:e=>e.name.startsWith(`channel/`)},integrations:{title:`What should your agent be able to work with?`,featured:[`extension/github-tools`,`connection/linear`,`connection/notion`,`connection/vercel`,`extension/agent-browser`,`experimental/self-modification`],includes:e=>!e.name.startsWith(`channel/`)}};function label(e){return e.title??e.name.split(`/`).at(-1)??e.name}function isPlannerItem(e,t){return t.name.includes(`/`)&&SECTIONS[e].includes(t)}function orderedSectionItems(e,t){let n=t.filter(t=>isPlannerItem(e,t)),r=SECTIONS[e].featured.map(e=>n.find(t=>t.name===e)).filter(e=>e!==void 0),i=new Set(r.map(e=>e.address));return[...r,...n.filter(e=>!i.has(e.address))]}function plannerLabel(e){return e.name===`connection/linear`?`Linear MCP`:label(e)}function sectionRows(e,t){return orderedSectionItems(e,t).map(e=>({value:e.address,label:plannerLabel(e),hint:e.description}))}function selectedInSection(e,t,n){return t.filter(t=>isPlannerItem(e,t)&&n.has(t.address)).map(e=>e.address)}function plannerNavigation(e,t){let n=(t.plannerContext?.prefixSteps??[]).map(e=>({label:e.label,complete:e.complete}));return{kind:`planner`,activeStep:n.length+e,firstNavigableStep:n.length,steps:[...n,...PLANNER_STEPS.map((e,n)=>{if(n===2)return{label:e};let r=selectedInSection(n===0?`channels`:`integrations`,t.catalog,t.selected).length;return r===0?{label:e}:{label:e,count:r}})]}}function replaceSectionSelection(e){for(let t of e.catalog)isPlannerItem(e.section,t)&&e.selected.delete(t.address);for(let t of e.addresses)e.selected.add(t)}async function editSection(e){let{section:t,catalog:n,prompter:r,selected:i}=e,a={message:SECTIONS[t].title,multiple:!0,search:!0,placeholder:t===`channels`?`Search channels`:`Search integrations`,navigation:plannerNavigation(t===`channels`?0:1,e),initialValues:selectedInSection(t,n,i),options:sectionRows(t,n)};t===`channels`&&(a.description=SECTIONS.channels.description),e.notices!==void 0&&(a.notices=e.notices);try{return replaceSectionSelection({section:t,catalog:n,selected:i,addresses:await r.select(a)}),`forward`}catch(e){if(!(e instanceof PlannerNavigationError))throw e;return replaceSectionSelection({section:t,catalog:n,selected:i,addresses:e.values.map(e=>{if(typeof e!=`string`)throw Error(`Registry planner returned a non-string item.`);return e})}),e.direction}}async function editPlan(e){let t=`channels`,n=e.notices;for(;;){if(t!==`review`){e.onScreen?.({screen:t===`channels`?`registry_channels`:`registry_integrations`});try{let r=await editSection({...e,section:t,notices:n});n=void 0,r===`back`?t===`integrations`&&(t=`channels`):t=t===`channels`?`integrations`:`review`}catch(e){if(!(e instanceof WizardCancelledError))throw e;return`cancelled`}continue}try{e.onScreen?.({screen:`registry_review`,registrySelectedCount:e.selected.size});let t=e.selected.size>0,r=[...e.selected].map(t=>{let n=e.itemsByAddress.get(t);if(n===void 0)throw Error(`Registry item "${t}" is no longer available.`);return n}),i=r.filter(e=>e.name.startsWith(`channel/`)),a=r.filter(e=>!e.name.startsWith(`channel/`)),o=[...i.length===0?[]:[{label:`Channels`,value:i.map(label).join(`, `)}],...a.length===0?[]:[{label:`Integrations`,value:a.map(label).join(`, `)}]],s={message:e.plannerContext?.reviewMessage??`Review additions`,metadata:[...e.plannerContext?.reviewMetadata??[],...o],navigation:plannerNavigation(2,e),options:[{value:`install`,label:t?e.plannerContext?.primaryActionLabel??`Install and set up`:e.plannerContext?.emptyActionLabel??`Finish without adding`},{value:`back`,label:`Back`}]};t||(s.description=`No channels or integrations selected.`),n!==void 0&&(s.notices=n);let c=await e.prompter.select(s);if(n=void 0,c===`install`)return`install`}catch(e){if(e instanceof PlannerNavigationError&&e.direction===`back`){t=`integrations`;continue}if(!(e instanceof WizardCancelledError))throw e;return`cancelled`}t=`integrations`}}function hasSettledOutcomes(e){return e!==void 0&&(e.items.length>0||e.failures.length>0||e.outcomes!==void 0)}async function runRegistryFlow(e){let t;try{let n=e.initialAddress?.trim(),r;if(n!==void 0&&n!==``){if(await e.prompter.select({message:`Add ${n}?`,options:[{value:`install`,label:`Install and set up`},{value:`cancel`,label:`Cancel`}]})===`cancel`)return{kind:`cancelled`};r=[{address:n,name:n,source:`Registry`}]}else{let t=e.deps?.browseRegistryCatalog??(await import(`#cli/commands/registry.js`)).browseRegistryCatalog,n=await withSpinner(e.prompter,`Loading registry…`,()=>t(e.appRoot)),i=[...n.items],a=new Set,o=n.errors.map(e=>({tone:`warning`,text:`${e.registry}: ${e.message}`})),s=new Map(i.map(e=>[e.address,e]));if(await editPlan({prompter:e.prompter,catalog:i,itemsByAddress:s,selected:a,notices:o,plannerContext:e.plannerContext,onScreen:e.onScreen})!==`install`)return{kind:`cancelled`};r=[...a].map(e=>{let t=s.get(e);if(t===void 0)throw Error(`Registry item "${e}" is no longer available.`);return t})}let i=e.deps?.installRegistryItem??(await import(`#cli/commands/registry.js`)).installRegistryItem,a=e.deps?.detectDeployment??(await import(`#setup/project-resolution.js`)).detectDeployment,o=e.deps?.runDeployFlow??(await import(`./deploy.js`)).runDeployFlow;t=createRegistrySession({detectDeployment:a,runDeployFlow:o}),e.onScreen?.({screen:`registry_install`});let s=t;for(let[t,n]of r.entries()){e.signal?.throwIfAborted(),e.onItemStart?.(n,t,r.length);try{let install=(t=e.signal)=>i(e.appRoot,n.address,{silent:!0,prompter:e.prompter,signal:t}),run=()=>e.runItem===void 0?install():e.runItem(install),t=await(e.prompter.withExclusiveTerminal?.(run)??run());s.add(label(n),t.output,t.setup)}catch(t){if(e.signal?.throwIfAborted(),t instanceof WizardCancelledError){s.addCancellation(label(n));continue}if(t instanceof HumanActionRequiredError)throw t;let r=(t instanceof Error?t.message:String(t)).trim()||`Installation failed.`,i=r.split(`
1
+ import{createRegistrySession}from"./registry-session.js";import{PlannerNavigationError}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{withSpinner}from"#setup/with-spinner.js";const PLANNER_STEPS=[`Channels`,`Integrations`,`Review`];var RegistryFlowFailedError=class extends Error{completed;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.name=`RegistryFlowFailedError`,this.completed=t}};const SECTIONS={channels:{title:`Where should people reach your agent?`,description:`You can add more later with /add.`,featured:[`channel/web`,`channel/slack`,`channel/github`,`channel/linear-agent`,`channel/photon-imessage`],includes:e=>e.name.startsWith(`channel/`)},integrations:{title:`What should your agent be able to work with?`,featured:[`extension/github-tools`,`connection/linear`,`connection/notion`,`connection/vercel`,`extension/agent-browser`,`eve/self-modification`],includes:e=>!e.name.startsWith(`channel/`)}};function label(e){return e.title??e.name.split(`/`).at(-1)??e.name}function isPlannerItem(e,t){return t.name.includes(`/`)&&SECTIONS[e].includes(t)}function orderedSectionItems(e,t){let n=t.filter(t=>isPlannerItem(e,t)),r=SECTIONS[e].featured.map(e=>n.find(t=>t.name===e)).filter(e=>e!==void 0),i=new Set(r.map(e=>e.address));return[...r,...n.filter(e=>!i.has(e.address))]}function plannerLabel(e){return e.name===`connection/linear`?`Linear MCP`:label(e)}function sectionRows(e,t){return orderedSectionItems(e,t).map(e=>({value:e.address,label:plannerLabel(e),hint:e.description}))}function selectedInSection(e,t,n){return t.filter(t=>isPlannerItem(e,t)&&n.has(t.address)).map(e=>e.address)}function plannerNavigation(e,t){let n=(t.plannerContext?.prefixSteps??[]).map(e=>({label:e.label,complete:e.complete}));return{kind:`planner`,activeStep:n.length+e,firstNavigableStep:n.length,steps:[...n,...PLANNER_STEPS.map((e,n)=>{if(n===2)return{label:e};let r=selectedInSection(n===0?`channels`:`integrations`,t.catalog,t.selected).length;return r===0?{label:e}:{label:e,count:r}})]}}function replaceSectionSelection(e){for(let t of e.catalog)isPlannerItem(e.section,t)&&e.selected.delete(t.address);for(let t of e.addresses)e.selected.add(t)}async function editSection(e){let{section:t,catalog:n,prompter:r,selected:i}=e,a={message:SECTIONS[t].title,multiple:!0,search:!0,placeholder:t===`channels`?`Search channels`:`Search integrations`,navigation:plannerNavigation(t===`channels`?0:1,e),initialValues:selectedInSection(t,n,i),options:sectionRows(t,n)};t===`channels`&&(a.description=SECTIONS.channels.description),e.notices!==void 0&&(a.notices=e.notices);try{return replaceSectionSelection({section:t,catalog:n,selected:i,addresses:await r.select(a)}),`forward`}catch(e){if(!(e instanceof PlannerNavigationError))throw e;return replaceSectionSelection({section:t,catalog:n,selected:i,addresses:e.values.map(e=>{if(typeof e!=`string`)throw Error(`Registry planner returned a non-string item.`);return e})}),e.direction}}async function editPlan(e){let t=`channels`,n=e.notices;for(;;){if(t!==`review`){e.onScreen?.({screen:t===`channels`?`registry_channels`:`registry_integrations`});try{let r=await editSection({...e,section:t,notices:n});n=void 0,r===`back`?t===`integrations`&&(t=`channels`):t=t===`channels`?`integrations`:`review`}catch(e){if(!(e instanceof WizardCancelledError))throw e;return`cancelled`}continue}try{e.onScreen?.({screen:`registry_review`,registrySelectedCount:e.selected.size});let t=e.selected.size>0,r=[...e.selected].map(t=>{let n=e.itemsByAddress.get(t);if(n===void 0)throw Error(`Registry item "${t}" is no longer available.`);return n}),i=r.filter(e=>e.name.startsWith(`channel/`)),a=r.filter(e=>!e.name.startsWith(`channel/`)),o=[...i.length===0?[]:[{label:`Channels`,value:i.map(label).join(`, `)}],...a.length===0?[]:[{label:`Integrations`,value:a.map(label).join(`, `)}]],s={message:e.plannerContext?.reviewMessage??`Review additions`,metadata:[...e.plannerContext?.reviewMetadata??[],...o],navigation:plannerNavigation(2,e),options:[{value:`install`,label:t?e.plannerContext?.primaryActionLabel??`Install and set up`:e.plannerContext?.emptyActionLabel??`Finish without adding`},{value:`back`,label:`Back`}]};t||(s.description=`No channels or integrations selected.`),n!==void 0&&(s.notices=n);let c=await e.prompter.select(s);if(n=void 0,c===`install`)return`install`}catch(e){if(e instanceof PlannerNavigationError&&e.direction===`back`){t=`integrations`;continue}if(!(e instanceof WizardCancelledError))throw e;return`cancelled`}t=`integrations`}}function hasSettledOutcomes(e){return e!==void 0&&(e.items.length>0||e.failures.length>0||e.outcomes!==void 0)}async function runRegistryFlow(e){let t;try{let n=e.initialAddress?.trim(),r;if(n!==void 0&&n!==``){if(await e.prompter.select({message:`Add ${n}?`,options:[{value:`install`,label:`Install and set up`},{value:`cancel`,label:`Cancel`}]})===`cancel`)return{kind:`cancelled`};r=[{address:n,name:n,source:`Registry`}]}else{let t=e.deps?.browseRegistryCatalog??(await import(`#cli/commands/registry.js`)).browseRegistryCatalog,n=await withSpinner(e.prompter,`Loading registry…`,()=>t(e.appRoot)),i=[...n.items],a=new Set,o=n.errors.map(e=>({tone:`warning`,text:`${e.registry}: ${e.message}`})),s=new Map(i.map(e=>[e.address,e]));if(await editPlan({prompter:e.prompter,catalog:i,itemsByAddress:s,selected:a,notices:o,plannerContext:e.plannerContext,onScreen:e.onScreen})!==`install`)return{kind:`cancelled`};r=[...a].map(e=>{let t=s.get(e);if(t===void 0)throw Error(`Registry item "${e}" is no longer available.`);return t})}let i=e.deps?.installRegistryItem??(await import(`#cli/commands/registry.js`)).installRegistryItem,a=e.deps?.detectDeployment??(await import(`#setup/project-resolution.js`)).detectDeployment,o=e.deps?.runDeployFlow??(await import(`./deploy.js`)).runDeployFlow;t=createRegistrySession({detectDeployment:a,runDeployFlow:o}),e.onScreen?.({screen:`registry_install`});let s=t;for(let[t,n]of r.entries()){e.signal?.throwIfAborted(),e.onItemStart?.(n,t,r.length);try{let install=(t=e.signal)=>i(e.appRoot,n.address,{silent:!0,prompter:e.prompter,signal:t}),run=()=>e.runItem===void 0?install():e.runItem(install),t=await(e.prompter.withExclusiveTerminal?.(run)??run());s.add(label(n),t.output,t.setup)}catch(t){if(e.signal?.throwIfAborted(),t instanceof WizardCancelledError){s.addCancellation(label(n));continue}if(t instanceof HumanActionRequiredError)throw t;let r=(t instanceof Error?t.message:String(t)).trim()||`Installation failed.`,i=r.split(`
2
2
  `).find(e=>e.trim()!==``);s.addFailure(label(n),r);let a={message:`Couldn't add ${label(n)}`,options:[{value:`skip`,label:`Skip ${label(n)}`},{value:`cancel`,label:`Cancel setup`}]};if(i!==void 0&&(a.description=i),await e.prompter.select(a)===`cancel`)return{kind:`done`,result:{...s.result(),cancelled:!0}}}}return{kind:`done`,result:await s.continueAfterInstall({appRoot:e.appRoot,prompter:e.prompter,signal:e.signal})}}catch(e){if(e instanceof WizardCancelledError){let e=t?.result();return hasSettledOutcomes(e)?{kind:`done`,result:{...e,cancelled:!0}}:{kind:`cancelled`}}let n=t?.result();throw hasSettledOutcomes(n)?new RegistryFlowFailedError(e,n):e}}export{RegistryFlowFailedError,runRegistryFlow};
@@ -1 +1 @@
1
- import{mkdir,readFile,writeFile}from"node:fs/promises";import{join}from"node:path";import{readFileSync}from"node:fs";import{readProjectLink}from"#setup/project-resolution.js";import{isObject}from"#shared/guards.js";import{hasEnvValue}from"#internal/resolve-model-endpoint-status.js";import{AI_GATEWAY_API_KEY_ENV_VAR}from"#setup/ai-gateway-api-key.js";import{findEnvFileWithKey}from"#setup/boxes/detect-ai-gateway.js";const PROVIDER_SELECTIONS=[`chatgpt`,`ai-gateway-key`,`ai-gateway-project`];function providerSettingsPath(e){return join(e,`.eve`,`provider.json`)}async function resolveAvailableProviders(e,t={}){let{signal:n,env:r=process.env}=t;n?.throwIfAborted();let[i,a,o]=await Promise.all([readProjectLink(e),findEnvFileWithKey(e,AI_GATEWAY_API_KEY_ENV_VAR),findEnvFileWithKey(e,`VERCEL_OIDC_TOKEN`)]);n?.throwIfAborted();let s=[`chatgpt`];return(a!==void 0||hasEnvValue(r[AI_GATEWAY_API_KEY_ENV_VAR]))&&s.push(`ai-gateway-key`),(i!==void 0||o!==void 0)&&s.push(`ai-gateway-project`),s}async function readProviderSelection(e){try{return parseProviderSelection(JSON.parse(await readFile(providerSettingsPath(e),`utf8`)))}catch{return}}function readProviderSelectionSync(e){try{return parseProviderSelection(JSON.parse(readFileSync(providerSettingsPath(e),`utf8`)))}catch{return}}async function writeProviderSelection(e,t){await mkdir(join(e,`.eve`),{recursive:!0}),await writeFile(providerSettingsPath(e),`${JSON.stringify({selected:t},null,2)}\n`,`utf8`)}function parseProviderSelection(e){return isObject(e)&&isProviderSelection(e.selected)?e.selected:void 0}function isProviderSelection(e){return PROVIDER_SELECTIONS.some(t=>t===e)}export{providerSettingsPath,readProviderSelection,readProviderSelectionSync,resolveAvailableProviders,writeProviderSelection};
1
+ import{mkdir,readFile,writeFile}from"node:fs/promises";import{isObject}from"#shared/guards.js";import{join}from"node:path";import{readFileSync}from"node:fs";import{readProjectLink}from"#setup/project-resolution.js";import{hasEnvValue}from"#internal/resolve-model-endpoint-status.js";import{AI_GATEWAY_API_KEY_ENV_VAR}from"#setup/ai-gateway-api-key.js";import{findEnvFileWithKey}from"#setup/boxes/detect-ai-gateway.js";const PROVIDER_SELECTIONS=[`chatgpt`,`ai-gateway-key`,`ai-gateway-project`];function providerSettingsPath(e){return join(e,`.eve`,`provider.json`)}async function resolveAvailableProviders(e,t={}){let{signal:n,env:r=process.env}=t;n?.throwIfAborted();let[i,a,o]=await Promise.all([readProjectLink(e),findEnvFileWithKey(e,AI_GATEWAY_API_KEY_ENV_VAR),findEnvFileWithKey(e,`VERCEL_OIDC_TOKEN`)]);n?.throwIfAborted();let s=[`chatgpt`];return(a!==void 0||hasEnvValue(r[AI_GATEWAY_API_KEY_ENV_VAR]))&&s.push(`ai-gateway-key`),(i!==void 0||o!==void 0)&&s.push(`ai-gateway-project`),s}async function readProviderSelection(e){try{return parseProviderSelection(JSON.parse(await readFile(providerSettingsPath(e),`utf8`)))}catch{return}}function readProviderSelectionSync(e){try{return parseProviderSelection(JSON.parse(readFileSync(providerSettingsPath(e),`utf8`)))}catch{return}}async function writeProviderSelection(e,t){await mkdir(join(e,`.eve`),{recursive:!0}),await writeFile(providerSettingsPath(e),`${JSON.stringify({selected:t},null,2)}\n`,`utf8`)}function parseProviderSelection(e){return isObject(e)&&isProviderSelection(e.selected)?e.selected:void 0}function isProviderSelection(e){return PROVIDER_SELECTIONS.some(t=>t===e)}export{providerSettingsPath,readProviderSelection,readProviderSelectionSync,resolveAvailableProviders,writeProviderSelection};
@@ -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{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.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.93`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.54.4`,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{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":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{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.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.93`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.55.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{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":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__",
@@ -1,7 +1,4 @@
1
1
  export declare const CHANNEL_AUDIENCES: readonly ["public", "private", "unknown"];
2
2
  /** Who can observe the conversation on its originating channel. */
3
3
  export type ChannelAudience = (typeof CHANNEL_AUDIENCES)[number];
4
- export interface ChannelAudienceMetadata {
5
- readonly audience?: ChannelAudience;
6
- }
7
4
  export declare function normalizeChannelAudience(value: unknown): ChannelAudience;
@@ -5,7 +5,8 @@ import type { RouteDefinition } from "#channel/routes.js";
5
5
  import type { Session, SessionHandle } from "#channel/session.js";
6
6
  import type { DeliverPayload, SessionAuthContext, TurnPolicy } from "#channel/types.js";
7
7
  import type { StepInput } from "#harness/types.js";
8
- import type { ChannelAudienceMetadata } from "#shared/channel-audience.js";
8
+ import type { AudienceInput } from "#shared/conversation-context.js";
9
+ import type { ChannelAudience } from "#shared/channel-audience.js";
9
10
  /**
10
11
  * Enriched return shape from a channel's {@link ChannelAdapter.fetchFile}
11
12
  * function. Return a bare {@link Buffer} when only bytes are known, or
@@ -38,14 +39,15 @@ export interface GenericReceiveInput<TReceiveTarget = Record<string, unknown>> {
38
39
  * The object passed to {@link defineChannel}. `routes` is required; `state`
39
40
  * seeds durable adapter state, `context` builds the per-step `channel` argument
40
41
  * for `events` and `deliver`, `events` handle session lifecycle, `receive`
41
- * accepts cross-channel handoffs, `fetchFile` stages remote file URLs, and
42
- * `metadata` projects observability data.
42
+ * accepts cross-channel handoffs, `fetchFile` stages remote file URLs,
43
+ * `audience` classifies conversation visibility, and `metadata` projects
44
+ * custom observability data.
43
45
  *
44
46
  * Generics: `TState` (adapter state), `TCtx` (context factory return type),
45
47
  * `TReceiveTarget` (cross-channel target shape), `TMetadata` (instrumentation
46
48
  * projection).
47
49
  */
48
- export interface GenericChannelDefinition<TEvents, TState = undefined, TCtx = void, TReceiveTarget = Record<string, unknown>, TMetadata extends Record<string, unknown> & ChannelAudienceMetadata = Record<string, unknown>> {
50
+ export interface GenericChannelDefinition<TEvents, TState = undefined, TCtx = void, TReceiveTarget = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>> {
49
51
  /** Policy used by message sends that do not provide an explicit override. */
50
52
  readonly turnPolicy?: TurnPolicy;
51
53
  deliver?(payload: DeliverPayload, ctx: TCtx): StepInput | void | Promise<StepInput | void>;
@@ -87,6 +89,13 @@ export interface GenericChannelDefinition<TEvents, TState = undefined, TCtx = vo
87
89
  * values such as `Date` or `Map`.
88
90
  */
89
91
  readonly metadata?: (state: NonNullable<TState>) => TMetadata;
92
+ /**
93
+ * Classifies who can observe the originating conversation. The hook runs
94
+ * after route auth with channel state, the authenticated principal, run mode,
95
+ * and deployment environment. Return `"unknown"` when classification is not
96
+ * confident; consumers treat it as non-public.
97
+ */
98
+ readonly audience?: (input: AudienceInput<TState>) => ChannelAudience;
90
99
  /**
91
100
  * Identifier of the adapter family this channel belongs to. Set by
92
101
  * higher-level wrappers (e.g. `slackChannel` passes `"slack"`) so downstream