diff --git a/editor/vscode/ai-workbook-ext/.eslintrc.json b/editor/vscode/ai-workbook-ext/.eslintrc.json new file mode 100644 index 000000000..86c86f379 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "@typescript-eslint/naming-convention": [ + "warn", + { + "selector": "import", + "format": [ "camelCase", "PascalCase" ] + } + ], + "@typescript-eslint/semi": "warn", + "curly": "warn", + "eqeqeq": "warn", + "no-throw-literal": "warn", + "semi": "off" + }, + "ignorePatterns": [ + "out", + "dist", + "**/*.d.ts" + ] +} \ No newline at end of file diff --git a/editor/vscode/ai-workbook-ext/.vscode-test.mjs b/editor/vscode/ai-workbook-ext/.vscode-test.mjs new file mode 100644 index 000000000..b62ba25f0 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/.vscode-test.mjs @@ -0,0 +1,5 @@ +import { defineConfig } from '@vscode/test-cli'; + +export default defineConfig({ + files: 'out/test/**/*.test.js', +}); diff --git a/editor/vscode/ai-workbook-ext/.vscode/extensions.json b/editor/vscode/ai-workbook-ext/.vscode/extensions.json new file mode 100644 index 000000000..db70f8889 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "dbaeumer.vscode-eslint", + "ms-vscode.extension-test-runner" + ] +} diff --git a/editor/vscode/ai-workbook-ext/.vscode/launch.json b/editor/vscode/ai-workbook-ext/.vscode/launch.json new file mode 100644 index 000000000..a0ca3cb93 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/.vscode/launch.json @@ -0,0 +1,17 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run Extension", + "type": "extensionHost", + "request": "launch", + "args": ["--extensionDevelopmentPath=${workspaceFolder}"], + "outFiles": ["${workspaceFolder}/out/**/*.js"], + "preLaunchTask": "${defaultBuildTask}" + } + ] +} diff --git a/editor/vscode/ai-workbook-ext/.vscode/settings.json b/editor/vscode/ai-workbook-ext/.vscode/settings.json new file mode 100644 index 000000000..8bf37e053 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/.vscode/settings.json @@ -0,0 +1,12 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "files.exclude": { + "out": false // set this to true to hide the "out" folder with the compiled JS files + }, + "search.exclude": { + "out": true // set this to false to include "out" folder in search results + }, + // Turn off tsc task auto detection since we have the necessary tasks as npm scripts + "typescript.tsc.autoDetect": "off", + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/editor/vscode/ai-workbook-ext/.vscode/tasks.json b/editor/vscode/ai-workbook-ext/.vscode/tasks.json new file mode 100644 index 000000000..3b17e53b6 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/.vscode/tasks.json @@ -0,0 +1,20 @@ +// See https://go.microsoft.com/fwlink/?LinkId=733558 +// for the documentation about the tasks.json format +{ + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "watch", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "presentation": { + "reveal": "never" + }, + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} diff --git a/editor/vscode/ai-workbook-ext/.vscodeignore b/editor/vscode/ai-workbook-ext/.vscodeignore new file mode 100644 index 000000000..72aa0fe2e --- /dev/null +++ b/editor/vscode/ai-workbook-ext/.vscodeignore @@ -0,0 +1,11 @@ +.vscode/** +.vscode-test/** +src/** +.gitignore +.yarnrc +vsc-extension-quickstart.md +**/tsconfig.json +**/.eslintrc.json +**/*.map +**/*.ts +**/.vscode-test.* diff --git a/editor/vscode/ai-workbook-ext/.yarnrc b/editor/vscode/ai-workbook-ext/.yarnrc new file mode 100644 index 000000000..f757a6ac5 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/.yarnrc @@ -0,0 +1 @@ +--ignore-engines true \ No newline at end of file diff --git a/editor/vscode/ai-workbook-ext/CHANGELOG.md b/editor/vscode/ai-workbook-ext/CHANGELOG.md new file mode 100644 index 000000000..0ccd82bd1 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/CHANGELOG.md @@ -0,0 +1,9 @@ +# Change Log + +All notable changes to the "ai-workbook-ext" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. + +## [Unreleased] + +- Initial release \ No newline at end of file diff --git a/editor/vscode/ai-workbook-ext/README.md b/editor/vscode/ai-workbook-ext/README.md new file mode 100644 index 000000000..1d207baf2 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/README.md @@ -0,0 +1,71 @@ +# ai-workbook-ext README + +This is the README for your extension "ai-workbook-ext". After writing up a brief description, we recommend including the following sections. + +## Features + +Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file. + +For example if there is an image subfolder under your extension project workspace: + +\!\[feature X\]\(images/feature-x.png\) + +> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow. + +## Requirements + +If you have any requirements or dependencies, add a section describing those and how to install and configure them. + +## Extension Settings + +Include if your extension adds any VS Code settings through the `contributes.configuration` extension point. + +For example: + +This extension contributes the following settings: + +* `myExtension.enable`: Enable/disable this extension. +* `myExtension.thing`: Set to `blah` to do something. + +## Known Issues + +Calling out known issues can help limit users opening duplicate issues against your extension. + +## Release Notes + +Users appreciate release notes as you update your extension. + +### 1.0.0 + +Initial release of ... + +### 1.0.1 + +Fixed issue #. + +### 1.1.0 + +Added features X, Y, and Z. + +--- + +## Following extension guidelines + +Ensure that you've read through the extensions guidelines and follow the best practices for creating your extension. + +* [Extension Guidelines](https://code.visualstudio.com/api/references/extension-guidelines) + +## Working with Markdown + +You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts: + +* Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux). +* Toggle preview (`Shift+Cmd+V` on macOS or `Shift+Ctrl+V` on Windows and Linux). +* Press `Ctrl+Space` (Windows, Linux, macOS) to see a list of Markdown snippets. + +## For more information + +* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown) +* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/) + +**Enjoy!** diff --git a/editor/vscode/ai-workbook-ext/editor/README.md b/editor/vscode/ai-workbook-ext/editor/README.md new file mode 100644 index 000000000..9fd75ea27 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/editor/README.md @@ -0,0 +1,105 @@ +# Editor + +## Usage (prod) + +One liner for local testing; run this inside the root of aiconfig repo. Create a model parser registry py file to get started. + +`python -m 'aiconfig.scripts.aiconfig_cli' edit --aiconfig-path=../cookbooks/Getting-Started/travel.aiconfig.json --server-mode='prod' ` + +### Install: + +Install python-aiconfig from pip, then set `aiconfig` alias (in shell, .bashrc, .zshrc, etc.) + +One-liner: +`pip install python-aiconfig; alias aiconfig="python -m 'aiconfig.scripts.aiconfig_cli'"` + +### Run + +`aiconfig edit --aiconfig-path=/my/path'` + +``` +[INFO] 2023-12-18 23:54:14,379 server.py:32: Edit config: { + "server_port": 8080, + "aiconfig_path": "/my/path" +} +[INFO] 2023-12-18 23:54:14,379 server.py:33: Editor server running on http://localhost:8080 +``` + +Go to url in browser to use app. + +### Loading model parsers + +To use a model parser that doesn't ship with aiconfig: 0. Make sure your model parser package is installed, e.g. +`pip install python-aiconfig-llama`, or +`pip install -e path/to/my/local/parser/package` + +1. Make a Python file e.g. my_editor_plugin.py. It must define a () -> None called `register_model_parsers. + Example: + +``` +from aiconfig import AIConfigRuntime +from llama import LlamaModelParser + + +def register_model_parsers() -> None: + model_path = "/Users/jonathan/Projects/aiconfig/models/llama-2-7b-chat.Q4_K_M.gguf" + llama_model_parser = LlamaModelParser(model_path) + AIConfigRuntime.register_model_parser(llama_model_parser, "llama-2-7b-chat") +``` + +2. Run aiconfig edit server with `--parsers-module-path="/path/to/my_editor_plugin.py"` + +e.g. `aiconfig edit --parsers-module-path="/path/to/my_editor_plugin.py"` + +3. Use editor as usual. + +## Dev + +### Install: + +`pip install -e path/to/local/aiconfig/python` +`alias aiconfig="python -m 'aiconfig.scripts.aiconfig_cli'"`` + +### Run backend and frontend servers: + +(debug mode will run the react server) +`aiconfig edit --aiconfig-path=/my/path --server-port=8080 --server-mode=debug_servers` + +More info: +`aiconfig --help` +`aiconfig edit --help` + +### Frontent + +Use React server localhost:3000 + +### Backend + +Tip: use `--server-mode=debug_backend` +Server will hot reload when you save file. Recommend disabling autosave. + +Send POST requests from + +- curl (https://stackoverflow.com/questions/22947905/flask-example-with-post) +- Chrome dev tools (https://stackoverflow.com/questions/14248296/making-http-requests-using-chrome-developer-tools) +- Jupyter: + +``` +import requests +url = 'http://localhost:8080/api/add_prompt' +data = { + "prompt_name": "gen_packing_list", + "prompt_data": { + + } + } +response = requests.post(url, json=data) +print(f"{response=}"), + +import json +response_json = json.loads(response.text) +message, output = response_json['message'], response_json['output'] +print(f"{message=}") +print("output:") +print(output) +``` diff --git a/editor/vscode/ai-workbook-ext/editor/__init__.py b/editor/vscode/ai-workbook-ext/editor/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/editor/vscode/ai-workbook-ext/editor/client/.gitignore b/editor/vscode/ai-workbook-ext/editor/client/.gitignore new file mode 100644 index 000000000..704a02e0a --- /dev/null +++ b/editor/vscode/ai-workbook-ext/editor/client/.gitignore @@ -0,0 +1,44 @@ +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* \ No newline at end of file diff --git a/editor/vscode/ai-workbook-ext/editor/client/@types/ufetch.d.ts b/editor/vscode/ai-workbook-ext/editor/client/@types/ufetch.d.ts new file mode 100644 index 000000000..926c50e31 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/editor/client/@types/ufetch.d.ts @@ -0,0 +1,13 @@ +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/editor/vscode/ai-workbook-ext/editor/client/__init__.py b/editor/vscode/ai-workbook-ext/editor/client/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/editor/vscode/ai-workbook-ext/editor/client/package.json b/editor/vscode/ai-workbook-ext/editor/client/package.json new file mode 100644 index 000000000..cf32d5169 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/editor/client/package.json @@ -0,0 +1,59 @@ +{ + "name": "client", + "version": "0.1.0", + "private": true, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "build:vscode": "node ./scripts/build-react-no-split.js", + "postbuild": "node postbuild.js", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "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/notifications": "^6.0.7", + "@mantine/prism": "^6.0.7", + "@tabler/icons-react": "^2.44.0", + "@vscode/webview-ui-toolkit": "^1.4.0", + "aiconfig": "../../../../../typescript", + "lodash": "^4.17.21", + "node-fetch": "^3.3.2", + "react": "^18", + "react-dom": "^18", + "react-markdown": "^8.0.6", + "remark-gfm": "^4.0.0", + "ufetch": "^1.6.0", + "url-join": "^5.0.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", + "react-scripts": "5.0.1", + "rewire": "^5.0.0", + "typescript": "^5" + } +} diff --git a/editor/vscode/ai-workbook-ext/editor/client/postbuild.js b/editor/vscode/ai-workbook-ext/editor/client/postbuild.js new file mode 100644 index 000000000..7017efbe0 --- /dev/null +++ b/editor/vscode/ai-workbook-ext/editor/client/postbuild.js @@ -0,0 +1,80 @@ +var path = require("path"); +const fs = require("fs"); + +const targetSource = "./build"; // Relative path to copy files from +const targetDestination = "../server/static"; // Relative path to copy files to + +/** + * Remove directory recursively + * @param {string} dir_path + * @see https://stackoverflow.com/a/42505874 + */ +function rimraf(dir_path) { + if (fs.existsSync(dir_path)) { + fs.readdirSync(dir_path).forEach(function (entry) { + var entry_path = path.join(dir_path, entry); + if (fs.lstatSync(entry_path).isDirectory()) { + rimraf(entry_path); + } else { + fs.unlinkSync(entry_path); + } + }); + fs.rmdirSync(dir_path); + } +} + +/** + * Copy a file + * @param {string} source + * @param {string} target + * @see https://stackoverflow.com/a/26038979 + */ +function copyFileSync(source, target) { + var targetFile = target; + // If target is a directory a new file with the same name will be created + if (fs.existsSync(target)) { + if (fs.lstatSync(target).isDirectory()) { + targetFile = path.join(target, path.basename(source)); + } + } + fs.writeFileSync(targetFile, fs.readFileSync(source)); +} + +/** + * Copy a folder recursively + * @param {string} source + * @param {string} target + * @see https://stackoverflow.com/a/26038979 + */ +function copyFolderRecursiveSync(source, target, root = false) { + var files = []; + // Check if folder needs to be created or integrated + var targetFolder = root ? target : path.join(target, path.basename(source)); + if (!fs.existsSync(targetFolder)) { + fs.mkdirSync(targetFolder); + } + // Copy + if (fs.lstatSync(source).isDirectory()) { + files = fs.readdirSync(source); + files.forEach(function (file) { + var curSource = path.join(source, file); + if (fs.lstatSync(curSource).isDirectory()) { + copyFolderRecursiveSync(curSource, targetFolder); + } else { + copyFileSync(curSource, targetFolder); + } + }); + } +} + +// Calculate absolute paths using the relative paths we defined at the top +const sourceFolder = path.resolve(targetSource); +const destinationFolder = path.resolve(targetDestination); + +// Remove destination folder if it exists to clear it +if (fs.existsSync(destinationFolder)) { + rimraf(destinationFolder); +} + +// Copy the build over +copyFolderRecursiveSync(sourceFolder, destinationFolder, true); diff --git a/editor/vscode/ai-workbook-ext/editor/client/public/index.html b/editor/vscode/ai-workbook-ext/editor/client/public/index.html new file mode 100644 index 000000000..94cfd9c4f --- /dev/null +++ b/editor/vscode/ai-workbook-ext/editor/client/public/index.html @@ -0,0 +1,43 @@ + + +
+ + + + + + + + + +
+ {children}
+
+ );
+ },
+ h1: CustomHeading,
+ h2: CustomHeading,
+ h3: CustomHeading,
+ h4: CustomHeading,
+ h5: CustomHeading,
+ h6: CustomHeading,
+ p({ children }) {
+ return