@elizaos/plugin-vision 1.2.1 → 2.0.0-alpha.2

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.
Files changed (106) hide show
  1. package/LICENSE +21 -0
  2. package/build.config.ts +53 -53
  3. package/dist/index.js +6716 -67
  4. package/dist/index.js.map +33 -1
  5. package/dist/workers/florence2-worker.js +111763 -307
  6. package/dist/workers/florence2-worker.js.map +92 -1
  7. package/dist/workers/ocr-worker.js +119177 -339
  8. package/dist/workers/ocr-worker.js.map +137 -1
  9. package/dist/workers/screen-capture-worker.js +350 -418
  10. package/dist/workers/screen-capture-worker.js.map +11 -1
  11. package/package.json +15 -20
  12. package/README.md +0 -270
  13. package/dist/action.d.ts +0 -8
  14. package/dist/action.js +0 -1212
  15. package/dist/action.js.map +0 -1
  16. package/dist/audio-capture-stream.d.ts +0 -42
  17. package/dist/audio-capture-stream.js +0 -516
  18. package/dist/audio-capture-stream.js.map +0 -1
  19. package/dist/audio-capture.d.ts +0 -25
  20. package/dist/audio-capture.js +0 -412
  21. package/dist/audio-capture.js.map +0 -1
  22. package/dist/basic.test.d.ts +0 -1
  23. package/dist/basic.test.js +0 -97
  24. package/dist/basic.test.js.map +0 -1
  25. package/dist/config.d.ts +0 -73
  26. package/dist/config.js +0 -254
  27. package/dist/config.js.map +0 -1
  28. package/dist/entity-tracker.d.ts +0 -32
  29. package/dist/entity-tracker.js +0 -361
  30. package/dist/entity-tracker.js.map +0 -1
  31. package/dist/errors.d.ts +0 -67
  32. package/dist/errors.js +0 -395
  33. package/dist/errors.js.map +0 -1
  34. package/dist/face-recognition.d.ts +0 -31
  35. package/dist/face-recognition.js +0 -332
  36. package/dist/face-recognition.js.map +0 -1
  37. package/dist/florence2-local.d.ts +0 -25
  38. package/dist/florence2-local.js +0 -280
  39. package/dist/florence2-local.js.map +0 -1
  40. package/dist/florence2-model.d.ts +0 -36
  41. package/dist/florence2-model.js +0 -503
  42. package/dist/florence2-model.js.map +0 -1
  43. package/dist/index.d.ts +0 -3
  44. package/dist/ocr-service-real.d.ts +0 -32
  45. package/dist/ocr-service-real.js +0 -396
  46. package/dist/ocr-service-real.js.map +0 -1
  47. package/dist/ocr-service.d.ts +0 -28
  48. package/dist/ocr-service.js +0 -216
  49. package/dist/ocr-service.js.map +0 -1
  50. package/dist/provider.d.ts +0 -2
  51. package/dist/provider.js +0 -285
  52. package/dist/provider.js.map +0 -1
  53. package/dist/screen-capture.d.ts +0 -16
  54. package/dist/screen-capture.js +0 -302
  55. package/dist/screen-capture.js.map +0 -1
  56. package/dist/service.d.ts +0 -73
  57. package/dist/service.js +0 -1662
  58. package/dist/service.js.map +0 -1
  59. package/dist/tests/e2e/index.d.ts +0 -8
  60. package/dist/tests/e2e/index.js +0 -33
  61. package/dist/tests/e2e/index.js.map +0 -1
  62. package/dist/tests/e2e/run-local.d.ts +0 -2
  63. package/dist/tests/e2e/run-local.js +0 -166
  64. package/dist/tests/e2e/run-local.js.map +0 -1
  65. package/dist/tests/e2e/screen-vision.d.ts +0 -11
  66. package/dist/tests/e2e/screen-vision.js +0 -384
  67. package/dist/tests/e2e/screen-vision.js.map +0 -1
  68. package/dist/tests/e2e/vision-autonomy.d.ts +0 -11
  69. package/dist/tests/e2e/vision-autonomy.js +0 -375
  70. package/dist/tests/e2e/vision-autonomy.js.map +0 -1
  71. package/dist/tests/e2e/vision-basic.d.ts +0 -11
  72. package/dist/tests/e2e/vision-basic.js +0 -434
  73. package/dist/tests/e2e/vision-basic.js.map +0 -1
  74. package/dist/tests/e2e/vision-capture-log.d.ts +0 -11
  75. package/dist/tests/e2e/vision-capture-log.js +0 -302
  76. package/dist/tests/e2e/vision-capture-log.js.map +0 -1
  77. package/dist/tests/e2e/vision-runtime.d.ts +0 -11
  78. package/dist/tests/e2e/vision-runtime.js +0 -357
  79. package/dist/tests/e2e/vision-runtime.js.map +0 -1
  80. package/dist/tests/e2e/vision-worker-tests.d.ts +0 -11
  81. package/dist/tests/e2e/vision-worker-tests.js +0 -466
  82. package/dist/tests/e2e/vision-worker-tests.js.map +0 -1
  83. package/dist/tests/test-pattern-generator.d.ts +0 -40
  84. package/dist/tests/test-pattern-generator.js +0 -191
  85. package/dist/tests/test-pattern-generator.js.map +0 -1
  86. package/dist/tests.d.ts +0 -3
  87. package/dist/tests.js +0 -11
  88. package/dist/tests.js.map +0 -1
  89. package/dist/types.d.ts +0 -222
  90. package/dist/types.js +0 -16
  91. package/dist/types.js.map +0 -1
  92. package/dist/vision-models.d.ts +0 -47
  93. package/dist/vision-models.js +0 -501
  94. package/dist/vision-models.js.map +0 -1
  95. package/dist/vision-worker-manager.d.ts +0 -61
  96. package/dist/vision-worker-manager.js +0 -668
  97. package/dist/vision-worker-manager.js.map +0 -1
  98. package/dist/workers/florence2-worker-simple.d.ts +0 -13
  99. package/dist/workers/florence2-worker-simple.js +0 -121
  100. package/dist/workers/florence2-worker-simple.js.map +0 -1
  101. package/dist/workers/florence2-worker.d.ts +0 -1
  102. package/dist/workers/ocr-worker.d.ts +0 -1
  103. package/dist/workers/screen-capture-worker.d.ts +0 -1
  104. package/dist/workers/worker-logger.d.ts +0 -9
  105. package/dist/workers/worker-logger.js +0 -95
  106. package/dist/workers/worker-logger.js.map +0 -1
@@ -1,396 +0,0 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
24
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
50
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
51
- if (ar || !(i in from)) {
52
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
53
- ar[i] = from[i];
54
- }
55
- }
56
- return to.concat(ar || Array.prototype.slice.call(from));
57
- };
58
- Object.defineProperty(exports, "__esModule", { value: true });
59
- exports.RealOCRService = void 0;
60
- var core_1 = require("@elizaos/core");
61
- var tesseract_js_1 = require("tesseract.js");
62
- var sharp_1 = require("sharp");
63
- var RealOCRService = /** @class */ (function () {
64
- function RealOCRService() {
65
- this.worker = null;
66
- this.initialized = false;
67
- this.initPromise = null;
68
- }
69
- RealOCRService.prototype.initialize = function () {
70
- return __awaiter(this, void 0, void 0, function () {
71
- return __generator(this, function (_a) {
72
- if (this.initialized) {
73
- return [2 /*return*/];
74
- }
75
- // Prevent multiple initializations
76
- if (this.initPromise) {
77
- return [2 /*return*/, this.initPromise];
78
- }
79
- this.initPromise = this._initialize();
80
- return [2 /*return*/, this.initPromise];
81
- });
82
- });
83
- };
84
- RealOCRService.prototype._initialize = function () {
85
- return __awaiter(this, void 0, void 0, function () {
86
- var _a, error_1;
87
- return __generator(this, function (_b) {
88
- switch (_b.label) {
89
- case 0:
90
- _b.trys.push([0, 2, , 3]);
91
- core_1.logger.info('[RealOCR] Initializing Tesseract.js...');
92
- // Create worker
93
- _a = this;
94
- return [4 /*yield*/, tesseract_js_1.default.createWorker('eng', 1, {
95
- logger: function (m) {
96
- if (m.status === 'recognizing text') {
97
- core_1.logger.debug("[RealOCR] Progress: ".concat((m.progress * 100).toFixed(1), "%"));
98
- }
99
- },
100
- })];
101
- case 1:
102
- // Create worker
103
- _a.worker = _b.sent();
104
- this.initialized = true;
105
- core_1.logger.info('[RealOCR] Tesseract.js initialized successfully');
106
- return [3 /*break*/, 3];
107
- case 2:
108
- error_1 = _b.sent();
109
- core_1.logger.error('[RealOCR] Failed to initialize:', error_1);
110
- throw error_1;
111
- case 3: return [2 /*return*/];
112
- }
113
- });
114
- });
115
- };
116
- RealOCRService.prototype.extractText = function (imageBuffer) {
117
- return __awaiter(this, void 0, void 0, function () {
118
- var processedBuffer, result, error_2;
119
- return __generator(this, function (_a) {
120
- switch (_a.label) {
121
- case 0:
122
- if (!!this.initialized) return [3 /*break*/, 2];
123
- return [4 /*yield*/, this.initialize()];
124
- case 1:
125
- _a.sent();
126
- _a.label = 2;
127
- case 2:
128
- if (!this.worker) {
129
- throw new Error('OCR worker not initialized');
130
- }
131
- _a.label = 3;
132
- case 3:
133
- _a.trys.push([3, 6, , 7]);
134
- return [4 /*yield*/, this.preprocessImage(imageBuffer)];
135
- case 4:
136
- processedBuffer = _a.sent();
137
- return [4 /*yield*/, this.worker.recognize(processedBuffer)];
138
- case 5:
139
- result = _a.sent();
140
- // Convert Tesseract result to our format
141
- return [2 /*return*/, this.convertTesseractResult(result)];
142
- case 6:
143
- error_2 = _a.sent();
144
- core_1.logger.error('[RealOCR] Text extraction failed:', error_2);
145
- throw error_2;
146
- case 7: return [2 /*return*/];
147
- }
148
- });
149
- });
150
- };
151
- RealOCRService.prototype.extractFromTile = function (tile) {
152
- return __awaiter(this, void 0, void 0, function () {
153
- return __generator(this, function (_a) {
154
- if (!tile.data) {
155
- return [2 /*return*/, {
156
- text: '',
157
- blocks: [],
158
- fullText: '',
159
- }];
160
- }
161
- return [2 /*return*/, this.extractText(tile.data)];
162
- });
163
- });
164
- };
165
- RealOCRService.prototype.preprocessImage = function (imageBuffer) {
166
- return __awaiter(this, void 0, void 0, function () {
167
- var processed, error_3;
168
- return __generator(this, function (_a) {
169
- switch (_a.label) {
170
- case 0:
171
- _a.trys.push([0, 2, , 3]);
172
- return [4 /*yield*/, (0, sharp_1.default)(imageBuffer)
173
- .grayscale() // Convert to grayscale
174
- .normalize() // Normalize contrast
175
- .sharpen() // Sharpen text
176
- .toBuffer()];
177
- case 1:
178
- processed = _a.sent();
179
- return [2 /*return*/, processed];
180
- case 2:
181
- error_3 = _a.sent();
182
- core_1.logger.warn('[RealOCR] Image preprocessing failed, using original:', error_3);
183
- return [2 /*return*/, imageBuffer];
184
- case 3: return [2 /*return*/];
185
- }
186
- });
187
- });
188
- };
189
- RealOCRService.prototype.convertTesseractResult = function (result) {
190
- var blocks = [];
191
- // Process lines as blocks
192
- var lines = result.data.lines || [];
193
- for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
194
- var line = lines_1[_i];
195
- if (line.confidence > 30) {
196
- // Filter low confidence
197
- blocks.push({
198
- text: line.text.trim(),
199
- bbox: {
200
- x: line.bbox.x0,
201
- y: line.bbox.y0,
202
- width: line.bbox.x1 - line.bbox.x0,
203
- height: line.bbox.y1 - line.bbox.y0,
204
- },
205
- confidence: line.confidence / 100,
206
- words: line.words.map(function (word) { return ({
207
- text: word.text,
208
- bbox: {
209
- x: word.bbox.x0,
210
- y: word.bbox.y0,
211
- width: word.bbox.x1 - word.bbox.x0,
212
- height: word.bbox.y1 - word.bbox.y0,
213
- },
214
- confidence: word.confidence / 100,
215
- }); }),
216
- });
217
- }
218
- }
219
- var fullText = result.data.text.trim();
220
- return {
221
- text: fullText,
222
- blocks: blocks,
223
- fullText: fullText,
224
- };
225
- };
226
- RealOCRService.prototype.extractStructuredData = function (imageBuffer) {
227
- return __awaiter(this, void 0, void 0, function () {
228
- var ocrResult;
229
- return __generator(this, function (_a) {
230
- switch (_a.label) {
231
- case 0: return [4 /*yield*/, this.extractText(imageBuffer)];
232
- case 1:
233
- ocrResult = _a.sent();
234
- return [2 /*return*/, {
235
- tables: this.detectTables(ocrResult),
236
- forms: this.detectForms(ocrResult),
237
- lists: this.detectLists(ocrResult),
238
- }];
239
- }
240
- });
241
- });
242
- };
243
- RealOCRService.prototype.detectTables = function (ocrResult) {
244
- var tables = [];
245
- // Group blocks by vertical alignment to detect table rows
246
- var rows = new Map();
247
- for (var _i = 0, _a = ocrResult.blocks; _i < _a.length; _i++) {
248
- var block = _a[_i];
249
- // Round Y position to group nearby blocks
250
- var rowY = Math.round(block.bbox.y / 20) * 20;
251
- if (!rows.has(rowY)) {
252
- rows.set(rowY, []);
253
- }
254
- rows.get(rowY).push(block);
255
- }
256
- // Find potential tables (multiple aligned rows)
257
- var sortedRows = Array.from(rows.entries()).sort(function (a, b) { return a[0] - b[0]; });
258
- var tableRows = [];
259
- var tableBounds = null;
260
- for (var _b = 0, sortedRows_1 = sortedRows; _b < sortedRows_1.length; _b++) {
261
- var _c = sortedRows_1[_b], y = _c[0], rowBlocks = _c[1];
262
- if (rowBlocks.length > 1) {
263
- // Sort blocks by X position
264
- rowBlocks.sort(function (a, b) { return a.bbox.x - b.bbox.x; });
265
- var rowTexts = rowBlocks.map(function (b) { return b.text; });
266
- tableRows.push(rowTexts);
267
- // Update table bounds
268
- if (!tableBounds) {
269
- tableBounds = __assign({}, rowBlocks[0].bbox);
270
- }
271
- else {
272
- tableBounds.x = Math.min(tableBounds.x, rowBlocks[0].bbox.x);
273
- tableBounds.width =
274
- Math.max.apply(Math, rowBlocks.map(function (b) { return b.bbox.x + b.bbox.width; })) - tableBounds.x;
275
- tableBounds.height = y + rowBlocks[0].bbox.height - tableBounds.y;
276
- }
277
- }
278
- else if (tableRows.length > 1 && tableBounds) {
279
- // End of table
280
- tables.push({
281
- rows: __spreadArray([], tableRows, true),
282
- bbox: __assign({}, tableBounds),
283
- });
284
- tableRows = [];
285
- tableBounds = null;
286
- }
287
- }
288
- // Add final table if exists
289
- if (tableRows.length > 1 && tableBounds) {
290
- tables.push({
291
- rows: tableRows,
292
- bbox: tableBounds,
293
- });
294
- }
295
- return tables;
296
- };
297
- RealOCRService.prototype.detectForms = function (ocrResult) {
298
- var forms = [];
299
- // Look for label-value patterns
300
- var blocks = ocrResult.blocks;
301
- for (var i = 0; i < blocks.length; i++) {
302
- var current = blocks[i];
303
- // Check if this looks like a label
304
- if (current.text.match(/[::]\s*$/)) {
305
- var label = current.text.replace(/[::]\s*$/, '').trim();
306
- // Look for value in nearby blocks
307
- for (var j = i + 1; j < blocks.length && j < i + 3; j++) {
308
- var next = blocks[j];
309
- // Check if horizontally aligned or just below
310
- var isAligned = Math.abs(current.bbox.y - next.bbox.y) < 10;
311
- var isBelow = next.bbox.y > current.bbox.y && next.bbox.y < current.bbox.y + current.bbox.height + 30;
312
- if (isAligned || isBelow) {
313
- forms.push({
314
- label: label,
315
- value: next.text.trim(),
316
- bbox: {
317
- x: Math.min(current.bbox.x, next.bbox.x),
318
- y: current.bbox.y,
319
- width: Math.max(current.bbox.x + current.bbox.width, next.bbox.x + next.bbox.width) -
320
- Math.min(current.bbox.x, next.bbox.x),
321
- height: next.bbox.y + next.bbox.height - current.bbox.y,
322
- },
323
- });
324
- break;
325
- }
326
- }
327
- }
328
- }
329
- return forms;
330
- };
331
- RealOCRService.prototype.detectLists = function (ocrResult) {
332
- var lists = [];
333
- var currentList = [];
334
- var listBounds = null;
335
- for (var _i = 0, _a = ocrResult.blocks; _i < _a.length; _i++) {
336
- var block = _a[_i];
337
- // Check for list markers
338
- var listMatch = block.text.match(/^[\u2022\u2023\u25E6\u2043\u2219•·‣⁃◦▪▫◆◇○●\-\*]\s+(.+)$/);
339
- var numberedMatch = block.text.match(/^(\d+\.|\d+\)|\(\d+\)|[a-zA-Z]\.)\s+(.+)$/);
340
- if (listMatch || numberedMatch) {
341
- var itemText = listMatch ? listMatch[1] : numberedMatch[2];
342
- currentList.push(itemText.trim());
343
- if (!listBounds) {
344
- listBounds = __assign({}, block.bbox);
345
- }
346
- else {
347
- listBounds.width = Math.max(listBounds.width, block.bbox.x + block.bbox.width - listBounds.x);
348
- listBounds.height = block.bbox.y + block.bbox.height - listBounds.y;
349
- }
350
- }
351
- else if (currentList.length > 0 && listBounds) {
352
- // End of list
353
- lists.push({
354
- items: __spreadArray([], currentList, true),
355
- bbox: __assign({}, listBounds),
356
- });
357
- currentList = [];
358
- listBounds = null;
359
- }
360
- }
361
- // Add final list if exists
362
- if (currentList.length > 0 && listBounds) {
363
- lists.push({
364
- items: currentList,
365
- bbox: listBounds,
366
- });
367
- }
368
- return lists;
369
- };
370
- RealOCRService.prototype.isInitialized = function () {
371
- return this.initialized;
372
- };
373
- RealOCRService.prototype.dispose = function () {
374
- return __awaiter(this, void 0, void 0, function () {
375
- return __generator(this, function (_a) {
376
- switch (_a.label) {
377
- case 0:
378
- if (!this.worker) return [3 /*break*/, 2];
379
- return [4 /*yield*/, this.worker.terminate()];
380
- case 1:
381
- _a.sent();
382
- this.worker = null;
383
- _a.label = 2;
384
- case 2:
385
- this.initialized = false;
386
- this.initPromise = null;
387
- core_1.logger.info('[RealOCR] Disposed');
388
- return [2 /*return*/];
389
- }
390
- });
391
- });
392
- };
393
- return RealOCRService;
394
- }());
395
- exports.RealOCRService = RealOCRService;
396
- //# sourceMappingURL=ocr-service-real.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ocr-service-real.js","sourceRoot":"","sources":["../src/ocr-service-real.ts"],"names":[],"mappings":"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","sourcesContent":["import { logger } from '@elizaos/core';\nimport Tesseract from 'tesseract.js';\nimport type { OCRResult, ScreenTile, BoundingBox } from './types';\nimport sharp from 'sharp';\n\nexport class RealOCRService {\n private worker: Tesseract.Worker | null = null;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Prevent multiple initializations\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = this._initialize();\n return this.initPromise;\n }\n\n private async _initialize(): Promise<void> {\n try {\n logger.info('[RealOCR] Initializing Tesseract.js...');\n\n // Create worker\n this.worker = await Tesseract.createWorker('eng', 1, {\n logger: (m) => {\n if (m.status === 'recognizing text') {\n logger.debug(`[RealOCR] Progress: ${(m.progress * 100).toFixed(1)}%`);\n }\n },\n });\n\n this.initialized = true;\n logger.info('[RealOCR] Tesseract.js initialized successfully');\n } catch (error) {\n logger.error('[RealOCR] Failed to initialize:', error);\n throw error;\n }\n }\n\n async extractText(imageBuffer: Buffer): Promise<OCRResult> {\n if (!this.initialized) {\n await this.initialize();\n }\n\n if (!this.worker) {\n throw new Error('OCR worker not initialized');\n }\n\n try {\n // Preprocess image for better OCR\n const processedBuffer = await this.preprocessImage(imageBuffer);\n\n // Perform OCR\n const result = await this.worker.recognize(processedBuffer);\n\n // Convert Tesseract result to our format\n return this.convertTesseractResult(result);\n } catch (error) {\n logger.error('[RealOCR] Text extraction failed:', error);\n throw error;\n }\n }\n\n async extractFromTile(tile: ScreenTile): Promise<OCRResult> {\n if (!tile.data) {\n return {\n text: '',\n blocks: [],\n fullText: '',\n };\n }\n\n return this.extractText(tile.data);\n }\n\n private async preprocessImage(imageBuffer: Buffer): Promise<Buffer> {\n try {\n // Enhance image for better OCR results\n const processed = await sharp(imageBuffer)\n .grayscale() // Convert to grayscale\n .normalize() // Normalize contrast\n .sharpen() // Sharpen text\n .toBuffer();\n\n return processed;\n } catch (error) {\n logger.warn('[RealOCR] Image preprocessing failed, using original:', error);\n return imageBuffer;\n }\n }\n\n private convertTesseractResult(result: Tesseract.RecognizeResult): OCRResult {\n const blocks: OCRResult['blocks'] = [];\n\n // Process lines as blocks\n const lines = (result.data as any).lines || [];\n for (const line of lines) {\n if (line.confidence > 30) {\n // Filter low confidence\n blocks.push({\n text: line.text.trim(),\n bbox: {\n x: line.bbox.x0,\n y: line.bbox.y0,\n width: line.bbox.x1 - line.bbox.x0,\n height: line.bbox.y1 - line.bbox.y0,\n },\n confidence: line.confidence / 100,\n words: line.words.map((word: any) => ({\n text: word.text,\n bbox: {\n x: word.bbox.x0,\n y: word.bbox.y0,\n width: word.bbox.x1 - word.bbox.x0,\n height: word.bbox.y1 - word.bbox.y0,\n },\n confidence: word.confidence / 100,\n })),\n });\n }\n }\n\n const fullText = result.data.text.trim();\n\n return {\n text: fullText,\n blocks,\n fullText,\n };\n }\n\n async extractStructuredData(imageBuffer: Buffer): Promise<{\n tables?: Array<{ rows: string[][]; bbox: BoundingBox }>;\n forms?: Array<{ label: string; value: string; bbox: BoundingBox }>;\n lists?: Array<{ items: string[]; bbox: BoundingBox }>;\n }> {\n const ocrResult = await this.extractText(imageBuffer);\n\n return {\n tables: this.detectTables(ocrResult),\n forms: this.detectForms(ocrResult),\n lists: this.detectLists(ocrResult),\n };\n }\n\n private detectTables(ocrResult: OCRResult): Array<{ rows: string[][]; bbox: BoundingBox }> {\n const tables: Array<{ rows: string[][]; bbox: BoundingBox }> = [];\n\n // Group blocks by vertical alignment to detect table rows\n const rows: Map<number, typeof ocrResult.blocks> = new Map();\n\n for (const block of ocrResult.blocks) {\n // Round Y position to group nearby blocks\n const rowY = Math.round(block.bbox.y / 20) * 20;\n\n if (!rows.has(rowY)) {\n rows.set(rowY, []);\n }\n rows.get(rowY)!.push(block);\n }\n\n // Find potential tables (multiple aligned rows)\n const sortedRows = Array.from(rows.entries()).sort((a, b) => a[0] - b[0]);\n\n let tableRows: string[][] = [];\n let tableBounds: BoundingBox | null = null;\n\n for (const [y, rowBlocks] of sortedRows) {\n if (rowBlocks.length > 1) {\n // Sort blocks by X position\n rowBlocks.sort((a, b) => a.bbox.x - b.bbox.x);\n\n const rowTexts = rowBlocks.map((b) => b.text);\n tableRows.push(rowTexts);\n\n // Update table bounds\n if (!tableBounds) {\n tableBounds = { ...rowBlocks[0].bbox };\n } else {\n tableBounds.x = Math.min(tableBounds.x, rowBlocks[0].bbox.x);\n tableBounds.width =\n Math.max(...rowBlocks.map((b) => b.bbox.x + b.bbox.width)) - tableBounds.x;\n tableBounds.height = y + rowBlocks[0].bbox.height - tableBounds.y;\n }\n } else if (tableRows.length > 1 && tableBounds) {\n // End of table\n tables.push({\n rows: [...tableRows],\n bbox: { ...tableBounds },\n });\n tableRows = [];\n tableBounds = null;\n }\n }\n\n // Add final table if exists\n if (tableRows.length > 1 && tableBounds) {\n tables.push({\n rows: tableRows,\n bbox: tableBounds,\n });\n }\n\n return tables;\n }\n\n private detectForms(\n ocrResult: OCRResult\n ): Array<{ label: string; value: string; bbox: BoundingBox }> {\n const forms: Array<{ label: string; value: string; bbox: BoundingBox }> = [];\n\n // Look for label-value patterns\n const blocks = ocrResult.blocks;\n\n for (let i = 0; i < blocks.length; i++) {\n const current = blocks[i];\n\n // Check if this looks like a label\n if (current.text.match(/[::]\\s*$/)) {\n const label = current.text.replace(/[::]\\s*$/, '').trim();\n\n // Look for value in nearby blocks\n for (let j = i + 1; j < blocks.length && j < i + 3; j++) {\n const next = blocks[j];\n\n // Check if horizontally aligned or just below\n const isAligned = Math.abs(current.bbox.y - next.bbox.y) < 10;\n const isBelow =\n next.bbox.y > current.bbox.y && next.bbox.y < current.bbox.y + current.bbox.height + 30;\n\n if (isAligned || isBelow) {\n forms.push({\n label,\n value: next.text.trim(),\n bbox: {\n x: Math.min(current.bbox.x, next.bbox.x),\n y: current.bbox.y,\n width:\n Math.max(current.bbox.x + current.bbox.width, next.bbox.x + next.bbox.width) -\n Math.min(current.bbox.x, next.bbox.x),\n height: next.bbox.y + next.bbox.height - current.bbox.y,\n },\n });\n break;\n }\n }\n }\n }\n\n return forms;\n }\n\n private detectLists(ocrResult: OCRResult): Array<{ items: string[]; bbox: BoundingBox }> {\n const lists: Array<{ items: string[]; bbox: BoundingBox }> = [];\n\n let currentList: string[] = [];\n let listBounds: BoundingBox | null = null;\n\n for (const block of ocrResult.blocks) {\n // Check for list markers\n const listMatch = block.text.match(\n /^[\\u2022\\u2023\\u25E6\\u2043\\u2219•·‣⁃◦▪▫◆◇○●\\-\\*]\\s+(.+)$/\n );\n const numberedMatch = block.text.match(/^(\\d+\\.|\\d+\\)|\\(\\d+\\)|[a-zA-Z]\\.)\\s+(.+)$/);\n\n if (listMatch || numberedMatch) {\n const itemText = listMatch ? listMatch[1] : numberedMatch![2];\n currentList.push(itemText.trim());\n\n if (!listBounds) {\n listBounds = { ...block.bbox };\n } else {\n listBounds.width = Math.max(\n listBounds.width,\n block.bbox.x + block.bbox.width - listBounds.x\n );\n listBounds.height = block.bbox.y + block.bbox.height - listBounds.y;\n }\n } else if (currentList.length > 0 && listBounds) {\n // End of list\n lists.push({\n items: [...currentList],\n bbox: { ...listBounds },\n });\n currentList = [];\n listBounds = null;\n }\n }\n\n // Add final list if exists\n if (currentList.length > 0 && listBounds) {\n lists.push({\n items: currentList,\n bbox: listBounds,\n });\n }\n\n return lists;\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n async dispose(): Promise<void> {\n if (this.worker) {\n await this.worker.terminate();\n this.worker = null;\n }\n this.initialized = false;\n this.initPromise = null;\n logger.info('[RealOCR] Disposed');\n }\n}\n"]}
@@ -1,28 +0,0 @@
1
- import type { OCRResult, ScreenTile, BoundingBox } from './types';
2
- export declare class OCRService {
3
- private realOCR;
4
- private initialized;
5
- private useFallback;
6
- initialize(): Promise<void>;
7
- extractText(imageBuffer: Buffer): Promise<OCRResult>;
8
- extractFromTile(tile: ScreenTile): Promise<OCRResult>;
9
- extractFromImage(imageBuffer: Buffer): Promise<OCRResult>;
10
- private fallbackOCR;
11
- extractStructuredData(imageBuffer: Buffer): Promise<{
12
- tables?: Array<{
13
- rows: string[][];
14
- bbox: BoundingBox;
15
- }>;
16
- forms?: Array<{
17
- label: string;
18
- value: string;
19
- bbox: BoundingBox;
20
- }>;
21
- lists?: Array<{
22
- items: string[];
23
- bbox: BoundingBox;
24
- }>;
25
- }>;
26
- isInitialized(): boolean;
27
- dispose(): Promise<void>;
28
- }