Compare commits

..

5 Commits

Author SHA1 Message Date
Kyle Corbitt
731406d1f4 Pseudo function signatures
Show pseudo function signatures in the variant editor box as a UX hint that you're typing in javascript and have access to the scenario.
2023-07-14 13:56:45 -07:00
Kyle Corbitt
3c59e4b774 Merge pull request #42 from OpenPipe/autoformat
implement format on save
2023-07-14 12:56:41 -07:00
Kyle Corbitt
a20f81939d implement format on save 2023-07-14 12:33:57 -07:00
Kyle Corbitt
972b1f2333 Merge pull request #41 from OpenPipe/github-actions
CI checks
2023-07-14 11:40:42 -07:00
Kyle Corbitt
2bd41fdfbf Merge pull request #40 from OpenPipe:completion-costs
store model and use to calculate completion costs
2023-07-14 11:07:15 -07:00
4 changed files with 67 additions and 28 deletions

View File

@@ -48,6 +48,7 @@
"openai": "4.0.0-beta.2",
"pluralize": "^8.0.0",
"posthog-js": "^1.68.4",
"prettier": "^3.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.10.1",
@@ -77,8 +78,8 @@
"eslint": "^8.40.0",
"eslint-config-next": "^13.4.2",
"eslint-plugin-unused-imports": "^2.0.0",
"monaco-editor": "^0.40.0",
"openapi-typescript": "^6.3.4",
"prettier": "^3.0.0",
"prisma": "^4.14.0",
"raw-loader": "^4.0.2",
"typescript": "^5.0.4",

22
pnpm-lock.yaml generated
View File

@@ -22,7 +22,7 @@ dependencies:
version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.6)(react@18.2.0)
'@monaco-editor/loader':
specifier: ^1.3.3
version: 1.3.3(monaco-editor@0.39.0)
version: 1.3.3(monaco-editor@0.40.0)
'@next-auth/prisma-adapter':
specifier: ^1.0.5
version: 1.0.5(@prisma/client@4.14.0)(next-auth@4.22.1)
@@ -107,6 +107,9 @@ dependencies:
posthog-js:
specifier: ^1.68.4
version: 1.68.4
prettier:
specifier: ^3.0.0
version: 3.0.0
react:
specifier: 18.2.0
version: 18.2.0
@@ -190,12 +193,12 @@ devDependencies:
eslint-plugin-unused-imports:
specifier: ^2.0.0
version: 2.0.0(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.40.0)
monaco-editor:
specifier: ^0.40.0
version: 0.40.0
openapi-typescript:
specifier: ^6.3.4
version: 6.3.4
prettier:
specifier: ^3.0.0
version: 3.0.0
prisma:
specifier: ^4.14.0
version: 4.14.0
@@ -2029,12 +2032,12 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.14
dev: true
/@monaco-editor/loader@1.3.3(monaco-editor@0.39.0):
/@monaco-editor/loader@1.3.3(monaco-editor@0.40.0):
resolution: {integrity: sha512-6KKF4CTzcJiS8BJwtxtfyYt9shBiEv32ateQ9T4UVogwn4HM/uPo9iJd2Dmbkpz8CM6Y0PDUpjnZzCwC+eYo2Q==}
peerDependencies:
monaco-editor: '>= 0.21.0 < 1'
dependencies:
monaco-editor: 0.39.0
monaco-editor: 0.40.0
state-local: 1.0.7
dev: false
@@ -5135,9 +5138,8 @@ packages:
ufo: 1.1.2
dev: true
/monaco-editor@0.39.0:
resolution: {integrity: sha512-zhbZ2Nx93tLR8aJmL2zI1mhJpsl87HMebNBM6R8z4pLfs8pj604pIVIVwyF1TivcfNtIPpMXL+nb3DsBmE/x6Q==}
dev: false
/monaco-editor@0.40.0:
resolution: {integrity: sha512-1wymccLEuFSMBvCk/jT1YDW/GuxMLYwnFwF9CDyYCxoTw2Pt379J3FUhwy9c43j51JdcxVPjwk0jm0EVDsBS2g==}
/ms@2.0.0:
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
@@ -5637,7 +5639,7 @@ packages:
resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==}
engines: {node: '>=14'}
hasBin: true
dev: true
dev: false
/pretty-format@29.6.1:
resolution: {integrity: sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==}

View File

@@ -1,9 +1,10 @@
import { Box, Button, HStack, Tooltip, useToast } from "@chakra-ui/react";
import { Box, Button, HStack, Tooltip, VStack, useToast } from "@chakra-ui/react";
import { useRef, useEffect, useState, useCallback } from "react";
import { useHandledAsyncCallback, useModifierKeyLabel } from "~/utils/hooks";
import { type PromptVariant } from "./types";
import { api } from "~/utils/api";
import { useAppStore } from "~/state/store";
import { editorBackground } from "~/state/sharedVariantEditor.slice";
// import openAITypes from "~/codegen/openai.types.ts.txt";
export default function VariantConfigEditor(props: { variant: PromptVariant }) {
@@ -27,11 +28,16 @@ export default function VariantConfigEditor(props: { variant: PromptVariant }) {
const toast = useToast();
const [onSave] = useHandledAsyncCallback(async () => {
const currentFn = editorRef.current?.getValue();
if (!editorRef.current) return;
await editorRef.current.getAction("editor.action.formatDocument")?.run();
const currentFn = editorRef.current.getValue();
if (!currentFn) return;
// Check if the editor has any typescript errors
const model = editorRef.current?.getModel();
const model = editorRef.current.getModel();
if (!model) return;
const markers = monaco?.editor.getModelMarkers({ resource: model.uri });
@@ -124,21 +130,21 @@ export default function VariantConfigEditor(props: { variant: PromptVariant }) {
/* eslint-disable-next-line react-hooks/exhaustive-deps */
}, [monaco, editorId]);
// useEffect(() => {
// const savedConfigChanged = lastSavedFn !== savedConfig;
// lastSavedFn = savedConfig;
// if (savedConfigChanged && editorRef.current?.getValue() !== savedConfig) {
// editorRef.current?.setValue(savedConfig);
// }
// checkForChanges();
// }, [savedConfig, checkForChanges]);
return (
<Box w="100%" pos="relative">
<div id={editorId} style={{ height: "300px", width: "100%" }}></div>
<VStack
spacing={0}
align="stretch"
fontSize="xs"
fontWeight="bold"
color="gray.600"
py={2}
bgColor={editorBackground}
>
<code>{`function constructPrompt(scenario: Scenario): Prompt {`}</code>
<div id={editorId} style={{ height: "300px", width: "100%" }}></div>
<code>{`return prompt; }`}</code>
</VStack>
{isChanged && (
<HStack pos="absolute" bottom={2} right={2}>
<Button

View File

@@ -2,6 +2,14 @@ import { type RouterOutputs } from "~/utils/api";
import { type SliceCreator } from "./store";
import loader from "@monaco-editor/loader";
import openAITypes from "~/codegen/openai.types.ts.txt";
import prettier from "prettier/standalone";
import parserTypescript from "prettier/plugins/typescript";
// @ts-expect-error for some reason missing from types
import parserEstree from "prettier/plugins/estree";
import { type languages } from "monaco-editor/esm/vs/editor/editor.api";
export const editorBackground = "#fafafa";
export type SharedVariantEditorSlice = {
monaco: null | ReturnType<typeof loader.__getMonacoInstance>;
@@ -11,6 +19,26 @@ export type SharedVariantEditorSlice = {
setScenarios: (scenarios: RouterOutputs["scenarios"]["list"]) => void;
};
const customFormatter: languages.DocumentFormattingEditProvider = {
provideDocumentFormattingEdits: async (model) => {
const val = model.getValue();
console.log("going to format!", val);
const text = await prettier.format(val, {
parser: "typescript",
plugins: [parserTypescript, parserEstree],
// We're showing these in pretty narrow panes so let's keep the print width low
printWidth: 60,
});
return [
{
range: model.getFullModelRange(),
text,
},
];
},
};
export const createVariantEditorSlice: SliceCreator<SharedVariantEditorSlice> = (set, get) => ({
monaco: loader.__getMonacoInstance(),
loadMonaco: async () => {
@@ -24,7 +52,7 @@ export const createVariantEditorSlice: SliceCreator<SharedVariantEditorSlice> =
inherit: true,
rules: [],
colors: {
"editor.background": "#fafafa",
"editor.background": editorBackground,
},
});
@@ -43,6 +71,8 @@ export const createVariantEditorSlice: SliceCreator<SharedVariantEditorSlice> =
monaco.Uri.parse("file:///openai.types.ts"),
);
monaco.languages.registerDocumentFormattingEditProvider("typescript", customFormatter);
set((state) => {
state.sharedVariantEditor.monaco = monaco;
});