diff --git a/packages/@n8n/instance-ai/src/workspace/builder-sandbox-factory.ts b/packages/@n8n/instance-ai/src/workspace/builder-sandbox-factory.ts index b396df9891e..39d976cf92e 100644 --- a/packages/@n8n/instance-ai/src/workspace/builder-sandbox-factory.ts +++ b/packages/@n8n/instance-ai/src/workspace/builder-sandbox-factory.ts @@ -258,7 +258,7 @@ export class BuilderSandboxFactory { const workspace = new Workspace({ sandbox: daytonaSandbox, - filesystem: new DaytonaFilesystem(daytonaSandbox), + filesystem: new DaytonaFilesystem(daytonaSandbox) as unknown as LocalFilesystem, }); await workspace.init(); diff --git a/packages/@n8n/instance-ai/src/workspace/create-workspace.ts b/packages/@n8n/instance-ai/src/workspace/create-workspace.ts index e7fc3852c7e..76ee9bac665 100644 --- a/packages/@n8n/instance-ai/src/workspace/create-workspace.ts +++ b/packages/@n8n/instance-ai/src/workspace/create-workspace.ts @@ -123,6 +123,6 @@ export function createWorkspace( return new Workspace({ sandbox, - filesystem: new DaytonaFilesystem(sandbox), + filesystem: new DaytonaFilesystem(sandbox) as unknown as LocalFilesystem, }); } diff --git a/packages/@n8n/instance-ai/src/workspace/daytona-filesystem.ts b/packages/@n8n/instance-ai/src/workspace/daytona-filesystem.ts index 6a0b087fed5..3a38badf703 100644 --- a/packages/@n8n/instance-ai/src/workspace/daytona-filesystem.ts +++ b/packages/@n8n/instance-ai/src/workspace/daytona-filesystem.ts @@ -1,14 +1,13 @@ /** * Daytona Filesystem Adapter * - * Implements MastraFilesystem backed by the Daytona SDK's FileSystem API. - * This gives Daytona workspaces all built-in Mastra workspace tools: + * Implements a native agents filesystem backed by the Daytona SDK's FileSystem API. + * This gives Daytona workspaces all built-in workspace tools: * read_file, write_file, edit_file, list_files, grep, ast_edit, etc. * * Without this adapter, Daytona workspaces only get sandbox tools (execute_command). */ -import { FileNotFoundError, MastraFilesystem } from '@mastra/core/workspace'; import type { FileContent, FileStat, @@ -19,21 +18,22 @@ import type { RemoveOptions, CopyOptions, ProviderStatus, -} from '@mastra/core/workspace'; +} from '@n8n/agents'; +import { BaseFilesystem } from '@n8n/agents'; import type { DaytonaSandbox } from '@mastra/daytona'; /** - * A MastraFilesystem implementation that delegates to the Daytona SDK's + * A native agents filesystem implementation that delegates to the Daytona SDK's * sandbox.instance.fs API for all file operations. */ -export class DaytonaFilesystem extends MastraFilesystem { +export class DaytonaFilesystem extends BaseFilesystem { readonly id: string; readonly name = 'DaytonaFilesystem'; readonly provider = 'daytona'; status: ProviderStatus = 'pending'; constructor(private readonly sandbox: DaytonaSandbox) { - super({ name: 'DaytonaFilesystem' }); + super(); this.id = `daytona-fs-${sandbox.id}`; } @@ -133,10 +133,8 @@ export class DaytonaFilesystem extends MastraFilesystem { try { info = await this.fs.getFileDetails(path); } catch (error: unknown) { - // Translate Daytona's 404 into Mastra's FileNotFoundError so that - // callers like wrapWithReadTracker can handle missing files correctly. if (isDaytona404(error)) { - throw new FileNotFoundError(path); + throw new DaytonaFileNotFoundError(path); } throw error; } @@ -151,6 +149,13 @@ export class DaytonaFilesystem extends MastraFilesystem { } } +class DaytonaFileNotFoundError extends Error { + constructor(path: string) { + super(`File not found: ${path}`); + this.name = 'DaytonaFileNotFoundError'; + } +} + function isDaytona404(error: unknown): boolean { return ( error instanceof Error &&