kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: switch zod-to-ts to zod-to-json-schema
rodzic
cce996ca39
commit
8a3c89ccc1
|
@ -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": {
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -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}
|
||||
\`\`\``
|
||||
}
|
||||
|
||||
|
|
14
src/utils.ts
14
src/utils.ts
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue