@blueharford/scrypted-spatial-awareness 0.6.27 → 0.6.29

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/plugin.zip CHANGED
Binary file
@@ -35410,31 +35410,38 @@ class SpatialReasoningEngine {
35410
35410
  // Load balancing for multiple LLMs
35411
35411
  llmDevices = [];
35412
35412
  llmIndex = 0;
35413
- /** Find LLM devices - uses configured device or auto-discovers all for load balancing */
35413
+ /** Find LLM devices - uses configured devices or auto-discovers all for load balancing */
35414
35414
  async findAllLlmDevices() {
35415
35415
  if (this.llmSearched)
35416
35416
  return;
35417
35417
  this.llmSearched = true;
35418
35418
  try {
35419
- // If a specific LLM device is configured, use only that one
35420
- if (this.config.llmDeviceId) {
35421
- const device = systemManager.getDeviceById(this.config.llmDeviceId);
35422
- if (device?.interfaces?.includes('ChatCompletion')) {
35423
- const providerTypeEnum = this.detectProviderType(device);
35424
- this.llmDevices.push({
35425
- device: device,
35426
- id: this.config.llmDeviceId,
35427
- name: device.name || this.config.llmDeviceId,
35428
- providerType: providerTypeEnum,
35429
- lastUsed: 0,
35430
- errorCount: 0,
35431
- });
35432
- this.console.log(`[LLM] Using configured LLM: ${device.name}`);
35433
- return;
35419
+ // If specific LLM devices are configured, use only those
35420
+ if (this.config.llmDeviceIds && this.config.llmDeviceIds.length > 0) {
35421
+ for (const deviceId of this.config.llmDeviceIds) {
35422
+ const device = systemManager.getDeviceById(deviceId);
35423
+ if (device?.interfaces?.includes('ChatCompletion')) {
35424
+ const providerTypeEnum = this.detectProviderType(device);
35425
+ this.llmDevices.push({
35426
+ device: device,
35427
+ id: deviceId,
35428
+ name: device.name || deviceId,
35429
+ providerType: providerTypeEnum,
35430
+ lastUsed: 0,
35431
+ errorCount: 0,
35432
+ });
35433
+ this.console.log(`[LLM] Using configured LLM: ${device.name}`);
35434
+ }
35435
+ else {
35436
+ this.console.warn(`[LLM] Configured device ${deviceId} not found or doesn't support ChatCompletion`);
35437
+ }
35434
35438
  }
35435
- else {
35436
- this.console.warn(`[LLM] Configured device ${this.config.llmDeviceId} not found or doesn't support ChatCompletion`);
35439
+ if (this.llmDevices.length > 0) {
35440
+ this.console.log(`[LLM] Using ${this.llmDevices.length} configured LLM provider(s)`);
35441
+ return;
35437
35442
  }
35443
+ // Fall through to auto-discovery if none of the configured devices worked
35444
+ this.console.warn('[LLM] No configured devices available, falling back to auto-discovery');
35438
35445
  }
35439
35446
  // Auto-discover all LLM devices for load balancing
35440
35447
  for (const id of Object.keys(systemManager.getSystemState())) {
@@ -35451,7 +35458,7 @@ class SpatialReasoningEngine {
35451
35458
  lastUsed: 0,
35452
35459
  errorCount: 0,
35453
35460
  });
35454
- this.console.log(`[LLM] Found: ${device.name}`);
35461
+ this.console.log(`[LLM] Auto-discovered: ${device.name}`);
35455
35462
  }
35456
35463
  }
35457
35464
  if (this.llmDevices.length === 0) {
@@ -37343,7 +37350,7 @@ class TrackingEngine {
37343
37350
  // Initialize spatial reasoning engine
37344
37351
  const spatialConfig = {
37345
37352
  enableLlm: config.useLlmDescriptions,
37346
- llmDeviceId: config.llmDeviceId,
37353
+ llmDeviceIds: config.llmDeviceIds,
37347
37354
  enableLandmarkLearning: config.enableLandmarkLearning ?? true,
37348
37355
  landmarkConfidenceThreshold: config.landmarkConfidenceThreshold ?? 0.7,
37349
37356
  contextCacheTtl: 60000, // 1 minute cache
@@ -39458,11 +39465,19 @@ class SpatialAwarenessPlugin extends sdk_1.ScryptedDeviceBase {
39458
39465
  group: 'MQTT Integration',
39459
39466
  },
39460
39467
  // Integrations
39461
- llmDevice: {
39462
- title: 'LLM Provider',
39468
+ llmPlugin: {
39469
+ title: 'LLM Plugin',
39463
39470
  type: 'device',
39471
+ deviceFilter: `interfaces.includes('DeviceProvider') && interfaces.includes('Settings')`,
39472
+ description: 'Select the LLM plugin to use (e.g., OpenAI, Anthropic, Ollama from @scrypted/llm)',
39473
+ group: 'Integrations',
39474
+ },
39475
+ llmProviders: {
39476
+ title: 'LLM Providers',
39477
+ type: 'device',
39478
+ multiple: true,
39464
39479
  deviceFilter: `interfaces.includes('ChatCompletion')`,
39465
- description: 'Select the LLM plugin to use for smart descriptions (e.g., OpenAI, Anthropic, Ollama)',
39480
+ description: 'Select which providers to use from your LLM plugin. Multiple providers will be load-balanced.',
39466
39481
  group: 'Integrations',
39467
39482
  },
39468
39483
  defaultNotifiers: {
@@ -39568,7 +39583,7 @@ class SpatialAwarenessPlugin extends sdk_1.ScryptedDeviceBase {
39568
39583
  loiteringThreshold: (this.storageSettings.values.loiteringThreshold || 3) * 1000,
39569
39584
  objectAlertCooldown: (this.storageSettings.values.objectAlertCooldown || 30) * 1000,
39570
39585
  useLlmDescriptions: this.storageSettings.values.useLlmDescriptions ?? true,
39571
- llmDeviceId: this.storageSettings.values.llmDevice || undefined,
39586
+ llmDeviceIds: this.parseLlmProviders(),
39572
39587
  llmDebounceInterval: (this.storageSettings.values.llmDebounceInterval || 30) * 1000,
39573
39588
  llmFallbackEnabled: this.storageSettings.values.llmFallbackEnabled ?? true,
39574
39589
  llmFallbackTimeout: (this.storageSettings.values.llmFallbackTimeout || 3) * 1000,
@@ -39610,6 +39625,34 @@ class SpatialAwarenessPlugin extends sdk_1.ScryptedDeviceBase {
39610
39625
  }
39611
39626
  }
39612
39627
  }
39628
+ /** Parse LLM providers from settings - handles both array and single value formats */
39629
+ parseLlmProviders() {
39630
+ const value = this.storageSettings.values.llmProviders;
39631
+ if (!value)
39632
+ return undefined;
39633
+ // Handle array format
39634
+ if (Array.isArray(value)) {
39635
+ const filtered = value.filter(Boolean);
39636
+ return filtered.length > 0 ? filtered : undefined;
39637
+ }
39638
+ // Handle JSON string format
39639
+ if (typeof value === 'string') {
39640
+ try {
39641
+ const parsed = JSON.parse(value);
39642
+ if (Array.isArray(parsed)) {
39643
+ const filtered = parsed.filter(Boolean);
39644
+ return filtered.length > 0 ? filtered : undefined;
39645
+ }
39646
+ // Single device ID string
39647
+ return value ? [value] : undefined;
39648
+ }
39649
+ catch {
39650
+ // Not JSON, treat as single device ID
39651
+ return value ? [value] : undefined;
39652
+ }
39653
+ }
39654
+ return undefined;
39655
+ }
39613
39656
  // ==================== DeviceProvider Implementation ====================
39614
39657
  async getDevice(nativeId) {
39615
39658
  let device = this.devices.get(nativeId);
@@ -39886,7 +39929,8 @@ class SpatialAwarenessPlugin extends sdk_1.ScryptedDeviceBase {
39886
39929
  key === 'llmDebounceInterval' ||
39887
39930
  key === 'llmFallbackEnabled' ||
39888
39931
  key === 'llmFallbackTimeout' ||
39889
- key === 'llmDevice' ||
39932
+ key === 'llmPlugin' ||
39933
+ key === 'llmProviders' ||
39890
39934
  key === 'enableTransitTimeLearning' ||
39891
39935
  key === 'enableConnectionSuggestions' ||
39892
39936
  key === 'enableLandmarkLearning' ||