diff --git a/cli/README.md b/cli/README.md
deleted file mode 100644
index f42f02f5a..000000000
--- a/cli/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# AIConfig CLI
-
-## Development
-
-In cli directory, development:
-
-```
-yarn && cd aiconfig-editor && yarn && cd ..
-yarn dev devserver
-```
-
-## Building
-
-In cli directory:
-
-```
-yarn build
-```
-
-Using `./dist/index.js` with `yarn start`:
-
-```
-yarn start server
-```
-
-Can also specify different ports with `-p`:
-
-```
-yarn start server -p 3001
-```
diff --git a/cli/aiconfig-editor/.eslintrc.json b/cli/aiconfig-editor/.eslintrc.json
deleted file mode 100644
index bffb357a7..000000000
--- a/cli/aiconfig-editor/.eslintrc.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": "next/core-web-vitals"
-}
diff --git a/cli/aiconfig-editor/.gitignore b/cli/aiconfig-editor/.gitignore
deleted file mode 100644
index fd3dbb571..000000000
--- a/cli/aiconfig-editor/.gitignore
+++ /dev/null
@@ -1,36 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-.yarn/install-state.gz
-
-# testing
-/coverage
-
-# next.js
-/.next/
-/out/
-
-# production
-/build
-
-# misc
-.DS_Store
-*.pem
-
-# debug
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-# local env files
-.env*.local
-
-# vercel
-.vercel
-
-# typescript
-*.tsbuildinfo
-next-env.d.ts
diff --git a/cli/aiconfig-editor/@types/ufetch.d.ts b/cli/aiconfig-editor/@types/ufetch.d.ts
deleted file mode 100644
index 926c50e31..000000000
--- a/cli/aiconfig-editor/@types/ufetch.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-declare module "ufetch" {
- export namespace ufetch {
- function setCookie(key: string, value: string, expiry: number): void;
- function getCookie(key: string): string;
-
- function post(path: string, data: any, options?: any);
- function get(path: string, options?: any);
- function put(path: string, data: any, options?: any);
- function _delete(path: string, data: any, options?: any);
-
- export { _delete as delete, setCookie, getCookie, post, get, put };
- }
-}
diff --git a/cli/aiconfig-editor/README.md b/cli/aiconfig-editor/README.md
deleted file mode 100644
index 1c6f30f85..000000000
--- a/cli/aiconfig-editor/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
-
-## Getting Started
-
-First, run the development server:
-
-```bash
-yarn dev
-```
-
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
-
-You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
-
-[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
-
-The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
-
-This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
-
-## Learn More
-
-To learn more about Next.js, take a look at the following resources:
-
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
-
-You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
-
-## Deploy on Vercel
-
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
-
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
diff --git a/cli/aiconfig-editor/next.config.js b/cli/aiconfig-editor/next.config.js
deleted file mode 100644
index a843cbee0..000000000
--- a/cli/aiconfig-editor/next.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/** @type {import('next').NextConfig} */
-const nextConfig = {
- reactStrictMode: true,
-}
-
-module.exports = nextConfig
diff --git a/cli/aiconfig-editor/package.json b/cli/aiconfig-editor/package.json
deleted file mode 100644
index 94430b50e..000000000
--- a/cli/aiconfig-editor/package.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "name": "aiconfig-editor",
- "version": "0.1.0",
- "private": true,
- "scripts": {
- "dev": "next dev",
- "build": "next build",
- "start": "next start",
- "lint": "next lint"
- },
- "dependencies": {
- "@emotion/react": "^11.11.1",
- "@mantine/carousel": "^6.0.7",
- "@mantine/core": "^6.0.7",
- "@mantine/dates": "^6.0.16",
- "@mantine/dropzone": "^6.0.7",
- "@mantine/form": "^6.0.7",
- "@mantine/hooks": "^6.0.7",
- "@mantine/modals": "^6.0.7",
- "@mantine/next": "^6.0.7",
- "@mantine/notifications": "^6.0.7",
- "@mantine/nprogress": "^6.0.7",
- "@mantine/prism": "^6.0.7",
- "@mantine/spotlight": "^6.0.7",
- "@mantine/tiptap": "^6.0.7",
- "@tabler/icons-react": "^2.44.0",
- "aiconfig": "^1.1.0",
- "lodash": "^4.17.21",
- "next": "14.0.2",
- "node-fetch": "^3.3.2",
- "react": "^18",
- "react-dom": "^18",
- "react-markdown": "^8.0.6",
- "remark-gfm": "^4.0.0",
- "ufetch": "^1.6.0"
- },
- "devDependencies": {
- "@types/lodash": "^4.14.202",
- "@types/node": "^20",
- "@types/react": "^18",
- "@types/react-dom": "^18",
- "eslint": "^8",
- "eslint-config-next": "14.0.2",
- "typescript": "^5"
- }
-}
diff --git a/cli/aiconfig-editor/pages/_app.tsx b/cli/aiconfig-editor/pages/_app.tsx
deleted file mode 100644
index fc5a17fb0..000000000
--- a/cli/aiconfig-editor/pages/_app.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import type { AppProps } from "next/app";
-
-import { MantineProvider } from "@mantine/core";
-import { Notifications } from "@mantine/notifications";
-import { useColorScheme } from "@mantine/hooks";
-
-export default function App({ Component, pageProps }: AppProps) {
- const preferredColorScheme = useColorScheme();
-
- return (
-
-
-
-
- );
-}
diff --git a/cli/aiconfig-editor/pages/_document.tsx b/cli/aiconfig-editor/pages/_document.tsx
deleted file mode 100644
index 54e8bf3e2..000000000
--- a/cli/aiconfig-editor/pages/_document.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Html, Head, Main, NextScript } from 'next/document'
-
-export default function Document() {
- return (
-
-
-
-
-
-
- )
-}
diff --git a/cli/aiconfig-editor/pages/api/aiconfig/load.ts b/cli/aiconfig-editor/pages/api/aiconfig/load.ts
deleted file mode 100644
index 2eb5e39c6..000000000
--- a/cli/aiconfig-editor/pages/api/aiconfig/load.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import type { NextApiRequest, NextApiResponse } from "next";
-import { AIConfigRuntime } from "aiconfig";
-import { ErrorResponse } from "@/src/shared/serverTypes";
-import {
- ClientAIConfig,
- ClientExecuteResult,
- ClientPromptOutput,
-} from "@/src/shared/types";
-
-type Data = {
- aiconfig: ClientAIConfig;
-};
-
-type RequestBody = {
- path: string;
-};
-
-export default function handler(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- if (req.method !== "POST") {
- return res.status(500).json({ error: "Method not allowed" });
- }
-
- const body: RequestBody = req.body;
-
- if (!body.path) {
- return res.status(500).json({ error: "No path provided" });
- }
-
- // TODO: load should probably be async?
- const aiconfig = AIConfigRuntime.load(body.path);
-
- // Refine outputs for client-side rendering. We only care about displaying (and deleting)
- // outputs directly from the editor
- const clientAIConfig: ClientAIConfig = {
- ...aiconfig,
- prompts: aiconfig.prompts.map((prompt) => ({
- ...prompt,
- outputs: prompt.outputs?.map((output) => {
- if (output.output_type === "execute_result") {
- const text = aiconfig.getOutputText(prompt, output);
- if (text) {
- // TODO: Once AIConfig output types are updated to be more structured, revisit and
- // ideally remove Client-specific types
- return {
- ...output,
- renderData: {
- type: "text",
- text,
- },
- } as ClientExecuteResult;
- }
- }
- return output as ClientPromptOutput;
- }),
- })),
- };
-
- res.status(200).json({ aiconfig: clientAIConfig });
-}
diff --git a/cli/aiconfig-editor/pages/api/aiconfig/save.ts b/cli/aiconfig-editor/pages/api/aiconfig/save.ts
deleted file mode 100644
index 30d05ddad..000000000
--- a/cli/aiconfig-editor/pages/api/aiconfig/save.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import type { NextApiRequest, NextApiResponse } from "next";
-import { ErrorResponse } from "@/src/shared/serverTypes";
-import { AIConfig, AIConfigRuntime, Output } from "aiconfig";
-import { ClientAIConfig } from "@/src/shared/types";
-
-type Data = {
- status: string;
-};
-
-type RequestBody = {
- path: string;
- aiconfig: ClientAIConfig;
-};
-
-export default async function handler(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- if (req.method !== "POST") {
- return res.status(500).json({ error: "Method not allowed" });
- }
-
- const body: RequestBody = req.body;
-
- if (!body.path) {
- return res.status(500).json({ error: "No path provided" });
- }
-
- if (!body.aiconfig) {
- return res.status(500).json({ error: "No aiconfig data provided" });
- }
-
- // TODO: Once ouputs are properly structured, remove this and use body.aiconfig directly
- const clientAIConfig = body.aiconfig;
- const config = {
- ...clientAIConfig,
- prompts: clientAIConfig.prompts.map((prompt) => ({
- ...prompt,
- outputs: prompt.outputs?.map((output) => {
- if (output.output_type === "execute_result") {
- const outputWithoutRenderData = { ...output, renderData: undefined };
- delete outputWithoutRenderData.renderData;
- return outputWithoutRenderData as Output;
- } else {
- return output as Output;
- }
- }),
- })),
- };
-
- // Construct the config and ensure proper serialization for saving
- const serializedConfig = await AIConfigRuntime.loadJSON(config);
- serializedConfig.save(body.path, { serializeOutputs: true });
-
- res.status(200).json({ status: "ok" });
-}
diff --git a/cli/aiconfig-editor/pages/api/files.ts b/cli/aiconfig-editor/pages/api/files.ts
deleted file mode 100644
index e40571555..000000000
--- a/cli/aiconfig-editor/pages/api/files.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import type { NextApiRequest, NextApiResponse } from "next";
-
-import { promises as fs } from "fs";
-import path from "path";
-import { EditorFile } from "@/src/shared/types";
-
-type Data = {
- files: EditorFile[];
-};
-
-type Error = {
- error: string;
-};
-
-type RequestBody = {
- path?: string;
-};
-
-export default async function handler(
- req: NextApiRequest,
- res: NextApiResponse
-) {
- if (req.method !== "POST") {
- return res.status(500).json({ error: "Method not allowed" });
- }
-
- const body: RequestBody = req.body;
-
- const relativePath = body.path ? body.path : ".";
-
- const directoryToRead = path.isAbsolute(relativePath)
- ? relativePath
- : path.join(process.cwd(), relativePath);
-
- const files = await fs.readdir(path.join(directoryToRead), {
- withFileTypes: true,
- });
-
- const filesResponse = files.map((file) => {
- const extension = path.extname(file.name);
-
- return {
- name: file.name,
- extension,
- path: file.path,
- isDirectory: file.isDirectory(),
- };
- });
-
- return res.status(200).json({ files: filesResponse });
-}
diff --git a/cli/aiconfig-editor/pages/editor.tsx b/cli/aiconfig-editor/pages/editor.tsx
deleted file mode 100644
index 4a4113fb6..000000000
--- a/cli/aiconfig-editor/pages/editor.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import EditorContainer from "@/src/components/EditorContainer";
-import { ClientAIConfig } from "@/src/shared/types";
-import { Flex, Loader } from "@mantine/core";
-import { AIConfig } from "aiconfig";
-import { useRouter } from "next/router";
-import { useCallback, useEffect, useState } from "react";
-import { ufetch } from "ufetch";
-
-export default function Editor() {
- // Use router to get the path, load the file using aiconfig.load, make it editable & use save to save it regularly
- // TODO: Settings, other things to edit, allowing plugins in editor (eg for custom model parsers in python or JS)
- const router = useRouter();
- const [aiconfig, setAiConfig] = useState();
-
- const loadConfig = useCallback(async () => {
- if (!router.query.path) {
- return;
- }
-
- const res = await ufetch.post(`/api/aiconfig/load`, {
- path: router.query.path,
- });
-
- setAiConfig(res.aiconfig);
- }, [router]);
-
- useEffect(() => {
- loadConfig();
- }, [loadConfig]);
-
- const onBackNavigation = useCallback(() => {
- if (!router.query.path) {
- return;
- } else {
- router.back();
- }
- }, [router]);
-
- const onSave = useCallback(
- async (aiconfig: AIConfig) => {
- const res = await ufetch.post(`/api/aiconfig/save`, {
- path: router.query.path,
- aiconfig,
- });
- return res;
- },
- [router]
- );
-
- return (
-
- {!aiconfig ? (
-
-
-
- ) : (
-
- )}
-
- );
-}
diff --git a/cli/aiconfig-editor/pages/index.tsx b/cli/aiconfig-editor/pages/index.tsx
deleted file mode 100644
index 89b173050..000000000
--- a/cli/aiconfig-editor/pages/index.tsx
+++ /dev/null
@@ -1,125 +0,0 @@
-import { EditorFile } from "@/src/shared/types";
-import { Button, Container, Group, Table, Text } from "@mantine/core";
-import Head from "next/head";
-import Link from "next/link";
-import { useRouter } from "next/router";
-import { useCallback, useEffect, useState } from "react";
-import { ufetch } from "ufetch";
-
-export default function Home() {
- // Get list of files in the currect directory; this should also use a path from the router to become a nested file tree that can be navigated
- const router = useRouter();
-
- const [files, setFiles] = useState([]);
-
- const getFiles = useCallback(async () => {
- const res = await ufetch.post("/api/files", { path: router.query.path });
-
- const newFiles = res.files.map((file: EditorFile) => {
- const disabled = !file.isDirectory && file.extension !== ".json";
-
- return {
- ...file,
- disabled,
- };
- });
-
- setFiles(newFiles);
- }, [router.query.path]);
-
- useEffect(() => {
- // Get files from current directory (will be whatever is passed as root directory when undefined, but needs to be handled server side
- getFiles();
- }, [getFiles]);
-
- const navigate = useCallback(
- (file: EditorFile) => {
- // If directory, then change path & also update the url route to add to history
- // If random file, should not be able to select
- // If aiconfig.json file, then open editor - can't actually detect yet, so will just try to parse
- // Use load_json
- console.log("navigate", file);
- console.log(file.isDirectory);
-
- const newPath = `${file.path}/${file.name}`;
- if (file.isDirectory) {
- router.push(`?path=${encodeURIComponent(newPath)}`);
- } else {
- router.push(`/editor?path=${encodeURIComponent(newPath)}`);
- // Uncomment to open editor in new tab
- // window.open(`/editor?path=${encodeURIComponent(file.path)}`, "_blank");
- }
- },
- [router]
- );
-
- const back = useCallback(() => {
- if (!router.query.path) {
- return;
- } else {
- router.back();
- }
- }, [router]);
-
- return (
- <>
-
- AIConfig Editor
-
-
-
-
-
-
-
-
-