@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.
- package/LICENSE +21 -0
- package/build.config.ts +53 -53
- package/dist/index.js +6716 -67
- package/dist/index.js.map +33 -1
- package/dist/workers/florence2-worker.js +111763 -307
- package/dist/workers/florence2-worker.js.map +92 -1
- package/dist/workers/ocr-worker.js +119177 -339
- package/dist/workers/ocr-worker.js.map +137 -1
- package/dist/workers/screen-capture-worker.js +350 -418
- package/dist/workers/screen-capture-worker.js.map +11 -1
- package/package.json +15 -20
- package/README.md +0 -270
- package/dist/action.d.ts +0 -8
- package/dist/action.js +0 -1212
- package/dist/action.js.map +0 -1
- package/dist/audio-capture-stream.d.ts +0 -42
- package/dist/audio-capture-stream.js +0 -516
- package/dist/audio-capture-stream.js.map +0 -1
- package/dist/audio-capture.d.ts +0 -25
- package/dist/audio-capture.js +0 -412
- package/dist/audio-capture.js.map +0 -1
- package/dist/basic.test.d.ts +0 -1
- package/dist/basic.test.js +0 -97
- package/dist/basic.test.js.map +0 -1
- package/dist/config.d.ts +0 -73
- package/dist/config.js +0 -254
- package/dist/config.js.map +0 -1
- package/dist/entity-tracker.d.ts +0 -32
- package/dist/entity-tracker.js +0 -361
- package/dist/entity-tracker.js.map +0 -1
- package/dist/errors.d.ts +0 -67
- package/dist/errors.js +0 -395
- package/dist/errors.js.map +0 -1
- package/dist/face-recognition.d.ts +0 -31
- package/dist/face-recognition.js +0 -332
- package/dist/face-recognition.js.map +0 -1
- package/dist/florence2-local.d.ts +0 -25
- package/dist/florence2-local.js +0 -280
- package/dist/florence2-local.js.map +0 -1
- package/dist/florence2-model.d.ts +0 -36
- package/dist/florence2-model.js +0 -503
- package/dist/florence2-model.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/ocr-service-real.d.ts +0 -32
- package/dist/ocr-service-real.js +0 -396
- package/dist/ocr-service-real.js.map +0 -1
- package/dist/ocr-service.d.ts +0 -28
- package/dist/ocr-service.js +0 -216
- package/dist/ocr-service.js.map +0 -1
- package/dist/provider.d.ts +0 -2
- package/dist/provider.js +0 -285
- package/dist/provider.js.map +0 -1
- package/dist/screen-capture.d.ts +0 -16
- package/dist/screen-capture.js +0 -302
- package/dist/screen-capture.js.map +0 -1
- package/dist/service.d.ts +0 -73
- package/dist/service.js +0 -1662
- package/dist/service.js.map +0 -1
- package/dist/tests/e2e/index.d.ts +0 -8
- package/dist/tests/e2e/index.js +0 -33
- package/dist/tests/e2e/index.js.map +0 -1
- package/dist/tests/e2e/run-local.d.ts +0 -2
- package/dist/tests/e2e/run-local.js +0 -166
- package/dist/tests/e2e/run-local.js.map +0 -1
- package/dist/tests/e2e/screen-vision.d.ts +0 -11
- package/dist/tests/e2e/screen-vision.js +0 -384
- package/dist/tests/e2e/screen-vision.js.map +0 -1
- package/dist/tests/e2e/vision-autonomy.d.ts +0 -11
- package/dist/tests/e2e/vision-autonomy.js +0 -375
- package/dist/tests/e2e/vision-autonomy.js.map +0 -1
- package/dist/tests/e2e/vision-basic.d.ts +0 -11
- package/dist/tests/e2e/vision-basic.js +0 -434
- package/dist/tests/e2e/vision-basic.js.map +0 -1
- package/dist/tests/e2e/vision-capture-log.d.ts +0 -11
- package/dist/tests/e2e/vision-capture-log.js +0 -302
- package/dist/tests/e2e/vision-capture-log.js.map +0 -1
- package/dist/tests/e2e/vision-runtime.d.ts +0 -11
- package/dist/tests/e2e/vision-runtime.js +0 -357
- package/dist/tests/e2e/vision-runtime.js.map +0 -1
- package/dist/tests/e2e/vision-worker-tests.d.ts +0 -11
- package/dist/tests/e2e/vision-worker-tests.js +0 -466
- package/dist/tests/e2e/vision-worker-tests.js.map +0 -1
- package/dist/tests/test-pattern-generator.d.ts +0 -40
- package/dist/tests/test-pattern-generator.js +0 -191
- package/dist/tests/test-pattern-generator.js.map +0 -1
- package/dist/tests.d.ts +0 -3
- package/dist/tests.js +0 -11
- package/dist/tests.js.map +0 -1
- package/dist/types.d.ts +0 -222
- package/dist/types.js +0 -16
- package/dist/types.js.map +0 -1
- package/dist/vision-models.d.ts +0 -47
- package/dist/vision-models.js +0 -501
- package/dist/vision-models.js.map +0 -1
- package/dist/vision-worker-manager.d.ts +0 -61
- package/dist/vision-worker-manager.js +0 -668
- package/dist/vision-worker-manager.js.map +0 -1
- package/dist/workers/florence2-worker-simple.d.ts +0 -13
- package/dist/workers/florence2-worker-simple.js +0 -121
- package/dist/workers/florence2-worker-simple.js.map +0 -1
- package/dist/workers/florence2-worker.d.ts +0 -1
- package/dist/workers/ocr-worker.d.ts +0 -1
- package/dist/workers/screen-capture-worker.d.ts +0 -1
- package/dist/workers/worker-logger.d.ts +0 -9
- package/dist/workers/worker-logger.js +0 -95
- package/dist/workers/worker-logger.js.map +0 -1
package/dist/face-recognition.js
DELETED
|
@@ -1,332 +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
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
-
exports.FaceRecognition = void 0;
|
|
51
|
-
var faceapi = require("face-api.js");
|
|
52
|
-
var core_1 = require("@elizaos/core");
|
|
53
|
-
var path = require("path");
|
|
54
|
-
var url_1 = require("url");
|
|
55
|
-
var __filename = (0, url_1.fileURLToPath)(import.meta.url);
|
|
56
|
-
var __dirname = path.dirname(__filename);
|
|
57
|
-
// Dynamic imports for optional dependencies
|
|
58
|
-
var Canvas, Image, ImageData;
|
|
59
|
-
function initializeCanvas() {
|
|
60
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
61
|
-
var canvas, error_1;
|
|
62
|
-
return __generator(this, function (_a) {
|
|
63
|
-
switch (_a.label) {
|
|
64
|
-
case 0:
|
|
65
|
-
_a.trys.push([0, 2, , 3]);
|
|
66
|
-
return [4 /*yield*/, Promise.resolve().then(function () { return require('canvas'); })];
|
|
67
|
-
case 1:
|
|
68
|
-
canvas = _a.sent();
|
|
69
|
-
Canvas = canvas.Canvas;
|
|
70
|
-
Image = canvas.Image;
|
|
71
|
-
ImageData = canvas.ImageData;
|
|
72
|
-
// Polyfill for face-api.js
|
|
73
|
-
faceapi.env.monkeyPatch({ Canvas: Canvas, Image: Image, ImageData: ImageData });
|
|
74
|
-
return [3 /*break*/, 3];
|
|
75
|
-
case 2:
|
|
76
|
-
error_1 = _a.sent();
|
|
77
|
-
core_1.logger.error('[FaceRecognition] Canvas module not available:', error_1);
|
|
78
|
-
throw new Error('Canvas module is required for face recognition. Install with: npm install canvas');
|
|
79
|
-
case 3: return [2 /*return*/];
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
var FaceRecognition = /** @class */ (function () {
|
|
85
|
-
function FaceRecognition() {
|
|
86
|
-
this.initialized = false;
|
|
87
|
-
this.faceLibrary = {
|
|
88
|
-
faces: new Map(),
|
|
89
|
-
embeddings: new Map(),
|
|
90
|
-
};
|
|
91
|
-
this.modelPath = path.join(__dirname, '..', 'models', 'face-api');
|
|
92
|
-
// Thresholds
|
|
93
|
-
this.FACE_MATCH_THRESHOLD = 0.6; // Euclidean distance threshold
|
|
94
|
-
this.MIN_FACE_SIZE = 50; // Minimum face size in pixels
|
|
95
|
-
}
|
|
96
|
-
FaceRecognition.prototype.initialize = function () {
|
|
97
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
98
|
-
var error_2;
|
|
99
|
-
return __generator(this, function (_a) {
|
|
100
|
-
switch (_a.label) {
|
|
101
|
-
case 0:
|
|
102
|
-
if (this.initialized) {
|
|
103
|
-
return [2 /*return*/];
|
|
104
|
-
}
|
|
105
|
-
_a.label = 1;
|
|
106
|
-
case 1:
|
|
107
|
-
_a.trys.push([1, 8, , 9]);
|
|
108
|
-
core_1.logger.info('[FaceRecognition] Loading face detection models...');
|
|
109
|
-
// Initialize canvas first
|
|
110
|
-
return [4 /*yield*/, initializeCanvas()];
|
|
111
|
-
case 2:
|
|
112
|
-
// Initialize canvas first
|
|
113
|
-
_a.sent();
|
|
114
|
-
// Load face-api.js models
|
|
115
|
-
return [4 /*yield*/, faceapi.nets.ssdMobilenetv1.loadFromDisk(this.modelPath)];
|
|
116
|
-
case 3:
|
|
117
|
-
// Load face-api.js models
|
|
118
|
-
_a.sent();
|
|
119
|
-
return [4 /*yield*/, faceapi.nets.faceLandmark68Net.loadFromDisk(this.modelPath)];
|
|
120
|
-
case 4:
|
|
121
|
-
_a.sent();
|
|
122
|
-
return [4 /*yield*/, faceapi.nets.faceRecognitionNet.loadFromDisk(this.modelPath)];
|
|
123
|
-
case 5:
|
|
124
|
-
_a.sent();
|
|
125
|
-
return [4 /*yield*/, faceapi.nets.faceExpressionNet.loadFromDisk(this.modelPath)];
|
|
126
|
-
case 6:
|
|
127
|
-
_a.sent();
|
|
128
|
-
return [4 /*yield*/, faceapi.nets.ageGenderNet.loadFromDisk(this.modelPath)];
|
|
129
|
-
case 7:
|
|
130
|
-
_a.sent();
|
|
131
|
-
this.initialized = true;
|
|
132
|
-
core_1.logger.info('[FaceRecognition] Models loaded successfully');
|
|
133
|
-
return [3 /*break*/, 9];
|
|
134
|
-
case 8:
|
|
135
|
-
error_2 = _a.sent();
|
|
136
|
-
core_1.logger.error('[FaceRecognition] Failed to load models:', error_2);
|
|
137
|
-
core_1.logger.info('[FaceRecognition] Download models from: https://github.com/justadudewhohacks/face-api.js-models');
|
|
138
|
-
throw error_2;
|
|
139
|
-
case 9: return [2 /*return*/];
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
};
|
|
144
|
-
FaceRecognition.prototype.detectFaces = function (imageData, width, height) {
|
|
145
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
146
|
-
var expectedSize, canvas, ctx, imageDataObj, detections, error_3;
|
|
147
|
-
var _this = this;
|
|
148
|
-
return __generator(this, function (_a) {
|
|
149
|
-
switch (_a.label) {
|
|
150
|
-
case 0:
|
|
151
|
-
if (!!this.initialized) return [3 /*break*/, 2];
|
|
152
|
-
return [4 /*yield*/, this.initialize()];
|
|
153
|
-
case 1:
|
|
154
|
-
_a.sent();
|
|
155
|
-
_a.label = 2;
|
|
156
|
-
case 2:
|
|
157
|
-
// Validate input parameters
|
|
158
|
-
if (!imageData || imageData.length === 0 || width <= 0 || height <= 0) {
|
|
159
|
-
core_1.logger.warn('[FaceRecognition] Invalid input parameters:', {
|
|
160
|
-
dataLength: (imageData === null || imageData === void 0 ? void 0 : imageData.length) || 0,
|
|
161
|
-
width: width,
|
|
162
|
-
height: height,
|
|
163
|
-
});
|
|
164
|
-
return [2 /*return*/, []];
|
|
165
|
-
}
|
|
166
|
-
expectedSize = width * height * 4;
|
|
167
|
-
if (imageData.length !== expectedSize) {
|
|
168
|
-
core_1.logger.warn('[FaceRecognition] Buffer size mismatch:', {
|
|
169
|
-
expected: expectedSize,
|
|
170
|
-
actual: imageData.length,
|
|
171
|
-
width: width,
|
|
172
|
-
height: height,
|
|
173
|
-
});
|
|
174
|
-
return [2 /*return*/, []];
|
|
175
|
-
}
|
|
176
|
-
_a.label = 3;
|
|
177
|
-
case 3:
|
|
178
|
-
_a.trys.push([3, 5, , 6]);
|
|
179
|
-
canvas = new Canvas(width, height);
|
|
180
|
-
ctx = canvas.getContext('2d');
|
|
181
|
-
imageDataObj = new ImageData(new Uint8ClampedArray(imageData), width, height);
|
|
182
|
-
ctx.putImageData(imageDataObj, 0, 0);
|
|
183
|
-
return [4 /*yield*/, faceapi
|
|
184
|
-
.detectAllFaces(canvas, new faceapi.SsdMobilenetv1Options({
|
|
185
|
-
minConfidence: 0.5,
|
|
186
|
-
maxResults: 10,
|
|
187
|
-
}))
|
|
188
|
-
.withFaceLandmarks()
|
|
189
|
-
.withFaceDescriptors()
|
|
190
|
-
.withFaceExpressions()
|
|
191
|
-
.withAgeAndGender()];
|
|
192
|
-
case 4:
|
|
193
|
-
detections = _a.sent();
|
|
194
|
-
return [2 /*return*/, detections.filter(function (d) {
|
|
195
|
-
var box = d.detection.box;
|
|
196
|
-
return box.width >= _this.MIN_FACE_SIZE && box.height >= _this.MIN_FACE_SIZE;
|
|
197
|
-
})];
|
|
198
|
-
case 5:
|
|
199
|
-
error_3 = _a.sent();
|
|
200
|
-
core_1.logger.error('[FaceRecognition] Face detection failed:', error_3);
|
|
201
|
-
return [2 /*return*/, []];
|
|
202
|
-
case 6: return [2 /*return*/];
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
};
|
|
207
|
-
FaceRecognition.prototype.recognizeFace = function (descriptor) {
|
|
208
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
209
|
-
var bestMatch, minDistance, _i, _a, _b, profileId, embeddings, _c, embeddings_1, knownEmbedding, distance;
|
|
210
|
-
return __generator(this, function (_d) {
|
|
211
|
-
bestMatch = null;
|
|
212
|
-
minDistance = Infinity;
|
|
213
|
-
// Compare with all known faces
|
|
214
|
-
for (_i = 0, _a = this.faceLibrary.embeddings; _i < _a.length; _i++) {
|
|
215
|
-
_b = _a[_i], profileId = _b[0], embeddings = _b[1];
|
|
216
|
-
for (_c = 0, embeddings_1 = embeddings; _c < embeddings_1.length; _c++) {
|
|
217
|
-
knownEmbedding = embeddings_1[_c];
|
|
218
|
-
distance = this.euclideanDistance(descriptor, knownEmbedding);
|
|
219
|
-
if (distance < this.FACE_MATCH_THRESHOLD && distance < minDistance) {
|
|
220
|
-
minDistance = distance;
|
|
221
|
-
bestMatch = { profileId: profileId, distance: distance };
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
return [2 /*return*/, bestMatch];
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
};
|
|
229
|
-
FaceRecognition.prototype.addOrUpdateFace = function (descriptor, attributes) {
|
|
230
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
231
|
-
var match, profile, embeddings, profileId, profile;
|
|
232
|
-
return __generator(this, function (_a) {
|
|
233
|
-
switch (_a.label) {
|
|
234
|
-
case 0: return [4 /*yield*/, this.recognizeFace(descriptor)];
|
|
235
|
-
case 1:
|
|
236
|
-
match = _a.sent();
|
|
237
|
-
if (match) {
|
|
238
|
-
profile = this.faceLibrary.faces.get(match.profileId);
|
|
239
|
-
profile.lastSeen = Date.now();
|
|
240
|
-
profile.seenCount++;
|
|
241
|
-
embeddings = this.faceLibrary.embeddings.get(match.profileId);
|
|
242
|
-
if (embeddings.length < 10) {
|
|
243
|
-
// Keep up to 10 embeddings per person
|
|
244
|
-
embeddings.push(Array.from(descriptor));
|
|
245
|
-
}
|
|
246
|
-
// Update attributes if provided
|
|
247
|
-
if (attributes) {
|
|
248
|
-
Object.assign(profile, attributes);
|
|
249
|
-
}
|
|
250
|
-
return [2 /*return*/, match.profileId];
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
profileId = "face-".concat(Date.now(), "-").concat(Math.random().toString(36).substr(2, 9));
|
|
254
|
-
profile = __assign({ id: profileId, embeddings: [Array.from(descriptor)], firstSeen: Date.now(), lastSeen: Date.now(), seenCount: 1 }, attributes);
|
|
255
|
-
this.faceLibrary.faces.set(profileId, profile);
|
|
256
|
-
this.faceLibrary.embeddings.set(profileId, [Array.from(descriptor)]);
|
|
257
|
-
core_1.logger.info("[FaceRecognition] New face registered: ".concat(profileId));
|
|
258
|
-
return [2 /*return*/, profileId];
|
|
259
|
-
}
|
|
260
|
-
return [2 /*return*/];
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
};
|
|
265
|
-
FaceRecognition.prototype.getFaceProfile = function (profileId) {
|
|
266
|
-
return this.faceLibrary.faces.get(profileId);
|
|
267
|
-
};
|
|
268
|
-
FaceRecognition.prototype.getAllProfiles = function () {
|
|
269
|
-
return Array.from(this.faceLibrary.faces.values());
|
|
270
|
-
};
|
|
271
|
-
FaceRecognition.prototype.euclideanDistance = function (a, b) {
|
|
272
|
-
var sum = 0;
|
|
273
|
-
var aArray = Array.from(a);
|
|
274
|
-
for (var i = 0; i < aArray.length; i++) {
|
|
275
|
-
sum += Math.pow(aArray[i] - b[i], 2);
|
|
276
|
-
}
|
|
277
|
-
return Math.sqrt(sum);
|
|
278
|
-
};
|
|
279
|
-
// Persistence methods
|
|
280
|
-
FaceRecognition.prototype.saveFaceLibrary = function (path) {
|
|
281
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
282
|
-
var data, fs;
|
|
283
|
-
return __generator(this, function (_a) {
|
|
284
|
-
switch (_a.label) {
|
|
285
|
-
case 0:
|
|
286
|
-
data = {
|
|
287
|
-
faces: Array.from(this.faceLibrary.faces.entries()),
|
|
288
|
-
embeddings: Array.from(this.faceLibrary.embeddings.entries()),
|
|
289
|
-
};
|
|
290
|
-
return [4 /*yield*/, Promise.resolve().then(function () { return require('fs/promises'); })];
|
|
291
|
-
case 1:
|
|
292
|
-
fs = _a.sent();
|
|
293
|
-
return [4 /*yield*/, fs.writeFile(path, JSON.stringify(data, null, 2))];
|
|
294
|
-
case 2:
|
|
295
|
-
_a.sent();
|
|
296
|
-
core_1.logger.info("[FaceRecognition] Face library saved to ".concat(path));
|
|
297
|
-
return [2 /*return*/];
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
};
|
|
302
|
-
FaceRecognition.prototype.loadFaceLibrary = function (path) {
|
|
303
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
304
|
-
var fs, data, _a, _b, error_4;
|
|
305
|
-
return __generator(this, function (_c) {
|
|
306
|
-
switch (_c.label) {
|
|
307
|
-
case 0:
|
|
308
|
-
_c.trys.push([0, 3, , 4]);
|
|
309
|
-
return [4 /*yield*/, Promise.resolve().then(function () { return require('fs/promises'); })];
|
|
310
|
-
case 1:
|
|
311
|
-
fs = _c.sent();
|
|
312
|
-
_b = (_a = JSON).parse;
|
|
313
|
-
return [4 /*yield*/, fs.readFile(path, 'utf-8')];
|
|
314
|
-
case 2:
|
|
315
|
-
data = _b.apply(_a, [_c.sent()]);
|
|
316
|
-
this.faceLibrary.faces = new Map(data.faces);
|
|
317
|
-
this.faceLibrary.embeddings = new Map(data.embeddings);
|
|
318
|
-
core_1.logger.info("[FaceRecognition] Loaded ".concat(this.faceLibrary.faces.size, " face profiles"));
|
|
319
|
-
return [3 /*break*/, 4];
|
|
320
|
-
case 3:
|
|
321
|
-
error_4 = _c.sent();
|
|
322
|
-
core_1.logger.warn('[FaceRecognition] Could not load face library:', error_4);
|
|
323
|
-
return [3 /*break*/, 4];
|
|
324
|
-
case 4: return [2 /*return*/];
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
});
|
|
328
|
-
};
|
|
329
|
-
return FaceRecognition;
|
|
330
|
-
}());
|
|
331
|
-
exports.FaceRecognition = FaceRecognition;
|
|
332
|
-
//# sourceMappingURL=face-recognition.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"face-recognition.js","sourceRoot":"","sources":["../src/face-recognition.ts"],"names":[],"mappings":"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","sourcesContent":["import * as faceapi from 'face-api.js';\nimport { logger } from '@elizaos/core';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\nimport type { FaceProfile, FaceLibrary } from './types';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Dynamic imports for optional dependencies\nlet Canvas: any, Image: any, ImageData: any;\n\nasync function initializeCanvas() {\n try {\n const canvas = await import('canvas');\n Canvas = canvas.Canvas;\n Image = canvas.Image;\n ImageData = canvas.ImageData;\n\n // Polyfill for face-api.js\n faceapi.env.monkeyPatch({ Canvas, Image, ImageData });\n } catch (error) {\n logger.error('[FaceRecognition] Canvas module not available:', error);\n throw new Error(\n 'Canvas module is required for face recognition. Install with: npm install canvas'\n );\n }\n}\n\nexport class FaceRecognition {\n private initialized = false;\n private faceLibrary: FaceLibrary = {\n faces: new Map(),\n embeddings: new Map(),\n };\n private modelPath = path.join(__dirname, '..', 'models', 'face-api');\n\n // Thresholds\n private readonly FACE_MATCH_THRESHOLD = 0.6; // Euclidean distance threshold\n private readonly MIN_FACE_SIZE = 50; // Minimum face size in pixels\n\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n try {\n logger.info('[FaceRecognition] Loading face detection models...');\n\n // Initialize canvas first\n await initializeCanvas();\n\n // Load face-api.js models\n await faceapi.nets.ssdMobilenetv1.loadFromDisk(this.modelPath);\n await faceapi.nets.faceLandmark68Net.loadFromDisk(this.modelPath);\n await faceapi.nets.faceRecognitionNet.loadFromDisk(this.modelPath);\n await faceapi.nets.faceExpressionNet.loadFromDisk(this.modelPath);\n await faceapi.nets.ageGenderNet.loadFromDisk(this.modelPath);\n\n this.initialized = true;\n logger.info('[FaceRecognition] Models loaded successfully');\n } catch (error) {\n logger.error('[FaceRecognition] Failed to load models:', error);\n logger.info(\n '[FaceRecognition] Download models from: https://github.com/justadudewhohacks/face-api.js-models'\n );\n throw error;\n }\n }\n\n async detectFaces(\n imageData: Buffer,\n width: number,\n height: number\n ): Promise<\n Array<{\n detection: faceapi.FaceDetection;\n landmarks: faceapi.FaceLandmarks68;\n descriptor: Float32Array;\n expressions: faceapi.FaceExpressions;\n ageGender?: { age: number; gender: string; genderProbability: number };\n }>\n > {\n if (!this.initialized) {\n await this.initialize();\n }\n\n // Validate input parameters\n if (!imageData || imageData.length === 0 || width <= 0 || height <= 0) {\n logger.warn('[FaceRecognition] Invalid input parameters:', {\n dataLength: imageData?.length || 0,\n width,\n height,\n });\n return [];\n }\n\n // Validate that the buffer size matches expected dimensions\n const expectedSize = width * height * 4; // RGBA\n if (imageData.length !== expectedSize) {\n logger.warn('[FaceRecognition] Buffer size mismatch:', {\n expected: expectedSize,\n actual: imageData.length,\n width,\n height,\n });\n return [];\n }\n\n try {\n // Create canvas from image data\n const canvas = new Canvas(width, height);\n const ctx = canvas.getContext('2d');\n const imageDataObj = new ImageData(new Uint8ClampedArray(imageData), width, height);\n ctx.putImageData(imageDataObj, 0, 0);\n\n // Detect faces with full analysis\n const detections = await faceapi\n .detectAllFaces(\n canvas as any,\n new faceapi.SsdMobilenetv1Options({\n minConfidence: 0.5,\n maxResults: 10,\n })\n )\n .withFaceLandmarks()\n .withFaceDescriptors()\n .withFaceExpressions()\n .withAgeAndGender();\n\n return detections.filter(\n (d: {\n detection: {\n box: {\n width: number;\n height: number;\n };\n };\n }) => {\n const box = d.detection.box;\n return box.width >= this.MIN_FACE_SIZE && box.height >= this.MIN_FACE_SIZE;\n }\n );\n } catch (error) {\n logger.error('[FaceRecognition] Face detection failed:', error);\n return [];\n }\n }\n\n async recognizeFace(\n descriptor: Float32Array\n ): Promise<{ profileId: string; distance: number } | null> {\n let bestMatch: { profileId: string; distance: number } | null = null;\n let minDistance = Infinity;\n\n // Compare with all known faces\n for (const [profileId, embeddings] of this.faceLibrary.embeddings) {\n for (const knownEmbedding of embeddings) {\n const distance = this.euclideanDistance(descriptor, knownEmbedding);\n\n if (distance < this.FACE_MATCH_THRESHOLD && distance < minDistance) {\n minDistance = distance;\n bestMatch = { profileId, distance };\n }\n }\n }\n\n return bestMatch;\n }\n\n async addOrUpdateFace(\n descriptor: Float32Array,\n attributes?: Partial<FaceProfile>\n ): Promise<string> {\n // Check if this face already exists\n const match = await this.recognizeFace(descriptor);\n\n if (match) {\n // Update existing profile\n const profile = this.faceLibrary.faces.get(match.profileId)!;\n profile.lastSeen = Date.now();\n profile.seenCount++;\n\n // Add new embedding for better recognition\n const embeddings = this.faceLibrary.embeddings.get(match.profileId)!;\n if (embeddings.length < 10) {\n // Keep up to 10 embeddings per person\n embeddings.push(Array.from(descriptor));\n }\n\n // Update attributes if provided\n if (attributes) {\n Object.assign(profile, attributes);\n }\n\n return match.profileId;\n } else {\n // Create new profile\n const profileId = `face-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const profile: FaceProfile = {\n id: profileId,\n embeddings: [Array.from(descriptor)],\n firstSeen: Date.now(),\n lastSeen: Date.now(),\n seenCount: 1,\n ...attributes,\n };\n\n this.faceLibrary.faces.set(profileId, profile);\n this.faceLibrary.embeddings.set(profileId, [Array.from(descriptor)]);\n\n logger.info(`[FaceRecognition] New face registered: ${profileId}`);\n return profileId;\n }\n }\n\n getFaceProfile(profileId: string): FaceProfile | undefined {\n return this.faceLibrary.faces.get(profileId);\n }\n\n getAllProfiles(): FaceProfile[] {\n return Array.from(this.faceLibrary.faces.values());\n }\n\n private euclideanDistance(a: Float32Array | number[], b: number[]): number {\n let sum = 0;\n const aArray = Array.from(a);\n for (let i = 0; i < aArray.length; i++) {\n sum += Math.pow(aArray[i] - b[i], 2);\n }\n return Math.sqrt(sum);\n }\n\n // Persistence methods\n async saveFaceLibrary(path: string): Promise<void> {\n const data = {\n faces: Array.from(this.faceLibrary.faces.entries()),\n embeddings: Array.from(this.faceLibrary.embeddings.entries()),\n };\n\n const fs = await import('fs/promises');\n await fs.writeFile(path, JSON.stringify(data, null, 2));\n logger.info(`[FaceRecognition] Face library saved to ${path}`);\n }\n\n async loadFaceLibrary(path: string): Promise<void> {\n try {\n const fs = await import('fs/promises');\n const data = JSON.parse(await fs.readFile(path, 'utf-8'));\n\n this.faceLibrary.faces = new Map(data.faces);\n this.faceLibrary.embeddings = new Map(data.embeddings);\n\n logger.info(`[FaceRecognition] Loaded ${this.faceLibrary.faces.size} face profiles`);\n } catch (error) {\n logger.warn('[FaceRecognition] Could not load face library:', error);\n }\n }\n}\n"]}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { Florence2Result } from './types';
|
|
2
|
-
interface Florence2LocalConfig {
|
|
3
|
-
modelPath?: string;
|
|
4
|
-
modelUrl?: string;
|
|
5
|
-
cacheDir?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare class Florence2Local {
|
|
8
|
-
private model;
|
|
9
|
-
private initialized;
|
|
10
|
-
private config;
|
|
11
|
-
private readonly IMAGE_SIZE;
|
|
12
|
-
private readonly VOCAB_SIZE;
|
|
13
|
-
constructor(config?: Florence2LocalConfig);
|
|
14
|
-
initialize(): Promise<void>;
|
|
15
|
-
analyzeImage(imageBuffer: Buffer): Promise<Florence2Result>;
|
|
16
|
-
private preprocessImage;
|
|
17
|
-
private runInference;
|
|
18
|
-
private parseModelOutput;
|
|
19
|
-
private generateCaptionFromFeatures;
|
|
20
|
-
private extractTagsFromCaption;
|
|
21
|
-
private enhancedFallback;
|
|
22
|
-
isInitialized(): boolean;
|
|
23
|
-
dispose(): Promise<void>;
|
|
24
|
-
}
|
|
25
|
-
export {};
|