@blueharford/scrypted-spatial-awareness 0.6.15 → 0.6.16
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 +90 -2
- package/out/main.nodejs.js.map +1 -1
- package/out/plugin.zip +0 -0
- package/package.json +1 -1
- package/src/core/topology-discovery.ts +96 -2
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/out/main.nodejs.js
CHANGED
|
@@ -36492,7 +36492,7 @@ class TopologyDiscoveryEngine {
|
|
|
36492
36492
|
],
|
|
36493
36493
|
},
|
|
36494
36494
|
],
|
|
36495
|
-
max_tokens:
|
|
36495
|
+
max_tokens: 4000, // Increased for detailed scene analysis
|
|
36496
36496
|
temperature: 0.3,
|
|
36497
36497
|
});
|
|
36498
36498
|
const content = result?.choices?.[0]?.message?.content;
|
|
@@ -36503,7 +36503,8 @@ class TopologyDiscoveryEngine {
|
|
|
36503
36503
|
if (jsonStr.startsWith('```')) {
|
|
36504
36504
|
jsonStr = jsonStr.replace(/```json?\n?/g, '').replace(/```$/g, '').trim();
|
|
36505
36505
|
}
|
|
36506
|
-
|
|
36506
|
+
// Try to recover truncated JSON
|
|
36507
|
+
const parsed = this.parseJsonWithRecovery(jsonStr, cameraName);
|
|
36507
36508
|
// Map parsed data to our types
|
|
36508
36509
|
if (Array.isArray(parsed.landmarks)) {
|
|
36509
36510
|
analysis.landmarks = parsed.landmarks.map((l) => ({
|
|
@@ -36643,6 +36644,93 @@ class TopologyDiscoveryEngine {
|
|
|
36643
36644
|
return 'distant';
|
|
36644
36645
|
return 'medium'; // Default to medium if not specified
|
|
36645
36646
|
}
|
|
36647
|
+
/** Try to parse JSON with recovery for truncated responses */
|
|
36648
|
+
parseJsonWithRecovery(jsonStr, context) {
|
|
36649
|
+
// First, try direct parse
|
|
36650
|
+
try {
|
|
36651
|
+
return JSON.parse(jsonStr);
|
|
36652
|
+
}
|
|
36653
|
+
catch (e) {
|
|
36654
|
+
// Log the raw response for debugging (first 500 chars)
|
|
36655
|
+
this.console.log(`[Discovery] Raw LLM response for ${context} (first 500 chars): ${jsonStr.substring(0, 500)}...`);
|
|
36656
|
+
}
|
|
36657
|
+
// Try to recover truncated JSON by finding complete sections
|
|
36658
|
+
try {
|
|
36659
|
+
// Find where valid JSON might end (look for last complete object/array)
|
|
36660
|
+
let recoveredJson = jsonStr;
|
|
36661
|
+
// Try to close unclosed strings
|
|
36662
|
+
const lastQuote = recoveredJson.lastIndexOf('"');
|
|
36663
|
+
const lastColon = recoveredJson.lastIndexOf(':');
|
|
36664
|
+
if (lastQuote > lastColon) {
|
|
36665
|
+
// We might be in the middle of a string value
|
|
36666
|
+
const beforeQuote = recoveredJson.substring(0, lastQuote);
|
|
36667
|
+
const afterLastCompleteEntry = beforeQuote.lastIndexOf('},');
|
|
36668
|
+
if (afterLastCompleteEntry > 0) {
|
|
36669
|
+
recoveredJson = beforeQuote.substring(0, afterLastCompleteEntry + 1);
|
|
36670
|
+
}
|
|
36671
|
+
}
|
|
36672
|
+
// Close any unclosed arrays/objects
|
|
36673
|
+
let openBraces = (recoveredJson.match(/{/g) || []).length;
|
|
36674
|
+
let closeBraces = (recoveredJson.match(/}/g) || []).length;
|
|
36675
|
+
let openBrackets = (recoveredJson.match(/\[/g) || []).length;
|
|
36676
|
+
let closeBrackets = (recoveredJson.match(/\]/g) || []).length;
|
|
36677
|
+
// Add missing closing brackets/braces
|
|
36678
|
+
while (closeBrackets < openBrackets) {
|
|
36679
|
+
recoveredJson += ']';
|
|
36680
|
+
closeBrackets++;
|
|
36681
|
+
}
|
|
36682
|
+
while (closeBraces < openBraces) {
|
|
36683
|
+
recoveredJson += '}';
|
|
36684
|
+
closeBraces++;
|
|
36685
|
+
}
|
|
36686
|
+
const recovered = JSON.parse(recoveredJson);
|
|
36687
|
+
this.console.log(`[Discovery] Recovered truncated JSON for ${context}`);
|
|
36688
|
+
return recovered;
|
|
36689
|
+
}
|
|
36690
|
+
catch (recoveryError) {
|
|
36691
|
+
// Last resort: try to extract just landmarks array
|
|
36692
|
+
try {
|
|
36693
|
+
const landmarksMatch = jsonStr.match(/"landmarks"\s*:\s*\[([\s\S]*?)(?:\]|$)/);
|
|
36694
|
+
const zonesMatch = jsonStr.match(/"zones"\s*:\s*\[([\s\S]*?)(?:\]|$)/);
|
|
36695
|
+
const result = { landmarks: [], zones: [], edges: {}, orientation: 'unknown' };
|
|
36696
|
+
if (landmarksMatch) {
|
|
36697
|
+
// Try to parse individual landmark objects
|
|
36698
|
+
const landmarksStr = landmarksMatch[1];
|
|
36699
|
+
const landmarkObjects = landmarksStr.match(/\{[^{}]*\}/g) || [];
|
|
36700
|
+
result.landmarks = landmarkObjects.map((obj) => {
|
|
36701
|
+
try {
|
|
36702
|
+
return JSON.parse(obj);
|
|
36703
|
+
}
|
|
36704
|
+
catch {
|
|
36705
|
+
return null;
|
|
36706
|
+
}
|
|
36707
|
+
}).filter(Boolean);
|
|
36708
|
+
this.console.log(`[Discovery] Extracted ${result.landmarks.length} landmarks from partial response for ${context}`);
|
|
36709
|
+
}
|
|
36710
|
+
if (zonesMatch) {
|
|
36711
|
+
const zonesStr = zonesMatch[1];
|
|
36712
|
+
const zoneObjects = zonesStr.match(/\{[^{}]*\}/g) || [];
|
|
36713
|
+
result.zones = zoneObjects.map((obj) => {
|
|
36714
|
+
try {
|
|
36715
|
+
return JSON.parse(obj);
|
|
36716
|
+
}
|
|
36717
|
+
catch {
|
|
36718
|
+
return null;
|
|
36719
|
+
}
|
|
36720
|
+
}).filter(Boolean);
|
|
36721
|
+
this.console.log(`[Discovery] Extracted ${result.zones.length} zones from partial response for ${context}`);
|
|
36722
|
+
}
|
|
36723
|
+
if (result.landmarks.length > 0 || result.zones.length > 0) {
|
|
36724
|
+
return result;
|
|
36725
|
+
}
|
|
36726
|
+
}
|
|
36727
|
+
catch (extractError) {
|
|
36728
|
+
// Give up
|
|
36729
|
+
}
|
|
36730
|
+
this.console.warn(`[Discovery] Could not recover JSON for ${context}`);
|
|
36731
|
+
throw new Error(`Failed to parse LLM response: truncated or malformed JSON`);
|
|
36732
|
+
}
|
|
36733
|
+
}
|
|
36646
36734
|
/** Resolve a camera reference (name or deviceId) to its deviceId */
|
|
36647
36735
|
resolveCameraRef(ref) {
|
|
36648
36736
|
if (!this.topology?.cameras || !ref)
|