From 2ac6774c1e0114ff8b9fe4ba1269f5e22ed34e26 Mon Sep 17 00:00:00 2001 From: tylerslaton Date: Wed, 26 Jun 2024 16:23:27 -0400 Subject: [PATCH] feat: add the ability to change the workspace Signed-off-by: tylerslaton --- actions/scripts/fetch.tsx | 12 +-- actions/scripts/new.tsx | 4 +- actions/scripts/update.tsx | 4 +- .../upload/actions.tsx => actions/upload.tsx | 4 +- actions/workspace.tsx | 6 ++ app/api/file/[name]/[tool]/route.ts | 6 +- app/api/file/[name]/route.ts | 10 +-- app/api/file/route.ts | 10 +-- components/script.tsx | 8 +- components/script/chatBar.tsx | 2 +- components/script/chatBar/upload.tsx | 21 +++-- components/script/chatBar/upload/files.tsx | 2 +- .../script/chatBar/upload/workspace.tsx | 88 +++++++++++++++++++ components/script/useChatSocket.tsx | 2 +- config/env.ts | 7 +- server.mjs | 11 +-- 16 files changed, 153 insertions(+), 44 deletions(-) rename components/script/chatBar/upload/actions.tsx => actions/upload.tsx (88%) create mode 100644 actions/workspace.tsx create mode 100644 components/script/chatBar/upload/workspace.tsx diff --git a/actions/scripts/fetch.tsx b/actions/scripts/fetch.tsx index 44456b23..7f3577a5 100644 --- a/actions/scripts/fetch.tsx +++ b/actions/scripts/fetch.tsx @@ -8,12 +8,12 @@ const external = (file: string): boolean => { }; export const path = async (file: string): Promise => { - if (!external(file)) return `${SCRIPTS_PATH}/${file}.gpt`; + if (!external(file)) return `${SCRIPTS_PATH()}/${file}.gpt`; return file; }; export const fetchFullScript = async (file: string): Promise => { - if (!external(file)) file = `${SCRIPTS_PATH}/${file}.gpt`; + if (!external(file)) file = `${SCRIPTS_PATH()}/${file}.gpt`; const gptscript = new GPTScript(); try { @@ -24,7 +24,7 @@ export const fetchFullScript = async (file: string): Promise => { } export const fetchScript = async (file: string): Promise => { - if (!external(file)) file = `${SCRIPTS_PATH}/${file}.gpt`; + if (!external(file)) file = `${SCRIPTS_PATH()}/${file}.gpt`; const gptscript = new GPTScript(); try { @@ -44,7 +44,7 @@ export const fetchScript = async (file: string): Promise => { export const fetchScripts = async (): Promise> => { try { - const files = await fs.readdir(SCRIPTS_PATH); + const files = await fs.readdir(SCRIPTS_PATH()); const gptFiles = files.filter(file => file.endsWith('.gpt')); if (gptFiles.length === 0) throw new Error('no files found in scripts directory'); @@ -52,7 +52,7 @@ export const fetchScripts = async (): Promise> => { const gptscript = new GPTScript(); const scripts: Record = {}; for (const file of gptFiles) { - const script = await gptscript.parse(`${SCRIPTS_PATH}/${file}`); + const script = await gptscript.parse(`${SCRIPTS_PATH()}/${file}`); let description = ''; for (let tool of script) { if (tool.type === 'text') continue; @@ -73,7 +73,7 @@ export const fetchScripts = async (): Promise> => { export const fetchScriptCode = async (file: string): Promise => { file = file.includes('.gpt') ? file : `${file}.gpt`; try { - return await fs.readFile(`${SCRIPTS_PATH}/${file}`, 'utf-8'); + return await fs.readFile(`${SCRIPTS_PATH()}/${file}`, 'utf-8'); } catch (e) { throw e; } diff --git a/actions/scripts/new.tsx b/actions/scripts/new.tsx index 189b2911..28001084 100644 --- a/actions/scripts/new.tsx +++ b/actions/scripts/new.tsx @@ -5,7 +5,7 @@ import fs from 'fs/promises'; export async function newFile(name: string, instructions: string, fileName: string) { try { - const files = await fs.readdir(SCRIPTS_PATH); + const files = await fs.readdir(SCRIPTS_PATH()); const gptFiles = files.filter(file => file.endsWith('.gpt')); if(gptFiles.includes(fileName)) throw new Error('file already exists'); @@ -13,7 +13,7 @@ export async function newFile(name: string, instructions: string, fileName: stri throw new Error('file cannot be empty and must end with .gpt'); } - await fs.writeFile(`${SCRIPTS_PATH}/${fileName}`, `---\nName: ${name}\nChat: true\n\n${instructions}\n\n`); + await fs.writeFile(`${SCRIPTS_PATH()}/${fileName}`, `---\nName: ${name}\nChat: true\n\n${instructions}\n\n`); return fileName.replace('.gpt', '') } catch (e) { throw e; diff --git a/actions/scripts/update.tsx b/actions/scripts/update.tsx index dfa68541..1e50b9fb 100644 --- a/actions/scripts/update.tsx +++ b/actions/scripts/update.tsx @@ -9,7 +9,7 @@ const external = (file: string): boolean => { }; export const path = async (file: string): Promise => { - if (!external(file)) return `${SCRIPTS_PATH}/${file}.gpt`; + if (!external(file)) return `${SCRIPTS_PATH()}/${file}.gpt`; return file; }; @@ -18,7 +18,7 @@ export const updateScript = async (file: string, script: Block[]) => { const gptscript = new GPTScript(); try { - await fs.writeFile(`${SCRIPTS_PATH}/${file}.gpt`, await gptscript.stringify(script)); + await fs.writeFile(`${SCRIPTS_PATH()}/${file}.gpt`, await gptscript.stringify(script)); } catch (e) { throw e; } diff --git a/components/script/chatBar/upload/actions.tsx b/actions/upload.tsx similarity index 88% rename from components/script/chatBar/upload/actions.tsx rename to actions/upload.tsx index 9c3dced7..84f318ca 100644 --- a/components/script/chatBar/upload/actions.tsx +++ b/actions/upload.tsx @@ -10,7 +10,7 @@ export async function uploadFile(formData: FormData) { const file = formData.get("file") as File; const arrayBuffer = await file.arrayBuffer(); const buffer = new Uint8Array(arrayBuffer); - await fs.writeFile(path.join(WORKSPACE_DIR,file.name), buffer); + await fs.writeFile(path.join(WORKSPACE_DIR(),file.name), buffer); revalidatePath("/"); } @@ -35,7 +35,7 @@ export async function deleteFile(path: string) { export async function lsWorkspaceFiles(): Promise { try { - const dirents = await fs.readdir(WORKSPACE_DIR, { withFileTypes: true }); + const dirents = await fs.readdir(WORKSPACE_DIR(), { withFileTypes: true }); const filesOnly = dirents.filter((dirent: Dirent) => !dirent.isDirectory()); return JSON.stringify(filesOnly); } catch (e) { diff --git a/actions/workspace.tsx b/actions/workspace.tsx new file mode 100644 index 00000000..f524561f --- /dev/null +++ b/actions/workspace.tsx @@ -0,0 +1,6 @@ +"use server" + +import { WORKSPACE_DIR, set_WORKSPACE_DIR } from '@/config/env'; + +export const getWorkspaceDir = async () => WORKSPACE_DIR(); +export const setWorkspaceDir = async (dir: string) => set_WORKSPACE_DIR(dir); \ No newline at end of file diff --git a/app/api/file/[name]/[tool]/route.ts b/app/api/file/[name]/[tool]/route.ts index 6bd4f44a..51de92b9 100644 --- a/app/api/file/[name]/[tool]/route.ts +++ b/app/api/file/[name]/[tool]/route.ts @@ -15,11 +15,11 @@ export async function PUT( try { const { name, tool } = params as any; - const script = await gptscript.parse(path.join(SCRIPTS_PATH,`${name}.gpt`)); + const script = await gptscript.parse(path.join(SCRIPTS_PATH(),`${name}.gpt`)); const updatedScript = updateScript(script, tool, (await req.json()) as Tool); - await fs.writeFile(path.join(SCRIPTS_PATH,`${name}.gpt`), await gptscript.stringify(updatedScript)); - return Response.json(await gptscript.parse(path.join(SCRIPTS_PATH,`${name}.gpt`))); + await fs.writeFile(path.join(SCRIPTS_PATH(),`${name}.gpt`), await gptscript.stringify(updatedScript)); + return Response.json(await gptscript.parse(path.join(SCRIPTS_PATH(),`${name}.gpt`))); } catch (e) { if (`${e}`.includes('no such file')){ return Response.json({ error: '.gpt file not found' }, { status: 404 }); diff --git a/app/api/file/[name]/route.ts b/app/api/file/[name]/route.ts index 93ca1fd0..6f60a1d2 100644 --- a/app/api/file/[name]/route.ts +++ b/app/api/file/[name]/route.ts @@ -19,7 +19,7 @@ export async function DELETE( ) { try { const { name } = params as any; - await fs.unlink(path.join(`${SCRIPTS_PATH}/${name}.gpt`)); + await fs.unlink(path.join(`${SCRIPTS_PATH()}/${name}.gpt`)); return Response.json({ success: true }); } catch (e) { return Response.json({ error: e }, { status: 500 }); @@ -28,7 +28,7 @@ export async function DELETE( // export async function PUT(req: Request) { // try { -// const scriptsPath = process.env.SCRIPTS_PATH || 'gptscripts'; +// const scriptsPath = process.env.SCRIPTS_PATH() || 'gptscripts'; // const { name } = req.params as any; // const content = await req.text(); @@ -46,7 +46,7 @@ export async function GET( ) { try { const { name } = params as any; - const script = await gptscript.parse(path.join(SCRIPTS_PATH,`${name}.gpt`)); + const script = await gptscript.parse(path.join(SCRIPTS_PATH(),`${name}.gpt`)); if (req.nextUrl.searchParams.get('nodeify') === 'true') { const { nodes, edges } = await nodeify(script); return Response.json({ nodes: nodes, edges: edges }); @@ -69,8 +69,8 @@ export async function PUT( const nodes = (await req.json()) as RFNode[]; const script = denodeify(nodes); - await fs.writeFile(path.join(SCRIPTS_PATH,`${name}.gpt`), await gptscript.stringify(script)); - return Response.json(await gptscript.parse(path.join(SCRIPTS_PATH,`${name}.gpt`))); + await fs.writeFile(path.join(SCRIPTS_PATH(),`${name}.gpt`), await gptscript.stringify(script)); + return Response.json(await gptscript.parse(path.join(SCRIPTS_PATH(),`${name}.gpt`))); } catch (e) { if (`${e}`.includes('no such file')){ return Response.json({ error: '.gpt file not found' }, { status: 404 }); diff --git a/app/api/file/route.ts b/app/api/file/route.ts index dfa8778c..157b2d6c 100644 --- a/app/api/file/route.ts +++ b/app/api/file/route.ts @@ -7,7 +7,7 @@ const gptscript = new GPTScript(); export async function GET() { try { - const files = await fs.readdir(SCRIPTS_PATH); + const files = await fs.readdir(SCRIPTS_PATH()); const gptFiles = files.filter(file => file.endsWith('.gpt')); if (gptFiles.length === 0) @@ -15,11 +15,11 @@ export async function GET() { const scripts: Record = {}; for (const file of gptFiles) { - const script = await gptscript.parse(`${SCRIPTS_PATH}/${file}`); + const script = await gptscript.parse(`${SCRIPTS_PATH()}/${file}`); let description = ''; for (let tool of script) { if (tool.type === 'text') continue; - description = tool.description; + description = tool.description || ''; break; } scripts[file] = description || ''; @@ -38,7 +38,7 @@ export async function GET() { export async function POST(_req: Request) { try { - const files = await fs.readdir(SCRIPTS_PATH); + const files = await fs.readdir(SCRIPTS_PATH()); const gptFiles = files.filter(file => file.endsWith('.gpt')); let id = 0; @@ -47,7 +47,7 @@ export async function POST(_req: Request) { id++; newFileName = `new-file-${id}.gpt`; } - await fs.writeFile(`${SCRIPTS_PATH}/${newFileName}`, '---\nname: main'); + await fs.writeFile(`${SCRIPTS_PATH()}/${newFileName}`, '---\nname: main'); return Response.json({ file: newFileName }); } catch (e) { return Response.json({ error: e }, { status: 500 }); diff --git a/components/script.tsx b/components/script.tsx index d44ede9d..a81fee86 100644 --- a/components/script.tsx +++ b/components/script.tsx @@ -9,6 +9,7 @@ import Loading from "@/components/loading"; import useChatSocket from '@/components/script/useChatSocket'; import { Button } from "@nextui-org/react"; import { fetchScript, path } from "@/actions/scripts/fetch"; +import { getWorkspaceDir } from "@/actions/workspace"; interface ScriptProps { file: string; @@ -34,7 +35,12 @@ const Script: React.FC = ({ file, className, messagesHeight = 'h-fu useEffect(() => { if (hasRun || !socket || !connected) return; if ( !tool.arguments?.properties || Object.keys(tool.arguments.properties).length === 0 ) { - path(file).then((path) => { socket.emit("run", path, tool.name, formValues) }); + path(file) + .then(async (path) => { + const workspace = await getWorkspaceDir() + return { path, workspace} + }) + .then(({path, workspace}) => { socket.emit("run", path, tool.name, formValues, workspace) }); setHasRun(true); } }, [tool, file, formValues]); diff --git a/components/script/chatBar.tsx b/components/script/chatBar.tsx index 546fbf93..bd83d9c2 100644 --- a/components/script/chatBar.tsx +++ b/components/script/chatBar.tsx @@ -67,7 +67,7 @@ const ChatBar = ({ onPress={onRestart} /> - +