Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: fs.mkdir doesn't throw an error if the directory already exists when the recursive: true option is passed.


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));
}
}
Comment on lines -133 to -143
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this isn't used

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't right now.

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";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My linter was complaining about Response.json not existing here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair, it is auto imported I believe. Also this whole API section can get removed soonish. It isn't used right now, not important but just adjacent.

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