Class: Mathpix::MCP::Tools::BatchConvertTool
- Defined in:
- lib/mathpix/mcp/tools/batch_convert_tool.rb
Overview
Batch Convert Tool
Converts multiple images in batch for efficiency Thin delegate to Mathpix::Client#snap with batch processing
Class Method Summary collapse
- .call(image_paths:, server_context:, formats: nil, parallel: false, max_parallel: 3, output_dir: nil) ⇒ Object
-
.convert_one(client, path, index, formats, dir) ⇒ Object
Convert a single image, writing its recognized content to a file and returning a result/error hash (never raises).
-
.process_batch_parallel(client, paths, formats, max_parallel, dir) ⇒ Object
Bounded thread pool: at most max_parallel concurrent HTTP requests.
- .process_batch_sequential(client, paths, formats, dir) ⇒ Object
Class Method Details
.call(image_paths:, server_context:, formats: nil, parallel: false, max_parallel: 3, output_dir: nil) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/mathpix/mcp/tools/batch_convert_tool.rb', line 45 def self.call(image_paths:, server_context:, formats: nil, parallel: false, max_parallel: 3, output_dir: nil) safe_execute do client = mathpix_client(server_context) # Extract formats or use defaults output_formats = extract_formats(formats, client) dir = output_dir && !output_dir.empty? ? File.(output_dir) : artifact_dir # Normalize paths normalized_paths = image_paths.map do |path| url?(path) ? path : normalize_path(path) end # Process images (concurrently when requested) results = if parallel process_batch_parallel(client, normalized_paths, output_formats, max_parallel.to_i, dir) else process_batch_sequential(client, normalized_paths, output_formats, dir) end # Format response response_data = { success: true, batch_size: image_paths.length, formats: output_formats, parallel: parallel, results: results, summary: { total: results.length, successful: results.count { |r| r[:success] }, failed: results.count { |r| !r[:success] } } } json_response(response_data) end end |
.convert_one(client, path, index, formats, dir) ⇒ Object
Convert a single image, writing its recognized content to a file and returning a result/error hash (never raises). The OCR text/latex is saved to disk rather than inlined so a large batch can't overflow the model context.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/mathpix/mcp/tools/batch_convert_tool.rb', line 88 def self.convert_one(client, path, index, formats, dir) result = client.snap(path, formats: formats) contents = { 'latex' => result.latex, 'text' => result.text, 'mathml' => result.mathml, 'asciimath' => result.asciimath }.compact stem = url?(path) ? "image_#{index}" : File.basename(path, File.extname(path)) saved = write_artifacts(contents, File.join(dir, "mathpix_#{sanitize(stem)}.tex")) { index: index, image_path: path, success: true, confidence: result.confidence, saved_files: saved, preview: preview_of(result.latex || result.text, 200) } rescue Mathpix::Error => e { index: index, image_path: path, success: false, error: e. } end |
.process_batch_parallel(client, paths, formats, max_parallel, dir) ⇒ Object
Bounded thread pool: at most max_parallel concurrent HTTP requests. Results are written back by original index so ordering is preserved.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/mathpix/mcp/tools/batch_convert_tool.rb', line 121 def self.process_batch_parallel(client, paths, formats, max_parallel, dir) max_parallel = 1 if max_parallel < 1 results = Array.new(paths.length) queue = Queue.new paths.each_with_index { |path, i| queue << [path, i] } worker_count = [max_parallel, paths.length].min workers = Array.new(worker_count) do Thread.new do loop do path, index = begin queue.pop(true) # non-blocking; raises ThreadError when empty rescue ThreadError break end results[index] = convert_one(client, path, index, formats, dir) end end end workers.each(&:join) results end |
.process_batch_sequential(client, paths, formats, dir) ⇒ Object
115 116 117 |
# File 'lib/mathpix/mcp/tools/batch_convert_tool.rb', line 115 def self.process_batch_sequential(client, paths, formats, dir) paths.map.with_index { |path, index| convert_one(client, path, index, formats, dir) } end |