neoagent 3.1.1-beta.9 → 3.2.0

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.
Files changed (150) hide show
  1. package/.env.example +2 -2
  2. package/README.md +5 -1
  3. package/docs/architecture.md +1 -1
  4. package/docs/benchmarking.md +68 -87
  5. package/docs/capabilities.md +1 -1
  6. package/docs/clients-and-devices.md +3 -4
  7. package/docs/configuration.md +1 -1
  8. package/docs/devices.md +1 -2
  9. package/docs/health.md +24 -0
  10. package/docs/index.md +2 -2
  11. package/docs/integrations-architecture.md +6 -0
  12. package/docs/integrations.md +15 -1
  13. package/docs/models.md +1 -1
  14. package/docs/persistence.md +1 -1
  15. package/docs/why-neoagent.md +1 -1
  16. package/flutter_app/README.md +0 -5
  17. package/flutter_app/android/app/src/main/AndroidManifest.xml +0 -14
  18. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/MainActivity.kt +0 -98
  19. package/flutter_app/lib/main.dart +0 -6
  20. package/flutter_app/lib/main_app_shell.dart +0 -2
  21. package/flutter_app/lib/main_controller.dart +2 -867
  22. package/flutter_app/lib/main_devices.dart +0 -73
  23. package/flutter_app/lib/main_integrations.dart +339 -187
  24. package/flutter_app/lib/main_launcher.dart +2 -212
  25. package/flutter_app/lib/main_models.dart +0 -259
  26. package/flutter_app/lib/main_navigation.dart +2 -14
  27. package/flutter_app/lib/main_operations.dart +322 -364
  28. package/flutter_app/lib/main_runtime.dart +9 -208
  29. package/flutter_app/lib/main_settings.dart +17 -199
  30. package/flutter_app/lib/main_shared.dart +20 -591
  31. package/flutter_app/lib/main_timeline.dart +26 -122
  32. package/flutter_app/lib/main_voice_assistant.dart +0 -5
  33. package/flutter_app/lib/src/backend_client.dart +0 -102
  34. package/flutter_app/lib/src/desktop_companion_io.dart +1 -65
  35. package/flutter_app/lib/src/desktop_companion_stub.dart +0 -12
  36. package/flutter_app/linux/flutter/generated_plugin_registrant.cc +0 -4
  37. package/flutter_app/linux/flutter/generated_plugins.cmake +0 -1
  38. package/flutter_app/macos/Flutter/GeneratedPluginRegistrant.swift +0 -2
  39. package/flutter_app/macos/Podfile.lock +56 -5
  40. package/flutter_app/pubspec.lock +0 -7
  41. package/flutter_app/pubspec.yaml +0 -2
  42. package/flutter_app/web/index.html +174 -0
  43. package/flutter_app/windows/flutter/generated_plugin_registrant.cc +0 -3
  44. package/flutter_app/windows/flutter/generated_plugins.cmake +0 -1
  45. package/landing/index.html +0 -2
  46. package/lib/manager.js +1 -1
  47. package/lib/schema_migrations.js +75 -0
  48. package/package.json +1 -4
  49. package/server/db/database.js +1 -133
  50. package/server/http/middleware.js +2 -16
  51. package/server/http/routes.js +0 -2
  52. package/server/public/.last_build_id +1 -1
  53. package/server/public/assets/NOTICES +0 -25
  54. package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
  55. package/server/public/flutter_bootstrap.js +1 -1
  56. package/server/public/index.html +174 -0
  57. package/server/public/main.dart.js +88081 -90036
  58. package/server/routes/auth.js +11 -2
  59. package/server/routes/settings.js +0 -5
  60. package/server/routes/voice_assistant.js +1 -128
  61. package/server/services/account/erasure.js +0 -3
  62. package/server/services/ai/deliverables/artifact_helpers.js +1 -1
  63. package/server/services/ai/loop/conversation_loop.js +6 -2
  64. package/server/services/ai/loop/tool_dispatch.js +0 -3
  65. package/server/services/ai/messagingFallback.js +1 -1
  66. package/server/services/ai/settings.js +0 -6
  67. package/server/services/ai/toolEvidence.js +1 -4
  68. package/server/services/ai/tools.js +0 -234
  69. package/server/services/desktop/auth.js +0 -3
  70. package/server/services/desktop/registry.js +2 -50
  71. package/server/services/integrations/neoarchive/provider.js +616 -0
  72. package/server/services/integrations/neorecall/client.js +140 -0
  73. package/server/services/integrations/neorecall/constants.js +87 -0
  74. package/server/services/integrations/neorecall/provider.js +163 -0
  75. package/server/services/integrations/registry.js +4 -2
  76. package/server/services/manager.js +0 -22
  77. package/server/services/memory/manager.js +44 -19
  78. package/server/services/memory/retrieval_reasoning.js +36 -14
  79. package/server/services/messaging/whatsapp.js +18 -0
  80. package/server/services/security/tool_categories.js +0 -5
  81. package/server/services/social_video/service.js +2 -20
  82. package/server/services/tasks/adapters/index.js +1 -1
  83. package/server/services/tasks/integration_runtime.js +3 -67
  84. package/server/services/tasks/runtime.js +1 -6
  85. package/server/services/tasks/task_repository.js +6 -13
  86. package/server/services/timeline/service.js +0 -224
  87. package/server/services/voice/message.js +0 -24
  88. package/server/services/voice/providers.js +42 -1
  89. package/server/services/voice/runtimeManager.js +9 -5
  90. package/server/services/voice/turnRunner.js +0 -22
  91. package/server/services/wearable/service.js +0 -5
  92. package/docs/recordings-and-health.md +0 -41
  93. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingBootReceiver.kt +0 -21
  94. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingForegroundService.kt +0 -586
  95. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingStateStore.kt +0 -78
  96. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingUploadClient.kt +0 -104
  97. package/flutter_app/lib/main_recordings.dart +0 -920
  98. package/flutter_app/lib/src/desktop_ocr_bridge.dart +0 -2
  99. package/flutter_app/lib/src/desktop_ocr_bridge_io.dart +0 -125
  100. package/flutter_app/lib/src/desktop_ocr_bridge_stub.dart +0 -30
  101. package/flutter_app/lib/src/desktop_passive_history.dart +0 -332
  102. package/flutter_app/lib/src/recording_bridge.dart +0 -232
  103. package/flutter_app/lib/src/recording_bridge_io.dart +0 -1027
  104. package/flutter_app/lib/src/recording_bridge_stub.dart +0 -120
  105. package/flutter_app/lib/src/recording_bridge_web.dart +0 -702
  106. package/flutter_app/lib/src/recording_chunk_queue.dart +0 -149
  107. package/flutter_app/lib/src/recording_chunk_queue_io.dart +0 -182
  108. package/flutter_app/lib/src/recording_payloads.dart +0 -95
  109. package/flutter_app/third_party/desktop_audio_capture/LICENSE +0 -21
  110. package/flutter_app/third_party/desktop_audio_capture/README.md +0 -262
  111. package/flutter_app/third_party/desktop_audio_capture/lib/audio_capture.dart +0 -65
  112. package/flutter_app/third_party/desktop_audio_capture/lib/config/mic_audio_config.dart +0 -153
  113. package/flutter_app/third_party/desktop_audio_capture/lib/config/system_adudio_config.dart +0 -110
  114. package/flutter_app/third_party/desktop_audio_capture/lib/mic/mic_audio_capture.dart +0 -461
  115. package/flutter_app/third_party/desktop_audio_capture/lib/model/audio_status.dart +0 -91
  116. package/flutter_app/third_party/desktop_audio_capture/lib/model/decibel_data.dart +0 -106
  117. package/flutter_app/third_party/desktop_audio_capture/lib/model/input_device_type.dart +0 -219
  118. package/flutter_app/third_party/desktop_audio_capture/lib/system/system_audio_capture.dart +0 -336
  119. package/flutter_app/third_party/desktop_audio_capture/linux/CMakeLists.txt +0 -101
  120. package/flutter_app/third_party/desktop_audio_capture/linux/audio_capture_plugin.cc +0 -692
  121. package/flutter_app/third_party/desktop_audio_capture/linux/include/audio_capture/audio_capture_plugin.h +0 -35
  122. package/flutter_app/third_party/desktop_audio_capture/linux/include/audio_capture/mic_capture_plugin.h +0 -36
  123. package/flutter_app/third_party/desktop_audio_capture/linux/include/desktop_audio_capture/audio_capture_plugin.h +0 -32
  124. package/flutter_app/third_party/desktop_audio_capture/linux/include/desktop_audio_capture/mic_capture_plugin.h +0 -32
  125. package/flutter_app/third_party/desktop_audio_capture/linux/mic_capture_plugin.cc +0 -878
  126. package/flutter_app/third_party/desktop_audio_capture/macos/Classes/AudioCapturePlugin.swift +0 -27
  127. package/flutter_app/third_party/desktop_audio_capture/macos/Classes/MicCapturePlugin.swift +0 -1172
  128. package/flutter_app/third_party/desktop_audio_capture/macos/Classes/SystemCapturePlugin.swift +0 -655
  129. package/flutter_app/third_party/desktop_audio_capture/macos/Resources/PrivacyInfo.xcprivacy +0 -12
  130. package/flutter_app/third_party/desktop_audio_capture/macos/desktop_audio_capture.podspec +0 -30
  131. package/flutter_app/third_party/desktop_audio_capture/pubspec.yaml +0 -87
  132. package/flutter_app/third_party/desktop_audio_capture/windows/CMakeLists.txt +0 -105
  133. package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin.cpp +0 -80
  134. package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin.h +0 -31
  135. package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin_c_api.cpp +0 -12
  136. package/flutter_app/third_party/desktop_audio_capture/windows/include/audio_capture/audio_capture_plugin_c_api.h +0 -23
  137. package/flutter_app/third_party/desktop_audio_capture/windows/include/desktop_audio_capture/audio_capture_plugin.h +0 -25
  138. package/flutter_app/third_party/desktop_audio_capture/windows/mic_capture_plugin.cpp +0 -1117
  139. package/flutter_app/third_party/desktop_audio_capture/windows/mic_capture_plugin.h +0 -115
  140. package/flutter_app/third_party/desktop_audio_capture/windows/system_audio_capture_plugin.cpp +0 -777
  141. package/flutter_app/third_party/desktop_audio_capture/windows/system_audio_capture_plugin.h +0 -87
  142. package/server/routes/recordings.js +0 -335
  143. package/server/routes/screenHistory.js +0 -190
  144. package/server/services/ai/recordingInsights.js +0 -105
  145. package/server/services/integrations/neomail/provider.js +0 -993
  146. package/server/services/recordings/deepgram.js +0 -58
  147. package/server/services/recordings/manager.js +0 -1273
  148. package/server/services/tasks/adapters/neomail_email_received.js +0 -46
  149. package/server/services/voice/screenshotContext.js +0 -73
  150. package/server/services/voice/turnCoordinator.js +0 -51
@@ -133,19 +133,13 @@ const _socialReachSettingsSection = _SettingsSection('social reach', <String>[
133
133
  'cookies',
134
134
  ]);
135
135
 
136
- const _voiceRecordingSettingsSection = _SettingsSection(
137
- 'voice recording',
138
- <String>[
139
- 'voice',
140
- 'recording',
141
- 'transcription',
142
- 'summary',
143
- 'speech',
144
- 'tts',
145
- 'stt',
146
- 'live',
147
- ],
148
- );
136
+ const _voiceSettingsSection = _SettingsSection('voice', <String>[
137
+ 'voice',
138
+ 'speech',
139
+ 'tts',
140
+ 'stt',
141
+ 'live',
142
+ ]);
149
143
 
150
144
  const _desktopSettingsSection = _SettingsSection('desktop', <String>[
151
145
  'desktop',
@@ -182,7 +176,7 @@ const List<_SettingsSection> _settingsSearchSections = <_SettingsSection>[
182
176
  _workspaceSettingsSection,
183
177
  _socialReachSettingsSection,
184
178
  _modelsSettingsSection,
185
- _voiceRecordingSettingsSection,
179
+ _voiceSettingsSection,
186
180
  _desktopSettingsSection,
187
181
  _securitySettingsSection,
188
182
  _diagnosticsSettingsSection,
@@ -198,8 +192,6 @@ class _SettingsPanelState extends State<SettingsPanel> {
198
192
  late Set<String> _enabledModels;
199
193
  late String _defaultChatModel;
200
194
  late String _defaultSubagentModel;
201
- late String _defaultRecordingTranscriptionModel;
202
- late String _defaultRecordingSummaryModel;
203
195
  late String _fallbackModel;
204
196
  late String _defaultSpeechModel;
205
197
  late String _voiceLiveProvider;
@@ -273,9 +265,6 @@ class _SettingsPanelState extends State<SettingsPanel> {
273
265
  }
274
266
  _defaultChatModel = controller.defaultChatModel;
275
267
  _defaultSubagentModel = controller.defaultSubagentModel;
276
- _defaultRecordingTranscriptionModel =
277
- controller.defaultRecordingTranscriptionModel;
278
- _defaultRecordingSummaryModel = controller.defaultRecordingSummaryModel;
279
268
  _fallbackModel = controller.fallbackModel;
280
269
  _defaultSpeechModel = controller.defaultSpeechModel;
281
270
  _voiceLiveProvider = controller.voiceLiveProvider;
@@ -370,8 +359,7 @@ class _SettingsPanelState extends State<SettingsPanel> {
370
359
  if (!widget.embedded)
371
360
  _PageTitle(
372
361
  title: 'Settings',
373
- subtitle:
374
- 'Workspace, models, recording, and diagnostics controls.',
362
+ subtitle: 'Workspace, models, and diagnostics controls.',
375
363
  trailing: _settingsSaveButton(controller),
376
364
  )
377
365
  else
@@ -442,9 +430,9 @@ class _SettingsPanelState extends State<SettingsPanel> {
442
430
  ],
443
431
  if (_matchesSettingsSection(
444
432
  searchQuery,
445
- _voiceRecordingSettingsSection,
433
+ _voiceSettingsSection,
446
434
  )) ...<Widget>[
447
- _buildVoiceAndRecordingSection(
435
+ _buildVoiceSection(
448
436
  controller: controller,
449
437
  modelChoices: modelChoices,
450
438
  routingModels: routingModels,
@@ -520,13 +508,6 @@ class _SettingsPanelState extends State<SettingsPanel> {
520
508
  enabledModels: _enabledModels.toList(),
521
509
  defaultChatModel: _defaultChatModel,
522
510
  defaultSubagentModel: _defaultSubagentModel,
523
- defaultRecordingTranscriptionProvider: 'deepgram',
524
- defaultRecordingTranscriptionModel: _defaultRecordingTranscriptionModel,
525
- defaultRecordingSummaryProvider: _providerForSelectedModel(
526
- _defaultRecordingSummaryModel,
527
- controller.supportedModels,
528
- ),
529
- defaultRecordingSummaryModel: _defaultRecordingSummaryModel,
530
511
  fallbackModel: _fallbackModel,
531
512
  defaultSpeechModel: _defaultSpeechModel,
532
513
  voiceSttProvider: controller.voiceSttProvider,
@@ -587,7 +568,7 @@ class _SettingsPanelState extends State<SettingsPanel> {
587
568
  const _SectionTitle('Overview'),
588
569
  const SizedBox(height: 10),
589
570
  Text(
590
- 'Configure workspace behavior, models, and recording defaults.',
571
+ 'Configure workspace behavior and model defaults.',
591
572
  style: TextStyle(color: _textSecondary, height: 1.45),
592
573
  ),
593
574
  const SizedBox(height: 14),
@@ -1389,7 +1370,7 @@ class _SettingsPanelState extends State<SettingsPanel> {
1389
1370
  );
1390
1371
  }
1391
1372
 
1392
- Widget _buildVoiceAndRecordingSection({
1373
+ Widget _buildVoiceSection({
1393
1374
  required NeoAgentController controller,
1394
1375
  required List<_ModelPickerOption> modelChoices,
1395
1376
  required List<ModelMeta> routingModels,
@@ -1402,76 +1383,13 @@ class _SettingsPanelState extends State<SettingsPanel> {
1402
1383
  child: Column(
1403
1384
  crossAxisAlignment: CrossAxisAlignment.start,
1404
1385
  children: <Widget>[
1405
- const _SectionTitle('Voice & Recording'),
1386
+ const _SectionTitle('Voice'),
1406
1387
  const SizedBox(height: 10),
1407
1388
  Text(
1408
- 'Defaults for transcription, summaries, and live voice.',
1389
+ 'Defaults for speech processing and live voice.',
1409
1390
  style: TextStyle(color: _textSecondary, height: 1.45),
1410
1391
  ),
1411
1392
  const SizedBox(height: 16),
1412
- Text(
1413
- 'Recording Defaults',
1414
- style: TextStyle(
1415
- fontWeight: FontWeight.w700,
1416
- color: _textPrimary,
1417
- ),
1418
- ),
1419
- const SizedBox(height: 12),
1420
- LayoutBuilder(
1421
- builder: (context, constraints) {
1422
- final compact = constraints.maxWidth < 940;
1423
- final cardWidth = compact
1424
- ? constraints.maxWidth
1425
- : (constraints.maxWidth - 12) / 2;
1426
- return Wrap(
1427
- spacing: 12,
1428
- runSpacing: 12,
1429
- children: <Widget>[
1430
- SizedBox(
1431
- width: cardWidth,
1432
- child: _RoutingSelectCard(
1433
- label: 'Recording Summary',
1434
- icon: Icons.summarize_outlined,
1435
- value: _ensureModelValue(
1436
- _defaultRecordingSummaryModel,
1437
- routingModels,
1438
- allowAuto: true,
1439
- ),
1440
- options: modelChoices,
1441
- onChanged: (value) {
1442
- if (value != null) {
1443
- setState(() {
1444
- _defaultRecordingSummaryModel = value;
1445
- _hasUnsavedChanges = true;
1446
- });
1447
- }
1448
- },
1449
- ),
1450
- ),
1451
- SizedBox(
1452
- width: cardWidth,
1453
- child: _RoutingSelectCard(
1454
- label: 'Recording Transcription',
1455
- icon: Icons.hearing_outlined,
1456
- value: _defaultRecordingTranscriptionModel,
1457
- options: _recordingTranscriptionOptions(
1458
- _defaultRecordingTranscriptionModel,
1459
- ),
1460
- onChanged: (value) {
1461
- if (value != null) {
1462
- setState(() {
1463
- _defaultRecordingTranscriptionModel = value;
1464
- _hasUnsavedChanges = true;
1465
- });
1466
- }
1467
- },
1468
- ),
1469
- ),
1470
- ],
1471
- );
1472
- },
1473
- ),
1474
- const Divider(height: 32),
1475
1393
  Text(
1476
1394
  'Speech Processing',
1477
1395
  style: TextStyle(
@@ -1630,7 +1548,7 @@ class _SettingsPanelState extends State<SettingsPanel> {
1630
1548
  const _SectionTitle('Desktop'),
1631
1549
  const SizedBox(height: 10),
1632
1550
  Text(
1633
- 'Desktop-only recording and companion controls for this computer.',
1551
+ 'Desktop-only companion controls for this computer.',
1634
1552
  style: TextStyle(color: _textSecondary, height: 1.45),
1635
1553
  ),
1636
1554
  const SizedBox(height: 16),
@@ -1655,16 +1573,6 @@ class _SettingsPanelState extends State<SettingsPanel> {
1655
1573
  keepRunningOnClose: controller.desktopKeepRunningOnClose,
1656
1574
  ),
1657
1575
  ),
1658
- SwitchListTile.adaptive(
1659
- value: controller.desktopAutoShowFloatingToolbar,
1660
- contentPadding: EdgeInsets.zero,
1661
- title: Text('Auto-show floating toolbar'),
1662
- subtitle: Text(
1663
- 'Open the compact recording bar automatically whenever a desktop studio session starts.',
1664
- style: TextStyle(color: _textSecondary),
1665
- ),
1666
- onChanged: controller.setDesktopAutoShowFloatingToolbar,
1667
- ),
1668
1576
  SwitchListTile.adaptive(
1669
1577
  value: controller.desktopAssistantHotkeyEnabled,
1670
1578
  contentPadding: EdgeInsets.zero,
@@ -1673,24 +1581,7 @@ class _SettingsPanelState extends State<SettingsPanel> {
1673
1581
  'Register $_desktopAssistantHotkeyLabel so the desktop shell is ready for the upcoming voice assistant summon flow.',
1674
1582
  style: TextStyle(color: _textSecondary),
1675
1583
  ),
1676
- onChanged: controller.recordingRuntime.supportsGlobalHotkeys
1677
- ? controller.setDesktopAssistantHotkeyEnabled
1678
- : null,
1679
- ),
1680
- const SizedBox(height: 12),
1681
- Wrap(
1682
- spacing: 10,
1683
- runSpacing: 10,
1684
- children: <Widget>[
1685
- _RecordingPermissionBadge(
1686
- label: 'Microphone',
1687
- state: controller.recordingRuntime.microphonePermission,
1688
- ),
1689
- _RecordingPermissionBadge(
1690
- label: 'System audio',
1691
- state: controller.recordingRuntime.systemAudioPermission,
1692
- ),
1693
- ],
1584
+ onChanged: controller.setDesktopAssistantHotkeyEnabled,
1694
1585
  ),
1695
1586
  const Divider(height: 32),
1696
1587
  Text(
@@ -1723,18 +1614,6 @@ class _SettingsPanelState extends State<SettingsPanel> {
1723
1614
  ? controller.setDesktopCompanionPaused
1724
1615
  : null,
1725
1616
  ),
1726
- SwitchListTile.adaptive(
1727
- value: controller.desktopPassiveHistoryEnabled,
1728
- contentPadding: EdgeInsets.zero,
1729
- title: Text('Passive screen history on this computer'),
1730
- subtitle: Text(
1731
- 'Capture OCR text plus app/window context locally for the user-wide Timeline. Screenshots stay transient and are not uploaded.',
1732
- style: TextStyle(color: _textSecondary),
1733
- ),
1734
- onChanged: controller.desktopCompanionEnabled
1735
- ? controller.setDesktopPassiveHistoryEnabled
1736
- : null,
1737
- ),
1738
1617
  const SizedBox(height: 12),
1739
1618
  TextFormField(
1740
1619
  initialValue: controller.desktopCompanionLabel,
@@ -1769,49 +1648,8 @@ class _SettingsPanelState extends State<SettingsPanel> {
1769
1648
  ? _warning
1770
1649
  : _success,
1771
1650
  ),
1772
- _DotStatus(
1773
- label: controller.desktopPassiveHistoryEnabled
1774
- ? 'History enabled'
1775
- : 'History disabled',
1776
- color: controller.desktopPassiveHistoryEnabled
1777
- ? _accent
1778
- : _textMuted,
1779
- ),
1780
1651
  ],
1781
1652
  ),
1782
- if (controller.desktopPassiveHistoryLastUploadedAt != null ||
1783
- controller.desktopPassiveHistoryLastError != null) ...<Widget>[
1784
- const SizedBox(height: 12),
1785
- Container(
1786
- width: double.infinity,
1787
- padding: const EdgeInsets.all(12),
1788
- decoration: BoxDecoration(
1789
- color: _bgSecondary.withValues(alpha: 0.66),
1790
- borderRadius: BorderRadius.circular(16),
1791
- border: Border.all(color: _borderLight),
1792
- ),
1793
- child: Column(
1794
- crossAxisAlignment: CrossAxisAlignment.start,
1795
- children: <Widget>[
1796
- if (controller.desktopPassiveHistoryLastUploadedAt
1797
- case final uploadedAt?)
1798
- Text(
1799
- 'Last upload: ${_formatTimestamp(DateTime.parse(uploadedAt))}',
1800
- style: TextStyle(color: _textSecondary),
1801
- ),
1802
- if (controller.desktopPassiveHistoryLastError
1803
- case final passiveError?)
1804
- Padding(
1805
- padding: const EdgeInsets.only(top: 6),
1806
- child: Text(
1807
- 'Last error: $passiveError',
1808
- style: TextStyle(color: _danger),
1809
- ),
1810
- ),
1811
- ],
1812
- ),
1813
- ),
1814
- ],
1815
1653
  if (controller.desktopCompanionErrorMessage
1816
1654
  case final message?) ...<Widget>[
1817
1655
  const SizedBox(height: 12),
@@ -2089,18 +1927,6 @@ class _SettingsPanelState extends State<SettingsPanel> {
2089
1927
  );
2090
1928
  }
2091
1929
 
2092
- String _providerForSelectedModel(String modelId, List<ModelMeta> models) {
2093
- if (modelId.trim().isEmpty || modelId == 'auto') {
2094
- return 'auto';
2095
- }
2096
- for (final model in models) {
2097
- if (model.id == modelId) {
2098
- return model.provider.trim().isEmpty ? 'auto' : model.provider;
2099
- }
2100
- }
2101
- return 'auto';
2102
- }
2103
-
2104
1930
  Map<String, dynamic> _buildProviderPayload() {
2105
1931
  final providerIds = <String>{
2106
1932
  ...widget.controller.aiProviders.map((provider) => provider.id),
@@ -2171,14 +1997,6 @@ class _SettingsPanelState extends State<SettingsPanel> {
2171
1997
  );
2172
1998
  }
2173
1999
 
2174
- List<_ModelPickerOption> _recordingTranscriptionOptions(String current) {
2175
- const List<String> defaults = <String>['nova-3', 'nova-2-general'];
2176
- final String normalizedCurrent = current.trim();
2177
- final Set<String> values = <String>{...defaults};
2178
- if (normalizedCurrent.isNotEmpty) values.add(normalizedCurrent);
2179
- return _simplePickerOptions(values.toList());
2180
- }
2181
-
2182
2000
  // Shared helper: small "Test" button + inline result row.
2183
2001
  Widget _buildInlineTestRow({
2184
2002
  required String label,