Skip to content

Commit cc301ce

Browse files
pre-release v0.2 (#293)
* Enhance ASR service descriptions and provider feedback in wizard.py - Updated the description for the 'asr-services' to remove the specific mention of 'Parakeet', making it more general. - Improved the console output for auto-selected services to include the transcription provider label, enhancing user feedback during service selection. * Implement LangFuse integration for observability and prompt management - Added LangFuse configuration options in the .env.template for observability and prompt management. - Introduced setup_langfuse method in ChronicleSetup to handle LangFuse initialization and configuration prompts. - Enhanced prompt management by integrating a centralized PromptRegistry for dynamic prompt retrieval and registration. - Updated various services to utilize prompts from the PromptRegistry, improving flexibility and maintainability. - Refactored OpenAI client initialization to support optional LangFuse tracing, enhancing observability during API interactions. - Added new prompt defaults for memory management and conversation handling, ensuring consistent behavior across the application. * Enhance LangFuse integration and service management - Added LangFuse service configuration in services.py and wizard.py, including paths, commands, and descriptions. - Implemented auto-selection for LangFuse during service setup, improving user experience. - Enhanced service startup process to display prompt management tips for LangFuse, guiding users on editing AI prompts. - Updated run_service_setup to handle LangFuse-specific parameters, including admin credentials and API keys, ensuring seamless integration with backend services. * Feat/better reprocess memory (#300) * Enhance ASR service descriptions and provider feedback in wizard.py (#290) - Updated the description for the 'asr-services' to remove the specific mention of 'Parakeet', making it more general. - Improved the console output for auto-selected services to include the transcription provider label, enhancing user feedback during service selection. * Refactor Obsidian and Knowledge Graph integration in services and setup - Removed redundant Obsidian and Knowledge Graph configuration checks from services.py, streamlining the command execution process. - Updated wizard.py to enhance user experience by setting default options for speaker recognition during service selection. - Improved Neo4j password handling in setup processes, ensuring consistent configuration prompts and feedback. - Introduced a new cron scheduler for managing scheduled tasks, enhancing the backend's automation capabilities. - Added new entity annotation features, allowing for corrections and updates to knowledge graph entities directly through the API. * Enhance ASR services configuration and VibeVoice integration - Added new configuration options for VibeVoice ASR in defaults.yml, including batching parameters for audio processing. - Updated Docker Compose files to mount the config directory, ensuring access to ASR service configurations. - Enhanced the VibeVoice transcriber to load configuration settings from defaults.yml, allowing for dynamic adjustments via environment variables. - Introduced quantization options for model loading in the VibeVoice transcriber, improving performance and flexibility. - Refactored the speaker identification process to streamline audio handling and improve logging for better debugging. - Updated documentation to reflect new configuration capabilities and usage instructions for the VibeVoice ASR provider. * Enhance LangFuse integration and memory reprocessing capabilities - Introduced functions for checking LangFuse configuration in services.py, ensuring proper setup for observability. - Updated wizard.py to facilitate user input for LangFuse configuration, including options for local and external setups. - Implemented memory reprocessing logic in memory services to update existing memories based on speaker re-identification. - Enhanced speaker recognition client to support per-segment identification, improving accuracy during reprocessing. - Refactored various components to streamline handling of LangFuse parameters and improve overall service management. * Enhance service management and user input handling - Updated services.py to include LangFuse configuration checks during service startup, improving observability setup. - Refactored wizard.py to utilize a masked input for Neo4j password prompts, enhancing user experience and security. - Improved cron scheduler in advanced_omi_backend to manage active tasks and validate cron expressions, ensuring robust job execution. - Enhanced speaker recognition client documentation to clarify user_id limitations, preparing for future multi-user support. - Updated knowledge graph routes to enforce validation on entity updates, ensuring at least one field is provided for updates. * fix: Plugin System Refactor (#301) * Refactor connect-omi.py for improved device selection and user interaction - Replaced references to the chronicle Bluetooth library with friend_lite for device management. - Removed the list_devices function and implemented a new prompt_user_to_pick_device function to enhance user interaction when selecting OMI/Neo devices. - Updated the find_and_set_omi_mac function to utilize the new device selection method, improving the overall flow of device connection. - Added a new scan_devices.py script for quick scanning of neo/neosapien devices, enhancing usability. - Updated README.md to reflect new usage instructions and prerequisites for connecting to OMI devices over Bluetooth. - Enhanced start.sh to ensure proper environment variable setup for macOS users. * Add friend-lite-sdk: Initial implementation of Python SDK for OMI/Friend Lite BLE devices - Introduced the friend-lite-sdk, a Python SDK for OMI/Friend Lite BLE devices, enabling audio streaming, button events, and transcription functionalities. - Added LICENSE and NOTICE files to clarify licensing and attribution. - Created pyproject.toml for package management, specifying dependencies and project metadata. - Developed core modules including bluetooth connection handling, button event parsing, audio decoding, and transcription capabilities. - Implemented example usage in README.md to guide users on installation and basic functionality. - Enhanced connect-omi.py to utilize the new SDK for improved device management and event handling. - Updated requirements.txt to reference the new SDK for local development. This commit lays the foundation for further enhancements and integrations with OMI devices. * Enhance client state and plugin architecture for button event handling - Introduced a new `markers` list in `ClientState` to collect button event data during sessions. - Added `add_marker` method to facilitate the addition of markers to the current session. - Implemented `on_button_event` method in the `BasePlugin` class to handle device button events, providing context data for button state and timestamps. - Updated `PluginRouter` to route button events to the appropriate plugin handler. - Enhanced conversation job handling to attach markers from Redis sessions, improving the tracking of button events during conversations. * Move plugins locatino - Introduced the Email Summarizer plugin that automatically sends email summaries upon conversation completion. - Implemented SMTP email service for sending formatted HTML and plain text emails. - Added configuration options for SMTP settings and email content in `config.yml`. - Created setup script for easy configuration of SMTP credentials and plugin orchestration. - Enhanced documentation with usage instructions and troubleshooting tips for the plugin. - Updated existing plugin architecture to support new event handling for email summaries. * Enhance Docker Compose and Plugin Management - Added external plugins directory to Docker Compose files for better plugin management. - Updated environment variables for MongoDB and Redis services to ensure consistent behavior. - Introduced new dependencies in `uv.lock` for improved functionality. - Refactored audio processing to support various audio formats and enhance error handling. - Implemented new plugin event types and services for better integration and communication between plugins. - Enhanced conversation and session management to support new closing mechanisms and event logging. * Update audio processing and event logging - Increased the maximum event log size in PluginRouter from 200 to 1000 for improved event tracking. - Refactored audio stream producer to dynamically read audio format from Redis session metadata, enhancing flexibility in audio handling. - Updated transcription job processing to utilize session-specific audio format settings, ensuring accurate audio processing. - Enhanced audio file writing utility to accept PCM parameters, allowing for better control over audio data handling. * Add markers list to ClientState and update timeout trigger comment - Introduced a new `markers` list in `ClientState` to track button event data during conversations. - Updated comment in `open_conversation_job` to clarify the behavior of the `timeout_triggered` variable, ensuring better understanding of session management. * Refactor audio file logging and error handling - Updated audio processing logs to consistently use the `filename` variable instead of `file.filename` for clarity. - Enhanced error logging to utilize the `filename` variable, improving traceability of issues during audio processing. - Adjusted title generation logic to handle cases where the filename is "unknown," ensuring a default title is used. - Minor refactor in conversation closing logs to use `user.user_id` for better consistency in user identification. * Enhance conversation retrieval with pagination and orphan handling - Updated `get_conversations` function to support pagination through `limit` and `offset` parameters, improving performance for large datasets. - Consolidated query logic to fetch both normal and orphan conversations in a single database call, reducing round-trips and enhancing efficiency. - Modified the response structure to include total count, limit, and offset in the returned data for better client-side handling. - Adjusted database indexing to optimize queries for paginated results, ensuring faster access to conversation data. * Refactor connection logging in transcribe function - Moved connection logging for the Wyoming server to a more structured format within the `transcribe_wyoming` function. - Ensured that connection attempts and successes are logged consistently for better traceability during audio transcription processes. * Feat/neo sdk (#302) * Update friend-lite-sdk for Neo1 device support and enhance documentation - Updated the friend-lite-sdk to version 0.3.0, reflecting the transition to support OMI/Neo1 BLE wearable devices. - Refactored the Bluetooth connection handling to introduce a new `WearableConnection` class, enhancing the connection lifecycle management for wearable devices. - Added a new `Neo1Connection` class for controlling Neo1 devices, including methods for sleep and wake functionalities. - Updated UUID constants to include Neo1-specific characteristics, improving device interaction capabilities. - Revised the plugin development guide to reflect changes in device naming and connection processes. - Removed outdated local OMI Bluetooth scripts and documentation to streamline the project structure and focus on wearable client development. * Refactor backend audio streaming to use Opus codec and enhance menu app functionality - Updated backend_sender.py to stream raw Opus audio instead of PCM, improving bandwidth efficiency. - Modified stream_to_backend function to handle Opus audio data and adjusted audio chunk parameters accordingly. - Enhanced main.py with new CLI commands for device scanning and connection management, improving user experience. - Introduced menu_app.py for a macOS menu bar application, providing a user-friendly interface for device management and status display. - Added README.md to document usage instructions and configuration details for the local wearable client. - Updated requirements.txt to include new dependencies for the menu app and service management. - Implemented service.py for managing launchd service installation and configuration on macOS, enabling auto-start on login. * Refactor audio processing and queue management in local wearable client - Removed the audio queue in favor of a dedicated BLE data queue and backend queue for improved data handling. - Enhanced the `connect_and_stream` function to streamline audio decoding and writing to the local file sink. - Updated the handling of BLE data to ensure robust queue management and error logging. - Improved task management during device disconnection to ensure proper cleanup and error handling. - Updated requirements.txt to specify a minimum version for easy_audio_interfaces, ensuring compatibility.
1 parent 112ee01 commit cc301ce

File tree

157 files changed

+11166
-1866
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

157 files changed

+11166
-1866
lines changed

backends/advanced/.env.template

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,11 @@ NEO4J_HOST=neo4j
5353
NEO4J_USER=neo4j
5454
NEO4J_PASSWORD=
5555

56-
# Langfuse API keys (for LLM observability)
56+
# Langfuse (for LLM observability and prompt management)
57+
LANGFUSE_HOST=
5758
LANGFUSE_PUBLIC_KEY=
5859
LANGFUSE_SECRET_KEY=
60+
LANGFUSE_BASE_URL=http://langfuse-web:3000
5961

6062
# Tailscale auth key (for remote service access)
6163
TS_AUTHKEY=

backends/advanced/Docs/plugin-development-guide.md

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ Chronicle's plugin system allows you to extend functionality by subscribing to e
2424
- **Configurable**: YAML-based configuration with environment variable support
2525
- **Isolated**: Each plugin runs independently with proper error handling
2626

27-
### Plugin Types
28-
29-
- **Core Plugins**: Built-in plugins (`homeassistant`, `test_event`)
30-
- **Community Plugins**: Auto-discovered plugins in `plugins/` directory
31-
3227
## Quick Start
3328

3429
### 1. Generate Plugin Boilerplate
@@ -207,6 +202,84 @@ async def on_memory_processed(self, context: PluginContext):
207202
await self.index_memory(memory)
208203
```
209204

205+
### 4. Button Events (`button.single_press`, `button.double_press`)
206+
207+
**When**: OMI device button is pressed
208+
**Context Data**:
209+
- `state` (str): Button state (`SINGLE_TAP`, `DOUBLE_TAP`)
210+
- `timestamp` (float): Unix timestamp of the event
211+
- `audio_uuid` (str): Current audio session UUID (may be None)
212+
- `session_id` (str): Streaming session ID (for conversation close)
213+
- `client_id` (str): Client device identifier
214+
215+
**Data Flow**:
216+
```
217+
OMI Device (BLE)
218+
→ Button press on physical device
219+
→ BLE characteristic notifies with 8-byte payload
220+
221+
friend-lite-sdk (extras/friend-lite-sdk/)
222+
→ parse_button_event() converts payload → ButtonState IntEnum
223+
224+
BLE Client (extras/local-wearable-client/ or mobile app)
225+
→ Formats as Wyoming protocol: {"type": "button-event", "data": {"state": "SINGLE_TAP"}}
226+
→ Sends over WebSocket
227+
228+
Backend (websocket_controller.py)
229+
→ _handle_button_event() stores marker on client_state
230+
→ Maps ButtonState → PluginEvent using enums (plugins/events.py)
231+
→ Dispatches granular event to plugin system
232+
233+
Plugin System
234+
→ Routed to subscribed plugins (e.g., test_button_actions)
235+
→ Plugins use PluginServices for system actions and cross-plugin calls
236+
```
237+
238+
**Use Cases**:
239+
- Close current conversation (single press)
240+
- Toggle smart home devices (double press)
241+
- Custom actions via cross-plugin communication
242+
243+
**Example**:
244+
```python
245+
async def on_button_event(self, context: PluginContext):
246+
if context.event == PluginEvent.BUTTON_SINGLE_PRESS:
247+
session_id = context.data.get('session_id')
248+
await context.services.close_conversation(session_id)
249+
```
250+
251+
### 5. Plugin Action Events (`plugin_action`)
252+
253+
**When**: Another plugin calls `context.services.call_plugin()`
254+
**Context Data**:
255+
- `action` (str): Action name (e.g., `toggle_lights`)
256+
- Plus any additional data from the calling plugin
257+
258+
**Use Cases**:
259+
- Cross-plugin communication (button press → toggle lights)
260+
- Service orchestration between plugins
261+
262+
**Example**:
263+
```python
264+
async def on_plugin_action(self, context: PluginContext):
265+
action = context.data.get('action')
266+
if action == 'toggle_lights':
267+
# Handle the action
268+
...
269+
```
270+
271+
### PluginServices
272+
273+
Plugins receive a `services` object on the context for system and cross-plugin interaction:
274+
275+
```python
276+
# Close the current conversation (triggers post-processing)
277+
await context.services.close_conversation(session_id, reason)
278+
279+
# Call another plugin's on_plugin_action() handler
280+
result = await context.services.call_plugin("homeassistant", "toggle_lights", data)
281+
```
282+
210283
## Creating Your First Plugin
211284

212285
### Step 1: Generate Boilerplate
@@ -225,7 +298,7 @@ import logging
225298
import re
226299
from typing import Any, Dict, List, Optional
227300

228-
from ..base import BasePlugin, PluginContext, PluginResult
301+
from advanced_omi_backend.plugins.base import BasePlugin, PluginContext, PluginResult
229302

230303
logger = logging.getLogger(__name__)
231304

@@ -671,7 +744,7 @@ async def on_conversation_complete(self, context):
671744
**Solution**:
672745
- Restart backend after adding dependencies
673746
- Verify imports are from correct modules
674-
- Check relative imports use `..base` for base classes
747+
- Use absolute imports for framework classes: `from advanced_omi_backend.plugins.base import BasePlugin`
675748

676749
### Database Connection Issues
677750

@@ -749,12 +822,13 @@ class ExternalServicePlugin(BasePlugin):
749822

750823
## Resources
751824

752-
- **Base Plugin Class**: `backends/advanced/src/advanced_omi_backend/plugins/base.py`
753-
- **Example Plugins**:
825+
- **Plugin Framework**: `backends/advanced/src/advanced_omi_backend/plugins/` (base.py, router.py, events.py, services.py)
826+
- **Plugin Implementations**: `plugins/` at repo root
754827
- Email Summarizer: `plugins/email_summarizer/`
755828
- Home Assistant: `plugins/homeassistant/`
756829
- Test Event: `plugins/test_event/`
757-
- **Plugin Generator**: `scripts/create_plugin.py`
830+
- Test Button Actions: `plugins/test_button_actions/`
831+
- **Plugin Generator**: `backends/advanced/scripts/create_plugin.py`
758832
- **Configuration**: `config/plugins.yml.template`
759833

760834
## Contributing Plugins

backends/advanced/docker-compose-test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ services:
2121
- ../../config:/app/config # Mount config directory with defaults.yml
2222
- ../../tests/configs:/app/test-configs:ro # Mount test-specific configs
2323
- ${PLUGINS_CONFIG:-../../tests/config/plugins.test.yml}:/app/config/plugins.yml # Mount test plugins config to correct location
24+
- ../../plugins:/app/plugins # External plugins directory
2425
environment:
2526
# Override with test-specific settings
2627
- MONGODB_URI=mongodb://mongo-test:27017/test_db
@@ -223,6 +224,7 @@ services:
223224
- ../../config:/app/config # Mount config directory with defaults.yml
224225
- ../../tests/configs:/app/test-configs:ro # Mount test-specific configs
225226
- ${PLUGINS_CONFIG:-../../tests/config/plugins.test.yml}:/app/config/plugins.yml # Mount test plugins config to correct location
227+
- ../../plugins:/app/plugins # External plugins directory
226228
environment:
227229
# Same environment as backend
228230
- MONGODB_URI=mongodb://mongo-test:27017/test_db

backends/advanced/docker-compose.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ services:
4040
- ./data/debug_dir:/app/debug_dir
4141
- ./data:/app/data
4242
- ../../config:/app/config # Mount entire config directory (includes config.yml, defaults.yml, plugins.yml)
43+
- ../../plugins:/app/plugins # External plugins directory
4344
environment:
4445
- DEEPGRAM_API_KEY=${DEEPGRAM_API_KEY}
4546
- PARAKEET_ASR_URL=${PARAKEET_ASR_URL}
@@ -95,6 +96,7 @@ services:
9596
- ./data/audio_chunks:/app/audio_chunks
9697
- ./data:/app/data
9798
- ../../config:/app/config # Mount entire config directory (includes config.yml, defaults.yml, plugins.yml)
99+
- ../../plugins:/app/plugins # External plugins directory
98100
environment:
99101
- DEEPGRAM_API_KEY=${DEEPGRAM_API_KEY}
100102
- PARAKEET_ASR_URL=${PARAKEET_ASR_URL}
@@ -212,8 +214,8 @@ services:
212214
- "6033:6033" # gRPC
213215
- "6034:6034" # HTTP
214216
volumes:
215-
- ./data/qdrant_data:/qdrant/storage
216-
217+
- ./data/qdrant_data:/qdrant/storage
218+
restart: unless-stopped
217219

218220
mongo:
219221
image: mongo:8.0.14
@@ -227,6 +229,7 @@ services:
227229
timeout: 5s
228230
retries: 5
229231
start_period: 10s
232+
restart: unless-stopped
230233

231234
redis:
232235
image: redis:7-alpine
@@ -235,6 +238,7 @@ services:
235238
volumes:
236239
- ./data/redis_data:/data
237240
command: redis-server --appendonly yes
241+
restart: unless-stopped
238242
healthcheck:
239243
test: ["CMD", "redis-cli", "ping"]
240244
interval: 5s
@@ -267,9 +271,6 @@ services:
267271
timeout: 10s
268272
retries: 5
269273
start_period: 30s
270-
profiles:
271-
- obsidian
272-
- knowledge-graph
273274

274275
# ollama:
275276
# image: ollama/ollama:latest

0 commit comments

Comments
 (0)