@blueharford/scrypted-spatial-awareness 0.6.24 → 0.6.25
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/dist/main.nodejs.js +1 -1
- package/dist/main.nodejs.js.map +1 -1
- package/dist/plugin.zip +0 -0
- package/out/main.nodejs.js +46 -20
- package/out/main.nodejs.js.map +1 -1
- package/out/plugin.zip +0 -0
- package/package.json +1 -1
- package/src/core/tracking-engine.ts +42 -19
- package/src/main.ts +2 -2
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/out/main.nodejs.js
CHANGED
|
@@ -37351,14 +37351,23 @@ class TrackingEngine {
|
|
|
37351
37351
|
recordLlmCall() {
|
|
37352
37352
|
this.lastLlmCallTime = Date.now();
|
|
37353
37353
|
}
|
|
37354
|
+
/** Check and record LLM call - returns false if rate limited */
|
|
37355
|
+
tryLlmCall() {
|
|
37356
|
+
if (!this.isLlmCallAllowed()) {
|
|
37357
|
+
this.console.log('[LLM] Rate limited, skipping LLM call');
|
|
37358
|
+
return false;
|
|
37359
|
+
}
|
|
37360
|
+
this.recordLlmCall();
|
|
37361
|
+
return true;
|
|
37362
|
+
}
|
|
37354
37363
|
/** Get spatial reasoning result for movement (uses RAG + LLM) with debouncing and fallback */
|
|
37355
37364
|
async getSpatialDescription(tracked, fromCameraId, toCameraId, transitTime, currentCameraId) {
|
|
37356
37365
|
const fallbackEnabled = this.config.llmFallbackEnabled ?? true;
|
|
37357
37366
|
const fallbackTimeout = this.config.llmFallbackTimeout ?? 3000;
|
|
37358
37367
|
try {
|
|
37359
37368
|
// Check rate limiting - if not allowed, return null to use basic description
|
|
37360
|
-
if (!this.
|
|
37361
|
-
this.console.log('LLM rate-limited, using basic notification');
|
|
37369
|
+
if (!this.tryLlmCall()) {
|
|
37370
|
+
this.console.log('[Movement] LLM rate-limited, using basic notification');
|
|
37362
37371
|
return null;
|
|
37363
37372
|
}
|
|
37364
37373
|
// Get snapshot from camera for LLM analysis (if LLM is enabled)
|
|
@@ -37369,8 +37378,6 @@ class TrackingEngine {
|
|
|
37369
37378
|
mediaObject = await camera.takePicture();
|
|
37370
37379
|
}
|
|
37371
37380
|
}
|
|
37372
|
-
// Record that we're making an LLM call
|
|
37373
|
-
this.recordLlmCall();
|
|
37374
37381
|
// Use spatial reasoning engine for rich context-aware description
|
|
37375
37382
|
// Apply timeout if fallback is enabled
|
|
37376
37383
|
let result;
|
|
@@ -37524,17 +37531,25 @@ class TrackingEngine {
|
|
|
37524
37531
|
this.console.log(`[Entry Alert] Prefetch result: "${spatialResult.description.substring(0, 60)}...", usedLlm=${spatialResult.usedLlm}`);
|
|
37525
37532
|
}
|
|
37526
37533
|
catch (e) {
|
|
37527
|
-
this.console.warn(`[Entry Alert] Prefetch failed,
|
|
37534
|
+
this.console.warn(`[Entry Alert] Prefetch failed, using basic description: ${e}`);
|
|
37535
|
+
// Don't make another LLM call - use basic description (no mediaObject = no LLM)
|
|
37528
37536
|
spatialResult = await this.spatialReasoning.generateEntryDescription(tracked, sighting.cameraId);
|
|
37529
37537
|
}
|
|
37530
37538
|
this.pendingDescriptions.delete(globalId);
|
|
37531
37539
|
}
|
|
37532
37540
|
else {
|
|
37533
|
-
//
|
|
37534
|
-
this.
|
|
37535
|
-
|
|
37536
|
-
|
|
37537
|
-
|
|
37541
|
+
// No prefetch available - only call LLM if rate limit allows
|
|
37542
|
+
if (this.tryLlmCall()) {
|
|
37543
|
+
this.console.log(`[Entry Alert] No prefetch, generating with LLM`);
|
|
37544
|
+
const mediaObject = this.snapshotCache.get(globalId);
|
|
37545
|
+
spatialResult = await this.spatialReasoning.generateEntryDescription(tracked, sighting.cameraId, mediaObject);
|
|
37546
|
+
this.console.log(`[Entry Alert] Got description: "${spatialResult.description.substring(0, 60)}...", usedLlm=${spatialResult.usedLlm}`);
|
|
37547
|
+
}
|
|
37548
|
+
else {
|
|
37549
|
+
// Rate limited - use basic description (no LLM)
|
|
37550
|
+
this.console.log(`[Entry Alert] Rate limited, using basic description`);
|
|
37551
|
+
spatialResult = await this.spatialReasoning.generateEntryDescription(tracked, sighting.cameraId);
|
|
37552
|
+
}
|
|
37538
37553
|
}
|
|
37539
37554
|
// Always use movement alert type for smart notifications with LLM descriptions
|
|
37540
37555
|
// The property_entry/property_exit types are legacy and disabled by default
|
|
@@ -37561,9 +37576,9 @@ class TrackingEngine {
|
|
|
37561
37576
|
if (mediaObject) {
|
|
37562
37577
|
this.snapshotCache.set(globalId, mediaObject);
|
|
37563
37578
|
this.console.log(`[Snapshot] Cached snapshot for ${globalId.slice(0, 8)} from ${cameraId}`);
|
|
37564
|
-
// Start LLM analysis immediately in parallel (don't await)
|
|
37579
|
+
// Start LLM analysis immediately in parallel (don't await) - but respect rate limits
|
|
37565
37580
|
const tracked = this.state.getObject(globalId);
|
|
37566
|
-
if (tracked && this.config.useLlmDescriptions) {
|
|
37581
|
+
if (tracked && this.config.useLlmDescriptions && this.tryLlmCall()) {
|
|
37567
37582
|
this.console.log(`[LLM Prefetch] Starting ${eventType} analysis for ${globalId.slice(0, 8)}`);
|
|
37568
37583
|
const descriptionPromise = eventType === 'exit'
|
|
37569
37584
|
? this.spatialReasoning.generateExitDescription(tracked, cameraId, mediaObject)
|
|
@@ -37576,6 +37591,9 @@ class TrackingEngine {
|
|
|
37576
37591
|
this.console.warn(`[LLM Prefetch] Failed for ${globalId.slice(0, 8)}: ${e}`);
|
|
37577
37592
|
});
|
|
37578
37593
|
}
|
|
37594
|
+
else if (tracked && this.config.useLlmDescriptions) {
|
|
37595
|
+
this.console.log(`[LLM Prefetch] Skipped for ${globalId.slice(0, 8)} - rate limited`);
|
|
37596
|
+
}
|
|
37579
37597
|
}
|
|
37580
37598
|
}
|
|
37581
37599
|
}
|
|
@@ -37644,17 +37662,25 @@ class TrackingEngine {
|
|
|
37644
37662
|
this.console.log(`[Exit Alert] Prefetch result: "${spatialResult.description.substring(0, 60)}...", usedLlm=${spatialResult.usedLlm}`);
|
|
37645
37663
|
}
|
|
37646
37664
|
catch (e) {
|
|
37647
|
-
this.console.warn(`[Exit Alert] Prefetch failed,
|
|
37665
|
+
this.console.warn(`[Exit Alert] Prefetch failed, using basic description: ${e}`);
|
|
37666
|
+
// Don't make another LLM call - use basic description
|
|
37648
37667
|
spatialResult = await this.spatialReasoning.generateExitDescription(current, sighting.cameraId);
|
|
37649
37668
|
}
|
|
37650
37669
|
this.pendingDescriptions.delete(tracked.globalId);
|
|
37651
37670
|
}
|
|
37652
37671
|
else {
|
|
37653
|
-
//
|
|
37654
|
-
this.
|
|
37655
|
-
|
|
37656
|
-
|
|
37657
|
-
|
|
37672
|
+
// No prefetch available - only call LLM if rate limit allows
|
|
37673
|
+
if (this.tryLlmCall()) {
|
|
37674
|
+
this.console.log(`[Exit Alert] No prefetch, generating with LLM`);
|
|
37675
|
+
const mediaObject = this.snapshotCache.get(tracked.globalId);
|
|
37676
|
+
spatialResult = await this.spatialReasoning.generateExitDescription(current, sighting.cameraId, mediaObject);
|
|
37677
|
+
this.console.log(`[Exit Alert] Got description: "${spatialResult.description.substring(0, 60)}...", usedLlm=${spatialResult.usedLlm}`);
|
|
37678
|
+
}
|
|
37679
|
+
else {
|
|
37680
|
+
// Rate limited - use basic description (no LLM)
|
|
37681
|
+
this.console.log(`[Exit Alert] Rate limited, using basic description`);
|
|
37682
|
+
spatialResult = await this.spatialReasoning.generateExitDescription(current, sighting.cameraId);
|
|
37683
|
+
}
|
|
37658
37684
|
}
|
|
37659
37685
|
// Use movement alert for exit too - smart notifications with LLM descriptions
|
|
37660
37686
|
await this.alertManager.checkAndAlert('movement', current, {
|
|
@@ -39197,8 +39223,8 @@ class SpatialAwarenessPlugin extends sdk_1.ScryptedDeviceBase {
|
|
|
39197
39223
|
llmDebounceInterval: {
|
|
39198
39224
|
title: 'LLM Rate Limit (seconds)',
|
|
39199
39225
|
type: 'number',
|
|
39200
|
-
defaultValue:
|
|
39201
|
-
description: 'Minimum time between LLM calls to prevent API
|
|
39226
|
+
defaultValue: 30,
|
|
39227
|
+
description: 'Minimum time between LLM calls to prevent API rate limiting. Increase if you get rate limit errors. (0 = no limit)',
|
|
39202
39228
|
group: 'AI & Spatial Reasoning',
|
|
39203
39229
|
},
|
|
39204
39230
|
llmFallbackEnabled: {
|