Skip to content

Commit e9a94f5

Browse files
committed
Add file delete tool
1 parent 35f9413 commit e9a94f5

File tree

3 files changed

+56
-8
lines changed

3 files changed

+56
-8
lines changed

apps/sandbox-container/container/index.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { exec } from 'node:child_process'
2-
import * as fs from 'node:fs/promises'
3-
import path from 'node:path'
41
import { serve } from '@hono/node-server'
52
import { zValidator } from '@hono/zod-validator'
63
import { Hono } from 'hono'
74
import { streamText } from 'hono/streaming'
85
import mime from 'mime'
6+
import { exec } from 'node:child_process'
7+
import * as fs from 'node:fs/promises'
8+
import path from 'node:path'
99

1010
import { ExecParams, FileList, FilesWrite } from '../shared/schema.ts'
1111

@@ -114,6 +114,28 @@ app.post('/files/contents', zValidator('json', FilesWrite), async (c) => {
114114
}
115115
})
116116

117+
/**
118+
* DELETE /files/contents/{filepath}
119+
*
120+
* Delete a file or directory
121+
*/
122+
app.delete('/files/contents/*', async (c) => {
123+
let reqPath = c.req.path.replace('/files/contents', '')
124+
reqPath = reqPath.endsWith('/') ? reqPath.substring(0, reqPath.length - 1) : reqPath
125+
try {
126+
await fs.rm(path.join(process.cwd(), reqPath), {recursive: true})
127+
return c.newResponse('ok', 200)
128+
} catch (e: any) {
129+
if (e.code) {
130+
if (e.code === 'ENOENT') {
131+
return c.notFound()
132+
}
133+
}
134+
135+
throw e
136+
}
137+
})
138+
117139
/**
118140
* POST /exec
119141
*

apps/sandbox-container/server/containerMcp.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
22
import { McpAgent } from 'agents/mcp'
33
import { z } from 'zod'
44

5+
import { Env, Props } from '.'
56
import { OPEN_CONTAINER_PORT } from '../shared/consts'
6-
import { ExecParams, FileList, FilesWrite } from '../shared/schema'
7+
import { ExecParams, FileList, FilePathParam, FilesWrite } from '../shared/schema'
78
import { MAX_CONTAINERS, proxyFetch, startAndWaitForPort } from './containerHelpers'
89
import { getContainerManager } from './containerManager'
910
import { BASE_INSTRUCTIONS } from './prompts'
1011
import { fileToBase64 } from './utils'
11-
import { Env, Props } from '.'
1212

1313
export class ContainerMcpAgent extends McpAgent<Env, Props> {
1414
server = new McpServer(
@@ -70,7 +70,21 @@ export class ContainerMcpAgent extends McpAgent<Env, Props> {
7070
}
7171
}
7272
)
73+
//COURT: At some point we should split the tools into separate files
74+
this.server.tool(
75+
'container_file_delete',
76+
'Delete file and its contents',
77+
{ args: FilePathParam},
78+
async ({ args }) => {
79+
const deleted = await this.container_file_delete(args)
80+
return {
81+
content: [{ type: 'text', text: `File deleted: ${deleted}.`}]
82+
}
83+
}
84+
85+
)
7386
this.server.tool(
87+
//TODO: make this file to be consistent with others
7488
'container_files_write',
7589
'Write file contents',
7690
{ args: FilesWrite },
@@ -229,11 +243,21 @@ export class ContainerMcpAgent extends McpAgent<Env, Props> {
229243
return json
230244
}
231245

246+
//TODO: Abstract these
247+
async container_file_delete(filePath: string): Promise<boolean>{
248+
const res = await proxyFetch(
249+
this.env.ENVIRONMENT,
250+
this.ctx.container,
251+
new Request(`http://host:${OPEN_CONTAINER_PORT}/files/contents/${filePath}`, {
252+
method: 'DELETE'
253+
}),
254+
OPEN_CONTAINER_PORT
255+
)
256+
return res.ok
257+
}
232258
async container_files_read(
233259
filePath: string
234260
): Promise<{ blob: Blob; mimeType: string | undefined }> {
235-
console.log('reading')
236-
console.log(filePath)
237261
const res = await proxyFetch(
238262
this.env.ENVIRONMENT,
239263
this.ctx.container,
@@ -269,7 +293,6 @@ export class ContainerMcpAgent extends McpAgent<Env, Props> {
269293
if (!res || !res.ok) {
270294
throw new Error(`Request to container failed: ${await res.text()}`)
271295
}
272-
const txt = await res.text()
273296
return `Wrote file: ${file.path}`
274297
}
275298
}

apps/sandbox-container/shared/schema.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ export const FilesWrite = z.object({
1313
text: z.string().describe('Full text content of the file you want to write.'),
1414
})
1515

16+
export type FilePathParam = z.infer<typeof FilePathParam>
17+
export const FilePathParam = z.string()
18+
1619
export type FileList = z.infer<typeof FileList>
1720
export const FileList = z.object({
1821
resources: z

0 commit comments

Comments
 (0)