Skip to content

Commit

Permalink
Merge pull request #32 from njhale/fix/dir-init
Browse files Browse the repository at this point in the history
fix: ensure app dirs exist
  • Loading branch information
njhale authored Jul 19, 2024
2 parents de7395c + 69c4dab commit cc90b3e
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 84 deletions.
8 changes: 3 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ yarn-error.log*
*.tsbuildinfo
next-env.d.ts

# app output
gptscripts

# ignore root level threads directory
/threads
# app output directories
/gptscripts
/threads
2 changes: 1 addition & 1 deletion actions/scripts/fetch.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use server"
import { Tool, GPTScript, Block } from '@gptscript-ai/gptscript';
import { Tool, Block } from '@gptscript-ai/gptscript';
import { SCRIPTS_PATH, gpt } from '@/config/env';
import fs from 'fs/promises';

Expand Down
23 changes: 11 additions & 12 deletions actions/scripts/new.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ import { SCRIPTS_PATH } from '@/config/env';
import fs from 'fs/promises';

export async function newFile(name: string, instructions: string, fileName: string) {
try {
const files = await fs.readdir(SCRIPTS_PATH());
const gptFiles = files.filter(file => file.endsWith('.gpt'));
const scriptsPath = SCRIPTS_PATH()
await fs.mkdir(scriptsPath, {recursive: true})

if(gptFiles.includes(fileName)) throw new Error('file already exists');
if (!fileName.endsWith('.gpt')) {
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`);
return fileName.replace('.gpt', '')
} catch (e) {
throw e;
const files = await fs.readdir(scriptsPath);
const gptFiles = files.filter(file => file.endsWith('.gpt'));

if (gptFiles.includes(fileName)) throw new Error('file already exists');
if (!fileName.endsWith('.gpt')) {
throw new Error('file cannot be empty and must end with .gpt');
}

await fs.writeFile(`${scriptsPath}/${fileName}`, `---\nName: ${name}\nChat: true\n\n${instructions}\n\n`);
return fileName.replace('.gpt', '')
}
14 changes: 1 addition & 13 deletions actions/threads.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export async function createThread(script: string, firstMessage?: string): Promi

if (firstMessage) {
const generatedThreadName = await generateThreadName(firstMessage)
renameThread(id, generatedThreadName);
await renameThread(id, generatedThreadName);
}

return {
Expand All @@ -129,15 +129,3 @@ export async function renameThread(id: string, name: string) {
threadMeta.name = name;
await fs.writeFile(path.join(threadPath, META_FILE), JSON.stringify(threadMeta));
}

export async function updateThread(id: string, thread: Thread) {
const threadsDir = THREADS_DIR();
const threadPath = path.join(threadsDir,id);

if (thread.state) await fs.writeFile(path.join(threadPath, STATE_FILE), thread.state);
if (thread.meta) {
const existingMeta = await fs.readFile(path.join(threadPath, META_FILE), "utf-8");
const mergedMeta = { ...JSON.parse(existingMeta), ...thread.meta };
await fs.writeFile(path.join(threadPath, META_FILE), JSON.stringify(mergedMeta));
}
}
28 changes: 13 additions & 15 deletions actions/upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,17 @@ import { WORKSPACE_DIR } from '@/config/env';
import { Dirent } from 'fs';

export async function uploadFile(formData: FormData) {
const workspaceDir = WORKSPACE_DIR()
await fs.mkdir(workspaceDir, { recursive: true })

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(workspaceDir, file.name), buffer);

revalidatePath("/");
}

export async function openFile(path: string): Promise<string> {
try {
const buffer = await fs.readFile(path);
const blob = new Blob([buffer]);
return URL.createObjectURL(blob);
} catch (error) {
console.error("Error opening file:", error);
throw error;
}
}
export async function deleteFile(path: string) {
try {
await fs.unlink(path);
Expand All @@ -34,11 +28,15 @@ export async function deleteFile(path: string) {
}

export async function lsWorkspaceFiles(): Promise<string> {
let files: Dirent[] = []
try {
const dirents = await fs.readdir(WORKSPACE_DIR(), { withFileTypes: true });
const filesOnly = dirents.filter((dirent: Dirent) => !dirent.isDirectory());
return JSON.stringify(filesOnly);
files = dirents.filter((dirent: Dirent) => !dirent.isDirectory());
} catch (e) {
throw e;
if ((e as NodeJS.ErrnoException).code !== 'ENOENT') {
throw e;
}
}
};

return JSON.stringify(files);
}
7 changes: 4 additions & 3 deletions app/api/file/[name]/[tool]/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const dynamic = 'force-dynamic' // defaults to autover'
import {NextResponse} from "next/server";
import {type Block, Tool} from '@gptscript-ai/gptscript'
import { Positions } from '../route';
import { promises as fs } from 'fs';
Expand All @@ -17,13 +18,13 @@ export async function PUT(
const updatedScript = updateScript(script, tool, (await req.json()) as Tool);

await fs.writeFile(path.join(SCRIPTS_PATH(),`${name}.gpt`), await gpt().stringify(updatedScript));
return Response.json(await gpt().parse(path.join(SCRIPTS_PATH(),`${name}.gpt`)));
return NextResponse.json(await gpt().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 });
return NextResponse.json({ error: '.gpt file not found' }, { status: 404 });
}
console.error(e)
return Response.json({ error: e }, {status: 500});
return NextResponse.json({ error: e }, {status: 500});
}
}

Expand Down
34 changes: 10 additions & 24 deletions app/api/file/[name]/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const dynamic = 'force-dynamic' // defaults to auto
import { NextRequest } from 'next/server'
import { NextRequest, NextResponse } from 'next/server'
import { type Block, Text } from '@gptscript-ai/gptscript'
import { promises as fs } from 'fs';
import path from 'path';
Expand All @@ -17,26 +17,12 @@ export async function DELETE(
try {
const { name } = params as any;
await fs.unlink(path.join(`${SCRIPTS_PATH()}/${name}.gpt`));
return Response.json({ success: true });
return NextResponse.json({ success: true });
} catch (e) {
return Response.json({ error: e }, { status: 500 });
return NextResponse.json({ error: e }, { status: 500 });
}
}

// export async function PUT(req: Request) {
// try {
// const scriptsPath = process.env.SCRIPTS_PATH() || 'gptscripts';
// const { name } = req.params as any;
// const content = await req.text();

// await fs.rename(`${scriptsPath}/${name}`, `${scriptsPath}/${name}.bak`);
// await fs.writeFile(`${scriptsPath}/${name}`, content);
// return Response.json({ success: true });
// } catch (e) {
// return Response.json({ error: e }, { status: 500 });
// }
// }

export async function GET(
req: NextRequest,
{ params }: { params: { slug: string } }
Expand All @@ -46,14 +32,14 @@ export async function GET(
const script = await gpt().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 });
return NextResponse.json({ nodes: nodes, edges: edges });
}
return Response.json(script);
return NextResponse.json(script);
} catch (e) {
if (`${e}`.includes('no such file')){
return Response.json({ error: '.gpt file not found' }, { status: 404 });
return NextResponse.json({ error: '.gpt file not found' }, { status: 404 });
}
return Response.json({ error: e }, {status: 500});
return NextResponse.json({ error: e }, {status: 500});
}
}

Expand All @@ -67,12 +53,12 @@ export async function PUT(
const script = denodeify(nodes);

await fs.writeFile(path.join(SCRIPTS_PATH(),`${name}.gpt`), await gpt().stringify(script));
return Response.json(await gpt().parse(path.join(SCRIPTS_PATH(),`${name}.gpt`)));
return NextResponse.json(await gpt().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 });
return NextResponse.json({ error: '.gpt file not found' }, { status: 404 });
}
return Response.json({ error: e }, {status: 500});
return NextResponse.json({ error: e }, {status: 500});
}
}

Expand Down
21 changes: 12 additions & 9 deletions app/api/file/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const dynamic = 'force-dynamic' // defaults to auto
import { GPTScript } from '@gptscript-ai/gptscript'
import { promises as fs } from 'fs';
import { NextResponse } from 'next/server';
import { SCRIPTS_PATH, gpt } from '@/config/env';

export async function GET() {
Expand All @@ -9,7 +9,7 @@ export async function GET() {
const gptFiles = files.filter(file => file.endsWith('.gpt'));

if (gptFiles.length === 0)
return Response.json({ error: 'no .gpt files found' }, { status: 404 });
return NextResponse.json({ error: 'no .gpt files found' }, { status: 404 });

const scripts: Record<string, string> = {};
for (const file of gptFiles) {
Expand All @@ -23,20 +23,23 @@ export async function GET() {
scripts[file] = description || '';
}

return Response.json(scripts);
return NextResponse.json(scripts);
} catch (e) {
const error = e as NodeJS.ErrnoException;
if (error.code === 'ENOENT'){
return Response.json({ error: 'no .gpt files found' }, { status: 404 });
return NextResponse.json({ error: 'no .gpt files found' }, { status: 404 });
}
console.error(e)
return Response.json({ error: e }, { status: 500 });
return NextResponse.json({ error: e }, { status: 500 });
}
}

export async function POST(_req: Request) {
try {
const files = await fs.readdir(SCRIPTS_PATH());
const scriptsPath = SCRIPTS_PATH()
await fs.mkdir(scriptsPath, { recursive: true })

const files = await fs.readdir(scriptsPath);
const gptFiles = files.filter(file => file.endsWith('.gpt'));

let id = 0;
Expand All @@ -45,9 +48,9 @@ export async function POST(_req: Request) {
id++;
newFileName = `new-file-${id}.gpt`;
}
await fs.writeFile(`${SCRIPTS_PATH()}/${newFileName}`, '---\nname: main');
return Response.json({ file: newFileName });
await fs.writeFile(`${scriptsPath}/${newFileName}`, '---\nname: main');
return NextResponse.json({ file: newFileName });
} catch (e) {
return Response.json({ error: e }, { status: 500 });
return NextResponse.json({ error: e }, { status: 500 });
}
}
2 changes: 1 addition & 1 deletion config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from "path";

export const SCRIPTS_PATH = () => process.env.SCRIPTS_PATH || "gptscripts";
export const WORKSPACE_DIR = () => process.env.GPTSCRIPT_WORKSPACE_DIR || "";
export const THREADS_DIR = () => process.env.THREADS_DIR|| path.join(WORKSPACE_DIR(), "threads");
export const THREADS_DIR = () => process.env.THREADS_DIR || path.join(WORKSPACE_DIR(), "threads");

export const set_WORKSPACE_DIR = (dir: string) => process.env.GPTSCRIPT_WORKSPACE_DIR = dir;
export const set_SCRIPTS_PATH = (dir: string) => process.env.SCRIPTS_PATH = dir;
Expand Down
2 changes: 1 addition & 1 deletion server.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {createServer} from "node:http";
import next from "next";
import {Server} from "socket.io";
import {GPTScript, RunEventType, RunState} from '@gptscript-ai/gptscript';
import {GPTScript, RunEventType} from '@gptscript-ai/gptscript';
import dotenv from 'dotenv';
import fs from 'fs';
import path from 'path';
Expand Down

0 comments on commit cc90b3e

Please sign in to comment.