Files
OpenPipe-llm/src/state/sharedVariantEditor.slice.ts
Kyle Corbitt c3e85607e0 Strip types from prompt variants
We want Monaco to treat the prompt constructor as Typescript so we get type checks, but we actually want to save the prompt constructor as Javascript so we can run it directly without transpiling.
2023-07-14 14:03:28 -07:00

103 lines
2.8 KiB
TypeScript

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 formatPromptConstructor from "~/utils/formatPromptConstructor";
export const editorBackground = "#fafafa";
export type SharedVariantEditorSlice = {
monaco: null | ReturnType<typeof loader.__getMonacoInstance>;
loadMonaco: () => Promise<void>;
scenarios: RouterOutputs["scenarios"]["list"];
updateScenariosModel: () => void;
setScenarios: (scenarios: RouterOutputs["scenarios"]["list"]) => void;
};
export const createVariantEditorSlice: SliceCreator<SharedVariantEditorSlice> = (set, get) => ({
monaco: loader.__getMonacoInstance(),
loadMonaco: async () => {
// We only want to run this client-side
if (typeof window === "undefined") return;
const monaco = await loader.init();
monaco.editor.defineTheme("customTheme", {
base: "vs",
inherit: true,
rules: [],
colors: {
"editor.background": editorBackground,
},
});
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
allowNonTsExtensions: true,
lib: ["esnext"],
});
monaco.editor.createModel(
`
${openAITypes}
declare var prompt: components["schemas"]["CreateChatCompletionRequest"];
`,
"typescript",
monaco.Uri.parse("file:///openai.types.ts"),
);
monaco.languages.registerDocumentFormattingEditProvider("typescript", {
provideDocumentFormattingEdits: async (model) => {
return [
{
range: model.getFullModelRange(),
text: await formatPromptConstructor(model.getValue()),
},
];
},
});
set((state) => {
state.sharedVariantEditor.monaco = monaco;
});
get().sharedVariantEditor.updateScenariosModel();
},
scenarios: [],
// scenariosModel: null,
setScenarios: (scenarios) => {
set((state) => {
state.sharedVariantEditor.scenarios = scenarios;
});
get().sharedVariantEditor.updateScenariosModel();
},
updateScenariosModel: () => {
const monaco = get().sharedVariantEditor.monaco;
if (!monaco) return;
const modelContents = `
const scenarios = ${JSON.stringify(
get().sharedVariantEditor.scenarios.map((s) => s.variableValues),
null,
2,
)} as const;
type Scenario = typeof scenarios[number];
declare var scenario: Scenario | null;
`;
const scenariosModel = monaco.editor.getModel(monaco.Uri.parse("file:///scenarios.ts"));
if (scenariosModel) {
scenariosModel.setValue(modelContents);
} else {
monaco.editor.createModel(
modelContents,
"typescript",
monaco.Uri.parse("file:///scenarios.ts"),
);
}
},
});