pi-ocr 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +394 -0
- package/extensions/index.ts +434 -0
- package/extensions/mineru.ts +276 -0
- package/extensions/ollama.ts +226 -0
- package/extensions/pix2text.ts +189 -0
- package/extensions/types.ts +27 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dlrow
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# pi-ocr
|
|
2
|
+
|
|
3
|
+
> ### ⚡ Zero setup. Works out of the box.
|
|
4
|
+
>
|
|
5
|
+
> Default backend: **MinerU** — a free cloud API. No install, no GPU, no API key.
|
|
6
|
+
> Just `pi install npm:pi-ocr` and OCR anything.
|
|
7
|
+
|
|
8
|
+
Multi-backend OCR for [Pi Coding Agent](https://pi.dev) — extract text, LaTeX math formulas, and tables from images and PDFs. Choose the backend that fits your needs: free cloud API, local GPU, or pure Python.
|
|
9
|
+
|
|
10
|
+
> Bridges the multimodal gap for non-vision LLMs like **DeepSeek**. When your model can't see images, `minimodel_ocr` acts as its eyes.
|
|
11
|
+
|
|
12
|
+
## Three Backends — One Tool
|
|
13
|
+
|
|
14
|
+
| Backend | Type | Best For |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| 🦙 **Ollama** | Local GPU | Math formulas (LaTeX), privacy, offline |
|
|
17
|
+
| ☁️ **MinerU** | Free cloud API | Complex PDFs, no GPU, zero setup |
|
|
18
|
+
| 📐 **Pix2Text** | Local Python | Math formulas + text, free Mathpix alternative |
|
|
19
|
+
|
|
20
|
+
Switch anytime with `/ocr` (no args) — a visual `SettingsList` menu lets you pick and configure everything without editing JSON:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
/ocr → opens settings: backend, model, PDF split toggle
|
|
24
|
+
/ocr <file> [task] → OCR a file
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
| | |
|
|
30
|
+
|---|---|
|
|
31
|
+
| 🔤 **Text** | General text recognition → Markdown |
|
|
32
|
+
| 🧮 **Formulas** | Math formulas → LaTeX (Ollama glm-ocr: 94.6 OmniDocBench) |
|
|
33
|
+
| 📊 **Tables** | Table structure → Markdown tables |
|
|
34
|
+
| 🖼️ **Figures** | Diagrams and illustrations → descriptions |
|
|
35
|
+
| 📄 **PDF** | Full PDF support across all backends |
|
|
36
|
+
| 🎛️ **Any model** | Ollama works with glm-ocr, llama3.2-vision, minicpm-v, etc. |
|
|
37
|
+
| ☁️ **Free cloud** | MinerU Agent API: no token, ≤10MB, ≤20 pages free |
|
|
38
|
+
| 📦 **Auto-split** | MinerU splits PDFs >20 pages into free-tier chunks |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Quickstart
|
|
43
|
+
|
|
44
|
+
### One command
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pi install npm:pi-ocr
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**That's it.** The default backend is ☁️ **MinerU** — a free cloud API with zero setup.
|
|
51
|
+
Start OCR'ing immediately:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
/ocr ./scan.png
|
|
55
|
+
/ocr ./document.pdf
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
> 💡 Want offline OCR or math formulas? Switch backends anytime with `/ocr` (no args).
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
### Optional: set up other backends
|
|
63
|
+
|
|
64
|
+
Only needed if you want to switch from the default MinerU.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### 🦙 Ollama setup
|
|
69
|
+
|
|
70
|
+
#### macOS
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# 1. Install Ollama
|
|
74
|
+
brew install ollama
|
|
75
|
+
|
|
76
|
+
# 2. Pull the default OCR model (~2.2 GB)
|
|
77
|
+
ollama pull glm-ocr
|
|
78
|
+
|
|
79
|
+
# 3. Multi-page PDF support (optional but recommended)
|
|
80
|
+
brew install poppler
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
> macOS uses built-in `sips` for single-page PDFs — zero extra deps for those.
|
|
84
|
+
> Multi-page PDFs need `poppler` for the `pdftoppm` tool.
|
|
85
|
+
|
|
86
|
+
#### Linux
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# 1. Install Ollama
|
|
90
|
+
curl -fsSL https://ollama.com/install.sh | sh
|
|
91
|
+
|
|
92
|
+
# 2. Pull the default OCR model (~2.2 GB)
|
|
93
|
+
ollama pull glm-ocr
|
|
94
|
+
|
|
95
|
+
# 3. PDF support (required on Linux)
|
|
96
|
+
sudo apt install poppler-utils # Debian/Ubuntu
|
|
97
|
+
sudo dnf install poppler-utils # Fedora
|
|
98
|
+
sudo pacman -S poppler # Arch
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### Verify
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Check Ollama is running and model is pulled
|
|
105
|
+
ollama list | grep glm-ocr
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
### 📐 Pix2Text setup
|
|
111
|
+
|
|
112
|
+
Pix2Text runs entirely in Python. Handles images and PDFs via a single API call — no manual conversion needed.
|
|
113
|
+
|
|
114
|
+
#### Step 1: Make sure you have Python 3.9+ (macOS/Linux)
|
|
115
|
+
|
|
116
|
+
| System | Check |
|
|
117
|
+
|---|---|
|
|
118
|
+
| macOS/Linux | `python3 --version` |
|
|
119
|
+
|
|
120
|
+
> ⚠️ **Important:** Know which Python you're using. Run `which python3` — if it shows `conda`, `brew`, or `/usr/bin/python3`, your `pip install` must target the same Python:
|
|
121
|
+
> ```bash
|
|
122
|
+
> # Conda Python
|
|
123
|
+
> pip install pix2text
|
|
124
|
+
>
|
|
125
|
+
> # System Python (may need --user or sudo)
|
|
126
|
+
> pip install --user pix2text
|
|
127
|
+
>
|
|
128
|
+
> # Brew Python (macOS)
|
|
129
|
+
> /opt/homebrew/bin/pip3 install pix2text
|
|
130
|
+
> ```
|
|
131
|
+
> If unsure, use `python3 -m pip install ...` — this always installs for the active `python3`.
|
|
132
|
+
|
|
133
|
+
#### Step 2: Install packages
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
python3 -m pip install pix2text
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### Step 3: Verify
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
python3 -c "from pix2text import Pix2Text; print('OK')"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
> First run downloads ONNX models (~50MB) to `~/.pix2text/`.
|
|
146
|
+
|
|
147
|
+
> First run downloads ONNX models (~50MB) to `~/.pix2text/`.
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### ☁️ MinerU (default — already working!)
|
|
153
|
+
|
|
154
|
+
**No setup required.** The free Agent API works immediately. No token, no account, no install.
|
|
155
|
+
|
|
156
|
+
Free tier limits:
|
|
157
|
+
- ≤ 10 MB per file
|
|
158
|
+
- ≤ 20 pages per request
|
|
159
|
+
- IP-based rate limiting
|
|
160
|
+
|
|
161
|
+
For files >10MB, compress first at [ilovepdf.com/compress_pdf](https://ilovepdf.com/compress_pdf).
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Usage
|
|
166
|
+
|
|
167
|
+
### Settings UI
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
/ocr
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Opens an interactive `SettingsList` with keyboard navigation:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
┌─ OCR Settings ─────────────────────────────────┐
|
|
177
|
+
│ OCR Backend [ollama / mineru / pix2text] │
|
|
178
|
+
│ MinerU: Split PDF [ON / OFF] │
|
|
179
|
+
│ Ollama Model [glm-ocr] │
|
|
180
|
+
│ ↑↓ navigate • ← → toggle • enter select • esc close │
|
|
181
|
+
└──────────────────────────────────────────────────┘
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
- **Backend**: ← → to cycle ollama/mineru/pix2text — saves immediately
|
|
185
|
+
- **MinerU Split**: ← → to toggle ON/OFF — when ON, PDFs >20 pages are auto-split
|
|
186
|
+
- **Model**: Enter opens a sub-menu with recommended models + custom input
|
|
187
|
+
|
|
188
|
+
### OCR a file
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
/ocr <file> [task] [model]
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
| Example | Result |
|
|
195
|
+
|---|---|
|
|
196
|
+
| `/ocr ./scan.png` | Auto-detect all content |
|
|
197
|
+
| `/ocr ./equation.jpg formula` | LaTeX formula output |
|
|
198
|
+
| `/ocr ./contract.pdf text` | Text-only extraction |
|
|
199
|
+
| `/ocr ./paper.pdf auto glm-ocr:q8_0` | Use specific model |
|
|
200
|
+
|
|
201
|
+
### Tasks
|
|
202
|
+
|
|
203
|
+
| Task | Description | Output format |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
| `auto` | Full document OCR (default) | Markdown + LaTeX mixed |
|
|
206
|
+
| `text` | Plain text recognition | Markdown |
|
|
207
|
+
| `formula` | Math formula recognition | LaTeX |
|
|
208
|
+
| `table` | Table structure recognition | Markdown tables |
|
|
209
|
+
| `figure` | Figure / diagram description | Natural language |
|
|
210
|
+
|
|
211
|
+
### LLM-invoked (automatic)
|
|
212
|
+
|
|
213
|
+
The extension registers a `minimodel_ocr` tool. The agent invokes it automatically:
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
> What formula is written in this screenshot?
|
|
217
|
+
> OCR this 50-page PDF into markdown.
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## MinerU PDF Splitting
|
|
223
|
+
|
|
224
|
+
When `MinerU: Split PDF >20 pages` is ON (default), large PDFs are automatically split into ≤20-page chunks. Each chunk is a separate request with 3s spacing:
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
Splitting 85-page PDF into ≤20-page chunks…
|
|
228
|
+
[1/5] uploading…
|
|
229
|
+
[1/5] running (12s)
|
|
230
|
+
[1/5] done
|
|
231
|
+
[2/5] waiting rate limit…
|
|
232
|
+
[2/5] uploading…
|
|
233
|
+
[2/5] running (18s)
|
|
234
|
+
[2/5] done
|
|
235
|
+
...
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Backend Comparison
|
|
241
|
+
|
|
242
|
+
| | 🦙 Ollama | ☁️ MinerU | 📐 **Pix2Text** |
|
|
243
|
+
|---|---|---|---|
|
|
244
|
+
| **Setup** | Install Ollama + pull model | None | `pip install` 3 packages |
|
|
245
|
+
| **GPU needed** | Recommended | No | No |
|
|
246
|
+
| **Internet** | No | Yes | No (first run: yes) |
|
|
247
|
+
| **Math formulas** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐ |
|
|
248
|
+
| **Complex PDFs** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
|
|
249
|
+
| **Chinese text** | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
|
|
250
|
+
| **File size limit** | None | 10MB (free) | None |
|
|
251
|
+
| **Page limit** | None | 20/request (free) | None |
|
|
252
|
+
| **Cost** | Free (local) | Free (rate-limited) | Free (local) |
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Supported File Types
|
|
257
|
+
|
|
258
|
+
| Format | Ollama | MinerU | Pix2Text |
|
|
259
|
+
|---|---|---|---|
|
|
260
|
+
| PNG, JPG, GIF, WEBP, BMP, TIFF | ✅ | ✅ | ✅ |
|
|
261
|
+
| PDF | ✅ | ✅ | ✅ |
|
|
262
|
+
| Docx, PPTx, Xlsx | ❌ | ✅ | ❌ |
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## PDF Support Details
|
|
267
|
+
|
|
268
|
+
| Backend | Conversion method | System deps |
|
|
269
|
+
|---|---|---|
|
|
270
|
+
| **Ollama** | `sips` (macOS page 1) / `pdftoppm` (multi-page, Linux) | `poppler` (multi-page only) |
|
|
271
|
+
| **MinerU** | Direct PDF upload — no conversion | None |
|
|
272
|
+
| **Pix2Text** | Built-in `recognize_pdf()` — no system deps | None |
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Configuration
|
|
277
|
+
|
|
278
|
+
All settings are persisted to `~/.pi/agent/settings.json`:
|
|
279
|
+
|
|
280
|
+
```json
|
|
281
|
+
{
|
|
282
|
+
"minimodelOcr": {
|
|
283
|
+
"backend": "ollama",
|
|
284
|
+
"model": "glm-ocr",
|
|
285
|
+
"ollamaHost": "http://localhost:11434",
|
|
286
|
+
"mineruSplitPdf": true
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Change settings via `/ocr` (interactive) or edit directly. Environment variables override file settings:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
export OLLAMA_HOST="http://localhost:11434"
|
|
295
|
+
export OCR_MODEL="glm-ocr"
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Troubleshooting
|
|
301
|
+
|
|
302
|
+
### Ollama: "fetch failed" / "ECONNREFUSED"
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
# Start Ollama in the background
|
|
306
|
+
ollama serve
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Ollama: "model not found"
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
ollama pull glm-ocr
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Pix2Text: "python3 not found"
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# Check your python:
|
|
319
|
+
which python3 && python3 --version
|
|
320
|
+
|
|
321
|
+
# If using conda:
|
|
322
|
+
conda activate base && pip install pix2text
|
|
323
|
+
|
|
324
|
+
# If using system python:
|
|
325
|
+
python3 -m pip install --user pix2text
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Pix2Text: "No module named 'pix2text'"
|
|
329
|
+
|
|
330
|
+
You likely installed with a different `pip` than your active `python3`:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
python3 -m pip install pix2text
|
|
334
|
+
```
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### MinerU: "429 Too Many Requests"
|
|
338
|
+
|
|
339
|
+
IP rate limit hit. Wait 1-2 minutes, or switch to Ollama/Pix2Text with `/ocr`.
|
|
340
|
+
|
|
341
|
+
### MinerU: "file page count exceeds lightweight API limit"
|
|
342
|
+
|
|
343
|
+
Enable PDF splitting: `/ocr` → toggle "MinerU: Split PDF" to ON.
|
|
344
|
+
|
|
345
|
+
### MinerU: "File too large for free MinerU API"
|
|
346
|
+
|
|
347
|
+
Compress the PDF at [ilovepdf.com/compress_pdf](https://ilovepdf.com/compress_pdf) or switch to a local backend with `/ocr`.
|
|
348
|
+
|
|
349
|
+
### macOS multi-page PDF: "pdftoppm not found"
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
brew install poppler
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Linux multi-page PDF: "pdftoppm not found"
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
# Debian/Ubuntu
|
|
359
|
+
sudo apt install poppler-utils
|
|
360
|
+
|
|
361
|
+
# Fedora
|
|
362
|
+
sudo dnf install poppler-utils
|
|
363
|
+
|
|
364
|
+
# Arch
|
|
365
|
+
sudo pacman -S poppler
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## How It Works
|
|
371
|
+
|
|
372
|
+
```
|
|
373
|
+
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────────┐
|
|
374
|
+
│ pi (DeepSeek) │────▶│ minimodel_ocr │────▶│ Ollama / MinerU │
|
|
375
|
+
│ (no vision) │ │ pi extension │ │ / Pix2Text │
|
|
376
|
+
└──────────────────┘ └──────────────────┘ └──────────────────────┘
|
|
377
|
+
│ │ │
|
|
378
|
+
│ "read this image" │ POST /api/generate │
|
|
379
|
+
│────────────────────────▶│ (Ollama) │
|
|
380
|
+
│ │ or POST /api/v1/agent │
|
|
381
|
+
│ │ (MinerU) │
|
|
382
|
+
│ │ or python3 subprocess │
|
|
383
|
+
│ │ (Pix2Text) │
|
|
384
|
+
│ │──────────────────────────▶│
|
|
385
|
+
│ │ OCR text response │
|
|
386
|
+
│ LaTeX / Markdown │◀──────────────────────────│
|
|
387
|
+
│◀────────────────────────│ │
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
The tool dispatches to your selected backend. Switch anytime with `/ocr` — no restart needed.
|
|
391
|
+
|
|
392
|
+
## License
|
|
393
|
+
|
|
394
|
+
MIT
|