eve 0.32.0 → 0.33.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 (178) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +8 -4
  3. package/dist/src/channel/channel-address.d.ts +4 -1
  4. package/dist/src/channel/channel-address.js +1 -1
  5. package/dist/src/channel/channel-operations.d.ts +3 -1
  6. package/dist/src/channel/compiled-channel.d.ts +2 -1
  7. package/dist/src/channel/cross-channel-receive.d.ts +5 -2
  8. package/dist/src/channel/cross-channel-receive.js +1 -1
  9. package/dist/src/channel/session.d.ts +6 -2
  10. package/dist/src/channel/session.js +1 -1
  11. package/dist/src/channel/types.d.ts +6 -0
  12. package/dist/src/channel/types.js +1 -1
  13. package/dist/src/chunks/{use-eve-agent-CX87G1vU.js → use-eve-agent-3oBnxzhV.js} +27 -17
  14. package/dist/src/chunks/{use-eve-agent-DwyRde1N.js → use-eve-agent-B-Hky2f4.js} +27 -17
  15. package/dist/src/cli/commands/agent-prompt/collect-intent.md +3 -0
  16. package/dist/src/cli/commands/agent-prompt/scaffold.md +4 -2
  17. package/dist/src/cli/commands/info.js +1 -1
  18. package/dist/src/cli/commands/init-repl.d.ts +1 -1
  19. package/dist/src/cli/commands/init-repl.js +1 -1
  20. package/dist/src/cli/commands/init.d.ts +7 -0
  21. package/dist/src/cli/commands/init.js +1 -1
  22. package/dist/src/cli/commands/integration-connect.d.ts +3 -3
  23. package/dist/src/cli/commands/integration-connect.js +1 -1
  24. package/dist/src/cli/commands/integration-setup.js +1 -1
  25. package/dist/src/cli/commands/set.d.ts +20 -0
  26. package/dist/src/cli/commands/set.js +1 -0
  27. package/dist/src/cli/dev/tui/runner.js +1 -1
  28. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  29. package/dist/src/cli/option-parsers.d.ts +3 -0
  30. package/dist/src/cli/option-parsers.js +1 -1
  31. package/dist/src/cli/run.js +1 -1
  32. package/dist/src/client/agent-info-schema.d.ts +28 -5
  33. package/dist/src/client/agent-info-schema.js +1 -1
  34. package/dist/src/client/session.js +1 -1
  35. package/dist/src/client/types.d.ts +3 -0
  36. package/dist/src/compiler/extension-compatibility.d.ts +19 -9
  37. package/dist/src/compiler/extension-compatibility.js +1 -1
  38. package/dist/src/compiler/manifest.d.ts +119 -19
  39. package/dist/src/compiler/manifest.js +1 -1
  40. package/dist/src/compiler/model-catalog.d.ts +2 -30
  41. package/dist/src/compiler/model-catalog.js +1 -1
  42. package/dist/src/compiler/module-map.d.ts +2 -2
  43. package/dist/src/compiler/module-map.js +2 -2
  44. package/dist/src/compiler/normalize-agent-config.js +1 -1
  45. package/dist/src/compiler/normalize-instructions.js +1 -1
  46. package/dist/src/compiler/normalize-manifest.js +2 -2
  47. package/dist/src/compiler/normalize-skill.js +1 -1
  48. package/dist/src/compiler/normalize-subagent.d.ts +5 -1
  49. package/dist/src/compiler/normalize-subagent.js +1 -1
  50. package/dist/src/compiler/remote-agent-node.d.ts +4 -1
  51. package/dist/src/compiler/workspace-resources.js +1 -1
  52. package/dist/src/context/dynamic-model-lifecycle.d.ts +7 -2
  53. package/dist/src/context/dynamic-model-lifecycle.js +1 -1
  54. package/dist/src/context/dynamic-subagent-lifecycle.js +1 -1
  55. package/dist/src/context/hook-lifecycle.js +1 -1
  56. package/dist/src/context/keys.d.ts +8 -0
  57. package/dist/src/context/keys.js +1 -1
  58. package/dist/src/evals/session.js +1 -1
  59. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  60. package/dist/src/execution/effective-agent-config.js +1 -1
  61. package/dist/src/execution/node-step.js +1 -1
  62. package/dist/src/execution/session-command-wire.js +1 -1
  63. package/dist/src/execution/session.d.ts +2 -0
  64. package/dist/src/execution/session.js +2 -2
  65. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  66. package/dist/src/execution/turn-control-receiver.d.ts +2 -0
  67. package/dist/src/execution/turn-control-receiver.js +1 -1
  68. package/dist/src/execution/workflow-steps.js +1 -1
  69. package/dist/src/harness/emission.d.ts +1 -1
  70. package/dist/src/harness/emission.js +1 -1
  71. package/dist/src/harness/step-hooks.d.ts +1 -1
  72. package/dist/src/harness/step-hooks.js +1 -1
  73. package/dist/src/harness/tool-loop.d.ts +1 -1
  74. package/dist/src/harness/tool-loop.js +2 -2
  75. package/dist/src/harness/types.d.ts +11 -5
  76. package/dist/src/harness/types.js +1 -1
  77. package/dist/src/internal/application/package.js +1 -1
  78. package/dist/src/internal/authored-definition/core.js +1 -1
  79. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  80. package/dist/src/internal/authored-module-loader.js +1 -1
  81. package/dist/src/internal/authored-module-map-loader.js +1 -1
  82. package/dist/src/internal/model-catalog.d.ts +46 -0
  83. package/dist/src/internal/model-catalog.js +1 -0
  84. package/dist/src/internal/nitro/host/build-vercel-agent-summary.js +1 -1
  85. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  86. package/dist/src/internal/nitro/host/dev-host-fingerprint.js +1 -1
  87. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  88. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +20 -10
  89. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  90. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  91. package/dist/src/internal/nitro/routes/info.js +1 -1
  92. package/dist/src/internal/vercel-agent-summary.d.ts +12 -3
  93. package/dist/src/internal/vercel-agent-summary.js +1 -1
  94. package/dist/src/protocol/message.d.ts +2 -2
  95. package/dist/src/protocol/message.js +1 -1
  96. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +5 -5
  97. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  98. package/dist/src/public/channels/discord/discordChannel.d.ts +3 -1
  99. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  100. package/dist/src/public/channels/eve.d.ts +3 -1
  101. package/dist/src/public/channels/eve.js +1 -1
  102. package/dist/src/public/channels/github/githubChannel.d.ts +3 -1
  103. package/dist/src/public/channels/github/githubChannel.js +1 -1
  104. package/dist/src/public/channels/index.d.ts +1 -1
  105. package/dist/src/public/channels/linear/linearChannel.d.ts +3 -1
  106. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  107. package/dist/src/public/channels/photon/photonIMessageChannel.d.ts +3 -1
  108. package/dist/src/public/channels/photon/photonIMessageChannel.js +1 -1
  109. package/dist/src/public/channels/slack/slackChannel.d.ts +3 -1
  110. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  111. package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -1
  112. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  113. package/dist/src/public/channels/telegram/telegramChannel.d.ts +3 -1
  114. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  115. package/dist/src/public/channels/twilio/twilioChannel.d.ts +3 -1
  116. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  117. package/dist/src/public/definitions/agent.d.ts +5 -7
  118. package/dist/src/public/definitions/agent.js +1 -1
  119. package/dist/src/public/definitions/channel.d.ts +3 -1
  120. package/dist/src/public/definitions/channel.js +1 -1
  121. package/dist/src/public/definitions/tool.d.ts +1 -5
  122. package/dist/src/public/definitions/tool.js +1 -1
  123. package/dist/src/public/index.d.ts +1 -1
  124. package/dist/src/runtime/agent/bootstrap.d.ts +19 -6
  125. package/dist/src/runtime/agent/bootstrap.js +1 -1
  126. package/dist/src/runtime/agent/model-catalog.d.ts +10 -0
  127. package/dist/src/runtime/agent/model-catalog.js +1 -0
  128. package/dist/src/runtime/agent/resolve-model.d.ts +8 -4
  129. package/dist/src/runtime/agent/resolve-model.js +1 -1
  130. package/dist/src/runtime/framework-channels/index.js +1 -1
  131. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  132. package/dist/src/runtime/resolve-agent.d.ts +2 -2
  133. package/dist/src/runtime/resolve-agent.js +1 -1
  134. package/dist/src/runtime/resolve-channel.js +1 -1
  135. package/dist/src/runtime/resolve-dynamic-subagent.d.ts +2 -5
  136. package/dist/src/runtime/subagents/dynamic-agent-config.d.ts +8 -7
  137. package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -1
  138. package/dist/src/runtime/types.d.ts +11 -4
  139. package/dist/src/setup/flows/deploy.d.ts +5 -3
  140. package/dist/src/setup/flows/deploy.js +1 -1
  141. package/dist/src/setup/flows/ensure-vercel-project.d.ts +5 -1
  142. package/dist/src/setup/flows/ensure-vercel-project.js +1 -1
  143. package/dist/src/setup/flows/model-source-change.d.ts +1 -0
  144. package/dist/src/setup/flows/model-source-change.js +1 -1
  145. package/dist/src/setup/integrations/discord/setup.js +1 -1
  146. package/dist/src/setup/integrations/github/setup.js +1 -1
  147. package/dist/src/setup/integrations/linear/setup.js +1 -1
  148. package/dist/src/setup/integrations/photon/setup-flow.js +1 -1
  149. package/dist/src/setup/integrations/slack/setup.js +1 -1
  150. package/dist/src/setup/scaffold/create/add-to-project.d.ts +2 -0
  151. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  152. package/dist/src/setup/scaffold/create/project.d.ts +3 -1
  153. package/dist/src/setup/scaffold/create/project.js +4 -4
  154. package/dist/src/shared/agent-definition.d.ts +23 -23
  155. package/dist/src/shared/agent-definition.js +1 -1
  156. package/dist/src/shared/channel-definition.d.ts +3 -1
  157. package/dist/src/shared/dynamic-tool-definition.d.ts +4 -10
  158. package/dist/src/shared/dynamic-tool-definition.js +1 -1
  159. package/dist/src/svelte/index.js +1 -1
  160. package/dist/src/svelte/use-eve-agent.js +1 -1
  161. package/dist/src/vue/index.js +1 -1
  162. package/dist/src/vue/use-eve-agent.js +1 -1
  163. package/docs/agent-config.md +30 -19
  164. package/docs/channels/chat-sdk.mdx +5 -5
  165. package/docs/channels/custom.mdx +20 -0
  166. package/docs/channels/discord.mdx +1 -0
  167. package/docs/channels/eve.mdx +2 -0
  168. package/docs/channels/github.mdx +1 -1
  169. package/docs/channels/linear.mdx +1 -1
  170. package/docs/channels/overview.mdx +19 -0
  171. package/docs/channels/photon.mdx +5 -2
  172. package/docs/channels/slack.mdx +5 -11
  173. package/docs/concepts/execution-model-and-durability.mdx +5 -8
  174. package/docs/concepts/sessions-runs-and-streaming.md +2 -2
  175. package/docs/guides/dynamic-capabilities.md +24 -20
  176. package/docs/installation.mdx +7 -1
  177. package/docs/reference/cli.md +33 -8
  178. package/package.json +1 -1
@@ -1 +1 @@
1
- import{setChannelInstrumentationKind}from"#channel/compiled-channel.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeChannelDefinition}from"#internal/authored-definition/channel.js";import{ResolveAgentError,createResolvedModuleSourceRef,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";import{isHttpRouteDefinition,isWebSocketRouteDefinition}from"#channel/routes.js";async function resolveChannelDefinition(r,i,a){try{let t=normalizeChannelDefinition(await loadResolvedModuleExport({definition:r,kindLabel:`channel`,moduleMap:i,nodeId:a}),`Expected the channel export "${r.exportName??`default`}" from "${r.logicalPath}" to match the public eve shape.`),n=createResolvedModuleSourceRef({exportName:r.exportName,logicalPath:r.logicalPath,sourceId:r.sourceId}),o=t.routes.find(e=>e.method.toUpperCase()===r.method.toUpperCase()&&e.path===r.urlPath),s=`channel:${r.name}`;setChannelInstrumentationKind(t,s);let c=t.adapter;c&&c.kind!==HTTP_ADAPTER_KIND&&(c.kind=s);let l=resolveHttpRoute(r,o),u=resolveWebSocketRoute(r,o);return{name:r.name,method:r.method,urlPath:r.urlPath,cors:r.cors,fetch:async(e,t)=>l?l.handler(e,t):Response.json({error:`No matching route handler.`,ok:!1},{status:404}),handler:l?.handler,websocket:u?.handler,receive:t.receive,definition:t,adapter:c,...n}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the channel definition from "${r.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:r.logicalPath,sourceId:r.sourceId})}}function resolveHttpRoute(e,t){if(!(t===void 0||e.method===`WEBSOCKET`||!isHttpRouteDefinition(t)))return t}function resolveWebSocketRoute(e,t){if(!(t===void 0||e.method!==`WEBSOCKET`||!isWebSocketRouteDefinition(t)))return t}export{resolveChannelDefinition};
1
+ import{setChannelInstrumentationKind}from"#channel/compiled-channel.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeChannelDefinition}from"#internal/authored-definition/channel.js";import{ResolveAgentError,createResolvedModuleSourceRef,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";import{isHttpRouteDefinition,isWebSocketRouteDefinition}from"#channel/routes.js";async function resolveChannelDefinition(r,i,a){try{let t=normalizeChannelDefinition(await loadResolvedModuleExport({definition:r,kindLabel:`channel`,moduleMap:i,nodeId:a}),`Expected the channel export "${r.exportName??`default`}" from "${r.logicalPath}" to match the public eve shape.`),n=createResolvedModuleSourceRef({exportName:r.exportName,logicalPath:r.logicalPath,sourceId:r.sourceId}),o=t.routes.find(e=>e.method.toUpperCase()===r.method.toUpperCase()&&e.path===r.urlPath),s=`channel:${r.name}`;setChannelInstrumentationKind(t,s);let c=t.adapter;c&&c.kind!==HTTP_ADAPTER_KIND&&(c.kind=s);let l=resolveHttpRoute(r,o),u=resolveWebSocketRoute(r,o);return{name:r.name,method:r.method,urlPath:r.urlPath,cors:r.cors,fetch:async(e,t)=>l?l.handler(e,t):Response.json({error:`No matching route handler.`,ok:!1},{status:404}),handler:l?.handler,websocket:u?.handler,receive:t.receive,definition:t,adapter:c,turnPolicy:t.turnPolicy,...n}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the channel definition from "${r.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:r.logicalPath,sourceId:r.sourceId})}}function resolveHttpRoute(e,t){if(!(t===void 0||e.method===`WEBSOCKET`||!isHttpRouteDefinition(t)))return t}function resolveWebSocketRoute(e,t){if(!(t===void 0||e.method!==`WEBSOCKET`||!isWebSocketRouteDefinition(t)))return t}export{resolveChannelDefinition};
@@ -1,12 +1,9 @@
1
1
  import type { CompiledDynamicSubagentDefinition } from "#compiler/remote-agent-node.js";
2
2
  import type { CompiledModuleMap } from "#compiler/module-map.js";
3
3
  import type { ResolvedDynamicSubagentDefinition } from "#runtime/types.js";
4
- import type { ModuleSourceRef } from "#shared/source-ref.js";
5
- type DynamicSubagentSource = ModuleSourceRef & CompiledDynamicSubagentDefinition;
6
4
  export declare function resolveDynamicSubagentDefinition(input: {
7
- readonly definition: DynamicSubagentSource;
5
+ readonly definition: CompiledDynamicSubagentDefinition;
8
6
  readonly moduleMap: CompiledModuleMap;
9
7
  readonly nodeId: string;
10
8
  }): Promise<ResolvedDynamicSubagentDefinition>;
11
- export declare function normalizeResolvedDynamicSubagentDefinition(definition: DynamicSubagentSource, value: unknown): ResolvedDynamicSubagentDefinition;
12
- export {};
9
+ export declare function normalizeResolvedDynamicSubagentDefinition(definition: CompiledDynamicSubagentDefinition, value: unknown): ResolvedDynamicSubagentDefinition;
@@ -1,5 +1,8 @@
1
+ import type { ContextAccessor } from "#context/key.js";
2
+ import type { RuntimeModelReference } from "#runtime/agent/bootstrap.js";
3
+ import type { RuntimeModelCatalog } from "#runtime/agent/model-catalog.js";
1
4
  import { type AgentLimitsDefinition, type AgentReasoningDefinition } from "#shared/agent-definition.js";
2
- import { type JsonObject } from "#shared/json.js";
5
+ import type { JsonObject } from "#shared/json.js";
3
6
  export interface DynamicSubagentAgentConfig {
4
7
  readonly compaction?: {
5
8
  readonly model?: DynamicSubagentModelReference;
@@ -11,12 +14,10 @@ export interface DynamicSubagentAgentConfig {
11
14
  readonly outputSchema?: JsonObject;
12
15
  readonly reasoning?: AgentReasoningDefinition;
13
16
  }
14
- export interface DynamicSubagentModelReference {
15
- readonly contextWindowTokens?: number;
16
- readonly id: string;
17
- readonly providerOptions?: Record<string, JsonObject>;
18
- }
17
+ export type DynamicSubagentModelReference = RuntimeModelReference;
19
18
  export declare function normalizeDynamicSubagentAgentConfig(input: {
19
+ readonly catalog?: RuntimeModelCatalog;
20
20
  readonly name: string;
21
+ readonly state: ContextAccessor;
21
22
  readonly value: unknown;
22
- }): DynamicSubagentAgentConfig;
23
+ }): Promise<DynamicSubagentAgentConfig>;
@@ -1 +1 @@
1
- import{serializeOutputSchema}from"#shared/tool-schema.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{parseJsonObject}from"#shared/json.js";import{isDynamicModelDefinition}from"#shared/agent-definition.js";function normalizeDynamicSubagentAgentConfig(n){let r=`Dynamic subagent "${n.name}" must return defineAgent(...), defineRemoteAgent(...), or null.`,i=normalizeAgentDefinition(n.value,r);if(!i.description)throw Error(`${r} The "description" field is required.`);if(i.build!==void 0)throw Error(`${r} The "build" field cannot be selected at runtime.`);if(i.experimental!==void 0)throw Error(`${r} The "experimental" field cannot be selected at runtime.`);if(isDynamicModelDefinition(i.model))throw Error(`${r} The returned "model" must be static.`);let a={description:i.description,model:normalizeModelReference({contextWindowTokens:i.modelContextWindowTokens,model:i.model,name:n.name,providerOptions:i.modelOptions?.providerOptions})};if(i.compaction!==void 0){let e={};i.compaction.model!==void 0&&(e.model=normalizeModelReference({contextWindowTokens:i.compaction.modelContextWindowTokens,model:i.compaction.model,name:n.name,providerOptions:i.modelOptions?.providerOptions})),i.compaction.thresholdPercent!==void 0&&(e.thresholdPercent=i.compaction.thresholdPercent),a.compaction=e}return i.limits!==void 0&&(a.limits=i.limits),i.outputSchema!==void 0&&(a.outputSchema=serializeOutputSchema(i.outputSchema)),i.reasoning!==void 0&&(a.reasoning=i.reasoning),a}function normalizeModelReference(e){if(typeof e.model!=`string`)throw Error(`Dynamic subagent "${e.name}" must return model IDs as strings so its agent config can cross durable workflow boundaries.`);let t={id:formatLanguageModelGatewayId(e.model)};return e.contextWindowTokens!==void 0&&(t.contextWindowTokens=e.contextWindowTokens),e.providerOptions!==void 0&&(t.providerOptions=Object.fromEntries(Object.entries(e.providerOptions).map(([e,t])=>[e,parseJsonObject(t)]))),t}export{normalizeDynamicSubagentAgentConfig};
1
+ import{serializeOutputSchema}from"#shared/tool-schema.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{isDynamicModelDefinition}from"#shared/agent-definition.js";import{resolveRuntimeModelSelection}from"#runtime/agent/resolve-model.js";async function normalizeDynamicSubagentAgentConfig(t){let n=`Dynamic subagent "${t.name}" must return defineAgent(...), defineRemoteAgent(...), or null.`,r=normalizeAgentDefinition(t.value,n);if(!r.description)throw Error(`${n} The "description" field is required.`);if(r.build!==void 0)throw Error(`${n} The "build" field cannot be selected at runtime.`);if(r.experimental!==void 0)throw Error(`${n} The "experimental" field cannot be selected at runtime.`);if(isDynamicModelDefinition(r.model))throw Error(`${n} The returned "model" must be static.`);let i={description:r.description,model:await normalizeDurableModelSelection({catalog:t.catalog,selection:{model:r.model,modelContextWindowTokens:r.modelContextWindowTokens,modelOptions:r.modelOptions},state:t.state})};if(r.compaction!==void 0){let e={};r.compaction.model!==void 0&&(e.model=await normalizeDurableModelSelection({catalog:t.catalog,selection:{model:r.compaction.model,modelContextWindowTokens:r.compaction.modelContextWindowTokens,modelOptions:r.modelOptions},state:t.state})),r.compaction.thresholdPercent!==void 0&&(e.thresholdPercent=r.compaction.thresholdPercent),i.compaction=e}return r.limits!==void 0&&(i.limits=r.limits),r.outputSchema!==void 0&&(i.outputSchema=serializeOutputSchema(r.outputSchema)),r.reasoning!==void 0&&(i.reasoning=r.reasoning),i}async function normalizeDurableModelSelection(e){return(await resolveRuntimeModelSelection({catalog:e.catalog,durability:`durable`,selection:e.selection,state:e.state})).reference}export{normalizeDynamicSubagentAgentConfig};
@@ -195,6 +195,7 @@ export interface ResolvedChannelDefinition extends ResolvedModuleSourceRef {
195
195
  readonly name: string;
196
196
  readonly method: ChannelRouteMethod;
197
197
  readonly adapter?: ChannelAdapter;
198
+ readonly turnPolicy?: CompiledChannel["turnPolicy"];
198
199
  readonly cors?: NormalizedChannelCorsOptions;
199
200
  readonly urlPath: string;
200
201
  readonly fetch: (req: Request, ctx: RouteContext) => Promise<Response>;
@@ -270,10 +271,16 @@ export interface ResolvedDynamicSubagentDefinition extends Readonly<ModuleSource
270
271
  /**
271
272
  * Runtime-owned additive agent configuration resolved from `agent.ts`.
272
273
  */
273
- export type ResolvedAgentDefinition = Readonly<Omit<InternalAgentDefinition, "build" | "source"> & {
274
- dynamicModel?: RuntimeDynamicModelReference;
274
+ type ResolvedAgentDefinitionBase = Omit<InternalAgentDefinition, "build" | "model" | "source"> & {
275
275
  source?: Readonly<NonNullable<InternalAgentDefinition["source"]>>;
276
- }>;
276
+ };
277
+ export type ResolvedAgentDefinition = Readonly<ResolvedAgentDefinitionBase & ({
278
+ dynamicModel?: never;
279
+ model: InternalAgentDefinition["model"];
280
+ } | {
281
+ dynamicModel: RuntimeDynamicModelReference;
282
+ model?: never;
283
+ })>;
277
284
  /**
278
285
  * Stable runtime metadata preserved alongside the resolved authored agent.
279
286
  */
@@ -326,7 +333,7 @@ export interface ResolvedDynamicInstructionsResolver extends Readonly<ModuleSour
326
333
  */
327
334
  export interface ResolvedAgent {
328
335
  readonly channels: readonly ResolvedChannelDefinition[];
329
- readonly config: ResolvedAgentDefinition;
336
+ readonly config?: ResolvedAgentDefinition;
330
337
  readonly connections: readonly ResolvedConnectionDefinition[];
331
338
  /**
332
339
  * Logical names of framework-provided channels the author opted out of by
@@ -3,9 +3,11 @@ import { type LinkProjectDeps } from "../boxes/link-project.js";
3
3
  import { type ResolveProvisioningDeps } from "../boxes/resolve-provisioning.js";
4
4
  import { detectDeployment } from "../project-resolution.js";
5
5
  import type { Prompter } from "../prompter.js";
6
+ import { runLoginFlow } from "./login.js";
6
7
  /** Injected for tests; defaults to the real detection and box effects. */
7
8
  export interface DeployFlowDeps {
8
9
  detectDeployment: typeof detectDeployment;
10
+ runLoginFlow: typeof runLoginFlow;
9
11
  resolveProvisioning?: ResolveProvisioningDeps;
10
12
  linkProject?: LinkProjectDeps;
11
13
  deployProject?: DeployProjectDeps;
@@ -25,9 +27,9 @@ export type DeployFlowResult = {
25
27
  * state is the safety-critical input for a deploy, so it is re-detected at
26
28
  * decision time, never trusted from an earlier render. An already-linked
27
29
  * project goes straight to the deploy box; an unlinked one walks the same
28
- * team/project pickers as onboarding (resolve-provisioning with the deploy
29
- * gate pre-answered — invoking deploy IS the deploy decision), then links
30
- * non-interactively so the deploy box never hits its bare-`vercel link`
30
+ * login and team/project flow as onboarding (resolve-provisioning with the
31
+ * deploy gate pre-answered — invoking deploy IS the deploy decision), then
32
+ * links non-interactively so the deploy box never hits its bare-`vercel link`
31
33
  * fallback. A non-interactive run with no link refuses with `needs-link`
32
34
  * before any side effect.
33
35
  */
@@ -1 +1 @@
1
- import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{withSpinner}from"../with-spinner.js";import{snapshotSetupState}from"../state.js";import{deployProject}from"../boxes/deploy-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runHeadless,runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";function productionUrlOf(e){return e.kind===`deployed`?e.productionUrl:void 0}async function runDeployFlow(t){let{appRoot:n,prompter:r,interactive:i,signal:a}=t,o={detectDeployment,...t.deps},s=await withSpinner(r,`Checking the current Vercel link...`,async()=>{let e=await o.detectDeployment(n,{signal:a});return a?.throwIfAborted(),projectResolutionFromDeployment(e)}),c=isProjectResolved(s);if(!c&&!i)return{kind:`needs-link`};let l=inProjectSetupState(n,s,{deploymentPending:!0}),u=c?[deployProject({prompter:r,headless:!i,deps:o.deployProject})]:[resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(r)),prompter:r,targetDirectory:n,mode:{headless:!1},deps:o.resolveProvisioning}),linkVercelProject({prompter:r,deps:o.linkProject}),deployProject({prompter:r,headless:!i,deps:o.deployProject})],d=prompterSink(r);if(!i)return{kind:`deployed`,productionUrl:productionUrlOf((await runHeadless(u,l,d,{snapshot:snapshotSetupState,signal:a})).project)};let f=await runInteractive(u,l,d,{snapshot:snapshotSetupState,signal:a});return f.kind===`cancelled`?{kind:`cancelled`}:{kind:`deployed`,productionUrl:productionUrlOf(f.state.project)}}export{runDeployFlow};
1
+ import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{withSpinner}from"../with-spinner.js";import{snapshotSetupState}from"../state.js";import{deployProject}from"../boxes/deploy-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runHeadless,runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";import{runLoginFlow}from"./login.js";function productionUrlOf(e){return e.kind===`deployed`?e.productionUrl:void 0}async function runDeployFlow(t){let{appRoot:n,prompter:r,interactive:i,signal:a}=t,o={detectDeployment,runLoginFlow,...t.deps},s=await withSpinner(r,`Checking the current Vercel link...`,async()=>{let e=await o.detectDeployment(n,{signal:a});return a?.throwIfAborted(),projectResolutionFromDeployment(e)}),c=isProjectResolved(s);if(!c&&!i)return{kind:`needs-link`};if(!c&&(await o.runLoginFlow({appRoot:n,prompter:r,signal:a})).kind===`cancelled`)return{kind:`cancelled`};let l=inProjectSetupState(n,s,{deploymentPending:!0}),u=c?[deployProject({prompter:r,headless:!i,deps:o.deployProject})]:[resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(r)),prompter:r,targetDirectory:n,mode:{headless:!1},deps:o.resolveProvisioning}),linkVercelProject({prompter:r,deps:o.linkProject}),deployProject({prompter:r,headless:!i,deps:o.deployProject})],d=prompterSink(r);if(!i)return{kind:`deployed`,productionUrl:productionUrlOf((await runHeadless(u,l,d,{snapshot:snapshotSetupState,signal:a})).project)};let f=await runInteractive(u,l,d,{snapshot:snapshotSetupState,signal:a});return f.kind===`cancelled`?{kind:`cancelled`}:{kind:`deployed`,productionUrl:productionUrlOf(f.state.project)}}export{runDeployFlow};
@@ -2,12 +2,16 @@ import { type LinkProjectDeps } from "../boxes/link-project.js";
2
2
  import { type ResolveProvisioningDeps } from "../boxes/resolve-provisioning.js";
3
3
  import type { Prompter } from "../prompter.js";
4
4
  import { readProjectLink, type VercelProjectReference } from "../project-resolution.js";
5
+ import { requireAuth } from "../vercel-project.js";
6
+ import { runLoginFlow } from "./login.js";
5
7
  export interface EnsureVercelProjectDeps {
6
8
  resolveProvisioning?: ResolveProvisioningDeps;
7
9
  linkProject?: LinkProjectDeps;
8
10
  readProjectLink: typeof readProjectLink;
11
+ requireAuth: typeof requireAuth;
12
+ runLoginFlow: typeof runLoginFlow;
9
13
  }
10
- /** Ensures a project link using eve-owned prompts and a non-interactive Vercel command. */
14
+ /** Ensures Vercel authentication and a project link using eve-owned prompts. */
11
15
  export declare function ensureVercelProject(input: {
12
16
  appRoot: string;
13
17
  prompter: Prompter;
@@ -1 +1 @@
1
- import{interactiveAsker,withAnswers}from"../ask.js";import{readProjectLink}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{WizardCancelledError}from"../step.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";async function ensureVercelProject(e){let t=e.deps?.readProjectLink??readProjectLink,n=await t(e.appRoot);if(n!==void 0)return n;let r=inProjectSetupState(e.appRoot,{kind:`unresolved`});if((await runInteractive([resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(e.prompter)),prompter:e.prompter,targetDirectory:e.appRoot,mode:{headless:!1},adoptExistingLink:!1,projectSelection:`create-or-link`,teamSelectMessage:e.teamSelectMessage,deps:e.deps?.resolveProvisioning}),linkVercelProject({prompter:e.prompter,deps:e.deps?.linkProject})],r,prompterSink(e.prompter),{snapshot:snapshotSetupState,signal:e.signal})).kind===`cancelled`)throw e.signal?.throwIfAborted(),new WizardCancelledError;let i=await t(e.appRoot);if(i===void 0)throw Error(`Vercel project linking failed.`);return i}export{ensureVercelProject};
1
+ import{interactiveAsker,withAnswers}from"../ask.js";import{readProjectLink}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{requireAuth}from"../vercel-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{WizardCancelledError}from"../step.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";import{runLoginFlow}from"./login.js";async function ensureVercelProject(e){let t=e.deps?.readProjectLink??readProjectLink,n=await(e.deps?.runLoginFlow??runLoginFlow)({appRoot:e.appRoot,prompter:e.prompter,signal:e.signal});if(n.kind===`cancelled`)throw new WizardCancelledError;n.kind!==`already`&&n.kind!==`logged-in`&&await(e.deps?.requireAuth??requireAuth)(e.appRoot,e.prompter,{signal:e.signal});let r=await t(e.appRoot);if(r!==void 0)return r;let i=inProjectSetupState(e.appRoot,{kind:`unresolved`});if((await runInteractive([resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(e.prompter)),prompter:e.prompter,targetDirectory:e.appRoot,mode:{headless:!1},adoptExistingLink:!1,projectSelection:`create-or-link`,teamSelectMessage:e.teamSelectMessage,deps:e.deps?.resolveProvisioning}),linkVercelProject({prompter:e.prompter,deps:e.deps?.linkProject})],i,prompterSink(e.prompter),{snapshot:snapshotSetupState,signal:e.signal})).kind===`cancelled`)throw e.signal?.throwIfAborted(),new WizardCancelledError;let a=await t(e.appRoot);if(a===void 0)throw Error(`Vercel project linking failed.`);return a}export{ensureVercelProject};
@@ -36,3 +36,4 @@ export declare function changeAgentModel(input: {
36
36
  readonly appRoot: string;
37
37
  readonly slug: string;
38
38
  }): Promise<ApplyModelOutcome>;
39
+ export declare function validateModelSlug(appRoot: string, slug: string): Promise<string | null>;
@@ -1 +1 @@
1
- import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{join}from"node:path";import{discoverAgent}from"#discover/discover-agent.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{createStaticSourceChange}from"#source-change/static-source-change.js";var import_picocolors=__toESM(require_picocolors(),1);function formatApplyModelSettingsOutcome(e){return e.kind===`rejected`?e.message:e.kind===`unchanged`?`Model settings are already up to date.`:e.changed.length===1&&e.changed[0]===`model`&&e.model!==void 0?`Model changed to ${import_picocolors.default.bold(e.model)}. Live on your next prompt.`:`Model settings updated: ${e.changed.map(t=>t===`model`?`model ${e.model??`updated`}`:t===`reasoning`?`reasoning ${e.reasoning??`provider default`}`:`Fast mode ${e.fastMode?`on`:`off`}`).join(`, `)}. Live on your next prompt.`}function formatApplyModelOutcome(e){switch(e.kind){case`changed`:return`Model changed to ${import_picocolors.default.bold(e.to)}. Live on your next prompt.`;case`unchanged`:return`Model is already \`${e.model}\`.`;case`rejected`:return e.message}}async function changeAgentModelSettings(e){let{appRoot:t,patch:r}=e;if(r.model.kind===`set`){let e=await validateModelSlug(t,r.model.value);if(e!==null)return{kind:`rejected`,message:e}}let{manifest:i}=await discoverAgent({agentRoot:join(t,`agent`),appRoot:t}),a=await createStaticSourceChange(i).updateModelSettings(r);if(a.kind===`bail`)return{kind:`rejected`,message:`Couldn't edit ${a.at.logicalPath}: ${a.reason}. Change the model settings by hand.`};if(a.changed.length===0)return{kind:`unchanged`};let o={kind:`changed`,changed:a.changed};return r.model.kind===`set`&&(o.model=r.model.value),r.reasoning.kind!==`keep`&&(o.reasoning=r.reasoning.kind===`set`?r.reasoning.value:null),r.gatewayServiceTier.kind!==`keep`&&(o.fastMode=r.gatewayServiceTier.kind===`set`),o}async function changeAgentModel(e){let{appRoot:t,slug:r}=e,i=await validateModelSlug(t,r);if(i!==null)return{kind:`rejected`,message:i};let{manifest:a}=await discoverAgent({agentRoot:join(t,`agent`),appRoot:t}),o=await createStaticSourceChange(a).updateModelName(r);return o.kind===`bail`?{kind:`rejected`,message:`Couldn't edit ${o.at.logicalPath}: ${o.reason}. Change \`model\` by hand.`}:o.from===o.to?{kind:`unchanged`,model:o.to}:{kind:`changed`,to:o.to}}async function validateModelSlug(e,t){if(!t.includes(`/`))return`\`${t}\` isn't a provider/model id (e.g. anthropic/claude-sonnet-5).`;let n=createCompiledRuntimeModelCatalogLoader(e);try{if(await n.getModelLimits(formatLanguageModelGatewayId(t))===null)return`I couldn't confirm \`${t}\` in the AI Gateway model catalog, so I didn't change agent.ts.`}catch{return null}return null}export{changeAgentModel,changeAgentModelSettings,formatApplyModelOutcome,formatApplyModelSettingsOutcome};
1
+ import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{join}from"node:path";import{discoverAgent}from"#discover/discover-agent.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{createStaticSourceChange}from"#source-change/static-source-change.js";var import_picocolors=__toESM(require_picocolors(),1);function formatApplyModelSettingsOutcome(e){return e.kind===`rejected`?e.message:e.kind===`unchanged`?`Model settings are already up to date.`:e.changed.length===1&&e.changed[0]===`model`&&e.model!==void 0?`Model changed to ${import_picocolors.default.bold(e.model)}. Live on your next prompt.`:`Model settings updated: ${e.changed.map(t=>t===`model`?`model ${e.model??`updated`}`:t===`reasoning`?`reasoning ${e.reasoning??`provider default`}`:`Fast mode ${e.fastMode?`on`:`off`}`).join(`, `)}. Live on your next prompt.`}function formatApplyModelOutcome(e){switch(e.kind){case`changed`:return`Model changed to ${import_picocolors.default.bold(e.to)}. Live on your next prompt.`;case`unchanged`:return`Model is already \`${e.model}\`.`;case`rejected`:return e.message}}async function changeAgentModelSettings(e){let{appRoot:t,patch:r}=e;if(r.model.kind===`set`){let e=await validateModelSlug(t,r.model.value);if(e!==null)return{kind:`rejected`,message:e}}let{manifest:i}=await discoverAgent({agentRoot:join(t,`agent`),appRoot:t}),a=await createStaticSourceChange(i).updateModelSettings(r);if(a.kind===`bail`)return{kind:`rejected`,message:`Couldn't edit ${a.at.logicalPath}: ${a.reason}. Change the model settings by hand.`};if(a.changed.length===0)return{kind:`unchanged`};let o={kind:`changed`,changed:a.changed};return r.model.kind===`set`&&(o.model=r.model.value),r.reasoning.kind!==`keep`&&(o.reasoning=r.reasoning.kind===`set`?r.reasoning.value:null),r.gatewayServiceTier.kind!==`keep`&&(o.fastMode=r.gatewayServiceTier.kind===`set`),o}async function changeAgentModel(e){let{appRoot:t,slug:r}=e,i=await validateModelSlug(t,r);if(i!==null)return{kind:`rejected`,message:i};let{manifest:a}=await discoverAgent({agentRoot:join(t,`agent`),appRoot:t}),o=await createStaticSourceChange(a).updateModelName(r);return o.kind===`bail`?{kind:`rejected`,message:`Couldn't edit ${o.at.logicalPath}: ${o.reason}. Change \`model\` by hand.`}:o.from===o.to?{kind:`unchanged`,model:o.to}:{kind:`changed`,to:o.to}}async function validateModelSlug(e,t){if(!t.includes(`/`))return`\`${t}\` isn't a provider/model id (e.g. anthropic/claude-sonnet-5).`;let n=createCompiledRuntimeModelCatalogLoader(e);try{if(await n.getModelLimits(formatLanguageModelGatewayId(t))===null)return`I couldn't confirm \`${t}\` in the AI Gateway model catalog, so I didn't change agent.ts.`}catch{return null}return null}export{changeAgentModel,changeAgentModelSettings,formatApplyModelOutcome,formatApplyModelSettingsOutcome,validateModelSlug};
@@ -4,6 +4,6 @@ import { discordChannel } from "eve/channels/discord";
4
4
  export default discordChannel({
5
5
  credentials: connectDiscordCredentials(${JSON.stringify(e)}),
6
6
  });
7
- `}async function prepareDiscordSetup(e,t=defaultDeps){if(e.environment.vercel.kind===`unavailable`)throw Error("Discord setup requires an authenticated Vercel CLI. Run `vercel login`, then retry.");e.presenter.log.info(`Create a Discord application or open an existing one, then go to Bot → Reset Token and copy the new bot token.
7
+ `}async function prepareDiscordSetup(e,t=defaultDeps){e.presenter.log.info(`Create a Discord application or open an existing one, then go to Bot → Reset Token and copy the new bot token.
8
8
  Create: https://discord.com/developers/applications?new_application=true
9
9
  Existing applications: https://discord.com/developers/applications`);let n=(await e.asker.ask(text({key:`discord-bot-token`,message:`Discord bot token`,required:!0,sensitive:!0,environment:`DISCORD_BOT_TOKEN`}))).trim(),r=await e.asker.ask(text({key:`discord-command-name`,message:`Discord command name`,detected:`ask`,required:!0,validate:validateCommandName})),i=await e.asker.ask(text({key:`discord-command-description`,message:`Discord command description`,detected:`Ask the eve agent`,required:!0,validate:e=>e.trim().length===0?`Command description is required.`:e.trim().length>100?`Command description must be 100 characters or fewer.`:null})),a=await e.resolveVercelProject(`Discord`);return{botToken:n,commandName:r.trim(),commandDescription:i.trim(),project:a,slug:await t.deriveConnectorSlug(e.appRoot)}}async function applyDiscordSetup(e,t,n=defaultDeps){let r=await n.resolveApplication(e.botToken),i=await n.provisionConnector({botToken:e.botToken,log:t.presenter.log,project:e.project,projectRoot:t.appRoot,slug:e.slug,signal:t.signal});await n.registerCommand(r.id,e.botToken,{name:e.commandName,description:e.commandDescription}),await n.configureEndpoint(e.botToken,i.id),await n.writeTextFile(join(t.appRoot,`agent/channels/discord.ts`),connectTemplate(i.uid),{force:t.force});let o=`https://discord.com/oauth2/authorize?client_id=${encodeURIComponent(r.id)}&scope=bot%20applications.commands&permissions=3072`;return t.presenter.nextSteps([`Install the Discord application, then try /${e.commandName}: ${o}`]),{deploymentRequired:!0,facts:[{label:`Discord application dashboard`,value:`https://discord.com/developers/applications/${r.id}/information`,kind:`url`}]}}const DISCORD_SETUP=defineSetupIntegration({kind:`discord`,label:`Discord`,hint:`Slash commands and interactions`,prepare:prepareDiscordSetup,apply:applyDiscordSetup});export{DISCORD_SETUP,applyDiscordSetup,prepareDiscordSetup};
@@ -12,4 +12,4 @@ export default githubChannel({
12
12
  botName: ${JSON.stringify(t)},
13
13
  credentials: connectGitHubCredentials(${JSON.stringify(e)}),${a}
14
14
  });
15
- `}async function prepareGitHubSetup(e,t=defaultDeps){if(e.environment.vercel.kind===`unavailable`)throw Error("GitHub setup requires an authenticated Vercel CLI. Run `vercel login`, then retry.");return{events:await e.asker.askMany(githubEventsQuestion),project:await e.resolveVercelProject(`GitHub`),slug:await t.deriveConnectorSlug(e.appRoot)}}async function applyGitHubSetup(e,t,r=defaultDeps){t.presenter.log.info(`GitHub App`),t.presenter.log.info(`Vercel Connect creates a GitHub App and routes verified webhooks to your deployed agent.`);let i=await r.provisionConnector({log:t.presenter.log,events:e.events,project:e.project,projectRoot:t.appRoot,slug:e.slug,signal:t.signal});return await r.writeTextFile(join(t.appRoot,`agent/channels/github.ts`),connectTemplate(i.uid,i.appSlug,e.events),{force:t.force}),t.presenter.nextSteps([`Deploy the agent, then open the GitHub App in Vercel Connect and install it in the organization or account where you want to use it.`,`Add @${i.appSlug} to a new issue, pull request, or review comment to invoke the agent. GitHub may not autocomplete or render the token as a linked mention.`]),{facts:[],deploymentRequired:!0}}const GITHUB_SETUP=defineSetupIntegration({kind:`github`,label:`GitHub`,hint:`Respond to issues, pull requests, and comments`,prepare:prepareGitHubSetup,apply:applyGitHubSetup});export{GITHUB_SETUP,applyGitHubSetup,prepareGitHubSetup};
15
+ `}async function prepareGitHubSetup(e,t=defaultDeps){return{events:await e.asker.askMany(githubEventsQuestion),project:await e.resolveVercelProject(`GitHub`),slug:await t.deriveConnectorSlug(e.appRoot)}}async function applyGitHubSetup(e,t,r=defaultDeps){t.presenter.log.info(`GitHub App`),t.presenter.log.info(`Vercel Connect creates a GitHub App and routes verified webhooks to your deployed agent.`);let i=await r.provisionConnector({log:t.presenter.log,events:e.events,project:e.project,projectRoot:t.appRoot,slug:e.slug,signal:t.signal});return await r.writeTextFile(join(t.appRoot,`agent/channels/github.ts`),connectTemplate(i.uid,i.appSlug,e.events),{force:t.force}),t.presenter.nextSteps([`Deploy the agent, then open the GitHub App in Vercel Connect and install it in the organization or account where you want to use it.`,`Add @${i.appSlug} to a new issue, pull request, or review comment to invoke the agent. GitHub may not autocomplete or render the token as a linked mention.`]),{facts:[],deploymentRequired:!0}}const GITHUB_SETUP=defineSetupIntegration({kind:`github`,label:`GitHub`,hint:`Respond to issues, pull requests, and comments`,prepare:prepareGitHubSetup,apply:applyGitHubSetup});export{GITHUB_SETUP,applyGitHubSetup,prepareGitHubSetup};
@@ -4,4 +4,4 @@ import { linearChannel } from "eve/channels/linear";
4
4
  export default linearChannel({
5
5
  credentials: connectLinearCredentials(${JSON.stringify(e)}),
6
6
  });
7
- `}async function prepareLinearSetup(e,t=defaultDeps){if(e.environment.vercel.kind===`unavailable`)throw Error("Linear setup requires an authenticated Vercel CLI. Run `vercel login`, then retry.");let n=await e.resolveVercelProject(`Linear`),r=linearSafeConnectorSlug(await t.deriveConnectorSlug(e.appRoot)),i=linearSafeConnectorSlug(await e.asker.ask(text({key:`linear.connector-name`,message:`Name your Linear agent`,recommended:r,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null}))),a=await t.findConnector({project:n,projectRoot:e.appRoot,slug:i,signal:e.signal});if(a===void 0)return{project:n,connector:{kind:`create`,slug:i}};let o=await e.asker.ask(select({key:`linear.existing-connector`,message:`A Linear connector named "${i}" already exists. What would you like to do?`,options:[{id:`reuse`,label:`Reuse existing connector`,value:`reuse`},{id:`new`,label:`Create a new connector`,value:`new`},{id:`exit`,label:`Exit setup`,value:`exit`}],recommended:`reuse`}));if(o===`exit`)throw new WizardCancelledError;return o===`reuse`?{project:n,connector:{kind:`reuse`,connector:a}}:{project:n,connector:{kind:`create`,slug:linearSafeConnectorSlug(await e.asker.ask(text({key:`linear.new-connector-name`,message:`Name the new Linear agent`,recommended:`${i}-2`,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null})))}}}async function applyLinearSetup(e,t,n=defaultDeps){let r=e.connector.kind===`reuse`?(await n.attachConnector({connector:e.connector.connector,log:t.presenter.log,project:e.project,projectRoot:t.appRoot,signal:t.signal}),e.connector.connector):await n.provisionConnector({log:t.presenter.log,project:e.project,projectRoot:t.appRoot,slug:e.connector.slug,signal:t.signal});return await n.writeTextFile(join(t.appRoot,`agent/channels/linear.ts`),connectTemplate(r.uid),{force:t.force}),t.presenter.nextSteps([`Deploy the agent, then open the Linear app in Vercel Connect and install it in the workspace where you want to delegate issues and comments.`,`Delegate an issue or mention the agent in an Agent Session to start a conversation.`]),{facts:[],deploymentRequired:!0}}const LINEAR_SETUP=defineSetupIntegration({kind:`linear`,label:`Linear Agent`,hint:`Delegate Linear issues and comments`,prepare:prepareLinearSetup,apply:applyLinearSetup});export{LINEAR_SETUP,applyLinearSetup,linearSafeConnectorSlug,prepareLinearSetup};
7
+ `}async function prepareLinearSetup(e,t=defaultDeps){let n=await e.resolveVercelProject(`Linear`),r=linearSafeConnectorSlug(await t.deriveConnectorSlug(e.appRoot)),i=linearSafeConnectorSlug(await e.asker.ask(text({key:`linear.connector-name`,message:`Name your Linear agent`,recommended:r,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null}))),a=await t.findConnector({project:n,projectRoot:e.appRoot,slug:i,signal:e.signal});if(a===void 0)return{project:n,connector:{kind:`create`,slug:i}};let o=await e.asker.ask(select({key:`linear.existing-connector`,message:`A Linear connector named "${i}" already exists. What would you like to do?`,options:[{id:`reuse`,label:`Reuse existing connector`,value:`reuse`},{id:`new`,label:`Create a new connector`,value:`new`},{id:`exit`,label:`Exit setup`,value:`exit`}],recommended:`reuse`}));if(o===`exit`)throw new WizardCancelledError;return o===`reuse`?{project:n,connector:{kind:`reuse`,connector:a}}:{project:n,connector:{kind:`create`,slug:linearSafeConnectorSlug(await e.asker.ask(text({key:`linear.new-connector-name`,message:`Name the new Linear agent`,recommended:`${i}-2`,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null})))}}}async function applyLinearSetup(e,t,n=defaultDeps){let r=e.connector.kind===`reuse`?(await n.attachConnector({connector:e.connector.connector,log:t.presenter.log,project:e.project,projectRoot:t.appRoot,signal:t.signal}),e.connector.connector):await n.provisionConnector({log:t.presenter.log,project:e.project,projectRoot:t.appRoot,slug:e.connector.slug,signal:t.signal});return await n.writeTextFile(join(t.appRoot,`agent/channels/linear.ts`),connectTemplate(r.uid),{force:t.force}),t.presenter.nextSteps([`Deploy the agent, then open the Linear app in Vercel Connect and install it in the workspace where you want to delegate issues and comments.`,`Delegate an issue or mention the agent in an Agent Session to start a conversation.`]),{facts:[],deploymentRequired:!0}}const LINEAR_SETUP=defineSetupIntegration({kind:`linear`,label:`Linear Agent`,hint:`Delegate Linear issues and comments`,prepare:prepareLinearSetup,apply:applyLinearSetup});export{LINEAR_SETUP,applyLinearSetup,linearSafeConnectorSlug,prepareLinearSetup};
@@ -4,7 +4,7 @@ import { photonIMessageChannel } from "eve/channels/photon";
4
4
  export default photonIMessageChannel({
5
5
  credentials: connectPhotonCredentials(${JSON.stringify(e)}),
6
6
  });
7
- `}async function preparePhotonSetup(e,r=defaultDeps){let i=basename(e.appRoot),a=await e.asker.ask(select({key:`photon-credentials`,message:`How would you like to configure Photon?`,options:[{id:`vercel`,value:`vercel-connect`,label:`Set up Vercel Connect`,hint:`Use a linked Vercel project`},{id:`portable`,value:`environment`,label:`Use portable credentials`,hint:`Configure the Photon webhook manually after deployment`}],recommended:e.environment.vercel.kind===`available`?`vercel-connect`:`environment`,required:!0}));if(a===`vercel-connect`&&e.environment.vercel.kind===`unavailable`)throw Error("Vercel Connect requires an authenticated Vercel CLI. Run `vercel login`, then retry Photon setup.");let o=`eve · ${i||`agent`}`,s=await e.asker.askEditable({key:`photon-project-source`,message:`Photon project`,options:[{id:`create`,value:`create`,label:`Create a new Photon project`,hint:`Name: ${o}`},{id:`existing`,value:`existing`,label:`Use an existing Photon project`,hint:`Enter its project credentials`}],recommended:`create`,required:!0,editable:{key:`photon-project-name`,value:`create`,label:`Name`,recommended:o,validate:e=>e.trim().length===0?`Project name cannot be empty.`:null}}),c=`create`;if(s.value===`existing`){let t=await e.asker.ask(text({key:`photon-project-id`,message:`Photon project ID`,required:!0})),r=await e.asker.ask(text({key:`photon-project-secret`,message:`Photon project secret`,required:!0,sensitive:!0,environment:`IMESSAGE_PROJECT_SECRET`}));c={projectId:t.trim(),projectSecret:r.trim()}}let l=c===`create`?void 0:await r.findDedicatedLine(c),u=l===void 0?await e.asker.ask(text({key:`photon-phone-number`,message:`Your iMessage phone number`,placeholder:`+15551234567`,required:!0,validate:validatePhotonPhoneNumber})):void 0,d=a===`vercel-connect`?await e.resolveVercelProject(`Photon`):void 0,f={agentName:i,credentials:a,photonProject:c,dedicatedLine:l,phoneNumber:u};return s.value===`create`&&(f.photonProjectName=s.text??o),d!==void 0&&(f.vercelProject=d),f}async function resolvePhotonProject(e,t,n){if(e.photonProject!==`create`)return n.useProject({...e.photonProject,dedicatedLine:e.dedicatedLine,phoneNumber:e.phoneNumber});if(e.phoneNumber===void 0)throw Error(`Photon phone number is required.`);let r=t.presenter.log.spinner?.(`Waiting for Photon approval…`,{kind:`external-action`,emphasis:`browser`}),i;try{let r=await n.provisionProject({projectName:e.photonProjectName??`eve · ${e.agentName||`agent`}`,phoneNumber:e.phoneNumber,signal:t.signal,onAuthorization(e){i=t.presenter.beginExternalAction({message:`Authorize Photon`,url:e.verificationUrl,userCode:e.userCode}),n.openUrl(e.verificationUrl)}});return i?.complete(),r}finally{r?.stop()}}async function applyPhotonSetup(e,t,n=defaultDeps){let r=await resolvePhotonProject(e,t,n);try{let i=join(t.appRoot,`agent/channels/photon.ts`);if(e.credentials===`vercel-connect`){let a=await n.deriveConnectorSlug(t.appRoot,e.agentName),o=await n.provisionConnector({credentials:r,log:t.presenter.log,project:e.vercelProject,projectRoot:t.appRoot,slug:a,signal:t.signal});await n.writeTextFile(i,connectTemplate(o.uid),{force:t.force})}else await n.appendEnv(join(t.appRoot,`.env.local`),{IMESSAGE_PROJECT_ID:r.projectId,IMESSAGE_PROJECT_SECRET:r.projectSecret}),await n.writeTextFile(i,`import { photonIMessageChannel } from "eve/channels/photon";
7
+ `}async function preparePhotonSetup(e,r=defaultDeps){let i=basename(e.appRoot),a=await e.asker.ask(select({key:`photon-credentials`,message:`How would you like to configure Photon?`,options:[{id:`vercel`,value:`vercel-connect`,label:`Set up Vercel Connect`,hint:`Use a linked Vercel project`},{id:`portable`,value:`environment`,label:`Use portable credentials`,hint:`Configure the Photon webhook manually after deployment`}],recommended:e.environment.vercel.kind===`available`?`vercel-connect`:`environment`,required:!0})),o=`eve · ${i||`agent`}`,s=await e.asker.askEditable({key:`photon-project-source`,message:`Photon project`,options:[{id:`create`,value:`create`,label:`Create a new Photon project`,hint:`Name: ${o}`},{id:`existing`,value:`existing`,label:`Use an existing Photon project`,hint:`Enter its project credentials`}],recommended:`create`,required:!0,editable:{key:`photon-project-name`,value:`create`,label:`Name`,recommended:o,validate:e=>e.trim().length===0?`Project name cannot be empty.`:null}}),c=`create`;if(s.value===`existing`){let t=await e.asker.ask(text({key:`photon-project-id`,message:`Photon project ID`,required:!0})),r=await e.asker.ask(text({key:`photon-project-secret`,message:`Photon project secret`,required:!0,sensitive:!0,environment:`IMESSAGE_PROJECT_SECRET`}));c={projectId:t.trim(),projectSecret:r.trim()}}let l=c===`create`?void 0:await r.findDedicatedLine(c),u=l===void 0?await e.asker.ask(text({key:`photon-phone-number`,message:`Your iMessage phone number`,placeholder:`+15551234567`,required:!0,validate:validatePhotonPhoneNumber})):void 0,d=a===`vercel-connect`?await e.resolveVercelProject(`Photon`):void 0,f={agentName:i,credentials:a,photonProject:c,dedicatedLine:l,phoneNumber:u};return s.value===`create`&&(f.photonProjectName=s.text??o),d!==void 0&&(f.vercelProject=d),f}async function resolvePhotonProject(e,t,n){if(e.photonProject!==`create`)return n.useProject({...e.photonProject,dedicatedLine:e.dedicatedLine,phoneNumber:e.phoneNumber});if(e.phoneNumber===void 0)throw Error(`Photon phone number is required.`);let r=t.presenter.log.spinner?.(`Waiting for Photon approval…`,{kind:`external-action`,emphasis:`browser`}),i;try{let r=await n.provisionProject({projectName:e.photonProjectName??`eve · ${e.agentName||`agent`}`,phoneNumber:e.phoneNumber,signal:t.signal,onAuthorization(e){i=t.presenter.beginExternalAction({message:`Authorize Photon`,url:e.verificationUrl,userCode:e.userCode}),n.openUrl(e.verificationUrl)}});return i?.complete(),r}finally{r?.stop()}}async function applyPhotonSetup(e,t,n=defaultDeps){let r=await resolvePhotonProject(e,t,n);try{let i=join(t.appRoot,`agent/channels/photon.ts`);if(e.credentials===`vercel-connect`){let a=await n.deriveConnectorSlug(t.appRoot,e.agentName),o=await n.provisionConnector({credentials:r,log:t.presenter.log,project:e.vercelProject,projectRoot:t.appRoot,slug:a,signal:t.signal});await n.writeTextFile(i,connectTemplate(o.uid),{force:t.force})}else await n.appendEnv(join(t.appRoot,`.env.local`),{IMESSAGE_PROJECT_ID:r.projectId,IMESSAGE_PROJECT_SECRET:r.projectSecret}),await n.writeTextFile(i,`import { photonIMessageChannel } from "eve/channels/photon";
8
8
 
9
9
  async function photonCredentials() {
10
10
  const projectId = process.env.IMESSAGE_PROJECT_ID;
@@ -1 +1 @@
1
- import{defineSetupIntegration}from"../types.js";import{installScaffoldDependencies,reportOverwrittenFiles}from"../shared/scaffold.js";import{deriveSlackConnectorSlug,ensureChannel}from"#setup/scaffold/index.js";import{WizardCancelledError}from"#setup/step.js";import{select}from"#setup/ask.js";import{inspectSlackbotConnectors,provisionSlackbot,reconcileSlackUid}from"#setup/slackbot.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";function slackbotFailureCopy(e){switch(e.state){case`not-installed`:return{reason:`Slackbot is not connected to a Slack workspace. Slack channel was not added.`,followUp:"Re-run `eve add channel/slack` after the workspace install is complete."};case`cleanup-failed`:return{reason:`The abandoned Slack connector could not be removed. Slack channel was not added.`,followUp:`Resolve the cleanup warning above before trying again.`};case`connector-lookup-failed`:return{reason:`Existing Slack connectors could not be inspected. Slack channel was not added.`,followUp:"Restore Vercel CLI access, then re-run `eve add channel/slack`."};case`installation-check-failed`:return{reason:`Slack workspace installation could not be verified. Slack channel was not added.`,followUp:"Verify Vercel Connect is reachable, then re-run `eve add channel/slack`."};case`existing-not-installed`:return{reason:`The existing Slack connector is not connected to a Slack workspace. Slack channel was not added.`,followUp:`Resolve the existing connector warning above before trying again.`};case`detach-failed`:return{reason:`Slackbot provisioning could not replace the existing trigger destination. Slack channel was not added.`,followUp:"Run the `vercel connect detach` and `vercel connect attach` commands above."};case`attach-failed`:return{reason:`Slackbot provisioning did not attach this project. Slack channel was not added.`,followUp:"Finish event delivery with the `vercel connect attach` command above."};case`create-failed`:return{reason:`Slackbot creation failed.`,followUp:"Add it later with `eve add channel/slack`."}}}const defaultDeps={deriveSlackConnectorSlug,ensureChannel,inspectConnectors:inspectSlackbotConnectors,provisionSlackbot,reconcileSlackUid};async function chooseConnector(e,t,n){return t.length===0?`create`:e.asker.ask(select({key:`slack-connector`,message:`Which Slack app would you like to use?`,options:[...t.map(e=>({id:e.uid,value:e,label:`Use ${e.uid}`,hint:e.uid===n?.uid?`Matches this agent`:void 0})),{id:`create`,value:`create`,label:`Create a new Slack app`}],recommended:n??t[0]??`create`,required:!0}))}async function prepareSlackSetup(e,t=defaultDeps){let n=await e.asker.ask(select({key:`slack-credentials`,message:`How would you like to configure Slack?`,options:[{id:`vercel`,value:`vercel-connect`,label:`Set up Vercel Connect`,hint:`Use a linked Vercel project`},{id:`portable`,value:`environment`,label:`Use portable credentials`,hint:`Read Slack tokens from environment variables`}],recommended:`vercel-connect`,required:!0})),r=await t.deriveSlackConnectorSlug(e.appRoot);if(n===`environment`)return{credentials:n,slug:r};if(e.environment.vercel.kind===`unavailable`)throw Error("Vercel Connect requires an authenticated Vercel CLI. Run `vercel login`, then retry Slack setup.");let i=await e.resolveVercelProject(`Slack`);if(i.projectId.length===0)throw Error(`Slack setup with Vercel Connect requires a linked Vercel project.`);let a=await t.inspectConnectors(e.presenter.log,e.appRoot,r,e.signal);return{credentials:n,slug:r,project:i,connector:a.state===`found`?await chooseConnector(e,a.connectors,a.preferred):`create`}}async function applySlackSetup(e,r,i=defaultDeps){if(e.credentials===`environment`){let t=await i.ensureChannel({projectRoot:r.appRoot,kind:`slack`,slackConnectorSlug:e.slug,slackCredentials:`environment`,force:r.force,skipDependencyMutation:!0});return reportOverwrittenFiles(r.presenter.log,t.filesOverwritten),r.presenter.log.success(`Scaffolded channel: slack`),r.presenter.nextSteps([`Set SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET in .env.local (listed in .env.example).`,`Configure your Slack app to send events to /eve/v1/slack on your public agent URL.`]),{facts:[],deploymentRequired:!0}}let o=await i.provisionSlackbot(r.presenter.log,r.appRoot,e.slug,void 0,{signal:r.signal,selectConnector:async()=>e.connector});if(r.signal?.throwIfAborted(),o.state===`cancelled`)throw new WizardCancelledError;if(o.state!==`attached`){let e=slackbotFailureCopy(o);throw Error(`${e.reason} ${e.followUp}`)}let s=await i.ensureChannel({projectRoot:r.appRoot,kind:`slack`,slackConnectorUid:o.connectorUid,slackConnectorSlug:e.slug,force:r.force,skipDependencyMutation:!0});if(reportOverwrittenFiles(r.presenter.log,s.filesOverwritten),s.action===`skipped`&&!await i.reconcileSlackUid(r.presenter.log,r.appRoot,o,`slack/${e.slug}`))throw Error(`Slack connector UID update is required before deployment.`);return r.presenter.log.success(`Scaffolded channel: slack`),await installScaffoldDependencies({changed:s.packageJsonUpdated.length>0,log:r.presenter.log,projectPath:r.appRoot,signal:r.signal}),{facts:o.chatUrl===void 0?[]:[{label:`Agent Slack DM`,value:slackMessageDeepLink(o.chatUrl),kind:`url`}],deploymentRequired:!0}}const SLACK_SETUP=defineSetupIntegration({kind:`slack`,label:`Slack`,hint:`Slack app mentions and DMs`,prepare:prepareSlackSetup,apply:applySlackSetup});export{SLACK_SETUP,applySlackSetup,prepareSlackSetup};
1
+ import{defineSetupIntegration}from"../types.js";import{installScaffoldDependencies,reportOverwrittenFiles}from"../shared/scaffold.js";import{deriveSlackConnectorSlug,ensureChannel}from"#setup/scaffold/index.js";import{WizardCancelledError}from"#setup/step.js";import{select}from"#setup/ask.js";import{inspectSlackbotConnectors,provisionSlackbot,reconcileSlackUid}from"#setup/slackbot.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";function slackbotFailureCopy(e){switch(e.state){case`not-installed`:return{reason:`Slackbot is not connected to a Slack workspace. Slack channel was not added.`,followUp:"Re-run `eve add channel/slack` after the workspace install is complete."};case`cleanup-failed`:return{reason:`The abandoned Slack connector could not be removed. Slack channel was not added.`,followUp:`Resolve the cleanup warning above before trying again.`};case`connector-lookup-failed`:return{reason:`Existing Slack connectors could not be inspected. Slack channel was not added.`,followUp:"Restore Vercel CLI access, then re-run `eve add channel/slack`."};case`installation-check-failed`:return{reason:`Slack workspace installation could not be verified. Slack channel was not added.`,followUp:"Verify Vercel Connect is reachable, then re-run `eve add channel/slack`."};case`existing-not-installed`:return{reason:`The existing Slack connector is not connected to a Slack workspace. Slack channel was not added.`,followUp:`Resolve the existing connector warning above before trying again.`};case`detach-failed`:return{reason:`Slackbot provisioning could not replace the existing trigger destination. Slack channel was not added.`,followUp:"Run the `vercel connect detach` and `vercel connect attach` commands above."};case`attach-failed`:return{reason:`Slackbot provisioning did not attach this project. Slack channel was not added.`,followUp:"Finish event delivery with the `vercel connect attach` command above."};case`create-failed`:return{reason:`Slackbot creation failed.`,followUp:"Add it later with `eve add channel/slack`."}}}const defaultDeps={deriveSlackConnectorSlug,ensureChannel,inspectConnectors:inspectSlackbotConnectors,provisionSlackbot,reconcileSlackUid};async function chooseConnector(e,t,n){return t.length===0?`create`:e.asker.ask(select({key:`slack-connector`,message:`Which Slack app would you like to use?`,options:[...t.map(e=>({id:e.uid,value:e,label:`Use ${e.uid}`,hint:e.uid===n?.uid?`Matches this agent`:void 0})),{id:`create`,value:`create`,label:`Create a new Slack app`}],recommended:n??t[0]??`create`,required:!0}))}async function prepareSlackSetup(e,t=defaultDeps){let n=await e.asker.ask(select({key:`slack-credentials`,message:`How would you like to configure Slack?`,options:[{id:`vercel`,value:`vercel-connect`,label:`Set up Vercel Connect`,hint:`Use a linked Vercel project`},{id:`portable`,value:`environment`,label:`Use portable credentials`,hint:`Read Slack tokens from environment variables`}],recommended:`vercel-connect`,required:!0})),r=await t.deriveSlackConnectorSlug(e.appRoot);if(n===`environment`)return{credentials:n,slug:r};let i=await e.resolveVercelProject(`Slack`);if(i.projectId.length===0)throw Error(`Slack setup with Vercel Connect requires a linked Vercel project.`);let a=await t.inspectConnectors(e.presenter.log,e.appRoot,r,e.signal);return{credentials:n,slug:r,project:i,connector:a.state===`found`?await chooseConnector(e,a.connectors,a.preferred):`create`}}async function applySlackSetup(e,r,i=defaultDeps){if(e.credentials===`environment`){let t=await i.ensureChannel({projectRoot:r.appRoot,kind:`slack`,slackConnectorSlug:e.slug,slackCredentials:`environment`,force:r.force,skipDependencyMutation:!0});return reportOverwrittenFiles(r.presenter.log,t.filesOverwritten),r.presenter.log.success(`Scaffolded channel: slack`),r.presenter.nextSteps([`Set SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET in .env.local (listed in .env.example).`,`Configure your Slack app to send events to /eve/v1/slack on your public agent URL.`]),{facts:[],deploymentRequired:!0}}let o=await i.provisionSlackbot(r.presenter.log,r.appRoot,e.slug,void 0,{signal:r.signal,selectConnector:async()=>e.connector});if(r.signal?.throwIfAborted(),o.state===`cancelled`)throw new WizardCancelledError;if(o.state!==`attached`){let e=slackbotFailureCopy(o);throw Error(`${e.reason} ${e.followUp}`)}let s=await i.ensureChannel({projectRoot:r.appRoot,kind:`slack`,slackConnectorUid:o.connectorUid,slackConnectorSlug:e.slug,force:r.force,skipDependencyMutation:!0});if(reportOverwrittenFiles(r.presenter.log,s.filesOverwritten),s.action===`skipped`&&!await i.reconcileSlackUid(r.presenter.log,r.appRoot,o,`slack/${e.slug}`))throw Error(`Slack connector UID update is required before deployment.`);return r.presenter.log.success(`Scaffolded channel: slack`),await installScaffoldDependencies({changed:s.packageJsonUpdated.length>0,log:r.presenter.log,projectPath:r.appRoot,signal:r.signal}),{facts:o.chatUrl===void 0?[]:[{label:`Agent Slack DM`,value:slackMessageDeepLink(o.chatUrl),kind:`url`}],deploymentRequired:!0}}const SLACK_SETUP=defineSetupIntegration({kind:`slack`,label:`Slack`,hint:`Slack app mentions and DMs`,prepare:prepareSlackSetup,apply:applySlackSetup});export{SLACK_SETUP,applySlackSetup,prepareSlackSetup};
@@ -1,9 +1,11 @@
1
1
  import type { PackageManagerKind } from "../../package-manager.js";
2
2
  import type { NodeEngineOverride } from "../../node-engine.js";
3
+ import type { AgentReasoningDefinition } from "../../../shared/agent-definition.js";
3
4
  import { type EvePackageContract } from "./project.js";
4
5
  export interface AddAgentToProjectOptions {
5
6
  projectRoot: string;
6
7
  model: string;
8
+ reasoning?: AgentReasoningDefinition;
7
9
  /**
8
10
  * The host project's package manager, which owns any manager-specific
9
11
  * generated project configuration. Defaults to pnpm.
@@ -1 +1 @@
1
- import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{readFile}from"node:fs/promises";import{join}from"node:path";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`^7.0.58`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.4.3`),f=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),p=[];for(let[e,n]of Object.entries(s)){let r=join(i.projectRoot,e);await writeTextFile(r,n),p.push(r)}let m=JSON.parse(await readFile(o,`utf8`)),h={"@vercel/connect":d,ai:u,eve:formatEveDependencySpecifier(l.version),zod:f},g={};for(let[e,t]of Object.entries(h))hasDeclaredDependency(m,e)||(g[e]=t);let _={};Object.keys(g).length>0&&(_.dependencies=g),isPackageManagerWorkspaceMember(a,i.projectRoot)||(_.nodeEngineRequirement=l.nodeEngine);let v=await patchPackageJson(o,_),y=(await patchWorkspaceRootPackageJson(a,i.projectRoot,{aiPackageVersion:u,nodeEngineRequirement:l.nodeEngine})).nodeEngineOverride??v.nodeEngineOverride;return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:i.projectRoot}),{filesWritten:p,dependenciesAdded:Object.keys(g).sort(),nodeEngineOverride:y}}export{addAgentToProject};
1
+ import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{readFile}from"node:fs/promises";import{join}from"node:path";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model,i.reasoning),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`^7.0.58`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.4.3`),f=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),p=[];for(let[e,n]of Object.entries(s)){let r=join(i.projectRoot,e);await writeTextFile(r,n),p.push(r)}let m=JSON.parse(await readFile(o,`utf8`)),h={"@vercel/connect":d,ai:u,eve:formatEveDependencySpecifier(l.version),zod:f},g={};for(let[e,t]of Object.entries(h))hasDeclaredDependency(m,e)||(g[e]=t);let _={};Object.keys(g).length>0&&(_.dependencies=g),isPackageManagerWorkspaceMember(a,i.projectRoot)||(_.nodeEngineRequirement=l.nodeEngine);let v=await patchPackageJson(o,_),y=(await patchWorkspaceRootPackageJson(a,i.projectRoot,{aiPackageVersion:u,nodeEngineRequirement:l.nodeEngine})).nodeEngineOverride??v.nodeEngineOverride;return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:i.projectRoot}),{filesWritten:p,dependenciesAdded:Object.keys(g).sort(),nodeEngineOverride:y}}export{addAgentToProject};
@@ -1,4 +1,5 @@
1
1
  import type { PackageManagerKind } from "../../package-manager.js";
2
+ import type { AgentReasoningDefinition } from "../../../shared/agent-definition.js";
2
3
  import { type WorkspaceRootMutation } from "../workspace-root.js";
3
4
  export declare const CURRENT_DIRECTORY_PROJECT_NAME = ".";
4
5
  export declare const DEFAULT_AI_PACKAGE_VERSION = "__AI_SDK_VERSION__";
@@ -40,13 +41,14 @@ export declare function byokProviderEnvVar(modelId: string): string;
40
41
  * subset `eve init` writes when adding an agent to an existing project, where
41
42
  * everything outside `agent/` belongs to the host app.
42
43
  */
43
- export declare function agentTemplateFiles(model: string): Record<string, string>;
44
+ export declare function agentTemplateFiles(model: string, reasoning?: AgentReasoningDefinition): Record<string, string>;
44
45
  export declare function formatEveDependencySpecifier(versionOrSpecifier: string): string;
45
46
  /** Trailing fields only written when the scaffold is not a workspace member. */
46
47
  export declare const ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX = ",\n \"engines\": {\n \"node\": \"__EVE_INIT_NODE_ENGINE__\"\n }\n";
47
48
  export interface ScaffoldBaseProjectOptions {
48
49
  projectName: string;
49
50
  model: string;
51
+ reasoning?: AgentReasoningDefinition;
50
52
  /**
51
53
  * The manager that owns command execution and manager-specific generated
52
54
  * project files for this scaffold.
@@ -1,8 +1,8 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.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.58`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.32.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){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).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{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.58`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.33.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":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return 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__",
5
- });
5
+ __EVE_INIT_REASONING__});
6
6
  `;function packageManagerAiPinTemplateSuffix(e){switch(e){case`bun`:case`npm`:return`,
7
7
  "overrides": {
8
8
  "ai": "__EVE_INIT_AI_SDK_VERSION__"
@@ -128,7 +128,7 @@ event. Do not start a continuation. When a completed event has
128
128
 
129
129
  export default defineAgent({
130
130
  model: "__EVE_INIT_MODEL__",
131
- modelOptions: {
131
+ __EVE_INIT_REASONING__ modelOptions: {
132
132
  providerOptions: {
133
133
  gateway: {
134
134
  byok: {
@@ -138,4 +138,4 @@ export default defineAgent({
138
138
  },
139
139
  },
140
140
  });
141
- `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=blockingCreateInPlaceEntries(await readdir(e));if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(t){let i=resolve(t.targetDirectory??process.cwd(),t.projectName),c=t.projectName===`.`,l=t.overwriteExisting??!1,u=t.byokProvider??!1,d=t.packageManager??`pnpm`,f=resolveEvePackageContract(t.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(t.workspaceProbeDirectory??i),h=isPackageManagerWorkspaceMember(d,m);if(c)await assertCanCreateInPlace(i,l);else if(await pathExists(i))throw Error(`Cannot create project because "${i}" already exists.`);let g={appName:basename(i),model:t.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,t.aiPackageVersion??`^7.0.58`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.3`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,t.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,t.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(i,{recursive:!0});for(let[e,a]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let o=`${i}/${e}`,s=await pathExists(o);await writeTextFile(o,renderTemplate(a,g),{force:c&&l}),s&&await t.onOverwriteFile?.(o)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:i,workspaceProbeRoot:m,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),i}async function isEveProject(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${n}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
141
+ `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=blockingCreateInPlaceEntries(await readdir(e));if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(t){let i=resolve(t.targetDirectory??process.cwd(),t.projectName),c=t.projectName===`.`,l=t.overwriteExisting??!1,u=t.byokProvider??!1,d=t.packageManager??`pnpm`,f=resolveEvePackageContract(t.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(t.workspaceProbeDirectory??i),h=isPackageManagerWorkspaceMember(d,m);if(c)await assertCanCreateInPlace(i,l);else if(await pathExists(i))throw Error(`Cannot create project because "${i}" already exists.`);let g={appName:basename(i),model:t.model,reasoning:t.reasoning,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,t.aiPackageVersion??`^7.0.58`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.3`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,t.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,t.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(i,{recursive:!0});for(let[e,a]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let o=`${i}/${e}`,s=await pathExists(o);await writeTextFile(o,renderTemplate(a,g),{force:c&&l}),s&&await t.onOverwriteFile?.(o)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:i,workspaceProbeRoot:m,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),i}async function isEveProject(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${n}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
@@ -43,6 +43,7 @@ export type ModelRouting = {
43
43
  export type InternalAgentModelDefinition = {
44
44
  id: string;
45
45
  contextWindowTokens?: number;
46
+ maxOutputTokens?: number;
46
47
  source?: ModuleSourceRef;
47
48
  providerOptions?: Record<string, JsonObject>;
48
49
  };
@@ -55,17 +56,15 @@ export type PublicAgentStaticModelDefinition = string | LanguageModel;
55
56
  export type AgentModelResolveContext = DynamicResolveContext;
56
57
  export interface PublicAgentModelSelectionDefinition {
57
58
  readonly model: PublicAgentStaticModelDefinition;
58
- /** Context window of the selected model, in tokens; never inherited from the fallback. */
59
+ /** Context window of the selected model, in tokens. */
59
60
  readonly modelContextWindowTokens?: number;
60
- /** Provider options for the selected model; defaults to the agent-level `modelOptions`. */
61
+ /** Provider options for the selected model. */
61
62
  readonly modelOptions?: AgentModelOptionsDefinition;
62
63
  }
63
- export type PublicAgentDynamicModelResult = PublicAgentStaticModelDefinition | PublicAgentModelSelectionDefinition | null;
64
+ export type PublicAgentDynamicModelResult = PublicAgentStaticModelDefinition | PublicAgentModelSelectionDefinition;
64
65
  export type AgentModelResolver = (event: unknown, ctx: AgentModelResolveContext) => PublicAgentDynamicModelResult | Promise<PublicAgentDynamicModelResult>;
65
- export type PublicAgentDynamicModelDefinition = DynamicSentinel<PublicAgentDynamicModelResult, PublicAgentStaticModelDefinition>;
66
+ export type PublicAgentDynamicModelDefinition = DynamicSentinel<PublicAgentDynamicModelResult>;
66
67
  export interface PublicAgentDynamicModelDefinitionInput {
67
- /** Compiled static model: build-time metadata and the active model when no scope is set. */
68
- readonly fallback: PublicAgentStaticModelDefinition;
69
68
  readonly events: DynamicSentinel<PublicAgentDynamicModelResult>["events"];
70
69
  }
71
70
  export declare function isDynamicModelDefinition(value: unknown): value is PublicAgentDynamicModelDefinition;
@@ -237,7 +236,7 @@ export type InternalAgentDefinition = {
237
236
  * package name or app-root basename). Authored definitions do not carry
238
237
  * a `name` field.
239
238
  */
240
- export type PublicAgentDefinition = {
239
+ type PublicAgentDefinitionBase = {
241
240
  /**
242
241
  * Human-readable description of the agent's purpose. Required for
243
242
  * subagents (authored under `subagents/<id>/agent.ts`): surfaced to
@@ -251,22 +250,6 @@ export type PublicAgentDefinition = {
251
250
  * {@link AgentExperimentalDefinition}.
252
251
  */
253
252
  readonly experimental?: AgentExperimentalDefinition;
254
- /**
255
- * Language model used for agent turns. Accepts an AI Gateway model ID, any AI
256
- * SDK-compatible language model, or `defineDynamic({ fallback, events })` for
257
- * scoped dynamic model selection.
258
- */
259
- readonly model: PublicAgentModelDefinition;
260
- /**
261
- * Optional override for the primary model's context window size, in tokens.
262
- *
263
- * Escape hatch for cases where eve cannot resolve the model's metadata via
264
- * the AI Gateway model catalog (e.g. a custom or unlisted model id). When
265
- * set, eve uses this value verbatim and skips the AI Gateway lookup. Prefer
266
- * leaving this unset so eve can stay in sync with provider metadata.
267
- */
268
- readonly modelContextWindowTokens?: number;
269
- readonly modelOptions?: AgentModelOptionsDefinition;
270
253
  /**
271
254
  * Provider-agnostic reasoning effort for the agent's turn model calls.
272
255
  * Support for individual levels depends on the selected model and provider.
@@ -284,3 +267,20 @@ export type PublicAgentDefinition = {
284
267
  */
285
268
  readonly outputSchema?: StandardJSONSchemaV1<unknown, unknown> | JsonObject;
286
269
  };
270
+ /**
271
+ * Shared public definition for an agent. Static models may carry definition-level
272
+ * metadata; dynamic models must return metadata with each concrete selection.
273
+ */
274
+ export type PublicAgentDefinition = PublicAgentDefinitionBase & ({
275
+ /** Language model used for agent turns. */
276
+ readonly model: PublicAgentStaticModelDefinition;
277
+ /** Optional context-window override for the static model. */
278
+ readonly modelContextWindowTokens?: number;
279
+ readonly modelOptions?: AgentModelOptionsDefinition;
280
+ } | {
281
+ /** Resolver that must select a concrete model before model-dependent work. */
282
+ readonly model: PublicAgentDynamicModelDefinition;
283
+ readonly modelContextWindowTokens?: never;
284
+ readonly modelOptions?: never;
285
+ });
286
+ export {};
@@ -1 +1 @@
1
- import{isDynamicSentinel}from"#shared/dynamic-tool-definition.js";function isDynamicModelDefinition(e){return isDynamicSentinel(e)&&`fallback`in e}export{isDynamicModelDefinition};
1
+ import{isDynamicSentinel}from"#shared/dynamic-tool-definition.js";function isDynamicModelDefinition(e){return isDynamicSentinel(e)}export{isDynamicModelDefinition};
@@ -3,7 +3,7 @@ import type { UserContent } from "ai";
3
3
  import type { ChannelReceiveContext } from "#channel/channel-operations.js";
4
4
  import type { RouteDefinition } from "#channel/routes.js";
5
5
  import type { Session, SessionHandle } from "#channel/session.js";
6
- import type { SessionAuthContext } from "#channel/types.js";
6
+ import type { SessionAuthContext, TurnPolicy } from "#channel/types.js";
7
7
  /**
8
8
  * Enriched return shape from a channel's {@link ChannelAdapter.fetchFile}
9
9
  * function. Return a bare {@link Buffer} when only bytes are known, or
@@ -40,6 +40,8 @@ export interface GenericReceiveInput<TReceiveTarget = Record<string, unknown>> {
40
40
  * projection).
41
41
  */
42
42
  export interface GenericChannelDefinition<TEvents, TState = undefined, TCtx = void, TReceiveTarget = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>> {
43
+ /** Policy used by message sends that do not provide an explicit override. */
44
+ readonly turnPolicy?: TurnPolicy;
43
45
  readonly state?: TState;
44
46
  /**
45
47
  * CORS policy for this channel's HTTP routes. `true` enables H3/Nitro's
@@ -106,25 +106,19 @@ export type DynamicToolEvents = {
106
106
  export type DynamicEvents<TResult = unknown> = {
107
107
  readonly [K in DynamicToolEventName]?: (event: unknown, ctx: DynamicResolveContext) => TResult | Promise<TResult>;
108
108
  };
109
- export type DynamicEventsWithFallback<TResult = unknown> = {
110
- readonly [K in DynamicToolEventName]?: (event: unknown, ctx: DynamicResolveContext) => Exclude<TResult, undefined> | Promise<Exclude<TResult, undefined>>;
111
- };
112
109
  /**
113
110
  * Marker discriminator for a `defineDynamic({ events })` export.
114
111
  */
115
112
  export declare const DYNAMIC_SENTINEL_KIND: "eve:dynamic";
116
113
  /**
117
114
  * Return value of `defineDynamic`: the runtime shape of a dynamic export,
118
- * stamped with a sentinel kind the compiler/normalizer detects. `TFallback`
119
- * is used by dynamic agent models.
115
+ * stamped with a sentinel kind the compiler/normalizer detects.
120
116
  */
121
- export type DynamicSentinel<TResult = unknown, TFallback = never> = {
117
+ export type DynamicSentinel<TResult = unknown> = {
122
118
  readonly kind: typeof DYNAMIC_SENTINEL_KIND;
123
119
  readonly events: DynamicEvents<TResult>;
124
- } & ([TFallback] extends [never] ? object : {
125
- readonly fallback: TFallback;
126
- });
127
- export declare function rejectDynamicSentinelFallback(sentinel: DynamicSentinel, message: string): void;
120
+ };
121
+ export declare function assertResolverOnlyDynamicSentinel(sentinel: DynamicSentinel, message: string): void;
128
122
  export declare function isDynamicSentinel(value: unknown): value is DynamicSentinel;
129
123
  /**
130
124
  * Symbol-based brand stamped by `defineTool` on every entry. Invisible
@@ -1 +1 @@
1
- const ALLOWED_DYNAMIC_TOOL_EVENTS=new Set([`session.started`,`turn.started`,`step.started`]),ALLOWED_DYNAMIC_INSTRUCTION_EVENTS=new Set([`session.started`,`turn.started`]),ALLOWED_DYNAMIC_SKILL_EVENTS=new Set([`session.started`,`turn.started`]),DYNAMIC_SENTINEL_KIND=`eve:dynamic`;function rejectDynamicSentinelFallback(e,t){if(`fallback`in e)throw Error(`${t} "fallback" is only supported on a dynamic agent model. For dynamic tools, skills, instructions, and subagents, return null when the capability should be omitted.`)}function isDynamicSentinel(e){return typeof e==`object`&&!!e&&e.kind===`eve:dynamic`}const TOOL_BRAND=Symbol.for(`eve:tool-brand`);function isBrandedToolEntry(e){return typeof e==`object`&&!!e&&e[TOOL_BRAND]===!0}const INSTRUCTIONS_BRAND=Symbol.for(`eve:instructions-brand`);function isBrandedInstructionsEntry(e){return typeof e==`object`&&!!e&&e[INSTRUCTIONS_BRAND]===!0}const SKILL_BRAND=Symbol.for(`eve:skill-brand`);function isBrandedSkillEntry(e){return typeof e==`object`&&!!e&&e[SKILL_BRAND]===!0}export{ALLOWED_DYNAMIC_INSTRUCTION_EVENTS,ALLOWED_DYNAMIC_SKILL_EVENTS,ALLOWED_DYNAMIC_TOOL_EVENTS,DYNAMIC_SENTINEL_KIND,INSTRUCTIONS_BRAND,SKILL_BRAND,TOOL_BRAND,isBrandedInstructionsEntry,isBrandedSkillEntry,isBrandedToolEntry,isDynamicSentinel,rejectDynamicSentinelFallback};
1
+ const ALLOWED_DYNAMIC_TOOL_EVENTS=new Set([`session.started`,`turn.started`,`step.started`]),ALLOWED_DYNAMIC_INSTRUCTION_EVENTS=new Set([`session.started`,`turn.started`]),ALLOWED_DYNAMIC_SKILL_EVENTS=new Set([`session.started`,`turn.started`]),DYNAMIC_SENTINEL_KIND=`eve:dynamic`;function assertResolverOnlyDynamicSentinel(e,t){let n=Object.keys(e).filter(e=>e!==`events`&&e!==`kind`);if(n.length>0)throw Error(`${t} Unknown key(s): ${n.join(`, `)}.`)}function isDynamicSentinel(e){return typeof e==`object`&&!!e&&e.kind===`eve:dynamic`}const TOOL_BRAND=Symbol.for(`eve:tool-brand`);function isBrandedToolEntry(e){return typeof e==`object`&&!!e&&e[TOOL_BRAND]===!0}const INSTRUCTIONS_BRAND=Symbol.for(`eve:instructions-brand`);function isBrandedInstructionsEntry(e){return typeof e==`object`&&!!e&&e[INSTRUCTIONS_BRAND]===!0}const SKILL_BRAND=Symbol.for(`eve:skill-brand`);function isBrandedSkillEntry(e){return typeof e==`object`&&!!e&&e[SKILL_BRAND]===!0}export{ALLOWED_DYNAMIC_INSTRUCTION_EVENTS,ALLOWED_DYNAMIC_SKILL_EVENTS,ALLOWED_DYNAMIC_TOOL_EVENTS,DYNAMIC_SENTINEL_KIND,INSTRUCTIONS_BRAND,SKILL_BRAND,TOOL_BRAND,assertResolverOnlyDynamicSentinel,isBrandedInstructionsEntry,isBrandedSkillEntry,isBrandedToolEntry,isDynamicSentinel};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-DwyRde1N.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-B-Hky2f4.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-DwyRde1N.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-B-Hky2f4.js";
2
2
 
3
3
  export { useEveAgent };
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-CX87G1vU.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-3oBnxzhV.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-CX87G1vU.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-3oBnxzhV.js";
2
2
 
3
3
  export { useEveAgent };