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

e5ae782705ee392bede099d3155931bde552d6b1

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
2 files changed, +16 -4Ignore whitespace
public/script.js+15 -4
@@ -3929,7 +3929,7 @@ export function createRawPrompt(prompt, api, instructOverride, quietToLoud, syst
3929 * @prop {number} [responseLength] Maximum response length. If unset, the global default value is used.3929 * @prop {number} [responseLength] Maximum response length. If unset, the global default value is used.
3930 * @prop {boolean} [trimNames] Whether to allow trimming "{{user}}:" and "{{char}}:" from the response.3930 * @prop {boolean} [trimNames] Whether to allow trimming "{{user}}:" and "{{char}}:" from the response.
3931 * @prop {string} [prefill] An optional prefill for the prompt.3931 * @prop {string} [prefill] An optional prefill for the prompt.
3932 * @prop {object} [jsonSchema] JSON schema to use for the structured generation. Usually requires a special instruction.3932 * @prop {JsonSchema} [jsonSchema] JSON schema to use for the structured generation. Usually requires a special instruction.
3933 */3933 */
39343934
3935/**3935/**
@@ -4041,7 +4041,7 @@ export async function generateRawData({ prompt = '', api = null, instructOverrid
4041 }4041 }
40424042
4043 if (jsonSchema) {4043 if (jsonSchema) {
4044 return extractJsonFromData(data, { mainApi: api });4044 return extractJsonFromData(data, { mainApi: api, returnInvalidJson: jsonSchema.returnInvalid });
4045 }4045 }
40464046
4047 return data;4047 return data;
@@ -4204,6 +4204,7 @@ function removeLastMessage() {
4204 * @property {object} value JSON schema value.4204 * @property {object} value JSON schema value.
4205 * @property {string} [description] Description of the schema.4205 * @property {string} [description] Description of the schema.
4206 * @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.4206 * @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.
4207 * @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.
4207 *4208 *
4208 * @typedef {object} GenerateOptions4209 * @typedef {object} GenerateOptions
4209 * @property {boolean} [automatic_trigger] If the generation was triggered automatically (e.g. group auto mode).4210 * @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
54195420
5420 if (jsonSchema) {5421 if (jsonSchema) {
5421 unblockGeneration(type);5422 unblockGeneration(type);
5422 return extractJsonFromData(data);5423 return extractJsonFromData(data, { returnInvalidJson: jsonSchema.returnInvalid ?? false });
5423 }5424 }
54245425
5425 //const getData = await response.json();5426 //const getData = await response.json();
@@ -6242,9 +6243,13 @@ export function extractMessageFromData(data, activeApi = null) {
6242/**6243/**
6243 * Extracts JSON from the response data.6244 * Extracts JSON from the response data.
6244 * @param {object} data Response data6245 * @param {object} data Response data
6246 * @param {object} [options] Extraction options
6247 * @param {string} [options.mainApi] Main API to use
6248 * @param {string} [options.chatCompletionSource] Chat completion source
6249 * @param {boolean} [options.returnInvalidJson=false] Whether to return the raw JSON string even if it fails to parse
6245 * @returns {string} Extracted JSON string from the response data6250 * @returns {string} Extracted JSON string from the response data
6246 */6251 */
6247export function extractJsonFromData(data, { mainApi = null, chatCompletionSource = null } = {}) {6252export function extractJsonFromData(data, { mainApi = null, chatCompletionSource = null, returnInvalidJson = false } = {}) {
6248 mainApi = mainApi ?? main_api;6253 mainApi = mainApi ?? main_api;
6249 chatCompletionSource = chatCompletionSource ?? oai_settings.chat_completion_source;6254 chatCompletionSource = chatCompletionSource ?? oai_settings.chat_completion_source;
62506255
@@ -6267,6 +6272,9 @@ export function extractJsonFromData(data, { mainApi = null, chatCompletionSource
6267 break;6272 break;
6268 case chat_completion_sources.PERPLEXITY:6273 case chat_completion_sources.PERPLEXITY:
6269 result = tryParse(removeReasoningFromString(text));6274 result = tryParse(removeReasoningFromString(text));
6275 if (!result && returnInvalidJson) {
6276 return text;
6277 }
6270 break;6278 break;
6271 case chat_completion_sources.VERTEXAI:6279 case chat_completion_sources.VERTEXAI:
6272 case chat_completion_sources.MAKERSUITE:6280 case chat_completion_sources.MAKERSUITE:
@@ -6287,6 +6295,9 @@ export function extractJsonFromData(data, { mainApi = null, chatCompletionSource
6287 case chat_completion_sources.ZAI:6295 case chat_completion_sources.ZAI:
6288 default:6296 default:
6289 result = tryParse(text);6297 result = tryParse(text);
6298 if (!result && returnInvalidJson) {
6299 return text;
6300 }
6290 break;6301 break;
6291 }6302 }
6292 } break;6303 } break;
public/scripts/custom-request.js+1 -0
@@ -51,6 +51,7 @@ import EventSourceStream from './sse-stream.js';
51 * @property {string} [reverse_proxy] - Optional reverse proxy URL51 * @property {string} [reverse_proxy] - Optional reverse proxy URL
52 * @property {string} [proxy_password] - Optional proxy password52 * @property {string} [proxy_password] - Optional proxy password
53 * @property {string} [custom_prompt_post_processing] - Optional custom prompt post-processing53 * @property {string} [custom_prompt_post_processing] - Optional custom prompt post-processing
54 * @property {import('../script.js').JsonSchema} [json_schema] - Optional JSON schema for structured generation
54 */55 */
5556
56/** @typedef {Record<string, any> & ChatCompletionPayloadBase} ChatCompletionPayload */57/** @typedef {Record<string, any> & ChatCompletionPayloadBase} ChatCompletionPayload */