From 0db87778c44b1169d607210991ee6cacacf06590 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Wed, 4 Feb 2026 15:48:21 -0800 Subject: [PATCH] fix(mistral): restore mistral configs for v2 version --- apps/sim/blocks/blocks/mistral_parse.ts | 145 +++++++++++++++++++++++- apps/sim/blocks/registry.ts | 7 +- apps/sim/tools/mistral/index.ts | 4 +- apps/sim/tools/mistral/parser.ts | 136 ++++++++++++---------- apps/sim/tools/registry.ts | 3 +- 5 files changed, 222 insertions(+), 73 deletions(-) diff --git a/apps/sim/blocks/blocks/mistral_parse.ts b/apps/sim/blocks/blocks/mistral_parse.ts index 424f65b8a..b78630ed9 100644 --- a/apps/sim/blocks/blocks/mistral_parse.ts +++ b/apps/sim/blocks/blocks/mistral_parse.ts @@ -143,11 +143,147 @@ export const MistralParseBlock: BlockConfig = { }, } +/** + * V2 Block - Restored from main branch for backwards compatibility + * Hidden from toolbar, uses filePath subblock ID for advanced mode + */ export const MistralParseV2Block: BlockConfig = { ...MistralParseBlock, type: 'mistral_parse_v2', name: 'Mistral Parser', description: 'Extract text from PDF documents', + hideFromToolbar: true, + subBlocks: [ + { + id: 'fileUpload', + title: 'PDF Document', + type: 'file-upload' as SubBlockType, + canonicalParamId: 'document', + acceptedTypes: 'application/pdf', + placeholder: 'Upload a PDF document', + mode: 'basic', + maxSize: 50, + }, + { + id: 'filePath', + title: 'PDF Document', + type: 'short-input' as SubBlockType, + canonicalParamId: 'document', + placeholder: 'Document URL', + mode: 'advanced', + }, + { + id: 'resultType', + title: 'Output Format', + type: 'dropdown', + options: [ + { id: 'markdown', label: 'Markdown' }, + { id: 'text', label: 'Plain Text' }, + { id: 'json', label: 'JSON' }, + ], + }, + { + id: 'pages', + title: 'Specific Pages', + type: 'short-input', + placeholder: 'e.g. 0,1,2 (leave empty for all pages)', + }, + { + id: 'apiKey', + title: 'API Key', + type: 'short-input' as SubBlockType, + placeholder: 'Enter your Mistral API key', + password: true, + required: true, + }, + ], + tools: { + access: ['mistral_parser_v2'], + config: { + tool: createVersionedToolSelector({ + baseToolSelector: () => 'mistral_parser', + suffix: '_v2', + fallbackToolId: 'mistral_parser_v2', + }), + params: (params) => { + if (!params || !params.apiKey || params.apiKey.trim() === '') { + throw new Error('Mistral API key is required') + } + + const parameters: Record = { + apiKey: params.apiKey.trim(), + resultType: params.resultType || 'markdown', + } + + // Original V2 pattern: fileUpload (basic) or filePath (advanced) or document (wired) + const documentInput = params.fileUpload || params.filePath || params.document + if (!documentInput) { + throw new Error('PDF document is required') + } + // Smart handling: object → fileUpload param, string → filePath param + if (typeof documentInput === 'object') { + parameters.fileUpload = documentInput + } else if (typeof documentInput === 'string') { + parameters.filePath = documentInput.trim() + } + + let pagesArray: number[] | undefined + if (params.pages && params.pages.trim() !== '') { + try { + pagesArray = params.pages + .split(',') + .map((p: string) => p.trim()) + .filter((p: string) => p.length > 0) + .map((p: string) => { + const num = Number.parseInt(p, 10) + if (Number.isNaN(num) || num < 0) { + throw new Error(`Invalid page number: ${p}`) + } + return num + }) + + if (pagesArray && pagesArray.length === 0) { + pagesArray = undefined + } + } catch (error: unknown) { + const errorMessage = error instanceof Error ? error.message : String(error) + throw new Error(`Page number format error: ${errorMessage}`) + } + } + + if (pagesArray && pagesArray.length > 0) { + parameters.pages = pagesArray + } + + return parameters + }, + }, + }, + inputs: { + document: { type: 'json', description: 'Document input (file upload or URL reference)' }, + filePath: { type: 'string', description: 'PDF document URL (advanced mode)' }, + fileUpload: { type: 'json', description: 'Uploaded PDF file (basic mode)' }, + apiKey: { type: 'string', description: 'Mistral API key' }, + resultType: { type: 'string', description: 'Output format type' }, + pages: { type: 'string', description: 'Page selection' }, + }, + outputs: { + pages: { type: 'array', description: 'Array of page objects from Mistral OCR' }, + model: { type: 'string', description: 'Mistral OCR model identifier' }, + usage_info: { type: 'json', description: 'Usage statistics from the API' }, + document_annotation: { type: 'string', description: 'Structured annotation data' }, + }, +} + +/** + * V3 Block - New file handling pattern with UserFile normalization + * Uses fileReference subblock ID with canonicalParamId for proper file handling + */ +export const MistralParseV3Block: BlockConfig = { + ...MistralParseBlock, + type: 'mistral_parse_v3', + name: 'Mistral Parser', + description: 'Extract text from PDF documents', hideFromToolbar: false, subBlocks: [ { @@ -196,13 +332,9 @@ export const MistralParseV2Block: BlockConfig = { }, ], tools: { - access: ['mistral_parser_v2'], + access: ['mistral_parser_v3'], config: { - tool: createVersionedToolSelector({ - baseToolSelector: () => 'mistral_parser', - suffix: '_v2', - fallbackToolId: 'mistral_parser_v2', - }), + tool: () => 'mistral_parser_v3', params: (params) => { if (!params || !params.apiKey || params.apiKey.trim() === '') { throw new Error('Mistral API key is required') @@ -213,6 +345,7 @@ export const MistralParseV2Block: BlockConfig = { resultType: params.resultType || 'markdown', } + // V3 pattern: normalize file inputs from basic/advanced modes const documentInput = normalizeFileInput( params.fileUpload || params.fileReference || params.document, { single: true } diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index 933456957..8b6d8ae59 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -79,7 +79,11 @@ import { MemoryBlock } from '@/blocks/blocks/memory' import { MicrosoftExcelBlock, MicrosoftExcelV2Block } from '@/blocks/blocks/microsoft_excel' import { MicrosoftPlannerBlock } from '@/blocks/blocks/microsoft_planner' import { MicrosoftTeamsBlock } from '@/blocks/blocks/microsoft_teams' -import { MistralParseBlock, MistralParseV2Block } from '@/blocks/blocks/mistral_parse' +import { + MistralParseBlock, + MistralParseV2Block, + MistralParseV3Block, +} from '@/blocks/blocks/mistral_parse' import { MongoDBBlock } from '@/blocks/blocks/mongodb' import { MySQLBlock } from '@/blocks/blocks/mysql' import { Neo4jBlock } from '@/blocks/blocks/neo4j' @@ -255,6 +259,7 @@ export const registry: Record = { microsoft_teams: MicrosoftTeamsBlock, mistral_parse: MistralParseBlock, mistral_parse_v2: MistralParseV2Block, + mistral_parse_v3: MistralParseV3Block, mongodb: MongoDBBlock, mysql: MySQLBlock, neo4j: Neo4jBlock, diff --git a/apps/sim/tools/mistral/index.ts b/apps/sim/tools/mistral/index.ts index 566b90f41..67fe05f8d 100644 --- a/apps/sim/tools/mistral/index.ts +++ b/apps/sim/tools/mistral/index.ts @@ -1,3 +1,3 @@ -import { mistralParserTool, mistralParserV2Tool } from '@/tools/mistral/parser' +import { mistralParserTool, mistralParserV2Tool, mistralParserV3Tool } from '@/tools/mistral/parser' -export { mistralParserTool, mistralParserV2Tool } +export { mistralParserTool, mistralParserV2Tool, mistralParserV3Tool } diff --git a/apps/sim/tools/mistral/parser.ts b/apps/sim/tools/mistral/parser.ts index 18bb612c8..44c80dd8a 100644 --- a/apps/sim/tools/mistral/parser.ts +++ b/apps/sim/tools/mistral/parser.ts @@ -349,74 +349,14 @@ export const mistralParserTool: ToolConfig = { +export const mistralParserV2Tool: ToolConfig = { id: 'mistral_parser_v2', name: 'Mistral PDF Parser', description: 'Parse PDF documents using Mistral OCR API', version: '2.0.0', - params: mistralParserV2Params, - request: { - url: '/api/tools/mistral/parse', - method: 'POST', - headers: (params) => { - return { - 'Content-Type': 'application/json', - Accept: 'application/json', - Authorization: `Bearer ${params.apiKey}`, - } - }, - body: (params) => { - if (!params || typeof params !== 'object') { - throw new Error('Invalid parameters: Parameters must be provided as an object') - } - if (!params.apiKey || typeof params.apiKey !== 'string' || params.apiKey.trim() === '') { - throw new Error('Missing or invalid API key: A valid Mistral API key is required') - } - - const file = params.file - if (!file || typeof file !== 'object') { - throw new Error('File input is required') - } - - const requestBody: Record = { - apiKey: params.apiKey, - resultType: params.resultType || 'markdown', - } - - requestBody.file = file - - if (params.pages) { - requestBody.pages = params.pages - } - if (params.includeImageBase64 !== undefined) { - requestBody.includeImageBase64 = params.includeImageBase64 - } - if (params.imageLimit !== undefined) { - requestBody.imageLimit = params.imageLimit - } - if (params.imageMinSize !== undefined) { - requestBody.imageMinSize = params.imageMinSize - } - - return requestBody - }, - }, + params: mistralParserTool.params, + request: mistralParserTool.request, transformResponse: async (response: Response) => { let ocrResult @@ -543,3 +483,73 @@ export const mistralParserV2Tool: ToolConfig = { + ...mistralParserV2Tool, + id: 'mistral_parser_v3', + version: '3.0.0', + params: { + file: { + type: 'file', + required: true, + visibility: 'hidden', + description: 'Normalized UserFile from file upload or file reference', + }, + resultType: mistralParserTool.params.resultType, + includeImageBase64: mistralParserTool.params.includeImageBase64, + pages: mistralParserTool.params.pages, + imageLimit: mistralParserTool.params.imageLimit, + imageMinSize: mistralParserTool.params.imageMinSize, + apiKey: mistralParserTool.params.apiKey, + }, + request: { + url: '/api/tools/mistral/parse', + method: 'POST', + headers: (params) => { + return { + 'Content-Type': 'application/json', + Accept: 'application/json', + Authorization: `Bearer ${params.apiKey}`, + } + }, + body: (params) => { + if (!params || typeof params !== 'object') { + throw new Error('Invalid parameters: Parameters must be provided as an object') + } + if (!params.apiKey || typeof params.apiKey !== 'string' || params.apiKey.trim() === '') { + throw new Error('Missing or invalid API key: A valid Mistral API key is required') + } + + // V3 expects normalized UserFile object via `file` param + const file = params.file + if (!file || typeof file !== 'object') { + throw new Error('File input is required: provide a file upload or file reference') + } + + const requestBody: Record = { + apiKey: params.apiKey, + resultType: params.resultType || 'markdown', + file: file, + } + + if (params.pages) { + requestBody.pages = params.pages + } + if (params.includeImageBase64 !== undefined) { + requestBody.includeImageBase64 = params.includeImageBase64 + } + if (params.imageLimit !== undefined) { + requestBody.imageLimit = params.imageLimit + } + if (params.imageMinSize !== undefined) { + requestBody.imageMinSize = params.imageMinSize + } + + return requestBody + }, + }, +} diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index 7bfb7acf2..67c00265c 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -1093,7 +1093,7 @@ import { microsoftTeamsWriteChannelTool, microsoftTeamsWriteChatTool, } from '@/tools/microsoft_teams' -import { mistralParserTool, mistralParserV2Tool } from '@/tools/mistral' +import { mistralParserTool, mistralParserV2Tool, mistralParserV3Tool } from '@/tools/mistral' import { mongodbDeleteTool, mongodbExecuteTool, @@ -2684,6 +2684,7 @@ export const tools: Record = { apollo_email_accounts: apolloEmailAccountsTool, mistral_parser: mistralParserTool, mistral_parser_v2: mistralParserV2Tool, + mistral_parser_v3: mistralParserV3Tool, reducto_parser: reductoParserTool, reducto_parser_v2: reductoParserV2Tool, textract_parser: textractParserTool,