validate json schema for openai api
This commit is contained in:
45
src/codegen/export-openai-schema.ts
Normal file
45
src/codegen/export-openai-schema.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import YAML from "yaml";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { openapiSchemaToJsonSchema } from "@openapi-contrib/openapi-schema-to-json-schema";
|
||||
import assert from "assert";
|
||||
|
||||
const OPENAPI_URL =
|
||||
"https://raw.githubusercontent.com/openai/openai-openapi/0c432eb66fd0c758fd8b9bd69db41c1096e5f4db/openapi.yaml";
|
||||
|
||||
const convertOpenApiToJsonSchema = async (url: string) => {
|
||||
// Fetch the openapi document
|
||||
const response = await fetch(url);
|
||||
const openApiYaml = await response.text();
|
||||
|
||||
// Parse the yaml document
|
||||
const openApiDocument = YAML.parse(openApiYaml) as unknown;
|
||||
|
||||
// Convert the openapi schema to json schema
|
||||
const jsonSchema = openapiSchemaToJsonSchema(openApiDocument);
|
||||
|
||||
const modelProperty = jsonSchema.components.schemas.CreateChatCompletionRequest.properties.model;
|
||||
|
||||
assert(modelProperty.oneOf.length === 2, "Expected model to have oneOf length of 2");
|
||||
|
||||
// We need to do a bit of surgery here since the Monaco editor doesn't like
|
||||
// the fact that the schema says `model` can be either a string or an enum,
|
||||
// and displays a warning in the editor. Let's stick with just an enum for
|
||||
// now and drop the string option.
|
||||
modelProperty.type = "string";
|
||||
modelProperty.enum = modelProperty.oneOf[1].enum;
|
||||
modelProperty.oneOf = undefined;
|
||||
|
||||
// Get the directory of the current script
|
||||
const currentDirectory = path.dirname(import.meta.url).replace("file://", "");
|
||||
|
||||
// Write the JSON schema to a file in the current directory
|
||||
fs.writeFileSync(
|
||||
path.join(currentDirectory, "openai.schema.json"),
|
||||
JSON.stringify(jsonSchema, null, 2)
|
||||
);
|
||||
};
|
||||
|
||||
convertOpenApiToJsonSchema(OPENAPI_URL)
|
||||
.then(() => console.log("JSON schema has been written successfully."))
|
||||
.catch((err) => console.error(err));
|
||||
2879
src/codegen/openai.schema.json
Normal file
2879
src/codegen/openai.schema.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -88,7 +88,7 @@ export default function ScenarioEditor({
|
||||
onDrop={onReorder}
|
||||
backgroundColor={isDragTarget ? "gray.100" : "transparent"}
|
||||
>
|
||||
<Stack alignSelf="flex-start" opacity={hovered ? 1 : 0}>
|
||||
<Stack alignSelf="flex-start" opacity={hovered ? 1 : 0} spacing={0}>
|
||||
<Tooltip label="Hide scenario" hasArrow>
|
||||
{/* for some reason the tooltip can't position itself properly relative to the icon without the wrapping box */}
|
||||
<Button
|
||||
|
||||
@@ -2,11 +2,12 @@ import { Box, Button, HStack, Tooltip, useToast } from "@chakra-ui/react";
|
||||
import { useMonaco } from "@monaco-editor/react";
|
||||
import { useRef, useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { useHandledAsyncCallback, useModifierKeyLabel } from "~/utils/hooks";
|
||||
import { PromptVariant } from "./types";
|
||||
import { JSONSerializable } from "~/server/types";
|
||||
import { type PromptVariant } from "./types";
|
||||
import { type JSONSerializable } from "~/server/types";
|
||||
import { api } from "~/utils/api";
|
||||
import openaiSchema from "~/codegen/openai.schema.json";
|
||||
|
||||
let isThemeDefined = false;
|
||||
let isEditorConfigured = false;
|
||||
|
||||
export default function VariantConfigEditor(props: { variant: PromptVariant }) {
|
||||
const monaco = useMonaco();
|
||||
@@ -69,7 +70,7 @@ export default function VariantConfigEditor(props: { variant: PromptVariant }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (monaco) {
|
||||
if (!isThemeDefined) {
|
||||
if (!isEditorConfigured) {
|
||||
monaco.editor.defineTheme("customTheme", {
|
||||
base: "vs",
|
||||
inherit: true,
|
||||
@@ -78,7 +79,21 @@ export default function VariantConfigEditor(props: { variant: PromptVariant }) {
|
||||
"editor.background": "#fafafa",
|
||||
},
|
||||
});
|
||||
isThemeDefined = true;
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
validate: true,
|
||||
schemas: [
|
||||
{
|
||||
uri: "https://api.openai.com/v1",
|
||||
fileMatch: ["*"],
|
||||
schema: {
|
||||
$schema: "http://json-schema.org/draft-07/schema#",
|
||||
$ref: "#/components/schemas/CreateChatCompletionRequest",
|
||||
components: openaiSchema.components,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
isEditorConfigured = true;
|
||||
}
|
||||
|
||||
const container = document.getElementById(editorId) as HTMLElement;
|
||||
|
||||
Reference in New Issue
Block a user