From e5ae782705ee392bede099d3155931bde552d6b1 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 2 May 2026 18:31:06 +0300 Subject: [PATCH] Add option to return malformed JSON string from extractJsonFromData (#5578) * feat: add option to return malformed JSON string from extractJsonFromData Fixes #5569 * fix: add fallback for Perplexity case --- public/script.js | 19 +++++++++++++++---- public/scripts/custom-request.js | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/public/script.js b/public/script.js index f3c51e9db..68a546111 100644 --- a/public/script.js +++ b/public/script.js @@ -3929,7 +3929,7 @@ export function createRawPrompt(prompt, api, instructOverride, quietToLoud, syst * @prop {number} [responseLength] Maximum response length. If unset, the global default value is used. * @prop {boolean} [trimNames] Whether to allow trimming "{{user}}:" and "{{char}}:" from the response. * @prop {string} [prefill] An optional prefill for the prompt. - * @prop {object} [jsonSchema] JSON schema to use for the structured generation. Usually requires a special instruction. + * @prop {JsonSchema} [jsonSchema] JSON schema to use for the structured generation. Usually requires a special instruction. */ /** @@ -4041,7 +4041,7 @@ export async function generateRawData({ prompt = '', api = null, instructOverrid } if (jsonSchema) { - return extractJsonFromData(data, { mainApi: api }); + return extractJsonFromData(data, { mainApi: api, returnInvalidJson: jsonSchema.returnInvalid }); } return data; @@ -4204,6 +4204,7 @@ function removeLastMessage() { * @property {object} value JSON schema value. * @property {string} [description] Description of the schema. * @property {boolean} [strict] If true, the schema will be used in strict mode, meaning that only the fields defined in the schema will be allowed. + * @property {boolean} [returnInvalid] If true, a string that can't be parsed as a JSON will be returned as is, instead of an empty object. * * @typedef {object} GenerateOptions * @property {boolean} [automatic_trigger] If the generation was triggered automatically (e.g. group auto mode). @@ -5419,7 +5420,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro if (jsonSchema) { unblockGeneration(type); - return extractJsonFromData(data); + return extractJsonFromData(data, { returnInvalidJson: jsonSchema.returnInvalid ?? false }); } //const getData = await response.json(); @@ -6242,9 +6243,13 @@ export function extractMessageFromData(data, activeApi = null) { /** * Extracts JSON from the response data. * @param {object} data Response data + * @param {object} [options] Extraction options + * @param {string} [options.mainApi] Main API to use + * @param {string} [options.chatCompletionSource] Chat completion source + * @param {boolean} [options.returnInvalidJson=false] Whether to return the raw JSON string even if it fails to parse * @returns {string} Extracted JSON string from the response data */ -export function extractJsonFromData(data, { mainApi = null, chatCompletionSource = null } = {}) { +export function extractJsonFromData(data, { mainApi = null, chatCompletionSource = null, returnInvalidJson = false } = {}) { mainApi = mainApi ?? main_api; chatCompletionSource = chatCompletionSource ?? oai_settings.chat_completion_source; @@ -6267,6 +6272,9 @@ export function extractJsonFromData(data, { mainApi = null, chatCompletionSource break; case chat_completion_sources.PERPLEXITY: result = tryParse(removeReasoningFromString(text)); + if (!result && returnInvalidJson) { + return text; + } break; case chat_completion_sources.VERTEXAI: case chat_completion_sources.MAKERSUITE: @@ -6287,6 +6295,9 @@ export function extractJsonFromData(data, { mainApi = null, chatCompletionSource case chat_completion_sources.ZAI: default: result = tryParse(text); + if (!result && returnInvalidJson) { + return text; + } break; } } break; diff --git a/public/scripts/custom-request.js b/public/scripts/custom-request.js index 82fbce6db..e40bff169 100644 --- a/public/scripts/custom-request.js +++ b/public/scripts/custom-request.js @@ -51,6 +51,7 @@ import EventSourceStream from './sse-stream.js'; * @property {string} [reverse_proxy] - Optional reverse proxy URL * @property {string} [proxy_password] - Optional proxy password * @property {string} [custom_prompt_post_processing] - Optional custom prompt post-processing + * @property {import('../script.js').JsonSchema} [json_schema] - Optional JSON schema for structured generation */ /** @typedef {Record & ChatCompletionPayloadBase} ChatCompletionPayload */