From 393591e28e765ef08a00f1e1ae39e801c6af5f3e Mon Sep 17 00:00:00 2001 From: babayaga Date: Tue, 1 Apr 2025 14:35:30 +0200 Subject: [PATCH] kbot:structured output - spieglein spieglein :) --- packages/kbot/.vscode/launch.json | 77 +++++++++++------ .../kbot/dist-in/commands/run-completion.js | 3 +- packages/kbot/dist-in/zod_schema.js | 31 +++++-- packages/kbot/dist-in/zod_types.d.ts | 4 +- packages/kbot/package-lock.json | 10 +++ packages/kbot/package.json | 1 + packages/kbot/schema.json | 4 +- packages/kbot/schema_ui.json | 5 +- packages/kbot/src/commands/run-completion.ts | 3 +- packages/kbot/src/zod_schema.ts | 31 +++++-- packages/kbot/src/zod_types.ts | 4 +- .../response-format/africa-countries.json | 84 +++++++++++++++++++ .../tests/response-format/africa-countries.md | 66 +++++++++++++++ .../kbot/tests/response-format/countries.json | 31 +++++++ 14 files changed, 306 insertions(+), 48 deletions(-) create mode 100644 packages/kbot/tests/response-format/africa-countries.json create mode 100644 packages/kbot/tests/response-format/africa-countries.md create mode 100644 packages/kbot/tests/response-format/countries.json diff --git a/packages/kbot/.vscode/launch.json b/packages/kbot/.vscode/launch.json index a4cffa27..cc096254 100644 --- a/packages/kbot/.vscode/launch.json +++ b/packages/kbot/.vscode/launch.json @@ -9,7 +9,7 @@ "request": "launch", "name": "create", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -32,7 +32,7 @@ "request": "launch", "name": "modify", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -54,7 +54,7 @@ "request": "launch", "name": "git", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -77,7 +77,7 @@ "request": "launch", "name": "templates:solidworks", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -100,7 +100,7 @@ "request": "launch", "name": "prompt:docker", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -125,7 +125,7 @@ "request": "launch", "name": "iterator", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -154,7 +154,7 @@ "request": "launch", "name": "search:google", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -177,7 +177,7 @@ "request": "launch", "name": "search:serpapi", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -199,7 +199,7 @@ "request": "launch", "name": "interact", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -224,7 +224,7 @@ "request": "launch", "name": "web", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -247,7 +247,7 @@ "request": "launch", "name": "deepseek", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -269,7 +269,7 @@ "request": "launch", "name": "tools:email", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -291,7 +291,7 @@ "request": "launch", "name": "tools:terminal:astro", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -313,7 +313,7 @@ "request": "launch", "name": "types", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -333,7 +333,7 @@ "request": "launch", "name": "tools:search", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -357,7 +357,7 @@ "request": "launch", "name": "assistant:code", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -383,7 +383,7 @@ "request": "launch", "name": "assistant:pdf", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -409,7 +409,7 @@ "request": "launch", "name": "assistant:md", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -431,12 +431,39 @@ "outputCapture": "std", "console": "integratedTerminal" }, + { + "type": "node", + "request": "launch", + "name": "response-format", + "skipFiles": [], + "program": "${workspaceFolder}\\dist-in\\main.js", + "outFiles": [ + "${workspaceFolder}/**/*.js" + ], + "cwd": "${workspaceFolder}", + "args": [ + "'return a list of african countries'", + "--disable='npm,terminal,interact,git,search'", + "--router2=openai", + "--format=./tests/response-format/countries.json", + "--model=openai/gpt-4o", + "--mode=completion", + "--filters=JSONParse", + "--dst=./tests/response-format/africa-countries.json", + ], + "resolveSourceMapLocations": [ + "${workspaceFolder}/**", + "!**/node_modules/**" + ], + "outputCapture": "std", + "console": "integratedTerminal" + }, { "type": "node", "request": "launch", "name": "each:glob", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -462,7 +489,7 @@ "request": "launch", "name": "each:array", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -494,7 +521,7 @@ "request": "launch", "name": "salamand", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -527,7 +554,7 @@ "request": "launch", "name": "tools:test", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -556,7 +583,7 @@ "request": "launch", "name": "images:jpg-svg", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -582,7 +609,7 @@ "request": "launch", "name": "images:jpg-svg-overlay", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], @@ -609,7 +636,7 @@ "request": "launch", "name": "hono", "skipFiles": [], - "program": "${workspaceFolder}\\main.js", + "program": "${workspaceFolder}\\dist-in\\main.js", "outFiles": [ "${workspaceFolder}/**/*.js" ], diff --git a/packages/kbot/dist-in/commands/run-completion.js b/packages/kbot/dist-in/commands/run-completion.js index 3f3ed3f1..7f285bda 100644 --- a/packages/kbot/dist-in/commands/run-completion.js +++ b/packages/kbot/dist-in/commands/run-completion.js @@ -38,9 +38,10 @@ export const runCompletion = async (client, params, options) => { const completion = await client.chat.completions.create({ model: options.model, messages: params.messages, + response_format: options.format, }); let result = completion.choices[0].message.content; result = await onCompletion(result, options); return result; }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLWNvbXBsZXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvcnVuLWNvbXBsZXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUMvQixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDaEQsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUE7QUFDakMsT0FBTyxFQUFFLElBQUksSUFBSSxLQUFLLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUNsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFJM0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUNwQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFDakQsT0FBTyxFQUFFLFlBQVksRUFBVSxNQUFNLGVBQWUsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFHM0MsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxTQUFjLEVBQUUsRUFBRSxPQUFrQixFQUFFLEVBQUU7SUFDekUsTUFBTSxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLE9BQW1CLElBQUksRUFBRSxDQUFDLENBQUE7SUFDaEUsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQy9CLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFO1lBQ3ZELEdBQUcsSUFBSTtZQUNQLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJO1lBQ3JDLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtTQUN2QixDQUFDLENBQUMsQ0FBQTtRQUNILEtBQUssQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDdEIsTUFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsT0FBTyxNQUFNLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFBO0lBQ3hFLENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7WUFDeEIsS0FBSyxFQUFFLEtBQUs7U0FDYixDQUFDLENBQUMsQ0FBQTtRQUNILE1BQU0sT0FBTyxHQUFXLE1BQU0sQ0FBQyxNQUFNLENBQVcsQ0FBQztRQUNqRCxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUMvQixDQUFDO0lBQ0QsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3JCLGtCQUFrQjtJQUNsQixPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxLQUFLLEVBQUUsTUFBYyxFQUFFLE1BQVcsRUFBRSxPQUFrQixFQUFFLEVBQUU7SUFDckYsSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDaEIsTUFBTSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFBO1FBQzFDLE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUNELE1BQU0sVUFBVSxHQUFHLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBQ3RELEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSztRQUNwQixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7S0FDMUIsQ0FBQyxDQUFBO0lBQ0YsSUFBSSxNQUFNLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFBO0lBQ2xELE1BQU0sR0FBRyxNQUFNLFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDNUMsT0FBTyxNQUFNLENBQUE7QUFDZixDQUFDLENBQUEifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLWNvbXBsZXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvcnVuLWNvbXBsZXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUMvQixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDaEQsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUE7QUFDakMsT0FBTyxFQUFFLElBQUksSUFBSSxLQUFLLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUNsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFJM0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUNwQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFDakQsT0FBTyxFQUFFLFlBQVksRUFBVSxNQUFNLGVBQWUsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFHM0MsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxTQUFjLEVBQUUsRUFBRSxPQUFrQixFQUFFLEVBQUU7SUFDekUsTUFBTSxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLE9BQW1CLElBQUksRUFBRSxDQUFDLENBQUE7SUFDaEUsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQy9CLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFO1lBQ3ZELEdBQUcsSUFBSTtZQUNQLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJO1lBQ3JDLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtTQUN2QixDQUFDLENBQUMsQ0FBQTtRQUNILEtBQUssQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDdEIsTUFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsT0FBTyxNQUFNLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFBO0lBQ3hFLENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7WUFDeEIsS0FBSyxFQUFFLEtBQUs7U0FDYixDQUFDLENBQUMsQ0FBQTtRQUNILE1BQU0sT0FBTyxHQUFXLE1BQU0sQ0FBQyxNQUFNLENBQVcsQ0FBQztRQUNqRCxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUMvQixDQUFDO0lBQ0QsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3JCLGtCQUFrQjtJQUNsQixPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxLQUFLLEVBQUUsTUFBYyxFQUFFLE1BQVcsRUFBRSxPQUFrQixFQUFFLEVBQUU7SUFDckYsSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDaEIsTUFBTSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFBO1FBQzFDLE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUNELE1BQU0sVUFBVSxHQUFHLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBQ3RELEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSztRQUNwQixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7UUFDekIsZUFBZSxFQUFFLE9BQU8sQ0FBQyxNQUFhO0tBQ3ZDLENBQUMsQ0FBQTtJQUNGLElBQUksTUFBTSxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQTtJQUNsRCxNQUFNLEdBQUcsTUFBTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQzVDLE9BQU8sTUFBTSxDQUFBO0FBQ2YsQ0FBQyxDQUFBIn0= \ No newline at end of file diff --git a/packages/kbot/dist-in/zod_schema.js b/packages/kbot/dist-in/zod_schema.js index e0a1806c..77544a05 100644 --- a/packages/kbot/dist-in/zod_schema.js +++ b/packages/kbot/dist-in/zod_schema.js @@ -3,13 +3,16 @@ import * as path from 'node:path'; import chalk from 'chalk'; import env from 'env-var'; import { generate_interfaces, ZodMetaMap, resolve, write } from '@polymech/commons'; +import { sync as exists } from '@polymech/fs/exists'; import { sync as writeFS } from '@polymech/fs/write'; +import { sync as readFS } from '@polymech/fs/read'; import { isArray, isFunction, isString } from '@polymech/core/primitives'; import { zodResponseFormat } from "openai/helpers/zod"; import { API_PREFIX, LOGGING_DIRECTORY, PREFERENCES_FILE_NAME } from './constants.js'; export const get_var = (key = '') => env.get(key).asString() || env.get(key.replace(/-/g, '_')).asString() || env.get(key.replace(/_/g, '-')).asString(); export const HOME = (sub = '') => path.join(process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'] || '', sub); export const PREFERENCES_DEFAULT = (key = 'KBOT_PREFERENCES') => get_var(key) || path.join(HOME(`.${API_PREFIX}`), PREFERENCES_FILE_NAME); +import { jsonSchemaToZod } from "json-schema-to-zod"; import { Filters } from './filters.js'; import { models_dist } from './models/index.js'; import { defaultTemplate } from './tools.js'; @@ -155,11 +158,29 @@ export const OptionsSchema = (opts) => { .optional() .default(false) .describe('Dry run - only write out parameters without making API calls')) - .add('format', z.any() + .add('format', z.string().optional().transform((val) => { + try { + let schema; + // Check if the string is a file path + if (exists(val) && val.endsWith('.json')) { + const content = readFS(val); + schema = JSON.parse(content.toString()); + } + else { + schema = JSON.parse(val); + } + const zodSchemaStr = jsonSchemaToZod(schema); + // Evaluate the string to get the actual Zod schema + const zodSchema = eval(`(${zodSchemaStr})`); + return zodResponseFormat(zodSchema, "format"); + } + catch (e) { + console.error(`Error parsing format: ${e}`); + return null; + } + }) .optional() - .default(null) - .describe('Zod schema for structured outputs') - .transform((val) => val ? zodResponseFormat(val, "format") : null)); + .describe('Zod schema for structured outputs. Can be a Zod schema, a JSON schema string, or a path to a JSON file.')); return schemaMap.root() .passthrough() .describe('IKBotOptions'); @@ -173,4 +194,4 @@ export const schemas = () => { write([OptionsSchema()], 'schema.json', 'kbot', {}); writeFS('schema_ui.json', schemaMap.getUISchema()); }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiem9kX3NjaGVtYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy96b2Rfc2NoZW1hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUE7QUFDdkIsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUE7QUFDakMsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFBO0FBQ3pCLE9BQU8sR0FBRyxNQUFNLFNBQVMsQ0FBQTtBQUN6QixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUVuRixPQUFPLEVBQUUsSUFBSSxJQUFJLE9BQU8sRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQ3BELE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUEyQixDQUFBO0FBQ3pFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBRXRELE9BQU8sRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQUVyRixNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsQ0FBQyxNQUFjLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFBO0FBQ2hLLE1BQU0sQ0FBQyxNQUFNLElBQUksR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLElB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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiem9kX3NjaGVtYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy96b2Rfc2NoZW1hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUE7QUFDdkIsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUE7QUFDakMsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFBO0FBQ3pCLE9BQU8sR0FBRyxNQUFNLFNBQVMsQ0FBQTtBQUN6QixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUNuRixPQUFPLEVBQUUsSUFBSSxJQUFJLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQ3BELE9BQU8sRUFBRSxJQUFJLElBQUksT0FBTyxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFDcEQsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUNsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQTtBQUN6RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUV0RCxPQUFPLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUFFLHFCQUFxQixFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFFckYsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLENBQUMsTUFBYyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQTtBQUNoSyxNQUFNLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQTtBQUMzSCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLE1BQWMsa0JBQWtCLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLFVBQVUsRUFBRSxDQUFDLEVBQUUscUJBQXFCLENBQUMsQ0FBQTtBQUNqSixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFDcEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUN0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDL0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUU1QyxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBUSxDQUFDLENBQUE7QUFFNUQsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO0FBR25JLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRztJQUNuQixVQUFVLEVBQUUsWUFBWTtJQUN4QixLQUFLLEVBQUUsT0FBTztJQUNkLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLE1BQU0sRUFBRSxRQUFRO0NBQ1IsQ0FBQTtBQUdWLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQzFCLEtBQUssQ0FBQyxVQUFVO0lBQ2hCLEtBQUssQ0FBQyxLQUFLO0lBQ1gsS0FBSyxDQUFDLFNBQVM7SUFDZixLQUFLLENBQUMsTUFBTTtDQUNiLENBQUMsQ0FBQTtBQUNGLG9GQUFvRjtBQUNwRjs7Ozs7O0VBTUU7QUFDRixNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUM5QixNQUFNO0lBQ04saUNBQWlDO0lBQ2pDLDZCQUE2QjtJQUM3QixnQ0FBZ0M7SUFDaEMsMENBQTBDO0lBQzFDLDZCQUE2QjtDQUM5QixDQUFDLENBQUMsUUFBUSxDQUFDLDhCQUE4QixDQUFDLENBQUE7QUFLM0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLG1CQUFtQixJQUFJLDZCQUE2QixFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFDcEgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLG1CQUFtQixJQUFJLHlCQUF5QixFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFFeEcsSUFBSSxTQUFTLENBQUE7QUFFYixNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsQ0FBQyxJQUFVLEVBQU8sRUFBRTtJQUUvQyxTQUFTLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBcUIsQ0FBQTtJQUNsRCxTQUFTLENBQUMsR0FBRyxDQUNYLE1BQU0sRUFDTixDQUFDLENBQUMsTUFBTSxFQUFFO1NBQ1AsR0FBRyxDQUFDLENBQUMsQ0FBQztTQUNOLE9BQU8sQ0FBQyxHQUFHLENBQUM7U0FDWixRQUFRLENBQUMsa0JBQWtCLENBQUMsRUFDN0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLENBQUM7U0FDekIsR0FBRyxDQUNGLFFBQVEsRUFDUixDQUFDLENBQUMsTUFBTSxFQUFFO1NBQ1AsUUFBUSxDQUFDLDREQUE0RCxDQUFDO1NBQ3RFLFFBQVEsRUFBRTtTQUNWLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FDMUI7U0FDQSxHQUFHLENBQ0YsUUFBUSxFQUNSLENBQUMsQ0FBQyxNQUFNLEVBQUU7U0FDUCxRQUFRLEVBQUU7U0FDVixRQUFRLENBQUMsMERBQTBELENBQUMsQ0FDeEU7U0FDQSxHQUFHLENBQ0YsS0FBSyxFQUNMLENBQUMsQ0FBQyxNQUFNLEVBQUU7U0FDUCxRQUFRLEVBQUU7U0FDVixRQUFRLENBQUMseUlBQXlJLENBQUMsQ0FDdko7U0FDQSxHQUFHLENBQ0YsTUFBTSxFQUNOLENBQUMsQ0FBQyxNQUFNLEVBQUU7U0FDUCxRQUFRLEVBQUU7U0FDVixRQUFRLENBQUMsNk9BQTZPLENBQUMsQ0FDM1A7U0FDQSxHQUFHLENBQ0YsU0FBUyxFQUNULENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQ2hCLE9BQU8sQ0FBQyxFQUFFLENBQUM7U0FDWCxRQUFRLENBQUMsMkNBQTJDLGVBQWUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FDMUY7U0FDQSxHQUFHLENBQ0YsY0FBYyxFQUNkLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQ2hCLFFBQVEsRUFBRTtTQUNWLE9BQU8sQ0FBQyxFQUFFLENBQUM7U0FDWCxRQUFRLENBQUMsbUNBQW1DLENBQUMsQ0FDakQ7U0FDQSxHQUFHLENBQ0YsT0FBTyxFQUNQLENBQUMsQ0FBQyxLQUFLLENBQ0w7UUFDRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNuQixDQUFDLENBQUMsTUFBTSxFQUFFO0tBQ1gsQ0FBQyxDQUFDLFFBQVEsRUFBRTtTQUNaLE9BQU8sQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDO1NBQzlCLFFBQVEsQ0FBQyw0RkFBNEYsZUFBZSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztTQUN2SSxTQUFTLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUNqRTtTQUNBLEdBQUcsQ0FDRixTQUFTLEVBQ1QsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDaEIsUUFBUSxFQUFFO1NBQ1YsUUFBUSxDQUFDLGdHQUFnRyxDQUFDLENBQzlHO1NBQ0EsR0FBRyxDQUNGLFNBQVMsRUFDVCxDQUFDLENBQUMsTUFBTSxFQUFFO1NBQ1AsUUFBUSxFQUFFO1NBQ1YsUUFBUSxDQUFDLHlCQUF5QixDQUFDLENBQ3ZDO1NBQ0EsR0FBRyxDQUNGLE9BQU8sRUFDUCxDQUFDLENBQUMsTUFBTSxFQUFFO1NBQ1AsUUFBUSxFQUFFO1NBQ1YsUUFBUSxDQUFDLHNEQUFzRCxXQUFXLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUM5RjtTQUNBLEdBQUcsQ0FDRixRQUFRLEVBQ1IsQ0FBQyxDQUFDLE1BQU0sRUFBRTtTQUNQLE9BQU8sQ0FBQyxZQUFZLENBQUM7U0FDckIsUUFBUSxDQUFDLCtDQUErQyxDQUFDLENBQzdEO1NBQ0EsR0FBRyxDQUNGLE1BQU0sRUFDTixLQUFLO1NBQ0YsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7U0FDcEIsUUFBUSxDQUFDO1lBQ04sS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO1lBQzlCLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUN6QixLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7WUFDN0IsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO09BQy9CLENBQUMsQ0FDSDtTQUNBLEdBQUcsQ0FDRixVQUFVLEVBQ1YsQ0FBQyxDQUFDLE1BQU0sRUFBRTtTQUNQLE9BQU8sQ0FBQyxDQUFDLENBQUM7U0FDVixRQUFRLENBQUMsbUNBQW1DLENBQUMsQ0FDakQ7U0FDQSxHQUFHLENBQ0YsU0FBUyxFQUNULENBQUMsQ0FBQyxNQUFNLEVBQUU7U0FDUCxRQUFRLEVBQUU7U0FDVixRQUFRLENBQUMsZ0VBQWdFLENBQUMsQ0FDOUU7U0FDQSxHQUFHLENBQ0YsU0FBUyxFQUNULENBQUMsQ0FBQyxNQUFNLEVBQUU7U0FDUCxRQUFRLEVBQUU7U0FDVixRQUFRLENBQUMsb0RBQW9ELENBQUMsQ0FDbEU7U0FDQSxHQUFHLENBQ0YsUUFBUSxFQUNSLENBQUMsQ0FBQyxNQUFNLEVBQUU7U0FDUCxRQUFRLEVBQUU7U0FDVixRQUFRLENBQUMsNkVBQTZFLENBQUMsQ0FDM0Y7U0FDQSxHQUFHLENBQ0YsTUFBTSxFQUNOLENBQUMsQ0FBQyxNQUFNLEVBQUU7U0FDUCxRQUFRLEVBQUU7U0FDVixRQUFRLENBQUMsaUJBQWlCLENBQUMsQ0FDL0I7U0FDQSxHQUFHLENBQ0YsYUFBYSxFQUNiLENBQUMsQ0FBQyxNQUFNLEVBQUU7U0FDUCxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztTQUM5QixRQUFRLENBQUMsMEdBQTBHLENBQUMsQ0FDeEg7U0FDQSxHQUFHLENBQ0YsTUFBTSxFQUNOLENBQUMsQ0FBQyxNQUFNLEVBQUU7U0FDUCxPQUFPLENBQUMsaUJBQWlCLENBQUM7U0FDMUIsUUFBUSxDQUFDLG1CQUFtQixDQUFDLENBQ2pDO1NBQ0EsR0FBRyxDQUNGLEtBQUssRUFDTCxDQUFDLENBQUMsTUFBTSxFQUFFO1NBQ1AsT0FBTyxDQUFDLFNBQVMsQ0FBQztTQUNsQixRQUFRLENBQUMsMEJBQTBCLENBQUMsQ0FDeEM7UUFDRCx3Q0FBd0M7UUFDeEMsb0ZBQW9GO1NBQ25GLEdBQUcsQ0FDRixXQUFXLEVBQ1gsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQzdCLFFBQVEsRUFBRTtTQUNWLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FDZjtTQUNBLEdBQUcsQ0FDRixTQUFTLEVBQ1QsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUNOLENBQUMsQ0FBQyxNQUFNLEVBQUU7UUFDVixDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUNsQixDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNuQixDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztLQUN0QixDQUFDO1NBQ0MsUUFBUSxFQUFFO1NBQ1YsT0FBTyxDQUFDLEVBQUUsQ0FBQztTQUNYLFFBQVEsQ0FBQzs7O3VCQUdLLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztTQUN2QyxTQUFTLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtRQUNqQixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxJQUFJLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3JELE9BQU8sR0FBRyxDQUFBO1FBQ1osQ0FBQztRQUNELElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFBO1FBQ2xELE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDN0QsT0FBTyxPQUFPLENBQUE7SUFDaEIsQ0FBQyxDQUFDLENBQ0w7U0FDQSxHQUFHLENBQ0YsS0FBSyxFQUNMLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDTixDQUFDLENBQUMsT0FBTyxFQUFFO1FBQ1gsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxLQUFLLE1BQU0sQ0FBQztLQUM1RCxDQUFDO1NBQ0MsUUFBUSxFQUFFO1NBQ1YsT0FBTyxDQUFDLEtBQUssQ0FBQztTQUNkLFFBQVEsQ0FBQyw4REFBOEQsQ0FBQyxDQUM1RTtTQUNBLEdBQUcsQ0FDRixRQUFRLEVBQ1IsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1FBQ3RDLElBQUksQ0FBQztZQUNILElBQUksTUFBTSxDQUFDO1lBQ1gscUNBQXFDO1lBQ3JDLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDekMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUM1QixNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUMxQyxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDM0IsQ0FBQztZQUNELE1BQU0sWUFBWSxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM3QyxtREFBbUQ7WUFDbkQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQztZQUM1QyxPQUFPLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUMsRUFBRSxDQUFDLENBQUE7WUFDM0MsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQyxDQUFDO1NBQ0MsUUFBUSxFQUFFO1NBQ1YsUUFBUSxDQUFDLHlHQUF5RyxDQUFDLENBQ3ZILENBQUM7SUFDSixPQUFPLFNBQVMsQ0FBQyxJQUFJLEVBQUU7U0FDcEIsV0FBVyxFQUFFO1NBQ2IsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFBO0FBQzdCLENBQUMsQ0FBQTtBQUdELE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxHQUFHLEVBQUU7SUFDeEIsbUJBQW1CLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxFQUFFLGtCQUFrQixDQUFDLENBQUE7SUFDMUQsbUJBQW1CLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLCtCQUErQixDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQzlGLE9BQU8sRUFBRSxDQUFBO0FBQ1gsQ0FBQyxDQUFBO0FBRUQsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLEdBQUcsRUFBRTtJQUMxQixLQUFLLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDbkQsT0FBTyxDQUFDLGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFBO0FBQ3BELENBQUMsQ0FBQSJ9 \ No newline at end of file diff --git a/packages/kbot/dist-in/zod_types.d.ts b/packages/kbot/dist-in/zod_types.d.ts index 6fc0d2a4..db6b0d21 100644 --- a/packages/kbot/dist-in/zod_types.d.ts +++ b/packages/kbot/dist-in/zod_types.d.ts @@ -427,6 +427,6 @@ export interface IKBotOptions { filters?: (string | ("JSON" | "JSONUnescape" | "JSONPretty" | "AlphaSort" | "code" | "JSONParse" | "trim")[] | string[] | ((...args_0: unknown[]) => unknown)[]); /** Dry run - only write out parameters without making API calls */ dry?: (boolean | string); - /** Zod schema for structured outputs */ - format?: any; + /** Zod schema for structured outputs. Can be a Zod schema, a JSON schema string, or a path to a JSON file. */ + format?: (string | undefined) | undefined; } diff --git a/packages/kbot/package-lock.json b/packages/kbot/package-lock.json index 6a394076..569962b6 100644 --- a/packages/kbot/package-lock.json +++ b/packages/kbot/package-lock.json @@ -20,6 +20,7 @@ "emojilib": "4.0.1", "env-var": "7.5.0", "glob": "11.0.1", + "json-schema-to-zod": "2.6.0", "marked": "14.1.4", "marked-terminal": "7.2.1", "mime-types": "2.1.35", @@ -4342,6 +4343,15 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-to-zod": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/json-schema-to-zod/-/json-schema-to-zod-2.6.0.tgz", + "integrity": "sha512-6sFZqOzHZeON8g2ZW5HJ114Hb/FffNCjWh8dgulJaKFkUqKCEWZAzF4+g07SQpfBZF7HXemwedtdLypZzmnVpQ==", + "license": "ISC", + "bin": { + "json-schema-to-zod": "dist/cjs/cli.js" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", diff --git a/packages/kbot/package.json b/packages/kbot/package.json index eea2c0f6..b2efc6c1 100644 --- a/packages/kbot/package.json +++ b/packages/kbot/package.json @@ -39,6 +39,7 @@ "emojilib": "4.0.1", "env-var": "7.5.0", "glob": "11.0.1", + "json-schema-to-zod": "2.6.0", "marked": "14.1.4", "marked-terminal": "7.2.1", "mime-types": "2.1.35", diff --git a/packages/kbot/schema.json b/packages/kbot/schema.json index 4273401e..c2befbe4 100644 --- a/packages/kbot/schema.json +++ b/packages/kbot/schema.json @@ -188,8 +188,8 @@ "description": "Dry run - only write out parameters without making API calls" }, "format": { - "default": null, - "description": "Zod schema for structured outputs" + "type": "string", + "description": "Zod schema for structured outputs. Can be a Zod schema, a JSON schema string, or a path to a JSON file." } }, "additionalProperties": true, diff --git a/packages/kbot/schema_ui.json b/packages/kbot/schema_ui.json index 9a1ba94c..2d4c4d88 100644 --- a/packages/kbot/schema_ui.json +++ b/packages/kbot/schema_ui.json @@ -127,8 +127,7 @@ "ui:placeholder": false }, "format": { - "ui:description": "Zod schema for structured outputs", - "ui:title": "Format", - "ui:placeholder": null + "ui:description": "Zod schema for structured outputs. Can be a Zod schema, a JSON schema string, or a path to a JSON file.", + "ui:title": "Format" } } \ No newline at end of file diff --git a/packages/kbot/src/commands/run-completion.ts b/packages/kbot/src/commands/run-completion.ts index 166c0c69..51ca7f71 100644 --- a/packages/kbot/src/commands/run-completion.ts +++ b/packages/kbot/src/commands/run-completion.ts @@ -11,7 +11,7 @@ import { logger } from '../index.js' import { dumpAsScript } from '../utils/script.js' import { applyFilters, Filter } from '../filters.js' import { variables } from '../variables.js' - +import { ResponseFormatJSONSchema } from 'openai/resources/shared.js' export const onCompletion = async (result: any = "", options: IKBotTask) => { result = applyFilters(result, options.filters as Filter[] || []) @@ -44,6 +44,7 @@ export const runCompletion = async (client: OpenAI, params: any, options: IKBotT const completion = await client.chat.completions.create({ model: options.model, messages: params.messages, + response_format: options.format as any, }) let result = completion.choices[0].message.content result = await onCompletion(result, options) diff --git a/packages/kbot/src/zod_schema.ts b/packages/kbot/src/zod_schema.ts index 238fd6fb..da3af02d 100644 --- a/packages/kbot/src/zod_schema.ts +++ b/packages/kbot/src/zod_schema.ts @@ -5,6 +5,7 @@ import env from 'env-var' import { generate_interfaces, ZodMetaMap, resolve, write } from '@polymech/commons' import { sync as exists } from '@polymech/fs/exists' import { sync as writeFS } from '@polymech/fs/write' +import { sync as readFS } from '@polymech/fs/read' import { isArray, isFunction, isString } from '@polymech/core/primitives' import { zodResponseFormat } from "openai/helpers/zod" @@ -13,7 +14,7 @@ import { API_PREFIX, LOGGING_DIRECTORY, PREFERENCES_FILE_NAME } from './constant export const get_var = (key: string = '') => env.get(key).asString() || env.get(key.replace(/-/g, '_')).asString() || env.get(key.replace(/_/g, '-')).asString() export const HOME = (sub = '') => path.join(process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'] || '', sub) export const PREFERENCES_DEFAULT = (key: string = 'KBOT_PREFERENCES') => get_var(key) || path.join(HOME(`.${API_PREFIX}`), PREFERENCES_FILE_NAME) - +import { jsonSchemaToZod } from "json-schema-to-zod" import { Filters } from './filters.js' import { models_dist } from './models/index.js' import { defaultTemplate } from './tools.js' @@ -227,11 +228,11 @@ export const OptionsSchema = (opts?: any): any => { It unwraps by default any code or data in Markdown. Choices:\n\t${Object.keys(Filters)}\n`) .transform((val) => { - if(isArray(val) && val.length && isFunction(val[0])){ + if (isArray(val) && val.length && isFunction(val[0])) { return val } let filters = isString(val) ? val.split(',') : val - filters = filters.map((f: any) => Filters[f]).filter(Boolean) + filters = filters.map((f: any) => Filters[f]).filter(Boolean) return filters }) ) @@ -247,11 +248,27 @@ export const OptionsSchema = (opts?: any): any => { ) .add( 'format', - z.any() + z.string().optional().transform((val) => { + try { + let schema; + // Check if the string is a file path + if (exists(val) && val.endsWith('.json')) { + const content = readFS(val); + schema = JSON.parse(content.toString()); + } else { + schema = JSON.parse(val); + } + const zodSchemaStr = jsonSchemaToZod(schema); + // Evaluate the string to get the actual Zod schema + const zodSchema = eval(`(${zodSchemaStr})`); + return zodResponseFormat(zodSchema, "format"); + } catch (e) { + console.error(`Error parsing format: ${e}`) + return null; + } + }) .optional() - .default(null) - .describe('Zod schema for structured outputs') - .transform((val) => val ? zodResponseFormat(val, "format") : null) + .describe('Zod schema for structured outputs. Can be a Zod schema, a JSON schema string, or a path to a JSON file.') ); return schemaMap.root() .passthrough() diff --git a/packages/kbot/src/zod_types.ts b/packages/kbot/src/zod_types.ts index 323954c5..c5d922a1 100644 --- a/packages/kbot/src/zod_types.ts +++ b/packages/kbot/src/zod_types.ts @@ -427,6 +427,6 @@ export interface IKBotOptions { filters?: (string | ("JSON" | "JSONUnescape" | "JSONPretty" | "AlphaSort" | "code" | "JSONParse" | "trim")[] | string[] | ((...args_0: unknown[]) => unknown)[]); /** Dry run - only write out parameters without making API calls */ dry?: (boolean | string); - /** Zod schema for structured outputs */ - format?: any; + /** Zod schema for structured outputs. Can be a Zod schema, a JSON schema string, or a path to a JSON file. */ + format?: (string | undefined) | undefined; } \ No newline at end of file diff --git a/packages/kbot/tests/response-format/africa-countries.json b/packages/kbot/tests/response-format/africa-countries.json new file mode 100644 index 00000000..9f44a968 --- /dev/null +++ b/packages/kbot/tests/response-format/africa-countries.json @@ -0,0 +1,84 @@ +{ + "cities": [ + { + "name": "Lagos", + "country": "Nigeria", + "population": 14779000 + }, + { + "name": "Cairo", + "country": "Egypt", + "population": 20484965 + }, + { + "name": "Kinshasa", + "country": "Democratic Republic of the Congo", + "population": 15075000 + }, + { + "name": "Johannesburg", + "country": "South Africa", + "population": 9574417 + }, + { + "name": "Nairobi", + "country": "Kenya", + "population": 5545000 + }, + { + "name": "Luanda", + "country": "Angola", + "population": 8200000 + }, + { + "name": "Addis Ababa", + "country": "Ethiopia", + "population": 4942826 + }, + { + "name": "Khartoum", + "country": "Sudan", + "population": 6400000 + }, + { + "name": "Dar es Salaam", + "country": "Tanzania", + "population": 6936403 + }, + { + "name": "Accra", + "country": "Ghana", + "population": 4540000 + }, + { + "name": "Algiers", + "country": "Algeria", + "population": 3415811 + }, + { + "name": "Casablanca", + "country": "Morocco", + "population": 3500000 + }, + { + "name": "Abidjan", + "country": "Ivory Coast", + "population": 5040000 + }, + { + "name": "Dakar", + "country": "Senegal", + "population": 3483664 + }, + { + "name": "Tunis", + "country": "Tunisia", + "population": 2750330 + }, + { + "name": "Douala", + "country": "Cameroon", + "population": 4050687 + } + ] +} \ No newline at end of file diff --git a/packages/kbot/tests/response-format/africa-countries.md b/packages/kbot/tests/response-format/africa-countries.md new file mode 100644 index 00000000..6a7387ef --- /dev/null +++ b/packages/kbot/tests/response-format/africa-countries.md @@ -0,0 +1,66 @@ +# African Countries List + +Here is a comprehensive list of African countries in alphabetical order: + +1. Algeria +2. Angola +3. Benin +4. Botswana +5. Burkina Faso +6. Burundi +7. Cameroon +8. Cape Verde +9. Central African Republic +10. Chad +11. Comoros +12. Congo +13. Democratic Republic of the Congo +14. Djibouti +15. Egypt +16. Equatorial Guinea +17. Eritrea +18. Ethiopia +19. Gabon +20. Gambia +21. Ghana +22. Guinea +23. Guinea-Bissau +24. Ivory Coast +25. Kenya +26. Lesotho +27. Liberia +28. Libya +29. Madagascar +30. Malawi +31. Mali +32. Mauritania +33. Mauritius +34. Morocco +35. Mozambique +36. Namibia +37. Niger +38. Nigeria +39. Rwanda +40. Sao Tome and Principe +41. Senegal +42. Seychelles +43. Sierra Leone +44. Somalia +45. South Africa +46. South Sudan +47. Sudan +48. Swaziland (Eswatini) +49. Tanzania +50. Togo +51. Tunisia +52. Uganda +53. Zambia +54. Zimbabwe + +Source: [United Nations - Member States](https://www.un.org/en/about-us/member-states) + +--- +Prompt: 'return a list of african countries' + +Kind regards, +Guenter \ No newline at end of file diff --git a/packages/kbot/tests/response-format/countries.json b/packages/kbot/tests/response-format/countries.json new file mode 100644 index 00000000..062caf87 --- /dev/null +++ b/packages/kbot/tests/response-format/countries.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://example.com/cities.schema.json", + "title": "Cities Wrapper", + "description": "An object containing a list of cities (without coordinates).", + "type": "object", + "properties": { + "cities": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "City name." + }, + "country": { + "type": "string", + "description": "Country where the city is located." + }, + "population": { + "type": "integer", + "description": "Total population of the city." + } + }, + "required": ["name", "country"] + } + } + }, + "required": ["cities"] +}