feat: switch zod-to-ts to zod-to-json-schema

Philipp Burckhardt 2023-06-19 20:23:27 -04:00
rodzic cce996ca39
commit 8a3c89ccc1
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: A2C3BCA4F31D1DDD
4 zmienionych plików z 22 dodań i 37 usunięć

Wyświetl plik

@ -65,7 +65,6 @@
"uuid": "^9.0.0",
"zod": "^3.21.4",
"zod-to-json-schema": "^3.21.2",
"zod-to-ts": "^1.1.4",
"zod-validation-error": "^1.3.0"
},
"devDependencies": {

Wyświetl plik

@ -86,9 +86,6 @@ dependencies:
zod-to-json-schema:
specifier: ^3.21.2
version: 3.21.2(zod@3.21.4)
zod-to-ts:
specifier: ^1.1.4
version: 1.1.4(typescript@5.1.3)(zod@3.21.4)
zod-validation-error:
specifier: ^1.3.0
version: 1.3.0(zod@3.21.4)
@ -4448,6 +4445,7 @@ packages:
resolution: {integrity: sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
/uglify-js@3.17.4:
resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
@ -4645,16 +4643,6 @@ packages:
zod: 3.21.4
dev: false
/zod-to-ts@1.1.4(typescript@5.1.3)(zod@3.21.4):
resolution: {integrity: sha512-jsCg+pTNxLAdJOfW4ul+SpechdGYEJPPnssSbqWdR2LSIkotT22k+UvqPb1nEHwe/YbEcbUOlZUfGM0npgR+Jg==}
peerDependencies:
typescript: ^4.9.4 || ^5.0.2
zod: ^3
dependencies:
typescript: 5.1.3
zod: 3.21.4
dev: false
/zod-validation-error@1.3.0(zod@3.21.4):
resolution: {integrity: sha512-4WoQnuWnj06kwKR4A+cykRxFmy+CTvwMQO5ogTXLiVx1AuvYYmMjixh7sbkSsQTr1Fvtss6d5kVz8PGeMPUQjQ==}
engines: {node: '>=16.0.0'}

Wyświetl plik

@ -2,7 +2,7 @@ import { JSONRepairError, jsonrepair } from 'jsonrepair'
import { dedent } from 'ts-dedent'
import { type SetRequired } from 'type-fest'
import { ZodType, z } from 'zod'
import { printNode, zodToTs } from 'zod-to-ts'
import { zodToJsonSchema } from 'zod-to-json-schema'
import * as errors from '@/errors'
import * as types from '@/types'
@ -275,22 +275,12 @@ export abstract class BaseChatCompletion<
return null
}
// TODO: replace zod-to-ts with zod-to-json-schema?
const { node } = zodToTs(outputSchema)
if (node.kind === 152) {
// Handle raw strings differently:
return dedent`Output a raw string only, without any additional text.`
}
const tsTypeString = printNode(node, {
removeComments: false,
// TODO: this doesn't seem to actually work, so we're doing it manually below
omitTrailingSemicolon: true,
noEmitHelpers: true
})
.replace(/^ {4}/gm, ' ')
.replace(/;$/gm, '')
const schema = zodToJsonSchema(outputSchema) as types.Jsonifiable
const schemaStr = stringifyForModel(schema, [
'default',
'additionalProperties',
'$schema'
])
let label: string
if (outputSchema instanceof z.ZodArray) {
label = 'JSON array (minified)'
@ -306,9 +296,9 @@ export abstract class BaseChatCompletion<
label = 'JSON value'
}
return dedent`Do not output code. Output a single ${label} in the following TypeScript format:
\`\`\`ts
${tsTypeString}
return dedent`Do not output code. Output a single ${label} according to the following JSON Schema:
\`\`\`json
${schemaStr}
\`\`\``
}

Wyświetl plik

@ -1,5 +1,6 @@
import { customAlphabet, urlAlphabet } from 'nanoid'
import type { ThrottledFunction } from 'p-throttle'
import { JsonValue } from 'type-fest'
import * as types from './types'
@ -132,7 +133,10 @@ export function chunkMultipleStrings(
* @param json - JSON value to stringify
* @returns stringified value with all double quotes around object keys removed
*/
export function stringifyForModel(json: types.Jsonifiable): string {
export function stringifyForModel(
json: types.Jsonifiable,
omit: string[] = []
): string {
const UNIQUE_PREFIX = defaultIDGeneratorFn()
return (
JSON.stringify(json, replacer)
@ -143,7 +147,11 @@ export function stringifyForModel(json: types.Jsonifiable): string {
/**
* Replacer function prefixing all keys with a unique identifier.
*/
function replacer(_: string, value: any) {
function replacer(key: string, value: JsonValue) {
if (omit.includes(key)) {
return undefined
}
if (value && typeof value === 'object') {
if (Array.isArray(value)) {
return value
@ -152,7 +160,7 @@ export function stringifyForModel(json: types.Jsonifiable): string {
const replacement = {}
for (const k in value) {
if (Object.hasOwnProperty.call(value, k)) {
if (Object.hasOwnProperty.call(value, k) && !omit.includes(k)) {
replacement[UNIQUE_PREFIX + k] = value[k]
}
}