Tool execution
Architecture
- Each tool module defines a
Context.Tagwith Effect schemas. ToolRegistryconstructs a managed runtime per module, injecting Bun platform services and path validation.makeAllToolsadapts each runtime into theToolSetconsumed byVercelAI.streamChat.
Managed runtimes
src/services/ToolRegistry.ts
// Create a managed runtime with all dependencies
const fileToolsRuntime = ManagedRuntime.make(
FileToolsLayer.pipe(
Layer.provide(pathValidationStack),
Layer.provide(BunContext.layer),
Layer.orDie, // Convert layer failures to defects
),
)
// Adapt runtimes to Vercel AI SDK format
const toolsMap = makeAllTools(
fileToolsRuntime,
searchToolsRuntime,
editToolsRuntime,
directoryToolsRuntime,
)
return {
tools: Effect.succeed(toolsMap),
listToolNames: Effect.succeed(Object.keys(toolsMap).sort()),
}
ManagedRuntime.makegives each service its own Effect environment.Layer.orDieconverts checked layer failures into defects so tool execution cannot proceed without prerequisites.
Adapter mapping
src/adapters/index.ts
export const makeAllTools = (
fileToolsRuntime: ManagedRuntime.ManagedRuntime<typeof FileTools>,
searchToolsRuntime: ManagedRuntime.ManagedRuntime<typeof SearchTools>,
editToolsRuntime: ManagedRuntime.ManagedRuntime<typeof EditTools>,
directoryToolsRuntime: ManagedRuntime.ManagedRuntime<typeof DirectoryTools>,
): ToolSet => ({
...makeFileToolsForVercel(fileToolsRuntime),
...makeSearchToolsForVercel(searchToolsRuntime),
...makeEditToolsForVercel(editToolsRuntime),
...makeDirectoryToolsForVercel(directoryToolsRuntime),
})
- Each adapter validates parameters with shared
@effect/schemastructs wrapped withSchema.standardSchemaV1()for AI SDK v6 compatibility. - The handler runs inside the managed runtime to access the correct services.
- Results are serialised to JSON automatically for the Vercel AI SDK.
Execution flow
VercelAI.streamChatreceives a tool call (step.toolCalls).- The adapter retrieves the appropriate runtime and executes the Effect.
- The tool returns structured data;
ToolResultPresenterrenders it in the CLI.
Tips
- Add new tools by creating a module + layer, adding a runtime in
ToolRegistry, and extendingmakeAllTools. - Reuse
PathValidationin every tool that touches the filesystem to avoid leaving the workspace. - Keep tool responses small and structured; the assistant summarises diffs and metadata more effectively than raw blobs.
Source
src/services/ToolRegistry.tssrc/adapters/index.tssrc/tools/**/*.ts