eve 0.19.0 → 0.21.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 (206) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/src/channel/types.d.ts +9 -5
  3. package/dist/src/chunks/{use-eve-agent-Dvy_Wjvq.js → use-eve-agent-CM24ZUEI.js} +48 -34
  4. package/dist/src/chunks/{use-eve-agent-Bh1NmXO9.js → use-eve-agent-CxcKypLZ.js} +48 -34
  5. package/dist/src/cli/dev/tui/setup-selection-input.js +1 -1
  6. package/dist/src/cli/dev/tui/stream-format.d.ts +4 -0
  7. package/dist/src/cli/dev/tui/stream-format.js +1 -1
  8. package/dist/src/cli/dev/tui/terminal-renderer.js +1 -1
  9. package/dist/src/cli/dev/tui/test/mock-terminal.d.ts +2 -0
  10. package/dist/src/cli/dev/tui/test/mock-terminal.js +1 -1
  11. package/dist/src/client/index.d.ts +1 -1
  12. package/dist/src/client/message-reducer-types.d.ts +11 -3
  13. package/dist/src/client/message-reducer.js +1 -1
  14. package/dist/src/compiler/manifest.js +1 -1
  15. package/dist/src/compiler/normalize-agent-config.js +1 -1
  16. package/dist/src/compiler/workspace-resources.js +1 -1
  17. package/dist/src/context/build-base-tool-context.d.ts +9 -0
  18. package/dist/src/context/build-base-tool-context.js +1 -0
  19. package/dist/src/context/build-dynamic-tools.js +1 -1
  20. package/dist/src/context/dynamic-skill-lifecycle.js +1 -1
  21. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  22. package/dist/src/context/keys.d.ts +0 -1
  23. package/dist/src/context/keys.js +1 -1
  24. package/dist/src/discover/sandbox.d.ts +0 -6
  25. package/dist/src/discover/sandbox.js +1 -1
  26. package/dist/src/evals/cli/eval.js +4 -1
  27. package/dist/src/evals/runner/discover.d.ts +10 -0
  28. package/dist/src/evals/runner/discover.js +1 -1
  29. package/dist/src/execution/create-session-step.d.ts +2 -1
  30. package/dist/src/execution/create-session-step.js +1 -1
  31. package/dist/src/execution/delegated-parent-notification.d.ts +6 -0
  32. package/dist/src/execution/delegated-parent-notification.js +1 -1
  33. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  34. package/dist/src/execution/dispatch-workflow-runtime-actions-step.js +1 -1
  35. package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +2 -0
  36. package/dist/src/execution/durable-session-store.d.ts +1 -0
  37. package/dist/src/execution/next-driver-action.d.ts +3 -0
  38. package/dist/src/execution/node-step.d.ts +8 -0
  39. package/dist/src/execution/node-step.js +1 -1
  40. package/dist/src/execution/run-session-limits.d.ts +21 -0
  41. package/dist/src/execution/run-session-limits.js +1 -0
  42. package/dist/src/execution/runtime-context.js +1 -1
  43. package/dist/src/execution/sandbox/abort-bound-session.d.ts +6 -0
  44. package/dist/src/execution/sandbox/abort-bound-session.js +1 -0
  45. package/dist/src/execution/sandbox/active-handles.d.ts +29 -0
  46. package/dist/src/execution/sandbox/active-handles.js +1 -0
  47. package/dist/src/execution/sandbox/bindings/docker.d.ts +2 -2
  48. package/dist/src/execution/sandbox/bindings/docker.js +1 -1
  49. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  50. package/dist/src/execution/sandbox/bindings/local-backend-utils.d.ts +1 -1
  51. package/dist/src/execution/sandbox/bindings/local-backend-utils.js +1 -1
  52. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
  53. package/dist/src/execution/sandbox/bindings/microsandbox-provider-state.d.ts +11 -0
  54. package/dist/src/execution/sandbox/bindings/microsandbox-provider-state.js +1 -0
  55. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +7 -4
  56. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
  57. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  58. package/dist/src/execution/sandbox/ensure.js +1 -1
  59. package/dist/src/execution/sandbox/prewarm.js +1 -1
  60. package/dist/src/execution/sandbox/require-sandbox.d.ts +3 -1
  61. package/dist/src/execution/sandbox/require-sandbox.js +1 -1
  62. package/dist/src/execution/session-callback-step.d.ts +6 -0
  63. package/dist/src/execution/session-callback-step.js +1 -1
  64. package/dist/src/execution/session.d.ts +14 -3
  65. package/dist/src/execution/session.js +2 -4
  66. package/dist/src/execution/skills/instructions.d.ts +8 -4
  67. package/dist/src/execution/skills/instructions.js +2 -2
  68. package/dist/src/execution/subagent-tool.d.ts +7 -0
  69. package/dist/src/execution/subagent-tool.js +1 -1
  70. package/dist/src/execution/subagent-usage-span.d.ts +9 -0
  71. package/dist/src/execution/subagent-usage-span.js +1 -0
  72. package/dist/src/execution/tool-auth.d.ts +2 -1
  73. package/dist/src/execution/tool-auth.js +1 -1
  74. package/dist/src/execution/turn-execution-cursor.d.ts +2 -0
  75. package/dist/src/execution/turn-workflow.js +1 -1
  76. package/dist/src/execution/web-fetch/tool.d.ts +6 -1
  77. package/dist/src/execution/web-fetch/tool.js +1 -1
  78. package/dist/src/execution/workflow-entry.d.ts +1 -0
  79. package/dist/src/execution/workflow-entry.js +1 -1
  80. package/dist/src/execution/workflow-runtime.js +1 -1
  81. package/dist/src/execution/workflow-skill-root.d.ts +6 -0
  82. package/dist/src/execution/workflow-skill-root.js +1 -0
  83. package/dist/src/execution/workflow-steps.d.ts +3 -0
  84. package/dist/src/execution/workflow-steps.js +1 -1
  85. package/dist/src/harness/advertised-tools.d.ts +1 -0
  86. package/dist/src/harness/advertised-tools.js +1 -1
  87. package/dist/src/harness/attachment-staging.js +1 -1
  88. package/dist/src/harness/compaction.d.ts +1 -1
  89. package/dist/src/harness/compaction.js +1 -1
  90. package/dist/src/harness/emission.js +1 -1
  91. package/dist/src/harness/execute-tool.d.ts +2 -1
  92. package/dist/src/harness/input-requests.d.ts +8 -0
  93. package/dist/src/harness/input-requests.js +1 -1
  94. package/dist/src/harness/model-call-error.js +1 -1
  95. package/dist/src/harness/runtime-actions.js +1 -1
  96. package/dist/src/harness/session-limit-continuation.d.ts +55 -0
  97. package/dist/src/harness/session-limit-continuation.js +1 -0
  98. package/dist/src/harness/session-limit-enforcement.d.ts +55 -0
  99. package/dist/src/harness/session-limit-enforcement.js +1 -0
  100. package/dist/src/harness/step-hooks.d.ts +1 -1
  101. package/dist/src/harness/step-hooks.js +1 -1
  102. package/dist/src/harness/subagent-depth.d.ts +1 -4
  103. package/dist/src/harness/subagent-depth.js +1 -1
  104. package/dist/src/harness/subagent-token-budget.d.ts +14 -0
  105. package/dist/src/harness/subagent-token-budget.js +1 -0
  106. package/dist/src/harness/tool-loop.js +1 -1
  107. package/dist/src/harness/tools.d.ts +2 -3
  108. package/dist/src/harness/tools.js +1 -1
  109. package/dist/src/harness/turn-cancellation.d.ts +8 -0
  110. package/dist/src/harness/turn-cancellation.js +1 -0
  111. package/dist/src/harness/turn-tag-state.d.ts +33 -0
  112. package/dist/src/harness/turn-tag-state.js +1 -1
  113. package/dist/src/harness/types.d.ts +23 -4
  114. package/dist/src/harness/workflow-sandbox.d.ts +1 -0
  115. package/dist/src/harness/workflow-sandbox.js +1 -1
  116. package/dist/src/harness/workflow-subagent-limit.d.ts +38 -0
  117. package/dist/src/harness/workflow-subagent-limit.js +1 -0
  118. package/dist/src/harness/workflow-tool-description.d.ts +6 -1
  119. package/dist/src/harness/workflow-tool-description.js +5 -3
  120. package/dist/src/internal/application/package.js +1 -1
  121. package/dist/src/internal/authored-definition/core.js +1 -1
  122. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  123. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  124. package/dist/src/internal/nitro/host/sandbox-shutdown-plugin.d.ts +40 -0
  125. package/dist/src/internal/nitro/host/sandbox-shutdown-plugin.js +1 -0
  126. package/dist/src/internal/nitro/host/start-production-server.js +1 -1
  127. package/dist/src/protocol/message.d.ts +31 -2
  128. package/dist/src/protocol/message.js +2 -2
  129. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +34 -3
  130. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  131. package/dist/src/public/channels/chat-sdk/index.d.ts +2 -0
  132. package/dist/src/public/channels/chat-sdk/index.js +1 -1
  133. package/dist/src/public/channels/chat-sdk/messageToUserContent.d.ts +13 -0
  134. package/dist/src/public/channels/chat-sdk/messageToUserContent.js +1 -0
  135. package/dist/src/public/channels/chat-sdk/notImplemented.d.ts +7 -0
  136. package/dist/src/public/channels/chat-sdk/notImplemented.js +1 -0
  137. package/dist/src/public/channels/slack/api.d.ts +14 -12
  138. package/dist/src/public/channels/slack/api.js +1 -1
  139. package/dist/src/public/definitions/approval.d.ts +4 -1
  140. package/dist/src/public/definitions/tool.d.ts +44 -0
  141. package/dist/src/public/definitions/tool.js +1 -1
  142. package/dist/src/public/tools/index.d.ts +1 -1
  143. package/dist/src/public/tools/index.js +1 -1
  144. package/dist/src/public/tools/internal.d.ts +3 -2
  145. package/dist/src/public/tools/internal.js +1 -1
  146. package/dist/src/runtime/actions/types.d.ts +9 -0
  147. package/dist/src/runtime/actions/types.js +1 -1
  148. package/dist/src/runtime/agent/bootstrap.d.ts +2 -0
  149. package/dist/src/runtime/agent/bootstrap.js +1 -1
  150. package/dist/src/runtime/connections/mcp-client.d.ts +2 -2
  151. package/dist/src/runtime/connections/mcp-client.js +1 -1
  152. package/dist/src/runtime/connections/openapi-client.d.ts +2 -2
  153. package/dist/src/runtime/connections/openapi-client.js +1 -1
  154. package/dist/src/runtime/connections/types.d.ts +6 -1
  155. package/dist/src/runtime/framework-tools/bash.js +1 -1
  156. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -1
  157. package/dist/src/runtime/framework-tools/glob.js +1 -1
  158. package/dist/src/runtime/framework-tools/grep.js +1 -1
  159. package/dist/src/runtime/framework-tools/read-file.js +1 -1
  160. package/dist/src/runtime/framework-tools/web-fetch.js +1 -1
  161. package/dist/src/runtime/framework-tools/write-file.js +1 -1
  162. package/dist/src/runtime/resolve-agent.js +1 -1
  163. package/dist/src/runtime/sandbox/keys.js +1 -1
  164. package/dist/src/runtime/sandbox/template-plan.js +1 -1
  165. package/dist/src/runtime/session-callback-route.js +1 -1
  166. package/dist/src/runtime/skills/sandbox-access.d.ts +1 -1
  167. package/dist/src/runtime/skills/sandbox-access.js +1 -1
  168. package/dist/src/runtime/workspace/seed-files.js +1 -1
  169. package/dist/src/sandbox/state.d.ts +0 -1
  170. package/dist/src/setup/scaffold/create/project.js +1 -1
  171. package/dist/src/setup/scaffold/create/web-template.d.ts +2 -2
  172. package/dist/src/setup/scaffold/create/web-template.js +77 -3
  173. package/dist/src/shared/agent-definition.d.ts +31 -3
  174. package/dist/src/shared/dynamic-tool-definition.d.ts +4 -1
  175. package/dist/src/shared/sandbox-backend.d.ts +7 -1
  176. package/dist/src/shared/skill-package.d.ts +2 -2
  177. package/dist/src/shared/skill-package.js +1 -1
  178. package/dist/src/shared/skill-paths.d.ts +28 -0
  179. package/dist/src/shared/skill-paths.js +2 -0
  180. package/dist/src/shared/token-usage.d.ts +22 -0
  181. package/dist/src/shared/token-usage.js +1 -0
  182. package/dist/src/shared/tool-definition.d.ts +1 -1
  183. package/dist/src/svelte/index.js +1 -1
  184. package/dist/src/svelte/use-eve-agent.js +1 -1
  185. package/dist/src/vue/index.js +1 -1
  186. package/dist/src/vue/use-eve-agent.js +1 -1
  187. package/docs/agent-config.md +32 -15
  188. package/docs/channels/chat-sdk.mdx +209 -0
  189. package/docs/channels/meta.json +1 -0
  190. package/docs/concepts/context-control.md +2 -2
  191. package/docs/concepts/default-harness.md +10 -0
  192. package/docs/concepts/sessions-runs-and-streaming.md +1 -1
  193. package/docs/guides/client/messages.mdx +4 -0
  194. package/docs/guides/client/streaming.mdx +17 -12
  195. package/docs/guides/dynamic-workflows.md +87 -0
  196. package/docs/guides/frontend/overview.mdx +5 -1
  197. package/docs/guides/meta.json +1 -0
  198. package/docs/guides/remote-agents.md +1 -0
  199. package/docs/reference/project-layout.md +5 -4
  200. package/docs/reference/typescript-api.md +26 -26
  201. package/docs/sandbox.mdx +4 -2
  202. package/docs/skills.mdx +3 -1
  203. package/docs/subagents.mdx +2 -1
  204. package/docs/tools/human-in-the-loop.md +1 -1
  205. package/docs/tools/overview.mdx +2 -0
  206. package/package.json +1 -1
@@ -113,6 +113,9 @@ declare const runtimeToolResultActionResultSchema: z.ZodObject<{
113
113
  }, z.core.$strict>;
114
114
  /**
115
115
  * Runtime-owned subagent result projected back into a harness resume call.
116
+ *
117
+ * `usage` carries the completed child session's token totals so the
118
+ * caller can attribute the subagent's spend.
116
119
  */
117
120
  export type RuntimeSubagentResultActionResult = z.infer<typeof runtimeSubagentResultActionResultSchema>;
118
121
  /**
@@ -124,6 +127,12 @@ declare const runtimeSubagentResultActionResultSchema: z.ZodObject<{
124
127
  kind: z.ZodLiteral<"subagent-result">;
125
128
  output: z.ZodType<import("../../shared/json.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("../../shared/json.ts").JsonValue, unknown>>;
126
129
  subagentName: z.ZodString;
130
+ usage: z.ZodOptional<z.ZodObject<{
131
+ cacheReadTokens: z.ZodNumber;
132
+ cacheWriteTokens: z.ZodNumber;
133
+ inputTokens: z.ZodNumber;
134
+ outputTokens: z.ZodNumber;
135
+ }, z.core.$strip>>;
127
136
  }, z.core.$strict>;
128
137
  /**
129
138
  * Runtime-owned action result produced by framework-owned loading code.
@@ -1 +1 @@
1
- import{z}from"#compiled/zod/index.js";import{jsonObjectSchema,jsonValueSchema}from"#shared/json-schemas.js";const runtimeToolCallActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`tool-call`),toolName:z.string()}).strict(),runtimeSubagentCallActionRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict(),runtimeRemoteAgentCallActionRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),runtimeLoadSkillActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`load-skill`)}).strict(),runtimeActionRequestSchema=z.discriminatedUnion(`kind`,[runtimeLoadSkillActionRequestSchema,runtimeRemoteAgentCallActionRequestSchema,runtimeSubagentCallActionRequestSchema,runtimeToolCallActionRequestSchema]);z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`tool-result`),output:jsonValueSchema,toolName:z.string()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`subagent-result`),output:jsonValueSchema,subagentName:z.string()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`load-skill-result`),output:jsonValueSchema,name:z.string().optional()}).strict();export{runtimeActionRequestSchema,runtimeRemoteAgentCallActionRequestSchema,runtimeToolCallActionRequestSchema};
1
+ import{z}from"#compiled/zod/index.js";import{jsonObjectSchema,jsonValueSchema}from"#shared/json-schemas.js";import{tokenUsageSchema}from"#shared/token-usage.js";const runtimeToolCallActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`tool-call`),toolName:z.string()}).strict(),runtimeSubagentCallActionRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict(),runtimeRemoteAgentCallActionRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),runtimeLoadSkillActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`load-skill`)}).strict(),runtimeActionRequestSchema=z.discriminatedUnion(`kind`,[runtimeLoadSkillActionRequestSchema,runtimeRemoteAgentCallActionRequestSchema,runtimeSubagentCallActionRequestSchema,runtimeToolCallActionRequestSchema]);z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`tool-result`),output:jsonValueSchema,toolName:z.string()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`subagent-result`),output:jsonValueSchema,subagentName:z.string(),usage:tokenUsageSchema.optional()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`load-skill-result`),output:jsonValueSchema,name:z.string().optional()}).strict();export{runtimeActionRequestSchema,runtimeRemoteAgentCallActionRequestSchema,runtimeToolCallActionRequestSchema};
@@ -2,6 +2,7 @@ import type { PreparedRuntimeTool } from "#runtime/sessions/turn.js";
2
2
  import type { ResolvedAgent } from "#runtime/types.js";
3
3
  import type { WorkspaceRuntimeSpec } from "#runtime/workspace/types.js";
4
4
  import type { InternalAgentModelDefinition } from "#shared/agent-definition.js";
5
+ import type { AvailableSkillDescription } from "#execution/skills/instructions.js";
5
6
  /**
6
7
  * Fixed internal model reference used only by the framework-owned bootstrap
7
8
  * runtime path.
@@ -15,6 +16,7 @@ export type RuntimeModelReference = Readonly<InternalAgentModelDefinition>;
15
16
  * Minimal runtime-owned agent shape prepared for one harness turn.
16
17
  */
17
18
  export interface RuntimeTurnAgent {
19
+ readonly availableSkills?: readonly AvailableSkillDescription[];
18
20
  readonly id: string;
19
21
  readonly instructions: readonly string[];
20
22
  /**
@@ -1 +1 @@
1
- import{composeRuntimeBasePrompt}from"#runtime/prompt/compose.js";const BOOTSTRAP_RUNTIME_MODEL_ID=`eve-bootstrap-model`,BOOTSTRAP_RUNTIME_SYSTEM_PROMPT=`You are the eve bootstrap agent. Be concise, stay grounded in the current conversation, and do not assume tools are available unless the runtime provides them.`;function createResolvedRuntimeTurnAgent(e){let t=e.agent;return{id:t.config.name,instructions:composeRuntimeBasePrompt({connections:t.connections,instructions:t.instructions,skills:t.skills,toolsAvailable:e.tools.length>0,workspaceSpec:t.workspaceSpec}),compactionModel:t.config.compaction?.model,model:t.config.model,nodeId:e.nodeId,outputSchema:t.config.outputSchema,reasoning:t.config.reasoning,tools:[...e.tools],workspaceSpec:t.workspaceSpec}}export{BOOTSTRAP_RUNTIME_MODEL_ID,BOOTSTRAP_RUNTIME_SYSTEM_PROMPT,createResolvedRuntimeTurnAgent};
1
+ import{composeRuntimeBasePrompt}from"#runtime/prompt/compose.js";const BOOTSTRAP_RUNTIME_MODEL_ID=`eve-bootstrap-model`,BOOTSTRAP_RUNTIME_SYSTEM_PROMPT=`You are the eve bootstrap agent. Be concise, stay grounded in the current conversation, and do not assume tools are available unless the runtime provides them.`;function createResolvedRuntimeTurnAgent(t){let n=t.agent;return{availableSkills:n.skills.map(e=>({description:e.description,name:e.name})),id:n.config.name,instructions:composeRuntimeBasePrompt({connections:n.connections,instructions:n.instructions,toolsAvailable:t.tools.length>0,workspaceSpec:n.workspaceSpec}),compactionModel:n.config.compaction?.model,model:n.config.model,nodeId:t.nodeId,outputSchema:n.config.outputSchema,reasoning:n.config.reasoning,tools:[...t.tools],workspaceSpec:n.workspaceSpec}}export{BOOTSTRAP_RUNTIME_MODEL_ID,BOOTSTRAP_RUNTIME_SYSTEM_PROMPT,createResolvedRuntimeTurnAgent};
@@ -1,7 +1,7 @@
1
1
  import { type MCPClient } from "#compiled/@ai-sdk/mcp/index.js";
2
2
  import type { ToolSet } from "ai";
3
3
  import type { ResolvedConnectionDefinition } from "#runtime/types.js";
4
- import type { ConnectionClient, ConnectionToolMetadata, ToolFilterDefinition } from "#runtime/connections/types.js";
4
+ import type { ConnectionClient, ConnectionToolExecuteOptions, ConnectionToolMetadata, ToolFilterDefinition } from "#runtime/connections/types.js";
5
5
  /**
6
6
  * Wraps one `MCPClient` from `@ai-sdk/mcp` for a single connection.
7
7
  *
@@ -44,7 +44,7 @@ export declare class McpConnectionClient implements ConnectionClient {
44
44
  * so callers re-enter the authorization flow instead of surfacing an
45
45
  * opaque transport error.
46
46
  */
47
- executeTool(toolName: string, args: unknown): Promise<unknown>;
47
+ executeTool(toolName: string, args: unknown, options?: ConnectionToolExecuteOptions): Promise<unknown>;
48
48
  close(): Promise<void>;
49
49
  }
50
50
  /**
@@ -1 +1 @@
1
- import{isObject}from"#shared/guards.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{ConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{evictScopedToken,resolveScopedToken}from"#runtime/connections/scoped-authorization.js";import{createMCPClient}from"#compiled/@ai-sdk/mcp/index.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";var McpConnectionClient=class{#e;#t;#n;#r;#i;constructor(e){this.#i=e}async connect(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#a();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#a(){let e=await resolveHeaders(this.#i),t=this.#i.url;try{return await createMCPClient({transport:{type:`http`,url:t,headers:e}})}catch(n){if(!isMcpHttpFallbackRetryableError(n))throw n;return await createMCPClient({transport:{type:`sse`,url:t,headers:e}})}}async getToolMetadata(){return(await this.#o()).metadata}async getTools(){return(await this.#o()).tools}async executeTool(e,t){try{let{tools:n}=await this.#o(),r=n[e];if(r?.execute===void 0)throw Error(`Tool "${e}" not found in connection "${this.#i.connectionName}".`);return await r.execute(t,{})}catch(e){return await this.#l(e)}}async#o(){if(this.#r!==void 0)return this.#r;if(this.#n!==void 0)return this.#n;this.#n=this.#s();try{return this.#r=await this.#n,this.#r}catch(e){throw this.#n=void 0,e}}async#s(){try{return await this.#c()}catch(e){return await this.#l(e)}}async#c(){let e=await this.connect(),t=await e.listTools(),n=this.#i.tools,r=n===void 0?t.tools:t.tools.filter(e=>passesToolFilter(e.name,n)),i=e.toolsFromDefinitions({tools:r});return{metadata:r.map(e=>({annotations:e.annotations,description:e.description??``,inputSchema:e.inputSchema??{},name:e.name,outputSchema:`outputSchema`in e&&e.outputSchema!==void 0?e.outputSchema:void 0})),tools:i}}async close(){this.#t!==void 0&&(await this.#t.close(),this.#t=void 0),this.#e=void 0,this.#n=void 0,this.#r=void 0}async#l(e){throw isMcpAuthRequiredError(e)?(await this.#u(),await this.close(),new ConnectionAuthorizationRequiredError(this.#i.connectionName,{message:`Connection "${this.#i.connectionName}" requires authorization (the server rejected the token).`})):e}async#u(){let e=await resolveConnectionAuthorization(this.#i);e!==void 0&&await evictScopedToken({authorization:e,connection:{url:this.#i.url},scope:this.#i.connectionName})}};function isMcpAuthRequiredError(e){return readHttpStatus(e)===401}function isMcpHttpFallbackRetryableError(e){let t=readHttpStatus(e);return t===400||t===404||t===405}function readHttpStatus(t){for(let n of walkErrorChain(t)){if(!isObject(n))continue;let t=readStatusField(n);if(t!==void 0)return t;let r=n.response;if(isObject(r)){let e=readStatusField(r);if(e!==void 0)return e}if(typeof n.message==`string`){let e=/\bHTTP\s+(\d{3})\b/u.exec(n.message);if(e?.[1]!==void 0)return Number(e[1])}}}function readStatusField(e){if(typeof e.status==`number`)return e.status;if(typeof e.statusCode==`number`)return e.statusCode}function*walkErrorChain(t){let n=t,r=new Set;for(;n!=null&&!r.has(n);){if(r.add(n),yield n,!isObject(n)||!(`cause`in n))return;n=n.cause}}function passesToolFilter(e,t){return t===void 0?!0:`allow`in t?t.allow.includes(e):!t.block.includes(e)}async function resolveHeaders(e){let n={},r,getCallbackContext=()=>r??=buildCallbackContext(),i=await resolveConnectionAuthorization(e,typeof e.authorization==`function`?getCallbackContext():void 0);if(i!==void 0&&(n.Authorization=`Bearer ${(await resolveToken(e,i)).token}`),e.headers!==void 0){let t=await resolveHeadersDefinition(e.headers,getCallbackContext);for(let[r,a]of Object.entries(t)){if(i!==void 0&&r.toLowerCase()===`authorization`)throw Error(`Connection "${e.connectionName}" headers must not include an "Authorization" key when "authorization" is also provided.`);n[r]=a}}return n}async function resolveToken(e,t){return await resolveScopedToken({authorization:t,connection:{url:e.url},scope:e.connectionName})}async function resolveHeadersDefinition(e,t){if(typeof e==`function`)return{...await e(t())};let n={},r=Object.entries(e);for(let[e,i]of r)n[e]=await resolveHeaderValue(i,t);return n}async function resolveHeaderValue(e,t){return typeof e==`function`?await e(t()):await e}export{McpConnectionClient,isMcpAuthRequiredError,passesToolFilter,resolveHeaders};
1
+ import{isObject}from"#shared/guards.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{ConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{evictScopedToken,resolveScopedToken}from"#runtime/connections/scoped-authorization.js";import{createMCPClient}from"#compiled/@ai-sdk/mcp/index.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";var McpConnectionClient=class{#e;#t;#n;#r;#i;constructor(e){this.#i=e}async connect(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#a();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#a(){let e=await resolveHeaders(this.#i),t=this.#i.url;try{return await createMCPClient({transport:{type:`http`,url:t,headers:e}})}catch(n){if(!isMcpHttpFallbackRetryableError(n))throw n;return await createMCPClient({transport:{type:`sse`,url:t,headers:e}})}}async getToolMetadata(){return(await this.#o()).metadata}async getTools(){return(await this.#o()).tools}async executeTool(e,t,n){try{let{tools:r}=await this.#o(),i=r[e];if(i?.execute===void 0)throw Error(`Tool "${e}" not found in connection "${this.#i.connectionName}".`);return await i.execute(t,{abortSignal:n?.abortSignal})}catch(e){return await this.#l(e)}}async#o(){if(this.#r!==void 0)return this.#r;if(this.#n!==void 0)return this.#n;this.#n=this.#s();try{return this.#r=await this.#n,this.#r}catch(e){throw this.#n=void 0,e}}async#s(){try{return await this.#c()}catch(e){return await this.#l(e)}}async#c(){let e=await this.connect(),t=await e.listTools(),n=this.#i.tools,r=n===void 0?t.tools:t.tools.filter(e=>passesToolFilter(e.name,n)),i=e.toolsFromDefinitions({tools:r});return{metadata:r.map(e=>({annotations:e.annotations,description:e.description??``,inputSchema:e.inputSchema??{},name:e.name,outputSchema:`outputSchema`in e&&e.outputSchema!==void 0?e.outputSchema:void 0})),tools:i}}async close(){this.#t!==void 0&&(await this.#t.close(),this.#t=void 0),this.#e=void 0,this.#n=void 0,this.#r=void 0}async#l(e){throw isMcpAuthRequiredError(e)?(await this.#u(),await this.close(),new ConnectionAuthorizationRequiredError(this.#i.connectionName,{message:`Connection "${this.#i.connectionName}" requires authorization (the server rejected the token).`})):e}async#u(){let e=await resolveConnectionAuthorization(this.#i);e!==void 0&&await evictScopedToken({authorization:e,connection:{url:this.#i.url},scope:this.#i.connectionName})}};function isMcpAuthRequiredError(e){return readHttpStatus(e)===401}function isMcpHttpFallbackRetryableError(e){let t=readHttpStatus(e);return t===400||t===404||t===405}function readHttpStatus(t){for(let n of walkErrorChain(t)){if(!isObject(n))continue;let t=readStatusField(n);if(t!==void 0)return t;let r=n.response;if(isObject(r)){let e=readStatusField(r);if(e!==void 0)return e}if(typeof n.message==`string`){let e=/\bHTTP\s+(\d{3})\b/u.exec(n.message);if(e?.[1]!==void 0)return Number(e[1])}}}function readStatusField(e){if(typeof e.status==`number`)return e.status;if(typeof e.statusCode==`number`)return e.statusCode}function*walkErrorChain(t){let n=t,r=new Set;for(;n!=null&&!r.has(n);){if(r.add(n),yield n,!isObject(n)||!(`cause`in n))return;n=n.cause}}function passesToolFilter(e,t){return t===void 0?!0:`allow`in t?t.allow.includes(e):!t.block.includes(e)}async function resolveHeaders(e){let n={},r,getCallbackContext=()=>r??=buildCallbackContext(),i=await resolveConnectionAuthorization(e,typeof e.authorization==`function`?getCallbackContext():void 0);if(i!==void 0&&(n.Authorization=`Bearer ${(await resolveToken(e,i)).token}`),e.headers!==void 0){let t=await resolveHeadersDefinition(e.headers,getCallbackContext);for(let[r,a]of Object.entries(t)){if(i!==void 0&&r.toLowerCase()===`authorization`)throw Error(`Connection "${e.connectionName}" headers must not include an "Authorization" key when "authorization" is also provided.`);n[r]=a}}return n}async function resolveToken(e,t){return await resolveScopedToken({authorization:t,connection:{url:e.url},scope:e.connectionName})}async function resolveHeadersDefinition(e,t){if(typeof e==`function`)return{...await e(t())};let n={},r=Object.entries(e);for(let[e,i]of r)n[e]=await resolveHeaderValue(i,t);return n}async function resolveHeaderValue(e,t){return typeof e==`function`?await e(t()):await e}export{McpConnectionClient,isMcpAuthRequiredError,passesToolFilter,resolveHeaders};
@@ -1,7 +1,7 @@
1
1
  import { type ToolSet } from "ai";
2
2
  import type { ResolvedConnectionDefinition } from "#runtime/types.js";
3
3
  import { type OpenApiOperation } from "#runtime/connections/openapi-operations.js";
4
- import type { ConnectionClient, ConnectionToolMetadata } from "#runtime/connections/types.js";
4
+ import type { ConnectionClient, ConnectionToolExecuteOptions, ConnectionToolMetadata } from "#runtime/connections/types.js";
5
5
  interface OpenApiToolCache {
6
6
  readonly metadata: readonly ConnectionToolMetadata[];
7
7
  readonly operations: ReadonlyMap<string, OpenApiOperation>;
@@ -37,7 +37,7 @@ export declare class OpenApiConnectionClient implements ConnectionClient {
37
37
  connect(): Promise<OpenApiToolCache>;
38
38
  getToolMetadata(): Promise<readonly ConnectionToolMetadata[]>;
39
39
  getTools(): Promise<ToolSet>;
40
- executeTool(toolName: string, args: unknown): Promise<OpenApiToolResult>;
40
+ executeTool(toolName: string, args: unknown, options?: ConnectionToolExecuteOptions): Promise<OpenApiToolResult>;
41
41
  close(): Promise<void>;
42
42
  }
43
43
  export {};
@@ -1 +1 @@
1
- import{isObject}from"#shared/guards.js";import{jsonSchema,tool}from"ai";import{passesToolFilter,resolveHeaders}from"#runtime/connections/mcp-client.js";import{HTTP_METHODS,operationDescription,operationName,uniqueName}from"#runtime/connections/openapi-operations.js";import{buildInputSchema,deref,derefSchema,isArray}from"#runtime/connections/openapi-schema.js";import{applySecurity,resolveSecurity}from"#runtime/connections/openapi-security.js";import{extractServerUrl,parseSpecDocument}from"#runtime/connections/openapi-spec.js";const SWAGGER_PARAMETER_SCHEMA_KEYS=[`default`,`enum`,`exclusiveMaximum`,`exclusiveMinimum`,`format`,`items`,`maximum`,`maxItems`,`maxLength`,`minimum`,`minItems`,`minLength`,`multipleOf`,`pattern`,`type`,`uniqueItems`];var OpenApiConnectionClient=class{#e;#t;#n;constructor(e){this.#n=e}async connect(){return this.#r()}async getToolMetadata(){return(await this.#r()).metadata}async getTools(){return(await this.#r()).tools}async executeTool(t,n){let r=await this.#r(),i=r.operations.get(t);if(i===void 0)throw Error(`Tool "${t}" not found in connection "${this.#n.connectionName}".`);return this.#f(i,r.baseUrl,isObject(n)?n:{})}async close(){this.#e=void 0,this.#t=void 0}async#r(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#i();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#i(){let i=await this.#o(),a=this.#a(i),o=this.#s(i),s=this.#n.tools,c=s===void 0?o:o.filter(e=>passesToolFilter(e.toolName,s)),l=[],u=new Map,d={};for(let r of c)u.set(r.toolName,r),l.push({description:r.description,inputSchema:r.inputSchema,name:r.toolName}),d[r.toolName]=tool({description:r.description,inputSchema:jsonSchema(r.inputSchema),execute:async t=>this.#f(r,a,isObject(t)?t:{})});return{metadata:l,operations:u,tools:d,baseUrl:a}}#a(e){let t=this.#n.url;if(typeof t==`string`&&t.trim().length>0)return t;let n=extractServerUrl(e,this.#n.spec);if(n!==void 0)return n;throw Error(`OpenAPI connection "${this.#n.connectionName}" has no base URL: set "baseUrl" or ensure the document declares an absolute "servers" entry or Swagger "host".`)}async#o(){let t=this.#n.spec;if(t===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" is missing its "spec" source.`);if(typeof t!=`string`)return t;let n;try{n=await fetch(t,{headers:{accept:`application/json, application/yaml, text/yaml, */*`}})}catch(e){throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${t}": ${String(e)}`)}if(!n.ok)throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${t}": HTTP ${n.status}.`);let r=await n.text(),i;try{i=parseSpecDocument(r)}catch(e){throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${t}" could not be parsed as JSON or YAML: ${String(e)}`)}if(!isObject(i))throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${t}" is not an OpenAPI document object.`);return i}#s(t){let n=t.paths;if(!isObject(n))return[];let r=[],i=new Set;for(let[u,d]of Object.entries(n)){if(!isObject(d))continue;let n=isArray(d.parameters)?d.parameters:[];for(let f of HTTP_METHODS){let a=d[f];if(!isObject(a))continue;let p=uniqueName(operationName(a,f,u),i),m=isArray(a.parameters)?a.parameters:[],h=[...n,...m],g=this.#c(t,h),_=this.#l(t,a.requestBody,h);r.push({toolName:p,method:f,pathTemplate:u,description:operationDescription(a),parameters:g,requestBody:_,inputSchema:buildInputSchema(g,_),security:resolveSecurity(t,a)})}}return r}#c(t,n){let r=[];for(let i of n){let n=isObject(i)?deref(t,i):i;if(!isObject(n))continue;let a=n.in;if(a!==`path`&&a!==`query`&&a!==`header`&&a!==`cookie`||typeof n.name!=`string`)continue;let o=this.#u(t,n);r.push({name:n.name,location:a,required:n.required===!0||a===`path`,schema:o,description:typeof n.description==`string`?n.description:void 0})}return r}#l(t,n,r=[]){if(isObject(n)){let r=deref(t,n);if(isObject(r)&&isObject(r.content)){let n=r.content,i=`application/json`in n?`application/json`:Object.keys(n)[0];if(i!==void 0){let a=n[i],o=isObject(a)&&isObject(a.schema)?derefSchema(t,a.schema):{};return{required:r.required===!0,contentType:i,schema:o}}}}return this.#d(t,r)}#u(t,n){if(isObject(n.schema))return derefSchema(t,n.schema);let r={};for(let e of SWAGGER_PARAMETER_SCHEMA_KEYS)n[e]!==void 0&&(r[e]=n[e]);return derefSchema(t,r)}#d(t,n){for(let r of n){let n=isObject(r)?deref(t,r):r;if(!isObject(n)||n.in!==`body`)continue;let i=isObject(n.schema)?derefSchema(t,n.schema):{};return{required:n.required===!0,contentType:`application/json`,schema:i}}}async#f(e,t,n){let r=await resolveHeaders(this.#n),a=e.pathTemplate,o=new URLSearchParams,s=[];for(let t of e.parameters){let e=n[t.name];e!=null&&(t.location===`path`?a=a.replace(`{${t.name}}`,encodeURIComponent(String(e))):t.location===`query`?appendQuery(o,t.name,e):t.location===`cookie`?s.push(`${t.name}=${encodeURIComponent(String(e))}`):r[t.name]=String(e))}if(applySecurity(e.security,this.#n,r,o,s),s.length>0){let e=r.cookie??r.Cookie;delete r.Cookie,r.cookie=[e,...s].filter(e=>!!e).join(`; `)}let c=new URL(joinPath(t,a));c.search=o.toString();let l;e.requestBody!==void 0&&n.body!==void 0&&(l=JSON.stringify(n.body),r[`content-type`]=e.requestBody.contentType);let u=await fetch(c,{method:e.method.toUpperCase(),headers:r,body:l});return{status:u.status,statusText:u.statusText,body:await readResponseBody(u)}}};function appendQuery(e,t,n){if(isArray(n)){for(let r of n)e.append(t,String(r));return}e.append(t,String(n))}function joinPath(e,t){return`${e.endsWith(`/`)?e.slice(0,-1):e}${t.startsWith(`/`)?t:`/${t}`}`}async function readResponseBody(e){let t=await e.text();if(t.length===0)return null;if((e.headers.get(`content-type`)??``).includes(`application/json`))try{return JSON.parse(t)}catch{return t}return t}export{OpenApiConnectionClient};
1
+ import{isObject}from"#shared/guards.js";import{jsonSchema,tool}from"ai";import{passesToolFilter,resolveHeaders}from"#runtime/connections/mcp-client.js";import{HTTP_METHODS,operationDescription,operationName,uniqueName}from"#runtime/connections/openapi-operations.js";import{buildInputSchema,deref,derefSchema,isArray}from"#runtime/connections/openapi-schema.js";import{applySecurity,resolveSecurity}from"#runtime/connections/openapi-security.js";import{extractServerUrl,parseSpecDocument}from"#runtime/connections/openapi-spec.js";const SWAGGER_PARAMETER_SCHEMA_KEYS=[`default`,`enum`,`exclusiveMaximum`,`exclusiveMinimum`,`format`,`items`,`maximum`,`maxItems`,`maxLength`,`minimum`,`minItems`,`minLength`,`multipleOf`,`pattern`,`type`,`uniqueItems`];var OpenApiConnectionClient=class{#e;#t;#n;constructor(e){this.#n=e}async connect(){return this.#r()}async getToolMetadata(){return(await this.#r()).metadata}async getTools(){return(await this.#r()).tools}async executeTool(t,n,r){let i=await this.#r(),a=i.operations.get(t);if(a===void 0)throw Error(`Tool "${t}" not found in connection "${this.#n.connectionName}".`);return this.#f(a,i.baseUrl,isObject(n)?n:{},{abortSignal:r?.abortSignal})}async close(){this.#e=void 0,this.#t=void 0}async#r(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#i();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#i(){let i=await this.#o(),a=this.#a(i),o=this.#s(i),s=this.#n.tools,c=s===void 0?o:o.filter(e=>passesToolFilter(e.toolName,s)),l=[],u=new Map,d={};for(let r of c)u.set(r.toolName,r),l.push({description:r.description,inputSchema:r.inputSchema,name:r.toolName}),d[r.toolName]=tool({description:r.description,inputSchema:jsonSchema(r.inputSchema),execute:async(t,n)=>this.#f(r,a,isObject(t)?t:{},{abortSignal:n?.abortSignal})});return{metadata:l,operations:u,tools:d,baseUrl:a}}#a(e){let t=this.#n.url;if(typeof t==`string`&&t.trim().length>0)return t;let n=extractServerUrl(e,this.#n.spec);if(n!==void 0)return n;throw Error(`OpenAPI connection "${this.#n.connectionName}" has no base URL: set "baseUrl" or ensure the document declares an absolute "servers" entry or Swagger "host".`)}async#o(){let t=this.#n.spec;if(t===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" is missing its "spec" source.`);if(typeof t!=`string`)return t;let n;try{n=await fetch(t,{headers:{accept:`application/json, application/yaml, text/yaml, */*`}})}catch(e){throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${t}": ${String(e)}`)}if(!n.ok)throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${t}": HTTP ${n.status}.`);let r=await n.text(),i;try{i=parseSpecDocument(r)}catch(e){throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${t}" could not be parsed as JSON or YAML: ${String(e)}`)}if(!isObject(i))throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${t}" is not an OpenAPI document object.`);return i}#s(t){let n=t.paths;if(!isObject(n))return[];let r=[],i=new Set;for(let[u,d]of Object.entries(n)){if(!isObject(d))continue;let n=isArray(d.parameters)?d.parameters:[];for(let f of HTTP_METHODS){let a=d[f];if(!isObject(a))continue;let p=uniqueName(operationName(a,f,u),i),m=isArray(a.parameters)?a.parameters:[],h=[...n,...m],g=this.#c(t,h),_=this.#l(t,a.requestBody,h);r.push({toolName:p,method:f,pathTemplate:u,description:operationDescription(a),parameters:g,requestBody:_,inputSchema:buildInputSchema(g,_),security:resolveSecurity(t,a)})}}return r}#c(t,n){let r=[];for(let i of n){let n=isObject(i)?deref(t,i):i;if(!isObject(n))continue;let a=n.in;if(a!==`path`&&a!==`query`&&a!==`header`&&a!==`cookie`||typeof n.name!=`string`)continue;let o=this.#u(t,n);r.push({name:n.name,location:a,required:n.required===!0||a===`path`,schema:o,description:typeof n.description==`string`?n.description:void 0})}return r}#l(t,n,r=[]){if(isObject(n)){let r=deref(t,n);if(isObject(r)&&isObject(r.content)){let n=r.content,i=`application/json`in n?`application/json`:Object.keys(n)[0];if(i!==void 0){let a=n[i],o=isObject(a)&&isObject(a.schema)?derefSchema(t,a.schema):{};return{required:r.required===!0,contentType:i,schema:o}}}}return this.#d(t,r)}#u(t,n){if(isObject(n.schema))return derefSchema(t,n.schema);let r={};for(let e of SWAGGER_PARAMETER_SCHEMA_KEYS)n[e]!==void 0&&(r[e]=n[e]);return derefSchema(t,r)}#d(t,n){for(let r of n){let n=isObject(r)?deref(t,r):r;if(!isObject(n)||n.in!==`body`)continue;let i=isObject(n.schema)?derefSchema(t,n.schema):{};return{required:n.required===!0,contentType:`application/json`,schema:i}}}async#f(e,t,n,r){let a=await resolveHeaders(this.#n),o=e.pathTemplate,s=new URLSearchParams,c=[];for(let t of e.parameters){let e=n[t.name];e!=null&&(t.location===`path`?o=o.replace(`{${t.name}}`,encodeURIComponent(String(e))):t.location===`query`?appendQuery(s,t.name,e):t.location===`cookie`?c.push(`${t.name}=${encodeURIComponent(String(e))}`):a[t.name]=String(e))}if(applySecurity(e.security,this.#n,a,s,c),c.length>0){let e=a.cookie??a.Cookie;delete a.Cookie,a.cookie=[e,...c].filter(e=>!!e).join(`; `)}let l=new URL(joinPath(t,o));l.search=s.toString();let u;e.requestBody!==void 0&&n.body!==void 0&&(u=JSON.stringify(n.body),a[`content-type`]=e.requestBody.contentType);let d=await fetch(l,{method:e.method.toUpperCase(),headers:a,body:u,signal:r?.abortSignal});return{status:d.status,statusText:d.statusText,body:await readResponseBody(d)}}};function appendQuery(e,t,n){if(isArray(n)){for(let r of n)e.append(t,String(r));return}e.append(t,String(n))}function joinPath(e,t){return`${e.endsWith(`/`)?e.slice(0,-1):e}${t.startsWith(`/`)?t:`/${t}`}`}async function readResponseBody(e){let t=await e.text();if(t.length===0)return null;if((e.headers.get(`content-type`)??``).includes(`application/json`))try{return JSON.parse(t)}catch{return t}return t}export{OpenApiConnectionClient};
@@ -382,11 +382,16 @@ export interface ConnectionToolMetadata {
382
382
  readonly name: string;
383
383
  readonly outputSchema?: Record<string, unknown>;
384
384
  }
385
+ /** Per-call options for {@link ConnectionClient.executeTool}. */
386
+ export interface ConnectionToolExecuteOptions {
387
+ /** Signal forwarded into the underlying transport. */
388
+ readonly abortSignal?: AbortSignal;
389
+ }
385
390
  /** A live client for a single connection. */
386
391
  export interface ConnectionClient {
387
392
  close(): Promise<void>;
388
393
  connect(): Promise<unknown>;
389
- executeTool(toolName: string, args: unknown): Promise<unknown>;
394
+ executeTool(toolName: string, args: unknown, options?: ConnectionToolExecuteOptions): Promise<unknown>;
390
395
  getToolMetadata(): Promise<readonly ConnectionToolMetadata[]>;
391
396
  getTools(): Promise<ToolSet>;
392
397
  }
@@ -1 +1 @@
1
- import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeBashOnSandbox}from"#execution/sandbox/bash-tool.js";const BASH_INPUT_SCHEMA={additionalProperties:!1,properties:{command:{description:`The shell command to execute.`,type:`string`}},required:[`command`],type:`object`},BASH_OUTPUT_SCHEMA={additionalProperties:!1,properties:{exitCode:{type:`number`},stderr:{type:`string`},stdout:{type:`string`},truncated:{type:`boolean`}},required:[`exitCode`,`stderr`,`stdout`,`truncated`],type:`object`};async function executeBash(e){return executeBashOnSandbox(await requireSandboxSession(),e)}const BASH_TOOL_DEFINITION={description:`Execute a shell command in the shared workspace environment.`,execute:executeBash,inputSchema:BASH_INPUT_SCHEMA,logicalPath:`eve:framework/bash`,name:`bash`,outputSchema:BASH_OUTPUT_SCHEMA,sourceId:`eve:bash-tool`,sourceKind:`module`};export{BASH_INPUT_SCHEMA,BASH_OUTPUT_SCHEMA,BASH_TOOL_DEFINITION};
1
+ import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeBashOnSandbox}from"#execution/sandbox/bash-tool.js";const BASH_INPUT_SCHEMA={additionalProperties:!1,properties:{command:{description:`The shell command to execute.`,type:`string`}},required:[`command`],type:`object`},BASH_OUTPUT_SCHEMA={additionalProperties:!1,properties:{exitCode:{type:`number`},stderr:{type:`string`},stdout:{type:`string`},truncated:{type:`boolean`}},required:[`exitCode`,`stderr`,`stdout`,`truncated`],type:`object`};async function executeBash(e,t){return executeBashOnSandbox(await requireSandboxSession(t?.abortSignal),e)}const BASH_TOOL_DEFINITION={description:`Execute a shell command in the shared workspace environment.`,execute:executeBash,inputSchema:BASH_INPUT_SCHEMA,logicalPath:`eve:framework/bash`,name:`bash`,outputSchema:BASH_OUTPUT_SCHEMA,sourceId:`eve:bash-tool`,sourceKind:`module`};export{BASH_INPUT_SCHEMA,BASH_OUTPUT_SCHEMA,BASH_TOOL_DEFINITION};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";import{ConnectionRegistryKey}from"#context/providers/connection-key.js";import{ConnectionAuthorizationFailedError,isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{resolveAuthorizationCallbackUrl,stampChallengeDisplayName}from"#runtime/connections/scoped-authorization.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";const logger=createLogger(`framework.connection-search-dynamic`),CONNECTION_SEARCH_OUTPUT_SCHEMA={items:{additionalProperties:!1,properties:{connection:{type:`string`},description:{type:`string`},error:{type:`string`},inputSchema:{type:`object`},needsAuthorization:{type:`boolean`},outputSchema:{type:`object`},qualifiedName:{type:`string`},tool:{type:`string`}},required:[`connection`,`description`],type:`object`},type:`array`},ConnectionSearchResultsKey=new ContextKey(`eve.connectionSearchResults`);function qualifiedConnectionToolName(e,t){return`${e}__${t}`}function tokenize(e){return e.toLowerCase().split(/[\s_\-./]+/).filter(e=>e.length>1)}function scoreMatch(e,t){let n=tokenize(t.name),r=tokenize(t.description),i=0;for(let t of e){for(let e of n)(e.includes(t)||t.includes(e))&&(i+=3);for(let e of r)(e.includes(t)||t.includes(e))&&(i+=1)}return i}async function resolveInteractiveAuth(e,t){let n=e.getConnections().find(e=>e.connectionName===t);if(n===void 0)return;let r=await resolveConnectionAuthorization(n);if(supportsInteractiveAuthorization(r))return r}async function completePendingAuthorizations(e){let n=loadContext(),r=new Set;for(let t of e.getConnections()){let i=getAuthorizationResult(t.connectionName);if(!i)continue;let a=await resolveInteractiveAuth(e,t.connectionName);if(!a)continue;let o=resolveConnectionPrincipal(t.connectionName,a),c=await a.completeAuthorization({callbackUrl:i.hookUrl,connection:{url:t.url??``},principal:o,resume:i.resume,callback:i.callback});writeCachedToken(n,t.connectionName,principalKey(o),c),r.add(t.connectionName)}return r}async function executeConnectionSearch(e){let n=loadContext(),i=n.get(ConnectionRegistryKey);if(i===void 0)return[];let s=await completePendingAuthorizations(i),l=e.limit??10,u=tokenize(e.keywords),d=[],f=[],m=e.connection!==void 0&&e.connection!==``?i.getConnections().filter(t=>t.connectionName===e.connection):i.getConnections(),h=[];for(let e of m){let t;try{t=await i.getClient(e.connectionName).getToolMetadata()}catch(t){if(isConnectionAuthorizationRequiredError(t)){if(s.has(e.connectionName)){logger.warn(`connection still unauthorized after authorization`,{connection:e.connectionName}),f.push({connection:e.connectionName,description:e.description,error:`Authorization for "${e.connectionName}" did not take effect; the token was rejected after sign-in.`});continue}let t=await resolveInteractiveAuth(i,e.connectionName);if(t){let n=getHookUrl(e.connectionName);if(n){let r=resolveConnectionPrincipal(e.connectionName,t),i=resolveAuthorizationCallbackUrl({authorization:t,callbackUrl:n});try{let{challenge:n,resume:a}=await t.startAuthorization({callbackUrl:i,connection:{url:e.url??``},principal:r});h.push({name:e.connectionName,challenge:stampChallengeDisplayName(n,t),hookUrl:i,resume:a})}catch(t){logger.warn(`startAuthorization failed`,{connection:e.connectionName,error:t instanceof Error?t:Error(String(t))})}}}f.push({connection:e.connectionName,description:e.description,needsAuthorization:!0});continue}if(isConnectionAuthorizationFailedError(t)){logger.warn(`connection authorization failed`,{connection:e.connectionName,reason:t.reason,retryable:t.retryable,error:t}),f.push({connection:e.connectionName,description:e.description,error:`Authorization failed for ${e.connectionName}: ${t.message}`});continue}let n=t instanceof Error?t.message:`unknown error`;logger.warn(`failed to load connection tools`,{connection:e.connectionName,error:t instanceof Error?t:Error(n)}),f.push({connection:e.connectionName,description:e.description,error:`Failed to load tools for "${e.connectionName}": ${n}`});continue}for(let n of t){let t=scoreMatch(u,n);t>0&&d.push({item:{connection:e.connectionName,description:n.description,inputSchema:n.inputSchema,outputSchema:n.outputSchema,qualifiedName:qualifiedConnectionToolName(e.connectionName,n.name),tool:n.name},score:t})}}if(h.length>0)return requestAuthorization(h);d.sort((e,t)=>t.score-e.score);let g=d.slice(0,l).map(e=>e.item);if(g.length>0){let e=[...g,...f],t=n.get(ConnectionSearchResultsKey)??[],r=new Map(t.map(e=>[e.qualifiedName,e]));for(let e of g)e.qualifiedName&&r.set(e.qualifiedName,e);return n.set(ConnectionSearchResultsKey,[...r.values()]),e}return m.map(e=>f.find(t=>t.connection===e.connectionName)||{connection:e.connectionName,description:e.description})}function extractDiscoveredTools(e){let t=new Map;for(let n of e){if(n.role!==`tool`)continue;let e=n.content;for(let n of e){if(n.type!==`tool-result`||n.toolName!==`connection_search`)continue;let e=n.output;if(e==null)continue;let r=typeof e==`object`&&`type`in e&&`value`in e?e.value:e;if(Array.isArray(r))for(let e of r)e.tool&&e.qualifiedName&&t.set(e.qualifiedName,e)}}return[...t.values()]}function createConnectionSearchEvents(){return{"step.started":async(e,n)=>{let a=loadContext().get(ConnectionRegistryKey);if(!a||a.getConnections().length===0)return null;let l=a.getConnections().map(e=>e.connectionName),u=extractDiscoveredTools(n.messages),p=loadContext().get(ConnectionSearchResultsKey)??[],h=new Map;for(let e of p)e.qualifiedName&&h.set(e.qualifiedName,e);for(let e of u)e.qualifiedName&&h.set(e.qualifiedName,e);let g=[...h.values()],_={};_.connection_search={description:`Search for tools across your connections. Discovered tools become directly callable by their qualified name (e.g. \`linear__list_issues\`) in your next response. Available connections: ${l.join(`, `)}.`,inputSchema:{type:`object`,additionalProperties:!1,properties:{keywords:{description:`Search keywords and expanded aliases. Distill intent into keywords; avoid stop words like 'a', 'the', 'in'.`,type:`string`},connection:{description:`Optional: limit search to a specific connection name.`,type:`string`},limit:{description:`Max results to return. Default 10.`,type:`number`}},required:[`keywords`]},async execute(e){return executeConnectionSearch(e)},outputSchema:CONNECTION_SEARCH_OUTPUT_SCHEMA};for(let e of g){let n=e.connection,l=e.tool,u=a.getConnectionApproval(n);_[qualifiedConnectionToolName(n,l)]={description:e.description,inputSchema:e.inputSchema??{type:`object`},approval:u,outputSchema:e.outputSchema,async execute(e){let a=loadContext().get(ConnectionRegistryKey),u=a.getConnections().find(e=>e.connectionName===n),p=await resolveInteractiveAuth(a,n),m=!1;if(p){let e=getAuthorizationResult(n);if(e){m=!0;let r=loadContext(),i=resolveConnectionPrincipal(n,p),a=await p.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:u?.url??``},principal:i,resume:e.resume,callback:e.callback});writeCachedToken(r,n,principalKey(i),a)}}try{return await a.getClient(n).executeTool(l,e)}catch(e){if(!isConnectionAuthorizationRequiredError(e)||!p)throw e;if(m)throw new ConnectionAuthorizationFailedError(n,{retryable:!1,reason:`token_rejected_after_authorization`,message:`Connection "${n}" rejected the token immediately after authorization.`});let t=getHookUrl(n);if(!t)throw e;let r=resolveConnectionPrincipal(n,p),a=resolveAuthorizationCallbackUrl({authorization:p,callbackUrl:t}),{challenge:s,resume:l}=await p.startAuthorization({callbackUrl:a,connection:{url:u?.url??``},principal:r});return requestAuthorization([{name:n,challenge:stampChallengeDisplayName(s,p),hookUrl:a,resume:l}])}}}}return _}}}function createConnectionSearchResolver(){let e=createConnectionSearchEvents();return{slug:`connection`,eventNames:Object.keys(e),events:e,sourceId:`eve:connection-search-dynamic`,sourceKind:`module`,logicalPath:`eve:framework/connection-search-dynamic`}}export{createConnectionSearchEvents,createConnectionSearchResolver,extractDiscoveredTools};
1
+ import{createLogger}from"#internal/logging.js";import{loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";import{ConnectionRegistryKey}from"#context/providers/connection-key.js";import{ConnectionAuthorizationFailedError,isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{resolveAuthorizationCallbackUrl,stampChallengeDisplayName}from"#runtime/connections/scoped-authorization.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";const logger=createLogger(`framework.connection-search-dynamic`),CONNECTION_SEARCH_OUTPUT_SCHEMA={items:{additionalProperties:!1,properties:{connection:{type:`string`},description:{type:`string`},error:{type:`string`},inputSchema:{type:`object`},needsAuthorization:{type:`boolean`},outputSchema:{type:`object`},qualifiedName:{type:`string`},tool:{type:`string`}},required:[`connection`,`description`],type:`object`},type:`array`},ConnectionSearchResultsKey=new ContextKey(`eve.connectionSearchResults`);function qualifiedConnectionToolName(e,t){return`${e}__${t}`}function tokenize(e){return e.toLowerCase().split(/[\s_\-./]+/).filter(e=>e.length>1)}function scoreMatch(e,t){let n=tokenize(t.name),r=tokenize(t.description),i=0;for(let t of e){for(let e of n)(e.includes(t)||t.includes(e))&&(i+=3);for(let e of r)(e.includes(t)||t.includes(e))&&(i+=1)}return i}async function resolveInteractiveAuth(e,t){let n=e.getConnections().find(e=>e.connectionName===t);if(n===void 0)return;let r=await resolveConnectionAuthorization(n);if(supportsInteractiveAuthorization(r))return r}async function completePendingAuthorizations(e){let n=loadContext(),r=new Set;for(let t of e.getConnections()){let i=getAuthorizationResult(t.connectionName);if(!i)continue;let a=await resolveInteractiveAuth(e,t.connectionName);if(!a)continue;let o=resolveConnectionPrincipal(t.connectionName,a),c=await a.completeAuthorization({callbackUrl:i.hookUrl,connection:{url:t.url??``},principal:o,resume:i.resume,callback:i.callback});writeCachedToken(n,t.connectionName,principalKey(o),c),r.add(t.connectionName)}return r}async function executeConnectionSearch(e){let n=loadContext(),i=n.get(ConnectionRegistryKey);if(i===void 0)return[];let s=await completePendingAuthorizations(i),l=e.limit??10,u=tokenize(e.keywords),d=[],f=[],m=e.connection!==void 0&&e.connection!==``?i.getConnections().filter(t=>t.connectionName===e.connection):i.getConnections(),g=[];for(let e of m){let t;try{t=await i.getClient(e.connectionName).getToolMetadata()}catch(t){if(isConnectionAuthorizationRequiredError(t)){if(s.has(e.connectionName)){logger.warn(`connection still unauthorized after authorization`,{connection:e.connectionName}),f.push({connection:e.connectionName,description:e.description,error:`Authorization for "${e.connectionName}" did not take effect; the token was rejected after sign-in.`});continue}let t=await resolveInteractiveAuth(i,e.connectionName);if(t){let n=getHookUrl(e.connectionName);if(n){let r=resolveConnectionPrincipal(e.connectionName,t),i=resolveAuthorizationCallbackUrl({authorization:t,callbackUrl:n});try{let{challenge:n,resume:a}=await t.startAuthorization({callbackUrl:i,connection:{url:e.url??``},principal:r});g.push({name:e.connectionName,challenge:stampChallengeDisplayName(n,t),hookUrl:i,resume:a})}catch(t){logger.warn(`startAuthorization failed`,{connection:e.connectionName,error:t instanceof Error?t:Error(String(t))})}}}f.push({connection:e.connectionName,description:e.description,needsAuthorization:!0});continue}if(isConnectionAuthorizationFailedError(t)){logger.warn(`connection authorization failed`,{connection:e.connectionName,reason:t.reason,retryable:t.retryable,error:t}),f.push({connection:e.connectionName,description:e.description,error:`Authorization failed for ${e.connectionName}: ${t.message}`});continue}let n=t instanceof Error?t.message:`unknown error`;logger.warn(`failed to load connection tools`,{connection:e.connectionName,error:t instanceof Error?t:Error(n)}),f.push({connection:e.connectionName,description:e.description,error:`Failed to load tools for "${e.connectionName}": ${n}`});continue}for(let n of t){let t=scoreMatch(u,n);t>0&&d.push({item:{connection:e.connectionName,description:n.description,inputSchema:n.inputSchema,outputSchema:n.outputSchema,qualifiedName:qualifiedConnectionToolName(e.connectionName,n.name),tool:n.name},score:t})}}if(g.length>0)return requestAuthorization(g);d.sort((e,t)=>t.score-e.score);let _=d.slice(0,l).map(e=>e.item);if(_.length>0){let e=[..._,...f],t=n.get(ConnectionSearchResultsKey)??[],r=new Map(t.map(e=>[e.qualifiedName,e]));for(let e of _)e.qualifiedName&&r.set(e.qualifiedName,e);return n.set(ConnectionSearchResultsKey,[...r.values()]),e}return m.map(e=>f.find(t=>t.connection===e.connectionName)||{connection:e.connectionName,description:e.description})}function extractDiscoveredTools(e){let t=new Map;for(let n of e){if(n.role!==`tool`)continue;let e=n.content;for(let n of e){if(n.type!==`tool-result`||n.toolName!==`connection_search`)continue;let e=n.output;if(e==null)continue;let r=typeof e==`object`&&`type`in e&&`value`in e?e.value:e;if(Array.isArray(r))for(let e of r)e.tool&&e.qualifiedName&&t.set(e.qualifiedName,e)}}return[...t.values()]}function createConnectionSearchEvents(){return{"step.started":async(e,n)=>{let a=loadContext().get(ConnectionRegistryKey);if(!a||a.getConnections().length===0)return null;let l=a.getConnections().map(e=>e.connectionName),u=extractDiscoveredTools(n.messages),p=loadContext().get(ConnectionSearchResultsKey)??[],g=new Map;for(let e of p)e.qualifiedName&&g.set(e.qualifiedName,e);for(let e of u)e.qualifiedName&&g.set(e.qualifiedName,e);let _=[...g.values()],v={};v.connection_search={description:`Search for tools across your connections. Discovered tools become directly callable by their qualified name (e.g. \`linear__list_issues\`) in your next response. Available connections: ${l.join(`, `)}.`,inputSchema:{type:`object`,additionalProperties:!1,properties:{keywords:{description:`Search keywords and expanded aliases. Distill intent into keywords; avoid stop words like 'a', 'the', 'in'.`,type:`string`},connection:{description:`Optional: limit search to a specific connection name.`,type:`string`},limit:{description:`Max results to return. Default 10.`,type:`number`}},required:[`keywords`]},async execute(e){return executeConnectionSearch(e)},outputSchema:CONNECTION_SEARCH_OUTPUT_SCHEMA};for(let e of _){let n=e.connection,l=e.tool,u=a.getConnectionApproval(n);v[qualifiedConnectionToolName(n,l)]={description:e.description,inputSchema:e.inputSchema??{type:`object`},approval:u,outputSchema:e.outputSchema,async execute(e,a){let u=loadContext().get(ConnectionRegistryKey),p=u.getConnections().find(e=>e.connectionName===n),m=await resolveInteractiveAuth(u,n),h=!1;if(m){let e=getAuthorizationResult(n);if(e){h=!0;let r=loadContext(),i=resolveConnectionPrincipal(n,m),a=await m.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:p?.url??``},principal:i,resume:e.resume,callback:e.callback});writeCachedToken(r,n,principalKey(i),a)}}try{return await u.getClient(n).executeTool(l,e,{abortSignal:a.abortSignal})}catch(e){if(!isConnectionAuthorizationRequiredError(e)||!m)throw e;if(h)throw new ConnectionAuthorizationFailedError(n,{retryable:!1,reason:`token_rejected_after_authorization`,message:`Connection "${n}" rejected the token immediately after authorization.`});let t=getHookUrl(n);if(!t)throw e;let r=resolveConnectionPrincipal(n,m),a=resolveAuthorizationCallbackUrl({authorization:m,callbackUrl:t}),{challenge:s,resume:l}=await m.startAuthorization({callbackUrl:a,connection:{url:p?.url??``},principal:r});return requestAuthorization([{name:n,challenge:stampChallengeDisplayName(s,m),hookUrl:a,resume:l}])}}}}return v}}}function createConnectionSearchResolver(){let e=createConnectionSearchEvents();return{slug:`connection`,eventNames:Object.keys(e),events:e,sourceId:`eve:connection-search-dynamic`,sourceKind:`module`,logicalPath:`eve:framework/connection-search-dynamic`}}export{createConnectionSearchEvents,createConnectionSearchResolver,extractDiscoveredTools};
@@ -1,2 +1,2 @@
1
- import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeGlobOnSandbox}from"#execution/sandbox/glob-tool.js";const GLOB_INPUT_SCHEMA={additionalProperties:!1,properties:{limit:{description:`Maximum number of results to return. Defaults to 100.`,maximum:1e3,minimum:1,type:`integer`},path:{description:`The directory to search in. Defaults to /workspace. Must be an absolute path. Omit to use the default.`,type:`string`},pattern:{description:`The glob pattern to match files against (e.g. "**/*.ts", "src/**/*.js").`,type:`string`}},required:[`pattern`],type:`object`},GLOB_OUTPUT_SCHEMA={additionalProperties:!1,properties:{content:{type:`string`},count:{type:`integer`},path:{type:`string`},truncated:{type:`boolean`}},required:[`content`,`count`,`path`,`truncated`],type:`object`};async function executeGlob(e){return executeGlobOnSandbox(await requireSandboxSession(),e)}const GLOB_TOOL_DEFINITION={description:[`Fast file pattern matching tool that works with any codebase size.`,``,`Usage:`,`- Supports glob patterns like "**/*.js" or "src/**/*.ts".`,`- Returns matching file paths.`,`- Use this tool when you need to find files by name patterns.`,`- If you are unsure of the correct file path, use the glob tool to look up filenames by glob pattern.`,`- Use the grep tool instead if you need to search file contents.`,`- Call this tool in parallel when you know there are multiple patterns to search for.`].join(`
1
+ import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeGlobOnSandbox}from"#execution/sandbox/glob-tool.js";const GLOB_INPUT_SCHEMA={additionalProperties:!1,properties:{limit:{description:`Maximum number of results to return. Defaults to 100.`,maximum:1e3,minimum:1,type:`integer`},path:{description:`The directory to search in. Defaults to /workspace. Must be an absolute path. Omit to use the default.`,type:`string`},pattern:{description:`The glob pattern to match files against (e.g. "**/*.ts", "src/**/*.js").`,type:`string`}},required:[`pattern`],type:`object`},GLOB_OUTPUT_SCHEMA={additionalProperties:!1,properties:{content:{type:`string`},count:{type:`integer`},path:{type:`string`},truncated:{type:`boolean`}},required:[`content`,`count`,`path`,`truncated`],type:`object`};async function executeGlob(e,t){return executeGlobOnSandbox(await requireSandboxSession(t?.abortSignal),e)}const GLOB_TOOL_DEFINITION={description:[`Fast file pattern matching tool that works with any codebase size.`,``,`Usage:`,`- Supports glob patterns like "**/*.js" or "src/**/*.ts".`,`- Returns matching file paths.`,`- Use this tool when you need to find files by name patterns.`,`- If you are unsure of the correct file path, use the glob tool to look up filenames by glob pattern.`,`- Use the grep tool instead if you need to search file contents.`,`- Call this tool in parallel when you know there are multiple patterns to search for.`].join(`
2
2
  `),execute:executeGlob,inputSchema:GLOB_INPUT_SCHEMA,logicalPath:`eve:framework/glob`,name:`glob`,outputSchema:GLOB_OUTPUT_SCHEMA,sourceId:`eve:glob-tool`,sourceKind:`module`};export{GLOB_INPUT_SCHEMA,GLOB_OUTPUT_SCHEMA,GLOB_TOOL_DEFINITION};
@@ -1,2 +1,2 @@
1
- import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeGrepOnSandbox}from"#execution/sandbox/grep-tool.js";const GREP_INPUT_SCHEMA={additionalProperties:!1,properties:{context:{description:`Number of surrounding context lines to include before and after each match. Defaults to 0.`,minimum:0,type:`integer`},glob:{description:`Filter files by glob pattern (e.g. "*.ts", "*.{ts,tsx}").`,type:`string`},ignoreCase:{description:`Perform case-insensitive search. Defaults to false.`,type:`boolean`},limit:{description:`Maximum number of matches to return per file. Defaults to 100.`,maximum:1e3,minimum:1,type:`integer`},literal:{description:`Treat the pattern as a literal string instead of a regular expression. Defaults to false.`,type:`boolean`},path:{description:`The directory or file to search in. Defaults to /workspace. Must be an absolute path. Omit to use the default.`,type:`string`},pattern:{description:`The regex pattern to search for in file contents (e.g. "log.*Error", "function\\s+\\w+").`,type:`string`}},required:[`pattern`],type:`object`},GREP_OUTPUT_SCHEMA={additionalProperties:!1,properties:{content:{type:`string`},matchCount:{type:`integer`},path:{type:`string`},truncated:{type:`boolean`}},required:[`content`,`matchCount`,`path`,`truncated`],type:`object`};async function executeGrep(e){return executeGrepOnSandbox(await requireSandboxSession(),e)}const GREP_TOOL_DEFINITION={description:[`Fast content search tool that works with any codebase size.`,``,`Usage:`,`- Searches file contents using regular expressions.`,`- Supports full regex syntax (e.g. "log.*Error", "function\\s+\\w+").`,`- Filter files by pattern with the glob parameter (e.g. "*.js", "*.{ts,tsx}").`,`- Returns matching lines with file paths and line numbers.`,`- Use this tool when you need to find files containing specific patterns.`,`- Use the glob tool instead if you only need to find files by name.`,`- Call this tool in parallel when you have multiple independent searches.`,`- Any line longer than 2000 characters is truncated.`].join(`
1
+ import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeGrepOnSandbox}from"#execution/sandbox/grep-tool.js";const GREP_INPUT_SCHEMA={additionalProperties:!1,properties:{context:{description:`Number of surrounding context lines to include before and after each match. Defaults to 0.`,minimum:0,type:`integer`},glob:{description:`Filter files by glob pattern (e.g. "*.ts", "*.{ts,tsx}").`,type:`string`},ignoreCase:{description:`Perform case-insensitive search. Defaults to false.`,type:`boolean`},limit:{description:`Maximum number of matches to return per file. Defaults to 100.`,maximum:1e3,minimum:1,type:`integer`},literal:{description:`Treat the pattern as a literal string instead of a regular expression. Defaults to false.`,type:`boolean`},path:{description:`The directory or file to search in. Defaults to /workspace. Must be an absolute path. Omit to use the default.`,type:`string`},pattern:{description:`The regex pattern to search for in file contents (e.g. "log.*Error", "function\\s+\\w+").`,type:`string`}},required:[`pattern`],type:`object`},GREP_OUTPUT_SCHEMA={additionalProperties:!1,properties:{content:{type:`string`},matchCount:{type:`integer`},path:{type:`string`},truncated:{type:`boolean`}},required:[`content`,`matchCount`,`path`,`truncated`],type:`object`};async function executeGrep(e,t){return executeGrepOnSandbox(await requireSandboxSession(t?.abortSignal),e)}const GREP_TOOL_DEFINITION={description:[`Fast content search tool that works with any codebase size.`,``,`Usage:`,`- Searches file contents using regular expressions.`,`- Supports full regex syntax (e.g. "log.*Error", "function\\s+\\w+").`,`- Filter files by pattern with the glob parameter (e.g. "*.js", "*.{ts,tsx}").`,`- Returns matching lines with file paths and line numbers.`,`- Use this tool when you need to find files containing specific patterns.`,`- Use the glob tool instead if you only need to find files by name.`,`- Call this tool in parallel when you have multiple independent searches.`,`- Any line longer than 2000 characters is truncated.`].join(`
2
2
  `),execute:executeGrep,inputSchema:GREP_INPUT_SCHEMA,logicalPath:`eve:framework/grep`,name:`grep`,outputSchema:GREP_OUTPUT_SCHEMA,sourceId:`eve:grep-tool`,sourceKind:`module`};export{GREP_INPUT_SCHEMA,GREP_OUTPUT_SCHEMA,GREP_TOOL_DEFINITION};
@@ -1,2 +1,2 @@
1
- import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeReadFileOnSandbox}from"#execution/sandbox/read-file-tool.js";const READ_FILE_INPUT_SCHEMA={additionalProperties:!1,properties:{filePath:{description:`The absolute path to the file to read.`,type:`string`},limit:{description:`Maximum number of lines to return. Defaults to 2000.`,minimum:1,type:`integer`},offset:{description:`1-based line number to start from. Defaults to 1.`,minimum:1,type:`integer`}},required:[`filePath`],type:`object`},READ_FILE_OUTPUT_SCHEMA={additionalProperties:!1,properties:{content:{type:`string`},nextOffset:{minimum:1,type:`integer`},path:{type:`string`},totalLines:{minimum:0,type:`integer`},truncated:{type:`boolean`}},required:[`content`,`path`,`totalLines`,`truncated`],type:`object`};async function executeReadFile(e){return executeReadFileOnSandbox(await requireSandboxSession(),e)}const READ_FILE_TOOL_DEFINITION={description:[`Read a file from the local filesystem. If the path does not exist, an error is returned.`,``,`Usage:`,`- The filePath parameter should be an absolute path.`,`- By default, this tool returns up to 2000 lines from the start of the file.`,`- The offset parameter is the line number to start from (1-indexed).`,`- To read later sections, call this tool again with a larger offset.`,`- Use the grep tool to find specific content in large files or files with long lines.`,`- If you are unsure of the correct file path, use the glob tool to look up filenames by glob pattern.`,'- Contents are returned with each line prefixed by its line number as `<line>: <content>`. For example, if a file has contents "foo\\n", you will receive "1: foo\\n".',`- Any line longer than 2000 characters is truncated.`,`- Call this tool in parallel when you know there are multiple files you want to read.`,`- Avoid tiny repeated slices (30 line chunks). If you need more context, read a larger window.`].join(`
1
+ import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeReadFileOnSandbox}from"#execution/sandbox/read-file-tool.js";const READ_FILE_INPUT_SCHEMA={additionalProperties:!1,properties:{filePath:{description:`The absolute path to the file to read.`,type:`string`},limit:{description:`Maximum number of lines to return. Defaults to 2000.`,minimum:1,type:`integer`},offset:{description:`1-based line number to start from. Defaults to 1.`,minimum:1,type:`integer`}},required:[`filePath`],type:`object`},READ_FILE_OUTPUT_SCHEMA={additionalProperties:!1,properties:{content:{type:`string`},nextOffset:{minimum:1,type:`integer`},path:{type:`string`},totalLines:{minimum:0,type:`integer`},truncated:{type:`boolean`}},required:[`content`,`path`,`totalLines`,`truncated`],type:`object`};async function executeReadFile(e,t){return executeReadFileOnSandbox(await requireSandboxSession(t?.abortSignal),e)}const READ_FILE_TOOL_DEFINITION={description:[`Read a file from the local filesystem. If the path does not exist, an error is returned.`,``,`Usage:`,`- The filePath parameter should be an absolute path.`,`- By default, this tool returns up to 2000 lines from the start of the file.`,`- The offset parameter is the line number to start from (1-indexed).`,`- To read later sections, call this tool again with a larger offset.`,`- Use the grep tool to find specific content in large files or files with long lines.`,`- If you are unsure of the correct file path, use the glob tool to look up filenames by glob pattern.`,'- Contents are returned with each line prefixed by its line number as `<line>: <content>`. For example, if a file has contents "foo\\n", you will receive "1: foo\\n".',`- Any line longer than 2000 characters is truncated.`,`- Call this tool in parallel when you know there are multiple files you want to read.`,`- Avoid tiny repeated slices (30 line chunks). If you need more context, read a larger window.`].join(`
2
2
  `),execute:executeReadFile,inputSchema:READ_FILE_INPUT_SCHEMA,logicalPath:`eve:framework/read-file`,name:`read_file`,outputSchema:READ_FILE_OUTPUT_SCHEMA,sourceId:`eve:read-file-tool`,sourceKind:`module`};export{READ_FILE_INPUT_SCHEMA,READ_FILE_OUTPUT_SCHEMA,READ_FILE_TOOL_DEFINITION};
@@ -1,2 +1,2 @@
1
- import{executeWebFetchTool}from"#execution/web-fetch/tool.js";async function executeWebFetch(e){return executeWebFetchTool(e)}const WEB_FETCH_INPUT_SCHEMA={additionalProperties:!1,properties:{format:{description:`The format to return the content in (text, markdown, or html). HTML responses are automatically converted to the requested format. Defaults to "markdown".`,enum:[`markdown`,`text`,`html`],type:`string`},timeout:{description:`Optional timeout in seconds. Defaults to 30, max 120.`,type:`number`},url:{description:`The fully-formed URL to fetch content from. Must start with http:// or https://.`,type:`string`}},required:[`url`],type:`object`},WEB_FETCH_OUTPUT_SCHEMA={additionalProperties:!1,properties:{content:{type:`string`},contentType:{type:`string`},truncated:{type:`boolean`},url:{type:`string`}},required:[`content`,`contentType`,`url`,`truncated`],type:`object`},WEB_FETCH_TOOL_DEFINITION={description:[`Fetch a webpage and return its content in the requested format. Use this to retrieve and analyze content from URLs.`,``,`Usage notes:`,`- The URL must be a fully-formed valid URL starting with http:// or https://`,`- HTML responses are automatically converted to markdown or plain text based on the requested format`,`- Format options: "markdown" (default), "text", or "html"`,`- Default timeout is 30 seconds (max 120 seconds)`,`- Maximum response size is 5 MB; content is further capped at the shared tool-output budget (50 KB / 2000 lines)`,`- This tool is read-only and does not modify any files`].join(`
1
+ import{executeWebFetchTool}from"#execution/web-fetch/tool.js";async function executeWebFetch(e,t){return executeWebFetchTool(e,{abortSignal:t?.abortSignal})}const WEB_FETCH_INPUT_SCHEMA={additionalProperties:!1,properties:{format:{description:`The format to return the content in (text, markdown, or html). HTML responses are automatically converted to the requested format. Defaults to "markdown".`,enum:[`markdown`,`text`,`html`],type:`string`},timeout:{description:`Optional timeout in seconds. Defaults to 30, max 120.`,type:`number`},url:{description:`The fully-formed URL to fetch content from. Must start with http:// or https://.`,type:`string`}},required:[`url`],type:`object`},WEB_FETCH_OUTPUT_SCHEMA={additionalProperties:!1,properties:{content:{type:`string`},contentType:{type:`string`},truncated:{type:`boolean`},url:{type:`string`}},required:[`content`,`contentType`,`url`,`truncated`],type:`object`},WEB_FETCH_TOOL_DEFINITION={description:[`Fetch a webpage and return its content in the requested format. Use this to retrieve and analyze content from URLs.`,``,`Usage notes:`,`- The URL must be a fully-formed valid URL starting with http:// or https://`,`- HTML responses are automatically converted to markdown or plain text based on the requested format`,`- Format options: "markdown" (default), "text", or "html"`,`- Default timeout is 30 seconds (max 120 seconds)`,`- Maximum response size is 5 MB; content is further capped at the shared tool-output budget (50 KB / 2000 lines)`,`- This tool is read-only and does not modify any files`].join(`
2
2
  `),execute:executeWebFetch,inputSchema:WEB_FETCH_INPUT_SCHEMA,logicalPath:`eve:framework/web-fetch`,name:`web_fetch`,outputSchema:WEB_FETCH_OUTPUT_SCHEMA,sourceId:`eve:web-fetch-tool`,sourceKind:`module`};export{WEB_FETCH_INPUT_SCHEMA,WEB_FETCH_OUTPUT_SCHEMA,WEB_FETCH_TOOL_DEFINITION};
@@ -1,2 +1,2 @@
1
- import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeWriteFileOnSandbox}from"#execution/sandbox/write-file-tool.js";const WRITE_FILE_INPUT_SCHEMA={additionalProperties:!1,properties:{content:{description:`Complete replacement file contents.`,type:`string`},filePath:{description:`The absolute path to the file to write (must be absolute, not relative).`,type:`string`}},required:[`filePath`,`content`],type:`object`},WRITE_FILE_OUTPUT_SCHEMA={additionalProperties:!1,properties:{existed:{type:`boolean`},path:{type:`string`}},required:[`existed`,`path`],type:`object`};async function executeWriteFile(e){return executeWriteFileOnSandbox(await requireSandboxSession(),e)}const WRITE_FILE_TOOL_DEFINITION={description:[`Writes a file to the local filesystem.`,``,`Usage:`,`- This tool will overwrite the existing file if there is one at the provided path.`,`- If this is an existing file, you MUST use the read_file tool first to read the file's contents. This tool will fail if you did not read the file first.`,`- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.`,`- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.`,`- Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.`].join(`
1
+ import{requireSandboxSession}from"#execution/sandbox/require-sandbox.js";import{executeWriteFileOnSandbox}from"#execution/sandbox/write-file-tool.js";const WRITE_FILE_INPUT_SCHEMA={additionalProperties:!1,properties:{content:{description:`Complete replacement file contents.`,type:`string`},filePath:{description:`The absolute path to the file to write (must be absolute, not relative).`,type:`string`}},required:[`filePath`,`content`],type:`object`},WRITE_FILE_OUTPUT_SCHEMA={additionalProperties:!1,properties:{existed:{type:`boolean`},path:{type:`string`}},required:[`existed`,`path`],type:`object`};async function executeWriteFile(e,t){return executeWriteFileOnSandbox(await requireSandboxSession(t?.abortSignal),e)}const WRITE_FILE_TOOL_DEFINITION={description:[`Writes a file to the local filesystem.`,``,`Usage:`,`- This tool will overwrite the existing file if there is one at the provided path.`,`- If this is an existing file, you MUST use the read_file tool first to read the file's contents. This tool will fail if you did not read the file first.`,`- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.`,`- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.`,`- Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.`].join(`
2
2
  `),execute:executeWriteFile,inputSchema:WRITE_FILE_INPUT_SCHEMA,logicalPath:`eve:framework/write-file`,name:`write_file`,outputSchema:WRITE_FILE_OUTPUT_SCHEMA,sourceId:`eve:write-file-tool`,sourceKind:`module`};export{WRITE_FILE_INPUT_SCHEMA,WRITE_FILE_OUTPUT_SCHEMA,WRITE_FILE_TOOL_DEFINITION};
@@ -1 +1 @@
1
- import{ResolveAgentError,createResolvedModuleSourceRef}from"#runtime/resolve-helpers.js";import{resolveChannelDefinition}from"#runtime/resolve-channel.js";import{resolveConnectionDefinition}from"#runtime/resolve-connection.js";import{resolveHookDefinition}from"#runtime/resolve-hook.js";import{resolveSandboxDefinition}from"#runtime/resolve-sandbox.js";import{resolveDynamicInstructionsDefinition}from"#runtime/resolve-dynamic-instructions.js";import{resolveDynamicSkillDefinition}from"#runtime/resolve-dynamic-skill.js";import{resolveDynamicToolDefinition}from"#runtime/resolve-dynamic-tool.js";import{resolveToolDefinition}from"#runtime/resolve-tool.js";async function resolveAgent(e){let t=e.manifest.skills.map(e=>({...e,metadata:e.metadata===void 0?void 0:{...e.metadata}})),r=[],i=[];for(let t of e.manifest.channels){if(t.kind===`disabled`){i.push(t.name);continue}r.push(await resolveChannelDefinition(t,e.moduleMap,e.nodeId))}let a=await Promise.all(e.manifest.tools.map(t=>resolveToolDefinition(t,e.moduleMap,e.nodeId))),o=await Promise.all((e.manifest.dynamicInstructions??[]).map(t=>resolveDynamicInstructionsDefinition(t,e.moduleMap,e.nodeId))),s=await Promise.all((e.manifest.dynamicSkills??[]).map(t=>resolveDynamicSkillDefinition(t,e.moduleMap,e.nodeId))),c=await Promise.all(e.manifest.dynamicTools.map(t=>resolveDynamicToolDefinition(t,e.moduleMap,e.nodeId))),l=await Promise.all(e.manifest.hooks.map(t=>resolveHookDefinition(t,e.moduleMap,e.nodeId))),u=await Promise.all(e.manifest.connections.map(t=>resolveConnectionDefinition(t,e.moduleMap,e.nodeId))),d=e.manifest.sandbox===null?null:await resolveSandboxDefinition(e.manifest.sandbox,e.moduleMap,e.nodeId),f=createResolvedInstructions(e.manifest.instructions),p=e.manifest.workspaceResourceRoot,m={channels:r,config:createResolvedAgentConfig(e.manifest),connections:u,disabledFrameworkChannels:i,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],workflowEnabled:e.manifest.workflowEnabled,dynamicInstructionsResolvers:o,dynamicSkillResolvers:s,dynamicToolResolvers:c,hooks:l,metadata:{agentRoot:e.manifest.agentRoot,appRoot:e.manifest.appRoot,diagnosticsSummary:e.manifest.diagnosticsSummary},sandbox:d,workspaceResourceRoot:p,skills:t,tools:a,workspaceSpec:{rootEntries:[...p.rootEntries]}};return f===void 0?m:{...m,instructions:f}}function createResolvedInstructions(e){if(e!==void 0)return{name:e.name,logicalPath:e.logicalPath,markdown:e.markdown,sourceId:e.sourceId,sourceKind:e.sourceKind}}function createResolvedAgentConfig(e){let n={model:e.config.model.source===void 0?{id:e.config.model.id,contextWindowTokens:e.config.model.contextWindowTokens,providerOptions:e.config.model.providerOptions}:{contextWindowTokens:e.config.model.contextWindowTokens,id:e.config.model.id,providerOptions:e.config.model.providerOptions,source:{exportName:e.config.model.source.exportName,sourceKind:`module`,logicalPath:e.config.model.source.logicalPath,sourceId:e.config.model.source.sourceId}},name:e.config.name};if(e.config.compaction!==void 0){let t={};e.config.compaction.model!==void 0&&(t.model=e.config.compaction.model.source===void 0?{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions}:{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions,source:{exportName:e.config.compaction.model.source.exportName,sourceKind:`module`,logicalPath:e.config.compaction.model.source.logicalPath,sourceId:e.config.compaction.model.source.sourceId}}),e.config.compaction.thresholdPercent!==void 0&&(t.thresholdPercent=e.config.compaction.thresholdPercent),n.compaction=t}return e.config.experimental!==void 0&&(n.experimental={workflow:e.config.experimental.workflow===void 0?void 0:{world:e.config.experimental.workflow.world}}),e.config.outputSchema!==void 0&&(n.outputSchema=e.config.outputSchema),e.config.reasoning!==void 0&&(n.reasoning=e.config.reasoning),e.config.source!==void 0&&(n.source=createResolvedModuleSourceRef(e.config.source)),e.config.limits!==void 0&&(n.limits={maxSubagentDepth:e.config.limits.maxSubagentDepth,maxInputTokensPerSession:e.config.limits.maxInputTokensPerSession,maxOutputTokensPerSession:e.config.limits.maxOutputTokensPerSession}),n}export{ResolveAgentError,resolveAgent};
1
+ import{ResolveAgentError,createResolvedModuleSourceRef}from"#runtime/resolve-helpers.js";import{resolveChannelDefinition}from"#runtime/resolve-channel.js";import{resolveConnectionDefinition}from"#runtime/resolve-connection.js";import{resolveHookDefinition}from"#runtime/resolve-hook.js";import{resolveSandboxDefinition}from"#runtime/resolve-sandbox.js";import{resolveDynamicInstructionsDefinition}from"#runtime/resolve-dynamic-instructions.js";import{resolveDynamicSkillDefinition}from"#runtime/resolve-dynamic-skill.js";import{resolveDynamicToolDefinition}from"#runtime/resolve-dynamic-tool.js";import{resolveToolDefinition}from"#runtime/resolve-tool.js";async function resolveAgent(e){let t=e.manifest.skills.map(e=>({...e,metadata:e.metadata===void 0?void 0:{...e.metadata}})),r=[],i=[];for(let t of e.manifest.channels){if(t.kind===`disabled`){i.push(t.name);continue}r.push(await resolveChannelDefinition(t,e.moduleMap,e.nodeId))}let a=await Promise.all(e.manifest.tools.map(t=>resolveToolDefinition(t,e.moduleMap,e.nodeId))),o=await Promise.all((e.manifest.dynamicInstructions??[]).map(t=>resolveDynamicInstructionsDefinition(t,e.moduleMap,e.nodeId))),s=await Promise.all((e.manifest.dynamicSkills??[]).map(t=>resolveDynamicSkillDefinition(t,e.moduleMap,e.nodeId))),c=await Promise.all(e.manifest.dynamicTools.map(t=>resolveDynamicToolDefinition(t,e.moduleMap,e.nodeId))),l=await Promise.all(e.manifest.hooks.map(t=>resolveHookDefinition(t,e.moduleMap,e.nodeId))),u=await Promise.all(e.manifest.connections.map(t=>resolveConnectionDefinition(t,e.moduleMap,e.nodeId))),d=e.manifest.sandbox===null?null:await resolveSandboxDefinition(e.manifest.sandbox,e.moduleMap,e.nodeId),f=createResolvedInstructions(e.manifest.instructions),p=e.manifest.workspaceResourceRoot,m={channels:r,config:createResolvedAgentConfig(e.manifest),connections:u,disabledFrameworkChannels:i,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],workflowEnabled:e.manifest.workflowEnabled,dynamicInstructionsResolvers:o,dynamicSkillResolvers:s,dynamicToolResolvers:c,hooks:l,metadata:{agentRoot:e.manifest.agentRoot,appRoot:e.manifest.appRoot,diagnosticsSummary:e.manifest.diagnosticsSummary},sandbox:d,workspaceResourceRoot:p,skills:t,tools:a,workspaceSpec:{rootEntries:[...p.rootEntries]}};return f===void 0?m:{...m,instructions:f}}function createResolvedInstructions(e){if(e!==void 0)return{name:e.name,logicalPath:e.logicalPath,markdown:e.markdown,sourceId:e.sourceId,sourceKind:e.sourceKind}}function createResolvedAgentConfig(e){let n={model:e.config.model.source===void 0?{id:e.config.model.id,contextWindowTokens:e.config.model.contextWindowTokens,providerOptions:e.config.model.providerOptions}:{contextWindowTokens:e.config.model.contextWindowTokens,id:e.config.model.id,providerOptions:e.config.model.providerOptions,source:{exportName:e.config.model.source.exportName,sourceKind:`module`,logicalPath:e.config.model.source.logicalPath,sourceId:e.config.model.source.sourceId}},name:e.config.name};if(e.config.compaction!==void 0){let t={};e.config.compaction.model!==void 0&&(t.model=e.config.compaction.model.source===void 0?{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions}:{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions,source:{exportName:e.config.compaction.model.source.exportName,sourceKind:`module`,logicalPath:e.config.compaction.model.source.logicalPath,sourceId:e.config.compaction.model.source.sourceId}}),e.config.compaction.thresholdPercent!==void 0&&(t.thresholdPercent=e.config.compaction.thresholdPercent),n.compaction=t}return e.config.experimental!==void 0&&(n.experimental={workflow:e.config.experimental.workflow===void 0?void 0:{world:e.config.experimental.workflow.world}}),e.config.outputSchema!==void 0&&(n.outputSchema=e.config.outputSchema),e.config.reasoning!==void 0&&(n.reasoning=e.config.reasoning),e.config.source!==void 0&&(n.source=createResolvedModuleSourceRef(e.config.source)),e.config.limits!==void 0&&(n.limits={maxSubagentDepth:e.config.limits.maxSubagentDepth,maxSubagents:e.config.limits.maxSubagents,maxInputTokensPerSession:e.config.limits.maxInputTokensPerSession,maxOutputTokensPerSession:e.config.limits.maxOutputTokensPerSession}),n}export{ResolveAgentError,resolveAgent};
@@ -1 +1 @@
1
- import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{realpath}from"node:fs/promises";import{createHash}from"node:crypto";import{getRuntimeCompiledArtifactsCacheKey,getRuntimeCompiledArtifactsSandboxAppRoot}from"#runtime/compiled-artifacts-source.js";import{loadCompileMetadata}from"#runtime/loaders/compile-metadata.js";async function createRuntimeSandboxKeys(e){return{sessionKey:await createRuntimeSandboxSessionKey(e),templateKey:await createRuntimeSandboxTemplateKey(e)}}async function createRuntimeSandboxTemplateKey(e){if(e.templatePlan.kind===`none`)return null;let t=await loadCompileMetadataForKeys(e.compiledArtifactsSource),n=await resolveRuntimeSandboxScope({backendName:e.backendName,compiledArtifactsSource:e.compiledArtifactsSource,scopeKind:e.templatePlan.kind===`source-graph`?`deployment`:`stable`}),r=resolveRuntimeSandboxVersionHash({compiledArtifactsSource:e.compiledArtifactsSource,metadata:t,nodeId:e.nodeId,sourceId:e.sourceId,templatePlan:e.templatePlan}),i=createStableHash(`${resolvePackageVersionForTemplateKey(t)}:6:${r}`).slice(0,20);return sanitizeRuntimeSandboxKey(`eve-sbx-tpl-${e.backendName}-${n}-${i}`)}function resolvePackageVersionForTemplateKey(t){return t?.generator.version??resolveInstalledPackageInfo().version}async function loadCompileMetadataForKeys(e){try{return await loadCompileMetadata({compiledArtifactsSource:e})}catch{return null}}async function createRuntimeSandboxSessionKey(e){let t=await resolveRuntimeSandboxScope({backendName:e.backendName,compiledArtifactsSource:e.compiledArtifactsSource,scopeKind:`deployment`}),n=sanitizeRuntimeSandboxKey(e.nodeId);return sanitizeRuntimeSandboxKey(`eve-sbx-ses-${e.backendName}-${t}-${e.sessionId}-${n}`)}async function resolveRuntimeSandboxScope(e){if(e.backendName===`vercel`){if(e.scopeKind===`stable`){let e=resolveVercelProjectScope();if(e!==void 0)return createStableHash(e).slice(0,16)}let t=process.env.VERCEL_DEPLOYMENT_ID?.trim();if(t!==void 0&&t.length>0)return createStableHash(t).slice(0,16)}let n=getRuntimeCompiledArtifactsSandboxAppRoot(e.compiledArtifactsSource);return n===void 0?createStableHash(getRuntimeCompiledArtifactsCacheKey(e.compiledArtifactsSource)).slice(0,16):createStableHash(await realpath(n)).slice(0,16)}function resolveRuntimeSandboxVersionHash(e){if(e.templatePlan.kind===`bootstrap`){let t=e.templatePlan.contentHash??resolveSourceGraphHash(e.metadata,e.compiledArtifactsSource);return createStableHash(`bootstrap:${e.templatePlan.revalidationKey??``}:${e.templatePlan.sourceHash}:${t}:${e.nodeId}:${e.sourceId}`)}return e.templatePlan.kind===`workspace-content`?createStableHash(`workspace-content:${e.templatePlan.contentHash??resolveSourceGraphHash(e.metadata,e.compiledArtifactsSource)}:${e.nodeId}:${e.sourceId}`):createStableHash(`source-graph:${resolveSourceGraphHash(e.metadata,e.compiledArtifactsSource)}:${e.nodeId}:${e.sourceId}`)}function resolveSourceGraphHash(e,t){return e?.discovery.sourceGraphHash??getRuntimeCompiledArtifactsCacheKey(t)}function resolveVercelProjectScope(){let e=process.env.VERCEL_PROJECT_ID?.trim();if(!(e===void 0||e.length===0))return`vercel-project:${e}`}function createStableHash(e){return createHash(`sha256`).update(e).digest(`hex`)}function sanitizeRuntimeSandboxKey(e){return e.replaceAll(/[^a-zA-Z0-9._-]+/g,`-`).slice(0,120)}export{createRuntimeSandboxKeys,createRuntimeSandboxTemplateKey};
1
+ import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{realpath}from"node:fs/promises";import{createHash}from"node:crypto";import{getRuntimeCompiledArtifactsCacheKey,getRuntimeCompiledArtifactsSandboxAppRoot}from"#runtime/compiled-artifacts-source.js";import{loadCompileMetadata}from"#runtime/loaders/compile-metadata.js";async function createRuntimeSandboxKeys(e){return{sessionKey:await createRuntimeSandboxSessionKey(e),templateKey:await createRuntimeSandboxTemplateKey(e)}}async function createRuntimeSandboxTemplateKey(e){if(e.templatePlan.kind===`none`)return null;let t=await loadCompileMetadataForKeys(e.compiledArtifactsSource),n=await resolveRuntimeSandboxScope({backendName:e.backendName,compiledArtifactsSource:e.compiledArtifactsSource,scopeKind:e.templatePlan.kind===`source-graph`?`deployment`:`stable`}),r=resolveRuntimeSandboxVersionHash({compiledArtifactsSource:e.compiledArtifactsSource,metadata:t,nodeId:e.nodeId,sourceId:e.sourceId,templatePlan:e.templatePlan}),i=createStableHash(`${resolvePackageVersionForTemplateKey(t)}:7:${r}`).slice(0,20);return sanitizeRuntimeSandboxKey(`eve-sbx-tpl-${e.backendName}-${n}-${i}`)}function resolvePackageVersionForTemplateKey(t){return t?.generator.version??resolveInstalledPackageInfo().version}async function loadCompileMetadataForKeys(e){try{return await loadCompileMetadata({compiledArtifactsSource:e})}catch{return null}}async function createRuntimeSandboxSessionKey(e){let t=await resolveRuntimeSandboxScope({backendName:e.backendName,compiledArtifactsSource:e.compiledArtifactsSource,scopeKind:`deployment`}),n=sanitizeRuntimeSandboxKey(e.nodeId);return sanitizeRuntimeSandboxKey(`eve-sbx-ses-${e.backendName}-${t}-${e.sessionId}-${n}`)}async function resolveRuntimeSandboxScope(e){if(e.backendName===`vercel`){if(e.scopeKind===`stable`){let e=resolveVercelProjectScope();if(e!==void 0)return createStableHash(e).slice(0,16)}let t=process.env.VERCEL_DEPLOYMENT_ID?.trim();if(t!==void 0&&t.length>0)return createStableHash(t).slice(0,16)}let n=getRuntimeCompiledArtifactsSandboxAppRoot(e.compiledArtifactsSource);return n===void 0?createStableHash(getRuntimeCompiledArtifactsCacheKey(e.compiledArtifactsSource)).slice(0,16):createStableHash(await realpath(n)).slice(0,16)}function resolveRuntimeSandboxVersionHash(e){if(e.templatePlan.kind===`bootstrap`){let t=e.templatePlan.contentHash??resolveSourceGraphHash(e.metadata,e.compiledArtifactsSource);return createStableHash(`bootstrap:${e.templatePlan.revalidationKey??``}:${e.templatePlan.sourceHash}:${t}:${e.nodeId}:${e.sourceId}`)}return e.templatePlan.kind===`workspace-content`?createStableHash(`workspace-content:${e.templatePlan.contentHash??resolveSourceGraphHash(e.metadata,e.compiledArtifactsSource)}:${e.nodeId}:${e.sourceId}`):createStableHash(`source-graph:${resolveSourceGraphHash(e.metadata,e.compiledArtifactsSource)}:${e.nodeId}:${e.sourceId}`)}function resolveSourceGraphHash(e,t){return e?.discovery.sourceGraphHash??getRuntimeCompiledArtifactsCacheKey(t)}function resolveVercelProjectScope(){let e=process.env.VERCEL_PROJECT_ID?.trim();if(!(e===void 0||e.length===0))return`vercel-project:${e}`}function createStableHash(e){return createHash(`sha256`).update(e).digest(`hex`)}function sanitizeRuntimeSandboxKey(e){return e.replaceAll(/[^a-zA-Z0-9._-]+/g,`-`).slice(0,120)}export{createRuntimeSandboxKeys,createRuntimeSandboxTemplateKey};
@@ -1 +1 @@
1
- function createRuntimeSandboxTemplatePlan(e){if(e.definition.bootstrap!==void 0){if(e.definition.sourceHash===void 0)throw Error(`Sandbox "${e.definition.logicalPath}" defines bootstrap() but has no compiled sourceHash.`);return{contentHash:e.workspaceResourceRoot.contentHash,kind:`bootstrap`,revalidationKey:e.definition.revalidationKey,sourceHash:e.definition.sourceHash}}return e.workspaceResourceRoot.rootEntries.length===0?{kind:`none`}:{contentHash:e.workspaceResourceRoot.contentHash,kind:`workspace-content`}}export{createRuntimeSandboxTemplatePlan};
1
+ function createRuntimeSandboxTemplatePlan(e){if(e.definition.bootstrap!==void 0){if(e.definition.sourceHash===void 0)throw Error(`Sandbox "${e.definition.logicalPath}" defines bootstrap() but has no compiled sourceHash.`);return{contentHash:e.workspaceResourceRoot.contentHash,kind:`bootstrap`,revalidationKey:e.definition.revalidationKey,sourceHash:e.definition.sourceHash}}return e.workspaceResourceRoot.contentHash===void 0&&e.workspaceResourceRoot.rootEntries.length===0?{kind:`none`}:{contentHash:e.workspaceResourceRoot.contentHash,kind:`workspace-content`}}export{createRuntimeSandboxTemplatePlan};
@@ -1 +1 @@
1
- import{EVE_CALLBACK_ROUTE_PATTERN}from"#protocol/routes.js";import{resumeHook}from"#internal/workflow/runtime.js";const HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX=`eve/v1/callback`,HANDLED_METHODS=[`POST`];function getSessionCallbackChannelDefinitions(){return HANDLED_METHODS.map(e=>buildCallbackChannelDefinition(e))}function getSessionCallbackChannelNames(){return new Set(HANDLED_METHODS.map(channelNameForMethod))}function buildCallbackChannelDefinition(t){let n=channelNameForMethod(t);return{name:n,method:t,urlPath:EVE_CALLBACK_ROUTE_PATTERN,fetch:handleSessionCallbackRequest,logicalPath:`framework://channels/${n}`,sourceId:`eve:framework:session-callback-${t.toLowerCase()}`,sourceKind:`module`}}function channelNameForMethod(e){return`${HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX}/${e.toLowerCase()}`}async function handleSessionCallbackRequest(e,n){let r=n.params.token;if(typeof r!=`string`||r.length===0)return Response.json({error:`Missing callback token.`,ok:!1},{status:400});let i;try{i=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}let a=projectSessionCallbackResult(i);if(a instanceof Response)return a;try{await resumeHook(r,{kind:`runtime-action-result`,results:[a]})}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}function projectSessionCallbackResult(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let t=e;return typeof t.callId!=`string`||t.callId.length===0?Response.json({error:`Missing callback callId.`,ok:!1},{status:400}):typeof t.subagentName!=`string`||t.subagentName.length===0?Response.json({error:`Missing callback subagentName.`,ok:!1},{status:400}):t.kind===`session.completed`?{callId:t.callId,kind:`subagent-result`,output:t.output??``,subagentName:t.subagentName}:t.kind===`session.failed`?{callId:t.callId,isError:!0,kind:`subagent-result`,output:t.error===void 0?{code:`REMOTE_AGENT_FAILED`,message:`Remote agent failed.`}:t.error,subagentName:t.subagentName}:Response.json({error:`Unsupported callback kind.`,ok:!1},{status:400})}export{HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX,getSessionCallbackChannelDefinitions,getSessionCallbackChannelNames,handleSessionCallbackRequest};
1
+ import{EVE_CALLBACK_ROUTE_PATTERN}from"#protocol/routes.js";import{resumeHook}from"#internal/workflow/runtime.js";import{tokenUsageSchema}from"#shared/token-usage.js";const HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX=`eve/v1/callback`,HANDLED_METHODS=[`POST`];function getSessionCallbackChannelDefinitions(){return HANDLED_METHODS.map(e=>buildCallbackChannelDefinition(e))}function getSessionCallbackChannelNames(){return new Set(HANDLED_METHODS.map(channelNameForMethod))}function buildCallbackChannelDefinition(t){let n=channelNameForMethod(t);return{name:n,method:t,urlPath:EVE_CALLBACK_ROUTE_PATTERN,fetch:handleSessionCallbackRequest,logicalPath:`framework://channels/${n}`,sourceId:`eve:framework:session-callback-${t.toLowerCase()}`,sourceKind:`module`}}function channelNameForMethod(e){return`${HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX}/${e.toLowerCase()}`}async function handleSessionCallbackRequest(e,n){let r=n.params.token;if(typeof r!=`string`||r.length===0)return Response.json({error:`Missing callback token.`,ok:!1},{status:400});let i;try{i=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}let a=projectSessionCallbackResult(i);if(a instanceof Response)return a;try{await resumeHook(r,{kind:`runtime-action-result`,results:[a]})}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}function projectSessionCallbackResult(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let t=e;if(typeof t.callId!=`string`||t.callId.length===0)return Response.json({error:`Missing callback callId.`,ok:!1},{status:400});if(typeof t.subagentName!=`string`||t.subagentName.length===0)return Response.json({error:`Missing callback subagentName.`,ok:!1},{status:400});if(t.kind===`session.completed`){let e={callId:t.callId,kind:`subagent-result`,output:t.output??``,subagentName:t.subagentName},n=parseCallbackUsage(t.usage);return n===void 0?e:{...e,usage:n}}return t.kind===`session.failed`?{callId:t.callId,isError:!0,kind:`subagent-result`,output:t.error===void 0?{code:`REMOTE_AGENT_FAILED`,message:`Remote agent failed.`}:t.error,subagentName:t.subagentName}:Response.json({error:`Unsupported callback kind.`,ok:!1},{status:400})}function parseCallbackUsage(e){if(e===void 0)return;let t=tokenUsageSchema.safeParse(e);return t.success?t.data:void 0}export{HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX,getSessionCallbackChannelDefinitions,getSessionCallbackChannelNames,handleSessionCallbackRequest};
@@ -2,7 +2,7 @@ import type { SandboxAccess } from "#sandbox/state.js";
2
2
  import type { SkillHandle } from "#execution/skills/types.js";
3
3
  /**
4
4
  * Validates a skill id before it is used as one path segment under
5
- * `/workspace/skills`.
5
+ * the sandbox skill root.
6
6
  */
7
7
  export declare function assertSafeSkillId(id: string): asserts id is string;
8
8
  /**
@@ -1 +1 @@
1
- import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";const FRONTMATTER_PATTERN=/^---\r?\n[\s\S]*?\r?\n---\r?\n?/;function assertSafeSkillId(e){if(e.length===0||e.trim()!==e||e.startsWith(`.`)||e.includes(`/`)||e.includes(`\\`)||e.includes(`..`)||/^[A-Za-z]:/.test(e))throw Error(`Expected skill id to be a non-empty safe path segment without whitespace, separators, "." prefix, or "..".`)}async function loadSkillFromSandbox(e,n,r=[]){assertSafeSkillId(n);let i=await requireSandboxSession(e),a=skillFilePath(n,`SKILL.md`),o=await i.readTextFile({path:a});if(o===null){let e=r.length>0?` Available skills: ${r.join(`, `)}.`:``;throw Error(`No skill named "${n}" at ${a}.${e}`)}return o.replace(FRONTMATTER_PATTERN,``)}function createSandboxSkillHandle(e,t){return assertSafeSkillId(t),{name:t,file(n){assertSafeSkillRelativePath(n);let r=skillFilePath(t,n);return{async bytes(){let t=await(await requireSandboxSession(e)).readBinaryFile({path:r});if(t===null)throw Error(`Skill file not found: ${r}`);return t},async text(){let t=await(await requireSandboxSession(e)).readTextFile({path:r});if(t===null)throw Error(`Skill file not found: ${r}`);return t}}}}}function assertSafeSkillRelativePath(e){if(e.length===0||e.startsWith(`/`)||e.includes(`\\`)||e.split(`/`).some(e=>e.length===0||e===`.`||e===`..`))throw Error(`Expected skill file path to be a relative path inside the skill directory.`)}async function requireSandboxSession(e){let t=await e.get();if(t===null)throw Error(`The sandbox is not available in the current authored runtime context.`);return t}function skillFilePath(t,n){return`${WORKSPACE_ROOT}/skills/${t}/${n}`}export{assertSafeSkillId,createSandboxSkillHandle,loadSkillFromSandbox};
1
+ import{resolveSandboxSkillReadPaths}from"#shared/skill-paths.js";const FRONTMATTER_PATTERN=/^---\r?\n[\s\S]*?\r?\n---\r?\n?/;function assertSafeSkillId(e){if(e.length===0||e.trim()!==e||e.startsWith(`.`)||e.includes(`/`)||e.includes(`\\`)||e.includes(`..`)||/^[A-Za-z]:/.test(e))throw Error(`Expected skill id to be a non-empty safe path segment without whitespace, separators, "." prefix, or "..".`)}async function loadSkillFromSandbox(n,r,i=[]){assertSafeSkillId(r);let a=await requireSandboxSession(n),o=await resolveSandboxSkillReadPaths({name:r,relativePath:`SKILL.md`,sandbox:a});for(let e of o){let n=await a.readTextFile({path:e});if(n!==null)return n.replace(FRONTMATTER_PATTERN,``)}let s=i.length>0?` Available skills: ${i.join(`, `)}.`:``;throw Error(`No skill named "${r}" at ${o[0]}.${s}`)}function createSandboxSkillHandle(t,n){return assertSafeSkillId(n),{name:n,file(r){return assertSafeSkillRelativePath(r),{async bytes(){let i=await requireSandboxSession(t),a=await resolveSandboxSkillReadPaths({name:n,relativePath:r,sandbox:i});for(let e of a){let t=await i.readBinaryFile({path:e});if(t!==null)return t}throw Error(`Skill file not found: ${a[0]}`)},async text(){let i=await requireSandboxSession(t),a=await resolveSandboxSkillReadPaths({name:n,relativePath:r,sandbox:i});for(let e of a){let t=await i.readTextFile({path:e});if(t!==null)return t}throw Error(`Skill file not found: ${a[0]}`)}}}}}function assertSafeSkillRelativePath(e){if(e.length===0||e.startsWith(`/`)||e.includes(`\\`)||e.split(`/`).some(e=>e.length===0||e===`.`||e===`..`))throw Error(`Expected skill file path to be a relative path inside the skill directory.`)}async function requireSandboxSession(e){let t=await e.get();if(t===null)throw Error(`The sandbox is not available in the current authored runtime context.`);return t}export{assertSafeSkillId,createSandboxSkillHandle,loadSkillFromSandbox};
@@ -1 +1 @@
1
- import{join,posix}from"node:path";import{readFile,readdir}from"node:fs/promises";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";async function materializeWorkspaceDirectory(e){let t=[];return await addMaterializedDirectoryFiles({files:t,logicalDirectoryPath:`.`,sourceDirectoryPath:e}),t.sort((e,t)=>e.path.localeCompare(t.path)),t}async function addMaterializedDirectoryFiles(r){let i=await readdir(r.sourceDirectoryPath,{withFileTypes:!0});for(let n of i){if(!n.isDirectory()&&!n.isFile())continue;let i=join(r.sourceDirectoryPath,n.name),a=posix.join(r.logicalDirectoryPath,n.name);if(n.isDirectory()){await addMaterializedDirectoryFiles({files:r.files,logicalDirectoryPath:a,sourceDirectoryPath:i});continue}r.files.push({content:await readFile(i),path:posix.join(WORKSPACE_ROOT,a)})}}export{materializeWorkspaceDirectory};
1
+ import{join,posix}from"node:path";import{readFile,readdir}from"node:fs/promises";import{MODEL_SKILL_ROOT}from"#shared/skill-paths.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";const RESOURCE_WORKSPACE_DIRECTORY=`workspace`,RESOURCE_SKILLS_DIRECTORY=`skills`;async function materializeWorkspaceDirectory(t){let n=[],s=await readdir(t,{withFileTypes:!0}),c=s.find(e=>e.name===RESOURCE_WORKSPACE_DIRECTORY&&e.isDirectory()),l=s.find(e=>e.name===RESOURCE_SKILLS_DIRECTORY&&e.isDirectory());return c!==void 0||l!==void 0?(c!==void 0&&await addMaterializedDirectoryFiles({files:n,logicalDirectoryPath:`.`,sourceDirectoryPath:join(t,RESOURCE_WORKSPACE_DIRECTORY),targetRoot:WORKSPACE_ROOT}),l!==void 0&&await addMaterializedDirectoryFiles({files:n,logicalDirectoryPath:`.`,sourceDirectoryPath:join(t,RESOURCE_SKILLS_DIRECTORY),targetRoot:MODEL_SKILL_ROOT})):await addMaterializedDirectoryFiles({files:n,logicalDirectoryPath:`.`,sourceDirectoryPath:t,targetRoot:WORKSPACE_ROOT}),n.sort((e,t)=>e.path.localeCompare(t.path)),n}async function addMaterializedDirectoryFiles(i){let a=await readdir(i.sourceDirectoryPath,{withFileTypes:!0});for(let r of a){if(!r.isDirectory()&&!r.isFile())continue;let a=join(i.sourceDirectoryPath,r.name),o=posix.join(i.logicalDirectoryPath,r.name);if(r.isDirectory()){await addMaterializedDirectoryFiles({files:i.files,logicalDirectoryPath:o,sourceDirectoryPath:a,targetRoot:i.targetRoot});continue}i.files.push({content:await readFile(a),path:posix.join(i.targetRoot,o)})}}export{materializeWorkspaceDirectory};
@@ -28,6 +28,5 @@ export interface SandboxState {
28
28
  */
29
29
  export interface SandboxAccess {
30
30
  captureState(): Promise<SandboxState>;
31
- dispose(): Promise<void>;
32
31
  get(): Promise<SandboxSession | null>;
33
32
  }
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`^7.0.0`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.19.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{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`^7.0.0`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.21.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";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -1,7 +1,7 @@
1
1
  export declare const WEB_APP_TEMPLATE_FILES: {
2
2
  readonly "agent/channels/eve.ts": 'import { eveChannel } from "eve/channels/eve";\nimport { localDev, placeholderAuth, vercelOidc } from "eve/channels/auth";\n\nexport default eveChannel({\n auth: [\n // Lets the eve TUI and your Vercel deployments reach the deployed agent.\n vercelOidc(),\n // Open on localhost for `eve dev` and the REPL; ignored in production.\n localDev(),\n // This placeholder will not allow browser requests in production.\n // Replace it with your app\'s auth provider, like Auth.js or Clerk,\n // or use none() for a public demo.\n placeholderAuth(),\n ],\n});\n';
3
- readonly "app/_components/agent-chat.tsx": '"use client";\n\nimport { useEveAgent } from "eve/react";\nimport { AlertCircleIcon } from "lucide-react";\nimport {\n Conversation,\n ConversationContent,\n ConversationScrollButton,\n} from "@/components/ai-elements/conversation";\nimport {\n PromptInput,\n type PromptInputMessage,\n PromptInputSubmit,\n PromptInputTextarea,\n} from "@/components/ai-elements/prompt-input";\nimport { cn } from "@/lib/utils";\nimport { AgentMessage } from "./agent-message";\n\nconst AGENT_NAME = "__EVE_INIT_APP_NAME__";\n\ntype AgentStatus = ReturnType<typeof useEveAgent>["status"];\n\nexport function AgentChat() {\n const agent = useEveAgent();\n const isBusy = agent.status === "submitted" || agent.status === "streaming";\n const isEmpty = agent.data.messages.length === 0;\n\n const handleSubmit = async (message: PromptInputMessage) => {\n const text = message.text.trim();\n if (!text || isBusy) return;\n\n await agent.send({ message: text });\n };\n\n const composer = (\n <PromptInput onSubmit={handleSubmit}>\n <PromptInputTextarea placeholder="Send a message…" />\n <PromptInputSubmit onStop={agent.stop} status={agent.status} />\n </PromptInput>\n );\n\n return (\n <main className="flex h-dvh flex-col overflow-hidden bg-background text-foreground">\n {isEmpty ? null : (\n <header className="flex h-14 shrink-0 items-center justify-center gap-3 pl-4 pr-2">\n <span className="flex min-w-0 items-center gap-2">\n <span className="truncate text-muted-foreground text-sm">{AGENT_NAME}</span>\n <StatusDot status={agent.status} />\n </span>\n </header>\n )}\n\n {agent.error ? (\n <div className="mx-auto w-full max-w-3xl shrink-0 px-4 pt-2 sm:px-6">\n <div className="flex items-start gap-3 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2.5 text-sm">\n <AlertCircleIcon className="mt-0.5 size-4 shrink-0 text-destructive" />\n <div>\n <p className="font-medium">Request failed</p>\n <p className="mt-0.5 text-muted-foreground">{agent.error.message}</p>\n </div>\n </div>\n </div>\n ) : null}\n\n {isEmpty ? null : (\n <Conversation className="min-h-0 flex-1">\n <ConversationContent className="mx-auto w-full max-w-3xl gap-6 px-4 py-6 sm:px-6">\n {agent.data.messages.map((message, index) => (\n <AgentMessage\n canRespond={!isBusy}\n isStreaming={\n agent.status === "streaming" && index === agent.data.messages.length - 1\n }\n key={message.id}\n message={message}\n onInputResponses={(inputResponses) => agent.send({ inputResponses })}\n />\n ))}\n </ConversationContent>\n <ConversationScrollButton />\n </Conversation>\n )}\n\n <div\n className={cn(\n "mx-auto w-full px-4 sm:px-6",\n isEmpty\n ? "flex max-w-xl flex-1 flex-col items-center justify-center gap-8 pb-[10vh]"\n : "max-w-3xl shrink-0 pb-6",\n )}\n >\n {isEmpty ? (\n <div className="flex flex-col items-center gap-3 text-center">\n <h1 className="font-medium text-5xl tracking-tighter">{AGENT_NAME}</h1>\n </div>\n ) : null}\n <div className="w-full">{composer}</div>\n </div>\n </main>\n );\n}\n\nfunction StatusDot({ status }: { readonly status: AgentStatus }) {\n const isLive = status === "submitted" || status === "streaming";\n const tone =\n status === "error"\n ? "bg-destructive"\n : isLive\n ? "bg-emerald-500"\n : status === "ready"\n ? "bg-muted-foreground"\n : "bg-muted-foreground/50";\n\n return (\n <span className="relative flex size-1">\n {isLive ? (\n <span\n className={cn(\n "absolute inline-flex size-full animate-ping rounded-full opacity-75",\n tone,\n )}\n />\n ) : null}\n <span className={cn("relative inline-flex size-1 rounded-full transition-colors", tone)} />\n </span>\n );\n}\n';
4
- readonly "app/_components/agent-message.tsx": '"use client";\n\nimport type {\n EveAuthorizationPart,\n EveDynamicToolPart,\n EveMessage,\n EveMessagePart,\n} from "eve/react";\nimport { CheckCircleIcon, ExternalLinkIcon, KeyRoundIcon, XCircleIcon } from "lucide-react";\nimport { Message, MessageContent, MessageResponse } from "@/components/ai-elements/message";\nimport { Reasoning, ReasoningContent, ReasoningTrigger } from "@/components/ai-elements/reasoning";\nimport {\n Tool,\n ToolContent,\n ToolHeader,\n ToolInput,\n ToolOutput,\n} from "@/components/ai-elements/tool";\nimport { Button } from "@/components/ui/button";\nimport { cn } from "@/lib/utils";\n\nexport type AgentInputResponse = {\n readonly optionId?: string;\n readonly requestId: string;\n readonly text?: string;\n};\n\nexport function AgentMessage({\n canRespond,\n isStreaming,\n message,\n onInputResponses,\n}: {\n readonly canRespond: boolean;\n readonly isStreaming: boolean;\n readonly message: EveMessage;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n}) {\n const lastTextIndex = message.parts.reduce(\n (last, part, index) => (part.type === "text" ? index : last),\n -1,\n );\n\n return (\n <Message\n data-optimistic={message.metadata?.optimistic ? "true" : undefined}\n from={message.role}\n >\n <MessageContent>\n {message.parts.map((part, index) => (\n <AgentMessagePart\n canRespond={canRespond}\n key={partKey(part, index)}\n onInputResponses={onInputResponses}\n part={part}\n showCaret={isStreaming && message.role === "assistant" && index === lastTextIndex}\n />\n ))}\n </MessageContent>\n </Message>\n );\n}\n\nfunction AgentMessagePart({\n canRespond,\n onInputResponses,\n part,\n showCaret,\n}: {\n readonly canRespond: boolean;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n readonly part: EveMessagePart;\n readonly showCaret: boolean;\n}) {\n switch (part.type) {\n case "step-start":\n return null;\n case "text":\n return (\n <MessageResponse caret="block" isAnimating={showCaret}>\n {part.text}\n </MessageResponse>\n );\n case "reasoning":\n return (\n <Reasoning defaultOpen isStreaming={part.state === "streaming"}>\n <ReasoningTrigger />\n <ReasoningContent>{part.text}</ReasoningContent>\n </Reasoning>\n );\n case "authorization":\n return <AuthorizationPrompt part={part} />;\n case "dynamic-tool":\n return (\n <Tool\n defaultOpen={part.state === "approval-requested" || part.state === "approval-responded"}\n >\n <ToolHeader\n state={part.state}\n title={part.toolName}\n toolName={part.toolName}\n type="dynamic-tool"\n />\n <ToolContent>\n <ToolInput input={part.input} />\n <InputRequestActions\n canRespond={canRespond}\n part={part}\n onInputResponses={onInputResponses}\n />\n <ToolOutput errorText={part.errorText} output={part.output} />\n </ToolContent>\n </Tool>\n );\n }\n}\n\nfunction AuthorizationPrompt({ part }: { readonly part: EveAuthorizationPart }) {\n const isAuthorized = part.state === "completed" && part.outcome === "authorized";\n const isCompleted = part.state === "completed";\n const Icon = isAuthorized ? CheckCircleIcon : isCompleted ? XCircleIcon : KeyRoundIcon;\n const instructions = part.authorization?.instructions;\n const shouldShowInstructions = instructions !== undefined && instructions !== part.description;\n\n return (\n <div\n className={cn(\n "space-y-3 rounded-md border p-3",\n isAuthorized\n ? "border-emerald-500/30 bg-emerald-500/5"\n : isCompleted\n ? "border-destructive/30 bg-destructive/5"\n : "border-blue-500/30 bg-blue-500/5",\n )}\n >\n <div className="flex items-start gap-3">\n <span\n className={cn(\n "mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full",\n isAuthorized\n ? "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300"\n : isCompleted\n ? "bg-destructive/10 text-destructive"\n : "bg-blue-500/10 text-blue-700 dark:text-blue-300",\n )}\n >\n <Icon className="size-4" />\n </span>\n <div className="min-w-0 flex-1 space-y-2">\n <p className="font-medium text-sm">{authorizationTitle(part)}</p>\n <p className="text-muted-foreground text-sm">{authorizationDescription(part)}</p>\n {shouldShowInstructions ? (\n <p className="text-muted-foreground text-sm">{instructions}</p>\n ) : null}\n {part.state === "required" && part.authorization?.userCode ? (\n <div className="flex flex-wrap items-center gap-2 text-sm">\n <span className="text-muted-foreground">Code</span>\n <code className="rounded-md bg-background px-2 py-1 font-mono">\n {part.authorization.userCode}\n </code>\n </div>\n ) : null}\n {part.state === "required" && part.authorization?.url ? (\n <Button asChild size="sm">\n <a href={part.authorization.url} rel="noreferrer" target="_blank">\n <ExternalLinkIcon className="size-4" />\n Sign in with {part.displayName}\n </a>\n </Button>\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n\nfunction authorizationTitle(part: EveAuthorizationPart): string {\n if (part.state === "required") {\n return `Connect ${part.displayName}`;\n }\n if (part.outcome === "authorized") {\n return `${part.displayName} connected`;\n }\n return `${part.displayName} authorization ${formatAuthorizationOutcome(part.outcome)}`;\n}\n\nfunction authorizationDescription(part: EveAuthorizationPart): string {\n if (part.state === "required") {\n return part.description;\n }\n if (part.outcome === "authorized") {\n return `${part.displayName} connected.`;\n }\n const tail = part.reason !== undefined ? ` (${part.reason})` : "";\n return `${part.displayName} authorization ${formatAuthorizationOutcome(part.outcome)}${tail}.`;\n}\n\nfunction formatAuthorizationOutcome(outcome: NonNullable<EveAuthorizationPart["outcome"]>): string {\n switch (outcome) {\n case "authorized":\n return "authorized";\n case "declined":\n return "declined";\n case "failed":\n return "failed";\n case "timed-out":\n return "timed out";\n }\n}\n\nfunction InputRequestActions({\n canRespond,\n onInputResponses,\n part,\n}: {\n readonly canRespond: boolean;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n readonly part: EveDynamicToolPart;\n}) {\n const inputRequest = part.toolMetadata?.eve?.inputRequest;\n if (!inputRequest) {\n return null;\n }\n\n const inputResponse = part.toolMetadata?.eve?.inputResponse;\n const selectedOption = inputRequest.options?.find(\n (option) => option.id === inputResponse?.optionId,\n );\n\n return (\n <div className="space-y-3 rounded-md border border-yellow-500/30 bg-yellow-500/5 p-3">\n <p className="text-muted-foreground text-sm">{inputRequest.prompt}</p>\n {inputResponse ? (\n <p className="font-medium text-sm">\n Responded: {selectedOption?.label ?? inputResponse.text ?? inputResponse.optionId}\n </p>\n ) : (\n <div className="flex flex-wrap gap-2">\n {inputRequest.options?.map((option) => (\n <Button\n disabled={!canRespond}\n key={option.id}\n onClick={() => {\n void onInputResponses([\n {\n optionId: option.id,\n requestId: inputRequest.requestId,\n },\n ]);\n }}\n size="sm"\n type="button"\n variant={option.style === "danger" ? "destructive" : "default"}\n >\n {option.label}\n </Button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction partKey(part: EveMessagePart, index: number): string {\n switch (part.type) {\n case "authorization":\n return `authorization:${part.turnId}:${part.stepIndex}:${part.name}`;\n case "dynamic-tool":\n return part.toolCallId;\n default:\n return `${part.type}:${index}`;\n }\n}\n';
3
+ readonly "app/_components/agent-chat.tsx": '"use client";\n\nimport type { UserContent } from "ai";\nimport { useEveAgent } from "eve/react";\nimport { AlertCircleIcon } from "lucide-react";\nimport {\n Conversation,\n ConversationContent,\n ConversationScrollButton,\n} from "@/components/ai-elements/conversation";\nimport {\n PromptInput,\n type PromptInputMessage,\n PromptInputSubmit,\n PromptInputTextarea,\n} from "@/components/ai-elements/prompt-input";\nimport { cn } from "@/lib/utils";\nimport { AgentMessage } from "./agent-message";\n\nconst AGENT_NAME = "__EVE_INIT_APP_NAME__";\n\ntype AgentStatus = ReturnType<typeof useEveAgent>["status"];\n\nexport function AgentChat() {\n const agent = useEveAgent();\n const isBusy = agent.status === "submitted" || agent.status === "streaming";\n const isEmpty = agent.data.messages.length === 0;\n\n const handleSubmit = async (message: PromptInputMessage) => {\n const text = message.text.trim();\n if ((text.length === 0 && message.files.length === 0) || isBusy) return;\n\n if (message.files.length === 0) {\n await agent.send({ message: text });\n return;\n }\n\n const parts: UserContent = [];\n if (text.length > 0) {\n parts.push({ text, type: "text" });\n }\n for (const file of message.files) {\n parts.push({\n data: file.url,\n filename: file.filename,\n mediaType: file.mediaType,\n type: "file",\n });\n }\n\n await agent.send({ message: parts });\n };\n\n const composer = (\n <PromptInput onSubmit={handleSubmit}>\n <PromptInputTextarea placeholder="Send a message…" />\n <PromptInputSubmit onStop={agent.stop} status={agent.status} />\n </PromptInput>\n );\n\n return (\n <main className="flex h-dvh flex-col overflow-hidden bg-background text-foreground">\n {isEmpty ? null : (\n <header className="flex h-14 shrink-0 items-center justify-center gap-3 pl-4 pr-2">\n <span className="flex min-w-0 items-center gap-2">\n <span className="truncate text-muted-foreground text-sm">{AGENT_NAME}</span>\n <StatusDot status={agent.status} />\n </span>\n </header>\n )}\n\n {agent.error ? (\n <div className="mx-auto w-full max-w-3xl shrink-0 px-4 pt-2 sm:px-6">\n <div className="flex items-start gap-3 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2.5 text-sm">\n <AlertCircleIcon className="mt-0.5 size-4 shrink-0 text-destructive" />\n <div>\n <p className="font-medium">Request failed</p>\n <p className="mt-0.5 text-muted-foreground">{agent.error.message}</p>\n </div>\n </div>\n </div>\n ) : null}\n\n {isEmpty ? null : (\n <Conversation className="min-h-0 flex-1">\n <ConversationContent className="mx-auto w-full max-w-3xl gap-6 px-4 py-6 sm:px-6">\n {agent.data.messages.map((message, index) => (\n <AgentMessage\n canRespond={!isBusy}\n isStreaming={\n agent.status === "streaming" && index === agent.data.messages.length - 1\n }\n key={message.id}\n message={message}\n onInputResponses={(inputResponses) => agent.send({ inputResponses })}\n />\n ))}\n </ConversationContent>\n <ConversationScrollButton />\n </Conversation>\n )}\n\n <div\n className={cn(\n "mx-auto w-full px-4 sm:px-6",\n isEmpty\n ? "flex max-w-xl flex-1 flex-col items-center justify-center gap-8 pb-[10vh]"\n : "max-w-3xl shrink-0 pb-6",\n )}\n >\n {isEmpty ? (\n <div className="flex flex-col items-center gap-3 text-center">\n <h1 className="font-medium text-5xl tracking-tighter">{AGENT_NAME}</h1>\n </div>\n ) : null}\n <div className="w-full">{composer}</div>\n </div>\n </main>\n );\n}\n\nfunction StatusDot({ status }: { readonly status: AgentStatus }) {\n const isLive = status === "submitted" || status === "streaming";\n const tone =\n status === "error"\n ? "bg-destructive"\n : isLive\n ? "bg-emerald-500"\n : status === "ready"\n ? "bg-muted-foreground"\n : "bg-muted-foreground/50";\n\n return (\n <span className="relative flex size-1">\n {isLive ? (\n <span\n className={cn(\n "absolute inline-flex size-full animate-ping rounded-full opacity-75",\n tone,\n )}\n />\n ) : null}\n <span className={cn("relative inline-flex size-1 rounded-full transition-colors", tone)} />\n </span>\n );\n}\n';
4
+ readonly "app/_components/agent-message.tsx": '"use client";\n\nimport type {\n EveAuthorizationPart,\n EveDynamicToolPart,\n EveMessage,\n EveMessagePart,\n} from "eve/react";\nimport {\n CheckCircleIcon,\n ExternalLinkIcon,\n FileIcon,\n ImageIcon,\n KeyRoundIcon,\n XCircleIcon,\n} from "lucide-react";\nimport { Message, MessageContent, MessageResponse } from "@/components/ai-elements/message";\nimport { Reasoning, ReasoningContent, ReasoningTrigger } from "@/components/ai-elements/reasoning";\nimport {\n Tool,\n ToolContent,\n ToolHeader,\n ToolInput,\n ToolOutput,\n} from "@/components/ai-elements/tool";\nimport { Button } from "@/components/ui/button";\nimport { cn } from "@/lib/utils";\n\nexport type AgentInputResponse = {\n readonly optionId?: string;\n readonly requestId: string;\n readonly text?: string;\n};\n\ntype EveFilePart = Extract<EveMessagePart, { type: "file" }>;\n\nexport function AgentMessage({\n canRespond,\n isStreaming,\n message,\n onInputResponses,\n}: {\n readonly canRespond: boolean;\n readonly isStreaming: boolean;\n readonly message: EveMessage;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n}) {\n const lastTextIndex = message.parts.reduce(\n (last, part, index) => (part.type === "text" ? index : last),\n -1,\n );\n\n return (\n <Message\n data-optimistic={message.metadata?.optimistic ? "true" : undefined}\n from={message.role}\n >\n <MessageContent>\n {message.parts.map((part, index) => (\n <AgentMessagePart\n canRespond={canRespond}\n key={partKey(part, index)}\n onInputResponses={onInputResponses}\n part={part}\n showCaret={isStreaming && message.role === "assistant" && index === lastTextIndex}\n />\n ))}\n </MessageContent>\n </Message>\n );\n}\n\nfunction AgentMessagePart({\n canRespond,\n onInputResponses,\n part,\n showCaret,\n}: {\n readonly canRespond: boolean;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n readonly part: EveMessagePart;\n readonly showCaret: boolean;\n}) {\n switch (part.type) {\n case "step-start":\n return null;\n case "text":\n return (\n <MessageResponse caret="block" isAnimating={showCaret}>\n {part.text}\n </MessageResponse>\n );\n case "reasoning":\n return (\n <Reasoning defaultOpen isStreaming={part.state === "streaming"}>\n <ReasoningTrigger />\n <ReasoningContent>{part.text}</ReasoningContent>\n </Reasoning>\n );\n case "file":\n return <AttachmentPart part={part} />;\n case "authorization":\n return <AuthorizationPrompt part={part} />;\n case "dynamic-tool":\n return (\n <Tool\n defaultOpen={part.state === "approval-requested" || part.state === "approval-responded"}\n >\n <ToolHeader\n state={part.state}\n title={part.toolName}\n toolName={part.toolName}\n type="dynamic-tool"\n />\n <ToolContent>\n <ToolInput input={part.input} />\n <InputRequestActions\n canRespond={canRespond}\n part={part}\n onInputResponses={onInputResponses}\n />\n <ToolOutput errorText={part.errorText} output={part.output} />\n </ToolContent>\n </Tool>\n );\n }\n}\n\nfunction AttachmentPart({ part }: { readonly part: EveFilePart }) {\n const label = part.filename ?? "Attachment";\n const detail = [part.mediaType, formatBytes(part.size)].filter(Boolean).join(" - ");\n const isImage = part.mediaType.startsWith("image/") && part.url !== undefined;\n const Icon = isImage ? ImageIcon : FileIcon;\n const body = (\n <span className="flex max-w-sm items-center gap-3 rounded-md border bg-background/60 p-2 text-sm">\n {isImage ? (\n <img alt={label} className="size-12 shrink-0 rounded-sm object-cover" src={part.url} />\n ) : (\n <span className="flex size-10 shrink-0 items-center justify-center rounded-sm bg-muted text-muted-foreground">\n <Icon className="size-4" />\n </span>\n )}\n <span className="min-w-0 flex-1">\n <span className="block truncate font-medium">{label}</span>\n {detail ? <span className="block truncate text-muted-foreground">{detail}</span> : null}\n </span>\n {part.url ? <ExternalLinkIcon className="size-4 shrink-0 text-muted-foreground" /> : null}\n </span>\n );\n\n return part.url ? (\n <a href={part.url} rel="noreferrer" target="_blank">\n {body}\n </a>\n ) : (\n body\n );\n}\n\nfunction AuthorizationPrompt({ part }: { readonly part: EveAuthorizationPart }) {\n const isAuthorized = part.state === "completed" && part.outcome === "authorized";\n const isCompleted = part.state === "completed";\n const Icon = isAuthorized ? CheckCircleIcon : isCompleted ? XCircleIcon : KeyRoundIcon;\n const instructions = part.authorization?.instructions;\n const shouldShowInstructions = instructions !== undefined && instructions !== part.description;\n\n return (\n <div\n className={cn(\n "space-y-3 rounded-md border p-3",\n isAuthorized\n ? "border-emerald-500/30 bg-emerald-500/5"\n : isCompleted\n ? "border-destructive/30 bg-destructive/5"\n : "border-blue-500/30 bg-blue-500/5",\n )}\n >\n <div className="flex items-start gap-3">\n <span\n className={cn(\n "mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full",\n isAuthorized\n ? "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300"\n : isCompleted\n ? "bg-destructive/10 text-destructive"\n : "bg-blue-500/10 text-blue-700 dark:text-blue-300",\n )}\n >\n <Icon className="size-4" />\n </span>\n <div className="min-w-0 flex-1 space-y-2">\n <p className="font-medium text-sm">{authorizationTitle(part)}</p>\n <p className="text-muted-foreground text-sm">{authorizationDescription(part)}</p>\n {shouldShowInstructions ? (\n <p className="text-muted-foreground text-sm">{instructions}</p>\n ) : null}\n {part.state === "required" && part.authorization?.userCode ? (\n <div className="flex flex-wrap items-center gap-2 text-sm">\n <span className="text-muted-foreground">Code</span>\n <code className="rounded-md bg-background px-2 py-1 font-mono">\n {part.authorization.userCode}\n </code>\n </div>\n ) : null}\n {part.state === "required" && part.authorization?.url ? (\n <Button asChild size="sm">\n <a href={part.authorization.url} rel="noreferrer" target="_blank">\n <ExternalLinkIcon className="size-4" />\n Sign in with {part.displayName}\n </a>\n </Button>\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n\nfunction authorizationTitle(part: EveAuthorizationPart): string {\n if (part.state === "required") {\n return `Connect ${part.displayName}`;\n }\n if (part.outcome === "authorized") {\n return `${part.displayName} connected`;\n }\n return `${part.displayName} authorization ${formatAuthorizationOutcome(part.outcome)}`;\n}\n\nfunction authorizationDescription(part: EveAuthorizationPart): string {\n if (part.state === "required") {\n return part.description;\n }\n if (part.outcome === "authorized") {\n return `${part.displayName} connected.`;\n }\n const tail = part.reason !== undefined ? ` (${part.reason})` : "";\n return `${part.displayName} authorization ${formatAuthorizationOutcome(part.outcome)}${tail}.`;\n}\n\nfunction formatAuthorizationOutcome(outcome: NonNullable<EveAuthorizationPart["outcome"]>): string {\n switch (outcome) {\n case "authorized":\n return "authorized";\n case "declined":\n return "declined";\n case "failed":\n return "failed";\n case "timed-out":\n return "timed out";\n }\n}\n\nfunction formatBytes(size: number | undefined): string | undefined {\n if (size === undefined) {\n return undefined;\n }\n if (size < 1024) {\n return `${size} B`;\n }\n if (size < 1024 * 1024) {\n return `${(size / 1024).toFixed(1)} KB`;\n }\n return `${(size / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction InputRequestActions({\n canRespond,\n onInputResponses,\n part,\n}: {\n readonly canRespond: boolean;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n readonly part: EveDynamicToolPart;\n}) {\n const inputRequest = part.toolMetadata?.eve?.inputRequest;\n if (!inputRequest) {\n return null;\n }\n\n const inputResponse = part.toolMetadata?.eve?.inputResponse;\n const selectedOption = inputRequest.options?.find(\n (option) => option.id === inputResponse?.optionId,\n );\n\n return (\n <div className="space-y-3 rounded-md border border-yellow-500/30 bg-yellow-500/5 p-3">\n <p className="text-muted-foreground text-sm">{inputRequest.prompt}</p>\n {inputResponse ? (\n <p className="font-medium text-sm">\n Responded: {selectedOption?.label ?? inputResponse.text ?? inputResponse.optionId}\n </p>\n ) : (\n <div className="flex flex-wrap gap-2">\n {inputRequest.options?.map((option) => (\n <Button\n disabled={!canRespond}\n key={option.id}\n onClick={() => {\n void onInputResponses([\n {\n optionId: option.id,\n requestId: inputRequest.requestId,\n },\n ]);\n }}\n size="sm"\n type="button"\n variant={option.style === "danger" ? "destructive" : "default"}\n >\n {option.label}\n </Button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction partKey(part: EveMessagePart, index: number): string {\n switch (part.type) {\n case "authorization":\n return `authorization:${part.turnId}:${part.stepIndex}:${part.name}`;\n case "dynamic-tool":\n return part.toolCallId;\n default:\n return `${part.type}:${index}`;\n }\n}\n';
5
5
  readonly "app/globals.css": '@import "tailwindcss";\n@source "../node_modules/streamdown/dist/*.js";\n\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-card: var(--card);\n --color-card-foreground: var(--card-foreground);\n --color-popover: var(--popover);\n --color-popover-foreground: var(--popover-foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-destructive: var(--destructive);\n --color-border: var(--border);\n --color-input: var(--input);\n --color-ring: var(--ring);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n --font-sans: "Geist", "Geist Fallback", ui-sans-serif, system-ui, sans-serif;\n --font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, monospace;\n}\n\n:root {\n color-scheme: light;\n /* Soft neutral page with white elevated surfaces so cards/composer pop. */\n --background: oklch(0.971 0 0);\n --foreground: oklch(0.16 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.16 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.16 0 0);\n --primary: oklch(0.19 0 0);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.94 0 0);\n --secondary-foreground: oklch(0.19 0 0);\n --muted: oklch(0.94 0 0);\n --muted-foreground: oklch(0.6 0 0);\n --accent: oklch(0.94 0 0);\n --accent-foreground: oklch(0.19 0 0);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.916 0 0);\n --input: oklch(0.916 0 0);\n --ring: oklch(0.708 0 0);\n --radius: 0.625rem;\n}\n\n@media (prefers-color-scheme: dark) {\n :root {\n color-scheme: dark;\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.205 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.922 0 0);\n --primary-foreground: oklch(0.205 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.269 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.556 0 0);\n }\n}\n\n* {\n border-color: var(--border);\n}\n\nhtml {\n height: 100%;\n}\n\nbody {\n min-height: 100%;\n margin: 0;\n background: var(--background);\n font-family: var(--font-sans);\n}\n\nbutton,\ninput,\ntextarea {\n font: inherit;\n}\n';
6
6
  readonly "app/layout.tsx": 'import type { Metadata } from "next";\nimport { Geist, Geist_Mono } from "next/font/google";\nimport type { ReactNode } from "react";\nimport { TooltipProvider } from "@/components/ui/tooltip";\nimport { cn } from "@/lib/utils";\nimport "./globals.css";\n\nconst sans = Geist({\n variable: "--font-sans",\n subsets: ["latin"],\n weight: "variable",\n display: "swap",\n});\n\nconst mono = Geist_Mono({\n variable: "--font-mono",\n subsets: ["latin"],\n weight: "variable",\n display: "swap",\n});\n\nexport const metadata: Metadata = {\n title: "__EVE_INIT_APP_NAME__",\n description: "A Next.js starter for eve agents with AI Elements.",\n};\n\nexport default function RootLayout({ children }: { readonly children: ReactNode }) {\n return (\n <html className={cn(sans.variable, mono.variable)} lang="en">\n <body>\n <TooltipProvider>{children}</TooltipProvider>\n </body>\n </html>\n );\n}\n';
7
7
  readonly "app/page.tsx": 'import { AgentChat } from "@/app/_components/agent-chat";\n\nexport default function Page() {\n return <AgentChat />;\n}\n';