@elizaos/plugin-vision 1.2.1
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/.npmignore +5 -0
- package/README.md +270 -0
- package/build.config.ts +70 -0
- package/dist/action.d.ts +8 -0
- package/dist/action.js +1212 -0
- package/dist/action.js.map +1 -0
- package/dist/audio-capture-stream.d.ts +42 -0
- package/dist/audio-capture-stream.js +516 -0
- package/dist/audio-capture-stream.js.map +1 -0
- package/dist/audio-capture.d.ts +25 -0
- package/dist/audio-capture.js +412 -0
- package/dist/audio-capture.js.map +1 -0
- package/dist/basic.test.d.ts +1 -0
- package/dist/basic.test.js +97 -0
- package/dist/basic.test.js.map +1 -0
- package/dist/config.d.ts +73 -0
- package/dist/config.js +254 -0
- package/dist/config.js.map +1 -0
- package/dist/entity-tracker.d.ts +32 -0
- package/dist/entity-tracker.js +361 -0
- package/dist/entity-tracker.js.map +1 -0
- package/dist/errors.d.ts +67 -0
- package/dist/errors.js +395 -0
- package/dist/errors.js.map +1 -0
- package/dist/face-recognition.d.ts +31 -0
- package/dist/face-recognition.js +332 -0
- package/dist/face-recognition.js.map +1 -0
- package/dist/florence2-local.d.ts +25 -0
- package/dist/florence2-local.js +280 -0
- package/dist/florence2-local.js.map +1 -0
- package/dist/florence2-model.d.ts +36 -0
- package/dist/florence2-model.js +503 -0
- package/dist/florence2-model.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +73 -0
- package/dist/index.js.map +1 -0
- package/dist/ocr-service-real.d.ts +32 -0
- package/dist/ocr-service-real.js +396 -0
- package/dist/ocr-service-real.js.map +1 -0
- package/dist/ocr-service.d.ts +28 -0
- package/dist/ocr-service.js +216 -0
- package/dist/ocr-service.js.map +1 -0
- package/dist/provider.d.ts +2 -0
- package/dist/provider.js +285 -0
- package/dist/provider.js.map +1 -0
- package/dist/screen-capture.d.ts +16 -0
- package/dist/screen-capture.js +302 -0
- package/dist/screen-capture.js.map +1 -0
- package/dist/service.d.ts +73 -0
- package/dist/service.js +1662 -0
- package/dist/service.js.map +1 -0
- package/dist/tests/e2e/index.d.ts +8 -0
- package/dist/tests/e2e/index.js +33 -0
- package/dist/tests/e2e/index.js.map +1 -0
- package/dist/tests/e2e/run-local.d.ts +2 -0
- package/dist/tests/e2e/run-local.js +166 -0
- package/dist/tests/e2e/run-local.js.map +1 -0
- package/dist/tests/e2e/screen-vision.d.ts +11 -0
- package/dist/tests/e2e/screen-vision.js +384 -0
- package/dist/tests/e2e/screen-vision.js.map +1 -0
- package/dist/tests/e2e/vision-autonomy.d.ts +11 -0
- package/dist/tests/e2e/vision-autonomy.js +375 -0
- package/dist/tests/e2e/vision-autonomy.js.map +1 -0
- package/dist/tests/e2e/vision-basic.d.ts +11 -0
- package/dist/tests/e2e/vision-basic.js +434 -0
- package/dist/tests/e2e/vision-basic.js.map +1 -0
- package/dist/tests/e2e/vision-capture-log.d.ts +11 -0
- package/dist/tests/e2e/vision-capture-log.js +302 -0
- package/dist/tests/e2e/vision-capture-log.js.map +1 -0
- package/dist/tests/e2e/vision-runtime.d.ts +11 -0
- package/dist/tests/e2e/vision-runtime.js +357 -0
- package/dist/tests/e2e/vision-runtime.js.map +1 -0
- package/dist/tests/e2e/vision-worker-tests.d.ts +11 -0
- package/dist/tests/e2e/vision-worker-tests.js +466 -0
- package/dist/tests/e2e/vision-worker-tests.js.map +1 -0
- package/dist/tests/test-pattern-generator.d.ts +40 -0
- package/dist/tests/test-pattern-generator.js +191 -0
- package/dist/tests/test-pattern-generator.js.map +1 -0
- package/dist/tests.d.ts +3 -0
- package/dist/tests.js +11 -0
- package/dist/tests.js.map +1 -0
- package/dist/types.d.ts +222 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/vision-models.d.ts +47 -0
- package/dist/vision-models.js +501 -0
- package/dist/vision-models.js.map +1 -0
- package/dist/vision-worker-manager.d.ts +61 -0
- package/dist/vision-worker-manager.js +668 -0
- package/dist/vision-worker-manager.js.map +1 -0
- package/dist/workers/florence2-worker-simple.d.ts +13 -0
- package/dist/workers/florence2-worker-simple.js +121 -0
- package/dist/workers/florence2-worker-simple.js.map +1 -0
- package/dist/workers/florence2-worker.d.ts +1 -0
- package/dist/workers/florence2-worker.js +328 -0
- package/dist/workers/florence2-worker.js.map +1 -0
- package/dist/workers/ocr-worker.d.ts +1 -0
- package/dist/workers/ocr-worker.js +354 -0
- package/dist/workers/ocr-worker.js.map +1 -0
- package/dist/workers/screen-capture-worker.d.ts +1 -0
- package/dist/workers/screen-capture-worker.js +427 -0
- package/dist/workers/screen-capture-worker.js.map +1 -0
- package/dist/workers/worker-logger.d.ts +9 -0
- package/dist/workers/worker-logger.js +95 -0
- package/dist/workers/worker-logger.js.map +1 -0
- package/package.json +100 -0
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
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);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
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;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.VisionBasicE2ETestSuite = void 0;
|
|
40
|
+
var core_1 = require("@elizaos/core");
|
|
41
|
+
var action_1 = require("../../action");
|
|
42
|
+
var VisionBasicE2ETestSuite = /** @class */ (function () {
|
|
43
|
+
function VisionBasicE2ETestSuite() {
|
|
44
|
+
var _this = this;
|
|
45
|
+
this.name = 'plugin-vision-basic-e2e';
|
|
46
|
+
this.description = 'Basic end-to-end tests for vision plugin functionality';
|
|
47
|
+
this.tests = [
|
|
48
|
+
{
|
|
49
|
+
name: 'Should initialize vision service',
|
|
50
|
+
fn: function (runtime) { return __awaiter(_this, void 0, void 0, function () {
|
|
51
|
+
var visionService, isActive, cameraInfo;
|
|
52
|
+
return __generator(this, function (_a) {
|
|
53
|
+
console.log('Testing vision service initialization...');
|
|
54
|
+
visionService = runtime.getService('VISION');
|
|
55
|
+
if (!visionService) {
|
|
56
|
+
throw new Error('Vision service not available - service must be registered');
|
|
57
|
+
}
|
|
58
|
+
isActive = visionService.isActive();
|
|
59
|
+
cameraInfo = visionService.getCameraInfo();
|
|
60
|
+
if (!isActive || !cameraInfo) {
|
|
61
|
+
// For CI/CD environments without cameras, check that service at least initializes
|
|
62
|
+
console.warn('⚠️ No camera detected. Service initialized but not active.');
|
|
63
|
+
console.log(' This is acceptable in CI/CD environments without cameras.');
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.log('✓ Vision service initialized and active');
|
|
67
|
+
console.log("\u2713 Connected to camera: ".concat(cameraInfo.name, " (ID: ").concat(cameraInfo.id, ")"));
|
|
68
|
+
}
|
|
69
|
+
return [2 /*return*/];
|
|
70
|
+
});
|
|
71
|
+
}); },
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'Should describe scene when requested',
|
|
75
|
+
fn: function (runtime) { return __awaiter(_this, void 0, void 0, function () {
|
|
76
|
+
var roomId, message, callbackCalled, callbackResponse, state, visionService, isValid;
|
|
77
|
+
var _this = this;
|
|
78
|
+
return __generator(this, function (_a) {
|
|
79
|
+
switch (_a.label) {
|
|
80
|
+
case 0:
|
|
81
|
+
console.log('Testing scene description action...');
|
|
82
|
+
roomId = (0, core_1.createUniqueUuid)(runtime, 'test-room');
|
|
83
|
+
message = {
|
|
84
|
+
id: (0, core_1.createUniqueUuid)(runtime, 'test-msg-describe'),
|
|
85
|
+
entityId: runtime.agentId,
|
|
86
|
+
content: { text: 'what do you see?' },
|
|
87
|
+
agentId: runtime.agentId,
|
|
88
|
+
roomId: roomId,
|
|
89
|
+
createdAt: Date.now(),
|
|
90
|
+
};
|
|
91
|
+
callbackCalled = false;
|
|
92
|
+
callbackResponse = null;
|
|
93
|
+
state = { values: {}, data: {}, text: '' };
|
|
94
|
+
visionService = runtime.getService('VISION');
|
|
95
|
+
return [4 /*yield*/, action_1.describeSceneAction.validate(runtime, message, state)];
|
|
96
|
+
case 1:
|
|
97
|
+
isValid = _a.sent();
|
|
98
|
+
if (!(!visionService || !visionService.isActive())) return [3 /*break*/, 3];
|
|
99
|
+
// If vision service is not active, validation should return false
|
|
100
|
+
if (isValid) {
|
|
101
|
+
throw new Error('Action validation should return false when vision service is not active');
|
|
102
|
+
}
|
|
103
|
+
console.log(' Action validation correctly returned false (vision not active)');
|
|
104
|
+
// But handler should still work and provide appropriate message
|
|
105
|
+
return [4 /*yield*/, action_1.describeSceneAction.handler(runtime, message, state, {}, function (response) { return __awaiter(_this, void 0, void 0, function () {
|
|
106
|
+
return __generator(this, function (_a) {
|
|
107
|
+
callbackCalled = true;
|
|
108
|
+
callbackResponse = response;
|
|
109
|
+
return [2 /*return*/, []];
|
|
110
|
+
});
|
|
111
|
+
}); })];
|
|
112
|
+
case 2:
|
|
113
|
+
// But handler should still work and provide appropriate message
|
|
114
|
+
_a.sent();
|
|
115
|
+
if (!callbackCalled) {
|
|
116
|
+
throw new Error('Callback was not called - action handler failed');
|
|
117
|
+
}
|
|
118
|
+
if (!callbackResponse || !callbackResponse.text) {
|
|
119
|
+
throw new Error('No response text returned from action');
|
|
120
|
+
}
|
|
121
|
+
console.log('✓ Scene description action handled unavailability correctly');
|
|
122
|
+
console.log(" Response: ".concat(callbackResponse.text));
|
|
123
|
+
// Verify it indicates camera not available
|
|
124
|
+
if (!callbackResponse.text.includes('cannot see') &&
|
|
125
|
+
!callbackResponse.text.includes('no camera')) {
|
|
126
|
+
throw new Error('Response does not indicate camera unavailability');
|
|
127
|
+
}
|
|
128
|
+
return [3 /*break*/, 5];
|
|
129
|
+
case 3:
|
|
130
|
+
// Vision is active, normal test flow
|
|
131
|
+
if (!isValid) {
|
|
132
|
+
throw new Error('describeSceneAction validation failed despite active vision');
|
|
133
|
+
}
|
|
134
|
+
console.log(' Action validation: passed');
|
|
135
|
+
return [4 /*yield*/, action_1.describeSceneAction.handler(runtime, message, state, {}, function (response) { return __awaiter(_this, void 0, void 0, function () {
|
|
136
|
+
return __generator(this, function (_a) {
|
|
137
|
+
callbackCalled = true;
|
|
138
|
+
callbackResponse = response;
|
|
139
|
+
return [2 /*return*/, []];
|
|
140
|
+
});
|
|
141
|
+
}); })];
|
|
142
|
+
case 4:
|
|
143
|
+
_a.sent();
|
|
144
|
+
if (!callbackCalled) {
|
|
145
|
+
throw new Error('Callback was not called - action handler failed');
|
|
146
|
+
}
|
|
147
|
+
if (!callbackResponse || !callbackResponse.text) {
|
|
148
|
+
throw new Error('No response text returned from action');
|
|
149
|
+
}
|
|
150
|
+
console.log('✓ Scene description action executed');
|
|
151
|
+
console.log(" Response: ".concat(callbackResponse.text));
|
|
152
|
+
if (callbackResponse.thought) {
|
|
153
|
+
console.log(" Thought: ".concat(callbackResponse.thought));
|
|
154
|
+
}
|
|
155
|
+
_a.label = 5;
|
|
156
|
+
case 5:
|
|
157
|
+
// Verify response contains expected action
|
|
158
|
+
if (!callbackResponse.actions || !callbackResponse.actions.includes('DESCRIBE_SCENE')) {
|
|
159
|
+
throw new Error('Response does not include DESCRIBE_SCENE action');
|
|
160
|
+
}
|
|
161
|
+
return [2 /*return*/];
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}); },
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: 'Should capture image when requested',
|
|
168
|
+
fn: function (runtime) { return __awaiter(_this, void 0, void 0, function () {
|
|
169
|
+
var roomId, message, callbackCalled, callbackResponse, state, visionService, isValid, attachment;
|
|
170
|
+
var _this = this;
|
|
171
|
+
return __generator(this, function (_a) {
|
|
172
|
+
switch (_a.label) {
|
|
173
|
+
case 0:
|
|
174
|
+
console.log('Testing image capture action...');
|
|
175
|
+
roomId = (0, core_1.createUniqueUuid)(runtime, 'test-room');
|
|
176
|
+
message = {
|
|
177
|
+
id: (0, core_1.createUniqueUuid)(runtime, 'test-msg-capture'),
|
|
178
|
+
entityId: runtime.agentId,
|
|
179
|
+
content: { text: 'take a photo' },
|
|
180
|
+
agentId: runtime.agentId,
|
|
181
|
+
roomId: roomId,
|
|
182
|
+
createdAt: Date.now(),
|
|
183
|
+
};
|
|
184
|
+
callbackCalled = false;
|
|
185
|
+
callbackResponse = null;
|
|
186
|
+
state = { values: {}, data: {}, text: '' };
|
|
187
|
+
visionService = runtime.getService('VISION');
|
|
188
|
+
return [4 /*yield*/, action_1.captureImageAction.validate(runtime, message, state)];
|
|
189
|
+
case 1:
|
|
190
|
+
isValid = _a.sent();
|
|
191
|
+
if (!(!visionService || !visionService.isActive())) return [3 /*break*/, 3];
|
|
192
|
+
// If vision service is not active, validation should return false
|
|
193
|
+
if (isValid) {
|
|
194
|
+
throw new Error('Action validation should return false when vision service is not active');
|
|
195
|
+
}
|
|
196
|
+
console.log(' Action validation correctly returned false (vision not active)');
|
|
197
|
+
// But handler should still work and provide appropriate message
|
|
198
|
+
return [4 /*yield*/, action_1.captureImageAction.handler(runtime, message, state, {}, function (response) { return __awaiter(_this, void 0, void 0, function () {
|
|
199
|
+
return __generator(this, function (_a) {
|
|
200
|
+
callbackCalled = true;
|
|
201
|
+
callbackResponse = response;
|
|
202
|
+
return [2 /*return*/, []];
|
|
203
|
+
});
|
|
204
|
+
}); })];
|
|
205
|
+
case 2:
|
|
206
|
+
// But handler should still work and provide appropriate message
|
|
207
|
+
_a.sent();
|
|
208
|
+
if (!callbackCalled) {
|
|
209
|
+
throw new Error('Callback was not called - action handler failed');
|
|
210
|
+
}
|
|
211
|
+
if (!callbackResponse || !callbackResponse.text) {
|
|
212
|
+
throw new Error('No response text returned from action');
|
|
213
|
+
}
|
|
214
|
+
console.log('✓ Image capture action handled unavailability correctly');
|
|
215
|
+
console.log(" Response: ".concat(callbackResponse.text));
|
|
216
|
+
// Verify it indicates camera not available
|
|
217
|
+
if (!callbackResponse.text.includes('cannot capture') &&
|
|
218
|
+
!callbackResponse.text.includes('no camera')) {
|
|
219
|
+
throw new Error('Response does not indicate camera unavailability');
|
|
220
|
+
}
|
|
221
|
+
return [3 /*break*/, 5];
|
|
222
|
+
case 3:
|
|
223
|
+
// Vision is active, normal test flow
|
|
224
|
+
if (!isValid) {
|
|
225
|
+
throw new Error('captureImageAction validation failed despite active vision');
|
|
226
|
+
}
|
|
227
|
+
console.log(' Action validation: passed');
|
|
228
|
+
return [4 /*yield*/, action_1.captureImageAction.handler(runtime, message, state, {}, function (response) { return __awaiter(_this, void 0, void 0, function () {
|
|
229
|
+
return __generator(this, function (_a) {
|
|
230
|
+
callbackCalled = true;
|
|
231
|
+
callbackResponse = response;
|
|
232
|
+
return [2 /*return*/, []];
|
|
233
|
+
});
|
|
234
|
+
}); })];
|
|
235
|
+
case 4:
|
|
236
|
+
_a.sent();
|
|
237
|
+
if (!callbackCalled) {
|
|
238
|
+
throw new Error('Callback was not called - action handler failed');
|
|
239
|
+
}
|
|
240
|
+
if (!callbackResponse || !callbackResponse.text) {
|
|
241
|
+
throw new Error('No response text returned from action');
|
|
242
|
+
}
|
|
243
|
+
console.log('✓ Image capture action executed');
|
|
244
|
+
console.log(" Response: ".concat(callbackResponse.text));
|
|
245
|
+
// If camera is active, we should have an attachment
|
|
246
|
+
if (!callbackResponse.attachments || callbackResponse.attachments.length === 0) {
|
|
247
|
+
throw new Error('No image attachment returned despite active camera');
|
|
248
|
+
}
|
|
249
|
+
attachment = callbackResponse.attachments[0];
|
|
250
|
+
if (!attachment.url || !attachment.url.startsWith('data:image/')) {
|
|
251
|
+
throw new Error('Invalid image attachment format');
|
|
252
|
+
}
|
|
253
|
+
console.log(" \u2713 Image attachment valid: ".concat(attachment.title));
|
|
254
|
+
_a.label = 5;
|
|
255
|
+
case 5:
|
|
256
|
+
// Verify response contains expected action
|
|
257
|
+
if (!callbackResponse.actions || !callbackResponse.actions.includes('CAPTURE_IMAGE')) {
|
|
258
|
+
throw new Error('Response does not include CAPTURE_IMAGE action');
|
|
259
|
+
}
|
|
260
|
+
return [2 /*return*/];
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}); },
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
name: 'Should provide vision context through provider',
|
|
267
|
+
fn: function (runtime) { return __awaiter(_this, void 0, void 0, function () {
|
|
268
|
+
var message, state;
|
|
269
|
+
return __generator(this, function (_a) {
|
|
270
|
+
switch (_a.label) {
|
|
271
|
+
case 0:
|
|
272
|
+
console.log('Testing vision provider...');
|
|
273
|
+
message = {
|
|
274
|
+
id: (0, core_1.createUniqueUuid)(runtime, 'test-msg-provider'),
|
|
275
|
+
entityId: runtime.agentId,
|
|
276
|
+
content: { text: 'test provider' },
|
|
277
|
+
agentId: runtime.agentId,
|
|
278
|
+
roomId: (0, core_1.createUniqueUuid)(runtime, 'test-room'),
|
|
279
|
+
createdAt: Date.now(),
|
|
280
|
+
};
|
|
281
|
+
return [4 /*yield*/, runtime.composeState(message)];
|
|
282
|
+
case 1:
|
|
283
|
+
state = _a.sent();
|
|
284
|
+
// Vision provider should always add data
|
|
285
|
+
if (state.values.visionAvailable === undefined) {
|
|
286
|
+
throw new Error('Vision provider data missing - provider not registered or failed');
|
|
287
|
+
}
|
|
288
|
+
console.log('✓ Vision provider data found in state');
|
|
289
|
+
console.log(" Vision available: ".concat(state.values.visionAvailable));
|
|
290
|
+
console.log(" Camera status: ".concat(state.values.cameraStatus));
|
|
291
|
+
// Verify vision context in formatted text
|
|
292
|
+
if (!state.text.includes('Visual Perception')) {
|
|
293
|
+
throw new Error('Vision context not included in state text');
|
|
294
|
+
}
|
|
295
|
+
console.log('✓ Vision context included in state text');
|
|
296
|
+
// If vision is available, verify scene data
|
|
297
|
+
if (state.values.visionAvailable && state.values.sceneDescription) {
|
|
298
|
+
console.log(" Scene description: ".concat(state.values.sceneDescription));
|
|
299
|
+
}
|
|
300
|
+
return [2 /*return*/];
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
}); },
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: 'Should handle scene changes efficiently',
|
|
307
|
+
fn: function (runtime) { return __awaiter(_this, void 0, void 0, function () {
|
|
308
|
+
var visionService, initialScene, updatedScene;
|
|
309
|
+
return __generator(this, function (_a) {
|
|
310
|
+
switch (_a.label) {
|
|
311
|
+
case 0:
|
|
312
|
+
console.log('Testing scene change detection...');
|
|
313
|
+
visionService = runtime.getService('VISION');
|
|
314
|
+
if (!visionService) {
|
|
315
|
+
throw new Error('Vision service not available');
|
|
316
|
+
}
|
|
317
|
+
if (!visionService.isActive()) {
|
|
318
|
+
console.warn('⚠️ Vision service not active - skipping scene change test');
|
|
319
|
+
console.log(' This is acceptable in environments without cameras');
|
|
320
|
+
return [2 /*return*/];
|
|
321
|
+
}
|
|
322
|
+
return [4 /*yield*/, visionService.getSceneDescription()];
|
|
323
|
+
case 1:
|
|
324
|
+
initialScene = _a.sent();
|
|
325
|
+
console.log(" Initial scene: ".concat(initialScene ? 'Available' : 'Pending...'));
|
|
326
|
+
// Wait for scene processing
|
|
327
|
+
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })];
|
|
328
|
+
case 2:
|
|
329
|
+
// Wait for scene processing
|
|
330
|
+
_a.sent();
|
|
331
|
+
return [4 /*yield*/, visionService.getSceneDescription()];
|
|
332
|
+
case 3:
|
|
333
|
+
updatedScene = _a.sent();
|
|
334
|
+
if (!updatedScene) {
|
|
335
|
+
throw new Error('No scene description available after 2 seconds');
|
|
336
|
+
}
|
|
337
|
+
console.log('✓ Scene monitoring active');
|
|
338
|
+
console.log(" Scene timestamp: ".concat(new Date(updatedScene.timestamp).toISOString()));
|
|
339
|
+
console.log(" Description: ".concat(updatedScene.description.substring(0, 100), "..."));
|
|
340
|
+
if (updatedScene.changePercentage !== undefined) {
|
|
341
|
+
console.log(" Last change: ".concat(updatedScene.changePercentage.toFixed(1), "%"));
|
|
342
|
+
}
|
|
343
|
+
return [2 /*return*/];
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
}); },
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
name: 'Should detect objects and people in scene',
|
|
350
|
+
fn: function (runtime) { return __awaiter(_this, void 0, void 0, function () {
|
|
351
|
+
var visionService, scene, objectTypes, _i, _a, _b, type, count, _c, _d, obj, _e, _f, person;
|
|
352
|
+
return __generator(this, function (_g) {
|
|
353
|
+
switch (_g.label) {
|
|
354
|
+
case 0:
|
|
355
|
+
console.log('Testing object and person detection...');
|
|
356
|
+
visionService = runtime.getService('VISION');
|
|
357
|
+
if (!visionService) {
|
|
358
|
+
throw new Error('Vision service not available');
|
|
359
|
+
}
|
|
360
|
+
if (!visionService.isActive()) {
|
|
361
|
+
console.warn('⚠️ Vision service not active - skipping detection test');
|
|
362
|
+
console.log(' This is acceptable in environments without cameras');
|
|
363
|
+
return [2 /*return*/];
|
|
364
|
+
}
|
|
365
|
+
// Wait for scene processing to accumulate frames
|
|
366
|
+
console.log(' Waiting for scene analysis...');
|
|
367
|
+
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 3000); })];
|
|
368
|
+
case 1:
|
|
369
|
+
_g.sent();
|
|
370
|
+
return [4 /*yield*/, visionService.getSceneDescription()];
|
|
371
|
+
case 2:
|
|
372
|
+
scene = _g.sent();
|
|
373
|
+
if (!scene) {
|
|
374
|
+
throw new Error('No scene description available after 3 seconds');
|
|
375
|
+
}
|
|
376
|
+
console.log('✓ Scene analysis complete');
|
|
377
|
+
console.log(" Description: ".concat(scene.description.substring(0, 100), "..."));
|
|
378
|
+
console.log(" Objects detected: ".concat(scene.objects.length));
|
|
379
|
+
console.log(" People detected: ".concat(scene.people.length));
|
|
380
|
+
// Verify object detection
|
|
381
|
+
if (scene.objects.length > 0) {
|
|
382
|
+
console.log(' Detected objects:');
|
|
383
|
+
objectTypes = scene.objects.reduce(function (acc, obj) {
|
|
384
|
+
acc[obj.type] = (acc[obj.type] || 0) + 1;
|
|
385
|
+
return acc;
|
|
386
|
+
}, {});
|
|
387
|
+
for (_i = 0, _a = Object.entries(objectTypes); _i < _a.length; _i++) {
|
|
388
|
+
_b = _a[_i], type = _b[0], count = _b[1];
|
|
389
|
+
console.log(" - ".concat(count, " ").concat(type, "(s)"));
|
|
390
|
+
}
|
|
391
|
+
// Verify objects have required fields
|
|
392
|
+
for (_c = 0, _d = scene.objects; _c < _d.length; _c++) {
|
|
393
|
+
obj = _d[_c];
|
|
394
|
+
if (!obj.id || !obj.type || obj.confidence === undefined || !obj.boundingBox) {
|
|
395
|
+
throw new Error('Detected object missing required fields');
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
// Verify person detection
|
|
400
|
+
if (scene.people.length > 0) {
|
|
401
|
+
console.log(' Detected people:');
|
|
402
|
+
for (_e = 0, _f = scene.people; _e < _f.length; _e++) {
|
|
403
|
+
person = _f[_e];
|
|
404
|
+
console.log(" - Person ".concat(person.id, ": ").concat(person.pose, " pose, facing ").concat(person.facing, ", confidence ").concat(person.confidence.toFixed(2)));
|
|
405
|
+
// Verify person has required fields
|
|
406
|
+
if (!person.id ||
|
|
407
|
+
!person.pose ||
|
|
408
|
+
!person.facing ||
|
|
409
|
+
person.confidence === undefined ||
|
|
410
|
+
!person.boundingBox) {
|
|
411
|
+
throw new Error('Detected person missing required fields');
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// If there's motion, we should detect something
|
|
416
|
+
if (scene.changePercentage > 10) {
|
|
417
|
+
console.log(" Scene change: ".concat(scene.changePercentage.toFixed(1), "%"));
|
|
418
|
+
if (scene.objects.length === 0 && scene.people.length === 0) {
|
|
419
|
+
console.warn(' ⚠️ Significant scene change but no objects/people detected');
|
|
420
|
+
console.log(' This might indicate the motion detection threshold needs adjustment');
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return [2 /*return*/];
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
}); },
|
|
427
|
+
},
|
|
428
|
+
];
|
|
429
|
+
}
|
|
430
|
+
return VisionBasicE2ETestSuite;
|
|
431
|
+
}());
|
|
432
|
+
exports.VisionBasicE2ETestSuite = VisionBasicE2ETestSuite;
|
|
433
|
+
exports.default = new VisionBasicE2ETestSuite();
|
|
434
|
+
//# sourceMappingURL=vision-basic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vision-basic.js","sourceRoot":"","sources":["../../../src/tests/e2e/vision-basic.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,sCAAiD;AAEjD,uCAAuE;AAEvE;IAAA;QAAA,iBA6YC;QA5YC,SAAI,GAAG,yBAAyB,CAAC;QACjC,gBAAW,GAAG,wDAAwD,CAAC;QAEvE,UAAK,GAAG;YACN;gBACE,IAAI,EAAE,kCAAkC;gBACxC,EAAE,EAAE,UAAO,OAAsB;;;wBAC/B,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;wBAElD,aAAa,GAAG,OAAO,CAAC,UAAU,CAAgB,QAAe,CAAC,CAAC;wBACzE,IAAI,CAAC,aAAa,EAAE,CAAC;4BACnB,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;wBAC/E,CAAC;wBAGK,QAAQ,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC;wBAGpC,UAAU,GAAG,aAAa,CAAC,aAAa,EAAE,CAAC;wBAEjD,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU,EAAE,CAAC;4BAC7B,kFAAkF;4BAClF,OAAO,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;4BAC5E,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;wBAC9E,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;4BACvD,OAAO,CAAC,GAAG,CAAC,sCAA0B,UAAU,CAAC,IAAI,mBAAS,UAAU,CAAC,EAAE,MAAG,CAAC,CAAC;wBAClF,CAAC;;;qBACF;aACF;YAED;gBACE,IAAI,EAAE,sCAAsC;gBAC5C,EAAE,EAAE,UAAO,OAAsB;;;;;;gCAC/B,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;gCAE7C,MAAM,GAAG,IAAA,uBAAgB,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gCAChD,OAAO,GAAW;oCACtB,EAAE,EAAE,IAAA,uBAAgB,EAAC,OAAO,EAAE,mBAAmB,CAAC;oCAClD,QAAQ,EAAE,OAAO,CAAC,OAAO;oCACzB,OAAO,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE;oCACrC,OAAO,EAAE,OAAO,CAAC,OAAO;oCACxB,MAAM,QAAA;oCACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iCACtB,CAAC;gCAEE,cAAc,GAAG,KAAK,CAAC;gCACvB,gBAAgB,GAAQ,IAAI,CAAC;gCAE3B,KAAK,GAAU,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;gCAGlD,aAAa,GAAG,OAAO,CAAC,UAAU,CAAgB,QAAe,CAAC,CAAC;gCAGzD,qBAAM,4BAAmB,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAA;;gCAArE,OAAO,GAAG,SAA2D;qCAEvE,CAAA,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAA,EAA3C,wBAA2C;gCAC7C,kEAAkE;gCAClE,IAAI,OAAO,EAAE,CAAC;oCACZ,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;gCACJ,CAAC;gCACD,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;gCAEhF,gEAAgE;gCAChE,qBAAM,4BAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,UAAO,QAAQ;;4CAC5E,cAAc,GAAG,IAAI,CAAC;4CACtB,gBAAgB,GAAG,QAAQ,CAAC;4CAC5B,sBAAO,EAAE,EAAC;;yCACX,CAAC,EAAA;;gCALF,gEAAgE;gCAChE,SAIE,CAAC;gCAEH,IAAI,CAAC,cAAc,EAAE,CAAC;oCACpB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gCACrE,CAAC;gCAED,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;oCAChD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;gCAC3D,CAAC;gCAED,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;gCAC3E,OAAO,CAAC,GAAG,CAAC,sBAAe,gBAAgB,CAAC,IAAI,CAAE,CAAC,CAAC;gCAEpD,2CAA2C;gCAC3C,IACE,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;oCAC7C,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAC5C,CAAC;oCACD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;gCACtE,CAAC;;;gCAED,qCAAqC;gCACrC,IAAI,CAAC,OAAO,EAAE,CAAC;oCACb,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;gCACjF,CAAC;gCACD,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;gCAE3C,qBAAM,4BAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,UAAO,QAAQ;;4CAC5E,cAAc,GAAG,IAAI,CAAC;4CACtB,gBAAgB,GAAG,QAAQ,CAAC;4CAC5B,sBAAO,EAAE,EAAC;;yCACX,CAAC,EAAA;;gCAJF,SAIE,CAAC;gCAEH,IAAI,CAAC,cAAc,EAAE,CAAC;oCACpB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gCACrE,CAAC;gCAED,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;oCAChD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;gCAC3D,CAAC;gCAED,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;gCACnD,OAAO,CAAC,GAAG,CAAC,sBAAe,gBAAgB,CAAC,IAAI,CAAE,CAAC,CAAC;gCACpD,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;oCAC7B,OAAO,CAAC,GAAG,CAAC,qBAAc,gBAAgB,CAAC,OAAO,CAAE,CAAC,CAAC;gCACxD,CAAC;;;gCAGH,2CAA2C;gCAC3C,IAAI,CAAC,gBAAgB,CAAC,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;oCACtF,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gCACrE,CAAC;;;;qBACF;aACF;YAED;gBACE,IAAI,EAAE,qCAAqC;gBAC3C,EAAE,EAAE,UAAO,OAAsB;;;;;;gCAC/B,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;gCAEzC,MAAM,GAAG,IAAA,uBAAgB,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gCAChD,OAAO,GAAW;oCACtB,EAAE,EAAE,IAAA,uBAAgB,EAAC,OAAO,EAAE,kBAAkB,CAAC;oCACjD,QAAQ,EAAE,OAAO,CAAC,OAAO;oCACzB,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;oCACjC,OAAO,EAAE,OAAO,CAAC,OAAO;oCACxB,MAAM,QAAA;oCACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iCACtB,CAAC;gCAEE,cAAc,GAAG,KAAK,CAAC;gCACvB,gBAAgB,GAAQ,IAAI,CAAC;gCAE3B,KAAK,GAAU,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;gCAGlD,aAAa,GAAG,OAAO,CAAC,UAAU,CAAgB,QAAe,CAAC,CAAC;gCAGzD,qBAAM,2BAAkB,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAA;;gCAApE,OAAO,GAAG,SAA0D;qCAEtE,CAAA,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAA,EAA3C,wBAA2C;gCAC7C,kEAAkE;gCAClE,IAAI,OAAO,EAAE,CAAC;oCACZ,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;gCACJ,CAAC;gCACD,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;gCAEhF,gEAAgE;gCAChE,qBAAM,2BAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,UAAO,QAAQ;;4CAC3E,cAAc,GAAG,IAAI,CAAC;4CACtB,gBAAgB,GAAG,QAAQ,CAAC;4CAC5B,sBAAO,EAAE,EAAC;;yCACX,CAAC,EAAA;;gCALF,gEAAgE;gCAChE,SAIE,CAAC;gCAEH,IAAI,CAAC,cAAc,EAAE,CAAC;oCACpB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gCACrE,CAAC;gCAED,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;oCAChD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;gCAC3D,CAAC;gCAED,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;gCACvE,OAAO,CAAC,GAAG,CAAC,sBAAe,gBAAgB,CAAC,IAAI,CAAE,CAAC,CAAC;gCAEpD,2CAA2C;gCAC3C,IACE,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;oCACjD,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAC5C,CAAC;oCACD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;gCACtE,CAAC;;;gCAED,qCAAqC;gCACrC,IAAI,CAAC,OAAO,EAAE,CAAC;oCACb,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;gCAChF,CAAC;gCACD,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;gCAE3C,qBAAM,2BAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,UAAO,QAAQ;;4CAC3E,cAAc,GAAG,IAAI,CAAC;4CACtB,gBAAgB,GAAG,QAAQ,CAAC;4CAC5B,sBAAO,EAAE,EAAC;;yCACX,CAAC,EAAA;;gCAJF,SAIE,CAAC;gCAEH,IAAI,CAAC,cAAc,EAAE,CAAC;oCACpB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gCACrE,CAAC;gCAED,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;oCAChD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;gCAC3D,CAAC;gCAED,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;gCAC/C,OAAO,CAAC,GAAG,CAAC,sBAAe,gBAAgB,CAAC,IAAI,CAAE,CAAC,CAAC;gCAEpD,oDAAoD;gCACpD,IAAI,CAAC,gBAAgB,CAAC,WAAW,IAAI,gBAAgB,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oCAC/E,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;gCACxE,CAAC;gCAEK,UAAU,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;gCACnD,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;oCACjE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;gCACrD,CAAC;gCAED,OAAO,CAAC,GAAG,CAAC,2CAA+B,UAAU,CAAC,KAAK,CAAE,CAAC,CAAC;;;gCAGjE,2CAA2C;gCAC3C,IAAI,CAAC,gBAAgB,CAAC,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;oCACrF,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;gCACpE,CAAC;;;;qBACF;aACF;YAED;gBACE,IAAI,EAAE,gDAAgD;gBACtD,EAAE,EAAE,UAAO,OAAsB;;;;;gCAC/B,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;gCAGpC,OAAO,GAAW;oCACtB,EAAE,EAAE,IAAA,uBAAgB,EAAC,OAAO,EAAE,mBAAmB,CAAC;oCAClD,QAAQ,EAAE,OAAO,CAAC,OAAO;oCACzB,OAAO,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE;oCAClC,OAAO,EAAE,OAAO,CAAC,OAAO;oCACxB,MAAM,EAAE,IAAA,uBAAgB,EAAC,OAAO,EAAE,WAAW,CAAC;oCAC9C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iCACtB,CAAC;gCAEY,qBAAM,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,EAAA;;gCAA3C,KAAK,GAAG,SAAmC;gCAEjD,yCAAyC;gCACzC,IAAI,KAAK,CAAC,MAAM,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;oCAC/C,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;gCACtF,CAAC;gCAED,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;gCACrD,OAAO,CAAC,GAAG,CAAC,8BAAuB,KAAK,CAAC,MAAM,CAAC,eAAe,CAAE,CAAC,CAAC;gCACnE,OAAO,CAAC,GAAG,CAAC,2BAAoB,KAAK,CAAC,MAAM,CAAC,YAAY,CAAE,CAAC,CAAC;gCAE7D,0CAA0C;gCAC1C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;oCAC9C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;gCAC/D,CAAC;gCACD,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;gCAEvD,4CAA4C;gCAC5C,IAAI,KAAK,CAAC,MAAM,CAAC,eAAe,IAAI,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;oCAClE,OAAO,CAAC,GAAG,CAAC,+BAAwB,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAE,CAAC,CAAC;gCACvE,CAAC;;;;qBACF;aACF;YAED;gBACE,IAAI,EAAE,yCAAyC;gBAC/C,EAAE,EAAE,UAAO,OAAsB;;;;;gCAC/B,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;gCAE3C,aAAa,GAAG,OAAO,CAAC,UAAU,CAAgB,QAAe,CAAC,CAAC;gCACzE,IAAI,CAAC,aAAa,EAAE,CAAC;oCACnB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;gCAClD,CAAC;gCAED,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC;oCAC9B,OAAO,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;oCAC3E,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;oCACrE,sBAAO;gCACT,CAAC;gCAGoB,qBAAM,aAAa,CAAC,mBAAmB,EAAE,EAAA;;gCAAxD,YAAY,GAAG,SAAyC;gCAC9D,OAAO,CAAC,GAAG,CAAC,2BAAoB,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAE,CAAC,CAAC;gCAE7E,4BAA4B;gCAC5B,qBAAM,IAAI,OAAO,CAAC,UAAC,OAAO,IAAK,OAAA,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EAAzB,CAAyB,CAAC,EAAA;;gCADzD,4BAA4B;gCAC5B,SAAyD,CAAC;gCAGrC,qBAAM,aAAa,CAAC,mBAAmB,EAAE,EAAA;;gCAAxD,YAAY,GAAG,SAAyC;gCAE9D,IAAI,CAAC,YAAY,EAAE,CAAC;oCAClB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;gCACpE,CAAC;gCAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;gCACzC,OAAO,CAAC,GAAG,CAAC,6BAAsB,IAAI,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAE,CAAC,CAAC;gCACpF,OAAO,CAAC,GAAG,CAAC,yBAAkB,YAAY,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,QAAK,CAAC,CAAC;gCAE/E,IAAI,YAAY,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;oCAChD,OAAO,CAAC,GAAG,CAAC,yBAAkB,YAAY,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAG,CAAC,CAAC;gCAC7E,CAAC;;;;qBACF;aACF;YAED;gBACE,IAAI,EAAE,2CAA2C;gBACjD,EAAE,EAAE,UAAO,OAAsB;;;;;gCAC/B,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;gCAEhD,aAAa,GAAG,OAAO,CAAC,UAAU,CAAgB,QAAe,CAAC,CAAC;gCACzE,IAAI,CAAC,aAAa,EAAE,CAAC;oCACnB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;gCAClD,CAAC;gCAED,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC;oCAC9B,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;oCACxE,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;oCACrE,sBAAO;gCACT,CAAC;gCAED,iDAAiD;gCACjD,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;gCAC/C,qBAAM,IAAI,OAAO,CAAC,UAAC,OAAO,IAAK,OAAA,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EAAzB,CAAyB,CAAC,EAAA;;gCAAzD,SAAyD,CAAC;gCAG5C,qBAAM,aAAa,CAAC,mBAAmB,EAAE,EAAA;;gCAAjD,KAAK,GAAG,SAAyC;gCAEvD,IAAI,CAAC,KAAK,EAAE,CAAC;oCACX,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;gCACpE,CAAC;gCAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;gCACzC,OAAO,CAAC,GAAG,CAAC,yBAAkB,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,QAAK,CAAC,CAAC;gCACxE,OAAO,CAAC,GAAG,CAAC,8BAAuB,KAAK,CAAC,OAAO,CAAC,MAAM,CAAE,CAAC,CAAC;gCAC3D,OAAO,CAAC,GAAG,CAAC,6BAAsB,KAAK,CAAC,MAAM,CAAC,MAAM,CAAE,CAAC,CAAC;gCAEzD,0BAA0B;gCAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oCAC7B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;oCAC7B,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CACtC,UAAC,GAAG,EAAE,GAAG;wCACP,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;wCACzC,OAAO,GAAG,CAAC;oCACb,CAAC,EACD,EAA4B,CAC7B,CAAC;oCAEF,WAAuD,EAA3B,KAAA,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAA3B,cAA2B,EAA3B,IAA2B,EAAE,CAAC;wCAA/C,WAAa,EAAZ,IAAI,QAAA,EAAE,KAAK,QAAA;wCACrB,OAAO,CAAC,GAAG,CAAC,gBAAS,KAAK,cAAI,IAAI,QAAK,CAAC,CAAC;oCAC3C,CAAC;oCAED,sCAAsC;oCACtC,WAA+B,EAAb,KAAA,KAAK,CAAC,OAAO,EAAb,cAAa,EAAb,IAAa,EAAE,CAAC;wCAAvB,GAAG;wCACZ,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;4CAC7E,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;wCAC7D,CAAC;oCACH,CAAC;gCACH,CAAC;gCAED,0BAA0B;gCAC1B,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oCAC5B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;oCAClC,WAAiC,EAAZ,KAAA,KAAK,CAAC,MAAM,EAAZ,cAAY,EAAZ,IAAY,EAAE,CAAC;wCAAzB,MAAM;wCACf,OAAO,CAAC,GAAG,CACT,uBAAgB,MAAM,CAAC,EAAE,eAAK,MAAM,CAAC,IAAI,2BAAiB,MAAM,CAAC,MAAM,0BAAgB,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE,CACtH,CAAC;wCAEF,oCAAoC;wCACpC,IACE,CAAC,MAAM,CAAC,EAAE;4CACV,CAAC,MAAM,CAAC,IAAI;4CACZ,CAAC,MAAM,CAAC,MAAM;4CACd,MAAM,CAAC,UAAU,KAAK,SAAS;4CAC/B,CAAC,MAAM,CAAC,WAAW,EACnB,CAAC;4CACD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;wCAC7D,CAAC;oCACH,CAAC;gCACH,CAAC;gCAED,gDAAgD;gCAChD,IAAI,KAAK,CAAC,gBAAgB,GAAG,EAAE,EAAE,CAAC;oCAChC,OAAO,CAAC,GAAG,CAAC,0BAAmB,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAG,CAAC,CAAC;oCACrE,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wCAC5D,OAAO,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;wCAC9E,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;oCAC1F,CAAC;gCACH,CAAC;;;;qBACF;aACF;SACF,CAAC;IACJ,CAAC;IAAD,8BAAC;AAAD,CAAC,AA7YD,IA6YC;AA7YY,0DAAuB;AA+YpC,kBAAe,IAAI,uBAAuB,EAAE,CAAC","sourcesContent":["import type { TestSuite, IAgentRuntime, Memory, State } from '@elizaos/core';\nimport { createUniqueUuid } from '@elizaos/core';\nimport { VisionService } from '../../service';\nimport { describeSceneAction, captureImageAction } from '../../action';\n\nexport class VisionBasicE2ETestSuite implements TestSuite {\n name = 'plugin-vision-basic-e2e';\n description = 'Basic end-to-end tests for vision plugin functionality';\n\n tests = [\n {\n name: 'Should initialize vision service',\n fn: async (runtime: IAgentRuntime) => {\n console.log('Testing vision service initialization...');\n\n const visionService = runtime.getService<VisionService>('VISION' as any);\n if (!visionService) {\n throw new Error('Vision service not available - service must be registered');\n }\n\n // Check if service is active\n const isActive = visionService.isActive();\n\n // Get camera info\n const cameraInfo = visionService.getCameraInfo();\n\n if (!isActive || !cameraInfo) {\n // For CI/CD environments without cameras, check that service at least initializes\n console.warn('⚠️ No camera detected. Service initialized but not active.');\n console.log(' This is acceptable in CI/CD environments without cameras.');\n } else {\n console.log('✓ Vision service initialized and active');\n console.log(`✓ Connected to camera: ${cameraInfo.name} (ID: ${cameraInfo.id})`);\n }\n },\n },\n\n {\n name: 'Should describe scene when requested',\n fn: async (runtime: IAgentRuntime) => {\n console.log('Testing scene description action...');\n\n const roomId = createUniqueUuid(runtime, 'test-room');\n const message: Memory = {\n id: createUniqueUuid(runtime, 'test-msg-describe'),\n entityId: runtime.agentId,\n content: { text: 'what do you see?' },\n agentId: runtime.agentId,\n roomId,\n createdAt: Date.now(),\n };\n\n let callbackCalled = false;\n let callbackResponse: any = null;\n\n const state: State = { values: {}, data: {}, text: '' };\n\n // Get vision service to check if active\n const visionService = runtime.getService<VisionService>('VISION' as any);\n\n // Validate the action\n const isValid = await describeSceneAction.validate(runtime, message, state);\n\n if (!visionService || !visionService.isActive()) {\n // If vision service is not active, validation should return false\n if (isValid) {\n throw new Error(\n 'Action validation should return false when vision service is not active'\n );\n }\n console.log(' Action validation correctly returned false (vision not active)');\n\n // But handler should still work and provide appropriate message\n await describeSceneAction.handler(runtime, message, state, {}, async (response) => {\n callbackCalled = true;\n callbackResponse = response;\n return [];\n });\n\n if (!callbackCalled) {\n throw new Error('Callback was not called - action handler failed');\n }\n\n if (!callbackResponse || !callbackResponse.text) {\n throw new Error('No response text returned from action');\n }\n\n console.log('✓ Scene description action handled unavailability correctly');\n console.log(` Response: ${callbackResponse.text}`);\n\n // Verify it indicates camera not available\n if (\n !callbackResponse.text.includes('cannot see') &&\n !callbackResponse.text.includes('no camera')\n ) {\n throw new Error('Response does not indicate camera unavailability');\n }\n } else {\n // Vision is active, normal test flow\n if (!isValid) {\n throw new Error('describeSceneAction validation failed despite active vision');\n }\n console.log(' Action validation: passed');\n\n await describeSceneAction.handler(runtime, message, state, {}, async (response) => {\n callbackCalled = true;\n callbackResponse = response;\n return [];\n });\n\n if (!callbackCalled) {\n throw new Error('Callback was not called - action handler failed');\n }\n\n if (!callbackResponse || !callbackResponse.text) {\n throw new Error('No response text returned from action');\n }\n\n console.log('✓ Scene description action executed');\n console.log(` Response: ${callbackResponse.text}`);\n if (callbackResponse.thought) {\n console.log(` Thought: ${callbackResponse.thought}`);\n }\n }\n\n // Verify response contains expected action\n if (!callbackResponse.actions || !callbackResponse.actions.includes('DESCRIBE_SCENE')) {\n throw new Error('Response does not include DESCRIBE_SCENE action');\n }\n },\n },\n\n {\n name: 'Should capture image when requested',\n fn: async (runtime: IAgentRuntime) => {\n console.log('Testing image capture action...');\n\n const roomId = createUniqueUuid(runtime, 'test-room');\n const message: Memory = {\n id: createUniqueUuid(runtime, 'test-msg-capture'),\n entityId: runtime.agentId,\n content: { text: 'take a photo' },\n agentId: runtime.agentId,\n roomId,\n createdAt: Date.now(),\n };\n\n let callbackCalled = false;\n let callbackResponse: any = null;\n\n const state: State = { values: {}, data: {}, text: '' };\n\n // Get vision service to check if active\n const visionService = runtime.getService<VisionService>('VISION' as any);\n\n // Validate the action\n const isValid = await captureImageAction.validate(runtime, message, state);\n\n if (!visionService || !visionService.isActive()) {\n // If vision service is not active, validation should return false\n if (isValid) {\n throw new Error(\n 'Action validation should return false when vision service is not active'\n );\n }\n console.log(' Action validation correctly returned false (vision not active)');\n\n // But handler should still work and provide appropriate message\n await captureImageAction.handler(runtime, message, state, {}, async (response) => {\n callbackCalled = true;\n callbackResponse = response;\n return [];\n });\n\n if (!callbackCalled) {\n throw new Error('Callback was not called - action handler failed');\n }\n\n if (!callbackResponse || !callbackResponse.text) {\n throw new Error('No response text returned from action');\n }\n\n console.log('✓ Image capture action handled unavailability correctly');\n console.log(` Response: ${callbackResponse.text}`);\n\n // Verify it indicates camera not available\n if (\n !callbackResponse.text.includes('cannot capture') &&\n !callbackResponse.text.includes('no camera')\n ) {\n throw new Error('Response does not indicate camera unavailability');\n }\n } else {\n // Vision is active, normal test flow\n if (!isValid) {\n throw new Error('captureImageAction validation failed despite active vision');\n }\n console.log(' Action validation: passed');\n\n await captureImageAction.handler(runtime, message, state, {}, async (response) => {\n callbackCalled = true;\n callbackResponse = response;\n return [];\n });\n\n if (!callbackCalled) {\n throw new Error('Callback was not called - action handler failed');\n }\n\n if (!callbackResponse || !callbackResponse.text) {\n throw new Error('No response text returned from action');\n }\n\n console.log('✓ Image capture action executed');\n console.log(` Response: ${callbackResponse.text}`);\n\n // If camera is active, we should have an attachment\n if (!callbackResponse.attachments || callbackResponse.attachments.length === 0) {\n throw new Error('No image attachment returned despite active camera');\n }\n\n const attachment = callbackResponse.attachments[0];\n if (!attachment.url || !attachment.url.startsWith('data:image/')) {\n throw new Error('Invalid image attachment format');\n }\n\n console.log(` ✓ Image attachment valid: ${attachment.title}`);\n }\n\n // Verify response contains expected action\n if (!callbackResponse.actions || !callbackResponse.actions.includes('CAPTURE_IMAGE')) {\n throw new Error('Response does not include CAPTURE_IMAGE action');\n }\n },\n },\n\n {\n name: 'Should provide vision context through provider',\n fn: async (runtime: IAgentRuntime) => {\n console.log('Testing vision provider...');\n\n // Compose state to trigger providers\n const message: Memory = {\n id: createUniqueUuid(runtime, 'test-msg-provider'),\n entityId: runtime.agentId,\n content: { text: 'test provider' },\n agentId: runtime.agentId,\n roomId: createUniqueUuid(runtime, 'test-room'),\n createdAt: Date.now(),\n };\n\n const state = await runtime.composeState(message);\n\n // Vision provider should always add data\n if (state.values.visionAvailable === undefined) {\n throw new Error('Vision provider data missing - provider not registered or failed');\n }\n\n console.log('✓ Vision provider data found in state');\n console.log(` Vision available: ${state.values.visionAvailable}`);\n console.log(` Camera status: ${state.values.cameraStatus}`);\n\n // Verify vision context in formatted text\n if (!state.text.includes('Visual Perception')) {\n throw new Error('Vision context not included in state text');\n }\n console.log('✓ Vision context included in state text');\n\n // If vision is available, verify scene data\n if (state.values.visionAvailable && state.values.sceneDescription) {\n console.log(` Scene description: ${state.values.sceneDescription}`);\n }\n },\n },\n\n {\n name: 'Should handle scene changes efficiently',\n fn: async (runtime: IAgentRuntime) => {\n console.log('Testing scene change detection...');\n\n const visionService = runtime.getService<VisionService>('VISION' as any);\n if (!visionService) {\n throw new Error('Vision service not available');\n }\n\n if (!visionService.isActive()) {\n console.warn('⚠️ Vision service not active - skipping scene change test');\n console.log(' This is acceptable in environments without cameras');\n return;\n }\n\n // Get initial scene description\n const initialScene = await visionService.getSceneDescription();\n console.log(` Initial scene: ${initialScene ? 'Available' : 'Pending...'}`);\n\n // Wait for scene processing\n await new Promise((resolve) => setTimeout(resolve, 2000));\n\n // Get updated scene description\n const updatedScene = await visionService.getSceneDescription();\n\n if (!updatedScene) {\n throw new Error('No scene description available after 2 seconds');\n }\n\n console.log('✓ Scene monitoring active');\n console.log(` Scene timestamp: ${new Date(updatedScene.timestamp).toISOString()}`);\n console.log(` Description: ${updatedScene.description.substring(0, 100)}...`);\n\n if (updatedScene.changePercentage !== undefined) {\n console.log(` Last change: ${updatedScene.changePercentage.toFixed(1)}%`);\n }\n },\n },\n\n {\n name: 'Should detect objects and people in scene',\n fn: async (runtime: IAgentRuntime) => {\n console.log('Testing object and person detection...');\n\n const visionService = runtime.getService<VisionService>('VISION' as any);\n if (!visionService) {\n throw new Error('Vision service not available');\n }\n\n if (!visionService.isActive()) {\n console.warn('⚠️ Vision service not active - skipping detection test');\n console.log(' This is acceptable in environments without cameras');\n return;\n }\n\n // Wait for scene processing to accumulate frames\n console.log(' Waiting for scene analysis...');\n await new Promise((resolve) => setTimeout(resolve, 3000));\n\n // Get scene description\n const scene = await visionService.getSceneDescription();\n\n if (!scene) {\n throw new Error('No scene description available after 3 seconds');\n }\n\n console.log('✓ Scene analysis complete');\n console.log(` Description: ${scene.description.substring(0, 100)}...`);\n console.log(` Objects detected: ${scene.objects.length}`);\n console.log(` People detected: ${scene.people.length}`);\n\n // Verify object detection\n if (scene.objects.length > 0) {\n console.log(' Detected objects:');\n const objectTypes = scene.objects.reduce(\n (acc, obj) => {\n acc[obj.type] = (acc[obj.type] || 0) + 1;\n return acc;\n },\n {} as Record<string, number>\n );\n\n for (const [type, count] of Object.entries(objectTypes)) {\n console.log(` - ${count} ${type}(s)`);\n }\n\n // Verify objects have required fields\n for (const obj of scene.objects) {\n if (!obj.id || !obj.type || obj.confidence === undefined || !obj.boundingBox) {\n throw new Error('Detected object missing required fields');\n }\n }\n }\n\n // Verify person detection\n if (scene.people.length > 0) {\n console.log(' Detected people:');\n for (const person of scene.people) {\n console.log(\n ` - Person ${person.id}: ${person.pose} pose, facing ${person.facing}, confidence ${person.confidence.toFixed(2)}`\n );\n\n // Verify person has required fields\n if (\n !person.id ||\n !person.pose ||\n !person.facing ||\n person.confidence === undefined ||\n !person.boundingBox\n ) {\n throw new Error('Detected person missing required fields');\n }\n }\n }\n\n // If there's motion, we should detect something\n if (scene.changePercentage > 10) {\n console.log(` Scene change: ${scene.changePercentage.toFixed(1)}%`);\n if (scene.objects.length === 0 && scene.people.length === 0) {\n console.warn(' ⚠️ Significant scene change but no objects/people detected');\n console.log(' This might indicate the motion detection threshold needs adjustment');\n }\n }\n },\n },\n ];\n}\n\nexport default new VisionBasicE2ETestSuite();\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TestSuite, IAgentRuntime } from '@elizaos/core';
|
|
2
|
+
export declare class VisionCaptureLogTestSuite implements TestSuite {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
tests: {
|
|
6
|
+
name: string;
|
|
7
|
+
fn: (runtime: IAgentRuntime) => Promise<void>;
|
|
8
|
+
}[];
|
|
9
|
+
}
|
|
10
|
+
declare const _default: VisionCaptureLogTestSuite;
|
|
11
|
+
export default _default;
|