From 88d3df628328226cc1d8b5ec3175b299beb8cfde Mon Sep 17 00:00:00 2001 From: Stu Alexandere Date: Fri, 5 Dec 2025 00:48:43 +0000 Subject: [PATCH 1/3] Changed name to chronicle # Conflicts: # README-K8S.md # backends/advanced/src/advanced_omi_backend/auth.py # backends/advanced/src/advanced_omi_backend/services/mycelia_sync.py # backends/advanced/webui/package-lock.json # backends/advanced/webui/package.json # quickstart.md # tests/infrastructure/infra_tests.robot # tests/integration/websocket_streaming_tests.robot --- .env.template | 16 +- CLAUDE.md | 26 +-- Docs/features.md | 10 +- Docs/getting-started.md | 32 ++-- Docs/init-system.md | 8 +- Docs/ports-and-access.md | 4 +- Makefile | 36 ++-- README-K8S.md | 42 ++--- README.md | 2 +- app/README.md | 18 +- app/app.json | 10 +- app/app/components/DeviceDetails.tsx | 2 +- app/app/components/DeviceListItem.tsx | 2 +- app/app/hooks/useAudioListener.ts | 2 +- app/app/hooks/useDeviceConnection.ts | 2 +- app/app/hooks/useDeviceScanning.ts | 2 +- app/app/index.tsx | 4 +- app/package.json | 4 +- backends/README.md | 4 +- backends/advanced/Docs/HTTPS_SETUP.md | 10 +- backends/advanced/Docs/README.md | 4 +- backends/advanced/Docs/UI.md | 2 +- backends/advanced/Docs/architecture.md | 6 +- backends/advanced/Docs/auth.md | 4 +- backends/advanced/Docs/memories.md | 8 +- backends/advanced/Docs/quickstart.md | 32 ++-- backends/advanced/docker-compose-test.yml | 114 ++++++------ backends/advanced/docker-compose.yml | 12 +- backends/advanced/init-https.sh | 6 +- backends/advanced/init.py | 24 +-- .../scripts/create_mycelia_api_key.py | 4 +- .../scripts/sync_friendlite_mycelia.py | 74 ++++---- backends/advanced/setup-https.sh | 6 +- .../src/advanced_omi_backend/app_config.py | 6 +- .../src/advanced_omi_backend/app_factory.py | 2 +- .../advanced/src/advanced_omi_backend/auth.py | 10 +- .../src/advanced_omi_backend/chat_service.py | 2 +- .../advanced_omi_backend/clients/__init__.py | 2 +- .../src/advanced_omi_backend/config.py | 2 +- .../controllers/system_controller.py | 10 +- .../controllers/websocket_controller.py | 2 +- .../src/advanced_omi_backend/database.py | 2 +- .../middleware/app_middleware.py | 2 +- .../advanced_omi_backend/models/__init__.py | 4 +- .../advanced_omi_backend/models/audio_file.py | 2 +- .../models/conversation.py | 4 +- .../routers/api_router.py | 2 +- .../routers/modules/__init__.py | 2 +- .../routers/modules/chat_routes.py | 2 +- .../routers/modules/client_routes.py | 2 +- .../routers/modules/conversation_routes.py | 2 +- .../routers/modules/health_routes.py | 24 +-- .../routers/modules/memory_routes.py | 2 +- .../routers/modules/system_routes.py | 2 +- .../routers/modules/user_routes.py | 2 +- .../routers/modules/websocket_routes.py | 2 +- .../advanced_omi_backend/services/__init__.py | 2 +- .../services/memory/__init__.py | 4 +- .../services/memory/config.py | 14 +- .../services/memory/providers/__init__.py | 6 +- .../{friend_lite.py => chronicle.py} | 0 .../services/memory/providers/mcp_client.py | 18 +- .../services/memory/providers/mycelia.py | 8 +- .../memory/providers/openmemory_mcp.py | 22 +-- .../services/memory/service_factory.py | 14 +- .../services/mycelia_sync.py | 58 +++--- .../workers/conversation_jobs.py | 7 +- .../workers/memory_jobs.py | 4 +- backends/advanced/ssl/generate-ssl.sh | 2 +- backends/advanced/start-k8s.sh | 4 +- backends/advanced/start-workers.sh | 2 +- backends/advanced/start.sh | 4 +- .../tests/test_conversation_models.py | 12 +- backends/advanced/tests/test_integration.py | 4 +- backends/advanced/upload_files.py | 6 +- backends/advanced/webui/README.md | 4 +- backends/advanced/webui/package-lock.json | 174 +++++++++--------- backends/advanced/webui/package.json | 4 +- .../webui/src/components/layout/Layout.tsx | 4 +- .../advanced/webui/src/pages/LoginPage.tsx | 2 +- .../advanced/webui/src/pages/Memories.tsx | 4 +- .../webui/src/pages/MemoriesRouter.tsx | 4 +- backends/advanced/webui/src/pages/System.tsx | 2 +- backends/advanced/webui/tsconfig.json | 1 + backends/charts/advanced-backend/Chart.yaml | 4 +- .../templates/deployment.yaml | 8 +- .../templates/workers-deployment.yaml | 4 +- backends/charts/advanced-backend/values.yaml | 4 +- backends/charts/webui/Chart.yaml | 4 +- .../charts/webui/templates/deployment.yaml | 4 +- backends/charts/webui/values.yaml | 2 +- extras/asr-services/README.md | 4 +- extras/asr-services/quickstart.md | 6 +- .../tests/test_parakeet_service.py | 2 +- extras/havpe-relay/README.md | 2 +- extras/havpe-relay/main.py | 2 +- extras/local-omi-bt/connect-omi.py | 6 +- extras/openmemory-mcp/README.md | 38 ++-- extras/openmemory-mcp/run.sh | 8 +- extras/openmemory-mcp/test_standalone.py | 2 +- extras/speaker-omni-experimental/README.md | 6 +- .../charts/templates/speaker-deployment.yaml | 2 +- .../charts/templates/webui-deployment.yaml | 4 +- extras/speaker-recognition/charts/values.yaml | 2 +- extras/speaker-recognition/init.py | 2 +- extras/speaker-recognition/quickstart.md | 2 +- .../simple_speaker_recognition/__init__.py | 2 +- .../speaker-recognition/ssl/generate-ssl.sh | 2 +- .../tests/test_speaker_service_integration.py | 2 +- k8s-manifests/cross-namespace-rbac.yaml | 8 +- quickstart.md | 30 +-- run-test.sh | 6 +- scripts/generate-k8s-configs.py | 12 +- scripts/k8s/cluster-status.sh | 2 +- scripts/k8s/load-env.sh | 2 +- scripts/manage-audio-files.sh | 2 +- services.py | 4 +- skaffold.yaml | 4 +- status.py | 8 +- tests/.env.test | 12 +- tests/Makefile | 4 +- tests/README.md | 6 +- tests/TESTING_USER_GUIDE.md | 2 +- tests/browser/browser_auth.robot | 2 +- tests/infrastructure/infra_tests.robot | 4 +- tests/libs/audio_stream_library.py | 28 +++ tests/resources/websocket_keywords.robot | 9 + tests/setup/setup_keywords.robot | 2 +- tests/setup/test_env.py | 2 +- tests/setup/test_manager_keywords.robot | 33 ++-- tests/tags.md | 4 +- wizard.py | 8 +- 132 files changed, 696 insertions(+), 636 deletions(-) rename backends/advanced/src/advanced_omi_backend/services/memory/providers/{friend_lite.py => chronicle.py} (100%) diff --git a/.env.template b/.env.template index 97495493..328d3301 100644 --- a/.env.template +++ b/.env.template @@ -1,7 +1,7 @@ # ======================================== -# FRIEND-LITE MASTER CONFIGURATION +# CHRONICLE MASTER CONFIGURATION # ======================================== -# This is the master configuration template for the entire Friend-Lite project. +# This is the master configuration template for the entire Chronicle project. # Copy this file to .env and customize values, then run 'make config' to generate # all service-specific configuration files. @@ -11,7 +11,7 @@ # Infrastructure namespaces INFRASTRUCTURE_NAMESPACE=infrastructure -APPLICATION_NAMESPACE=friend-lite +APPLICATION_NAMESPACE=chronicle # Deployment mode: docker-compose, kubernetes, or distributed DEPLOYMENT_MODE=docker-compose @@ -24,7 +24,7 @@ CONTAINER_REGISTRY=localhost:32000 # ======================================== # Primary domain/IP for all services -# Examples: localhost, 192.168.1.100, friend-lite.example.com, 100.x.x.x (Tailscale) +# Examples: localhost, 192.168.1.100, chronicle.example.com, 100.x.x.x (Tailscale) DOMAIN=localhost # Service ports (Docker Compose mode) @@ -105,7 +105,7 @@ PARAKEET_ASR_URL=http://host.docker.internal:8767 # MongoDB configuration MONGODB_URI=mongodb://mongo:${MONGODB_PORT} -MONGODB_K8S_URI=mongodb://mongodb.${INFRASTRUCTURE_NAMESPACE}.svc.cluster.local:27017/friend-lite +MONGODB_K8S_URI=mongodb://mongodb.${INFRASTRUCTURE_NAMESPACE}.svc.cluster.local:27017/chronicle # Qdrant configuration QDRANT_BASE_URL=qdrant @@ -120,12 +120,12 @@ NEO4J_PASSWORD=neo4j-password # MEMORY PROVIDER CONFIGURATION # ======================================== -# Memory Provider: friend_lite or openmemory_mcp -MEMORY_PROVIDER=friend_lite +# Memory Provider: chronicle or openmemory_mcp +MEMORY_PROVIDER=chronicle # OpenMemory MCP configuration (when MEMORY_PROVIDER=openmemory_mcp) OPENMEMORY_MCP_URL=http://host.docker.internal:8765 -OPENMEMORY_CLIENT_NAME=friend_lite +OPENMEMORY_CLIENT_NAME=chronicle OPENMEMORY_USER_ID=openmemory OPENMEMORY_TIMEOUT=30 diff --git a/CLAUDE.md b/CLAUDE.md index 0f579d33..ec326b6d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -Friend-Lite is at the core an AI-powered personal system - various devices, including but not limited to wearables from OMI can be used for at the very least audio capture, speaker specific transcription, memory extraction and retrieval. +Chronicle is at the core an AI-powered personal system - various devices, including but not limited to wearables from OMI can be used for at the very least audio capture, speaker specific transcription, memory extraction and retrieval. On top of that - it is being designed to support other services, that can help a user with these inputs such as reminders, action items, personal diagnosis etc. This supports a comprehensive web dashboard for management. @@ -147,7 +147,7 @@ docker compose up --build - **Job Tracker**: Tracks pipeline jobs with stage events (audio โ†’ transcription โ†’ memory) and completion status - **Task Management**: BackgroundTaskManager tracks all async tasks to prevent orphaned processes - **Unified Transcription**: Deepgram/Mistral transcription with fallback to offline ASR services -- **Memory System**: Pluggable providers (Friend-Lite native or OpenMemory MCP) +- **Memory System**: Pluggable providers (Chronicle native or OpenMemory MCP) - **Authentication**: Email-based login with MongoDB ObjectId user system - **Client Management**: Auto-generated client IDs as `{user_id_suffix}-{device_name}`, centralized ClientManager - **Data Storage**: MongoDB (`audio_chunks` collection for conversations), vector storage (Qdrant or OpenMemory) @@ -161,7 +161,7 @@ Required: - LLM Service: Memory extraction and action items (OpenAI or Ollama) Recommended: - - Vector Storage: Qdrant (Friend-Lite provider) or OpenMemory MCP server + - Vector Storage: Qdrant (Chronicle provider) or OpenMemory MCP server - Transcription: Deepgram, Mistral, or offline ASR services Optional: @@ -179,8 +179,8 @@ Optional: 4. **Speech-Driven Conversation Creation**: User-facing conversations only created when speech is detected 5. **Dual Storage System**: Audio sessions always stored in `audio_chunks`, conversations created in `conversations` collection only with speech 6. **Versioned Processing**: Transcript and memory versions tracked with active version pointers -7. **Memory Processing**: Pluggable providers (Friend-Lite native with individual facts or OpenMemory MCP delegation) -8. **Memory Storage**: Direct Qdrant (Friend-Lite) or OpenMemory server (MCP provider) +7. **Memory Processing**: Pluggable providers (Chronicle native with individual facts or OpenMemory MCP delegation) +8. **Memory Storage**: Direct Qdrant (Chronicle) or OpenMemory server (MCP provider) 9. **Action Items**: Automatic task detection with "Simon says" trigger phrases 10. **Audio Optimization**: Speech segment extraction removes silence automatically 11. **Task Tracking**: BackgroundTaskManager ensures proper cleanup of all async operations @@ -230,11 +230,11 @@ DEEPGRAM_API_KEY=your-deepgram-key-here # Optional: TRANSCRIPTION_PROVIDER=deepgram # Memory Provider -MEMORY_PROVIDER=friend_lite # or openmemory_mcp +MEMORY_PROVIDER=chronicle # or openmemory_mcp # Database MONGODB_URI=mongodb://mongo:27017 -# Database name: friend-lite +# Database name: chronicle QDRANT_BASE_URL=qdrant # Network Configuration @@ -246,12 +246,12 @@ CORS_ORIGINS=http://localhost:3000,http://localhost:5173 ### Memory Provider Configuration -Friend-Lite supports two pluggable memory backends: +Chronicle supports two pluggable memory backends: -#### Friend-Lite Memory Provider (Default) +#### Chronicle Memory Provider (Default) ```bash -# Use Friend-Lite memory provider (default) -MEMORY_PROVIDER=friend_lite +# Use Chronicle memory provider (default) +MEMORY_PROVIDER=chronicle # LLM Configuration for memory extraction LLM_PROVIDER=openai @@ -269,7 +269,7 @@ MEMORY_PROVIDER=openmemory_mcp # OpenMemory MCP Server Configuration OPENMEMORY_MCP_URL=http://host.docker.internal:8765 -OPENMEMORY_CLIENT_NAME=friend_lite +OPENMEMORY_CLIENT_NAME=chronicle OPENMEMORY_USER_ID=openmemory OPENMEMORY_TIMEOUT=30 @@ -279,7 +279,7 @@ OPENAI_API_KEY=your-openai-key-here ### Transcription Provider Configuration -Friend-Lite supports multiple transcription services: +Chronicle supports multiple transcription services: ```bash # Option 1: Deepgram (High quality, recommended) diff --git a/Docs/features.md b/Docs/features.md index 25c5671c..57e3413f 100644 --- a/Docs/features.md +++ b/Docs/features.md @@ -1,11 +1,11 @@ -# Friend-Lite Features & Architecture +# Chronicle Features & Architecture ## Core Features -Friend-Lite supports AI-powered personal systems through multiple OMI-compatible audio devices: +Chronicle supports AI-powered personal systems through multiple OMI-compatible audio devices: **Memory System:** -- **Advanced memory system** with pluggable providers (Friend-Lite native or OpenMemory MCP) +- **Advanced memory system** with pluggable providers (Chronicle native or OpenMemory MCP) - **Memory extraction** from conversations with individual fact storage - **Semantic memory search** with relevance threshold filtering and live results - **Memory count display** with total count tracking from native providers @@ -38,7 +38,7 @@ DevKit2 streams audio via Bluetooth using OPUS codec. The processing pipeline in **AI Processing:** - LLM-based conversation analysis (OpenAI or local Ollama) -- **Dual memory system**: Friend-Lite native or OpenMemory MCP integration +- **Dual memory system**: Chronicle native or OpenMemory MCP integration - Enhanced memory extraction with individual fact storage - **Semantic search** with relevance scoring and threshold filtering - Smart deduplication and memory updates (ADD/UPDATE/DELETE) @@ -87,7 +87,7 @@ Choose one based on your needs: **Features:** - Audio processing pipeline with real-time WebSocket support -- **Pluggable memory system**: Choose between Friend-Lite native or OpenMemory MCP +- **Pluggable memory system**: Choose between Chronicle native or OpenMemory MCP - Enhanced memory extraction with individual fact storage (no generic fallbacks) - **Semantic memory search** with relevance threshold filtering and total count display - **Speaker-based memory filtering**: Optional control over processing based on participant presence diff --git a/Docs/getting-started.md b/Docs/getting-started.md index 2f647b7b..6483f00f 100644 --- a/Docs/getting-started.md +++ b/Docs/getting-started.md @@ -1,16 +1,16 @@ # Getting Started -# Friend-Lite Backend Quickstart Guide +# Chronicle Backend Quickstart Guide -> ๐Ÿ“– **New to friend-lite?** This is your starting point! After reading this, continue with [architecture.md](./architecture.md) for technical details. +> ๐Ÿ“– **New to chronicle?** This is your starting point! After reading this, continue with [architecture.md](./architecture.md) for technical details. ## Overview -Friend-Lite is an eco-system of services to support "AI wearable" agents/functionality. +Chronicle is an eco-system of services to support "AI wearable" agents/functionality. At the moment, the basic functionalities are: - Audio capture (via WebSocket, from OMI device, files, or a laptop) - Audio transcription -- **Advanced memory system** with pluggable providers (Friend-Lite native or OpenMemory MCP) +- **Advanced memory system** with pluggable providers (Chronicle native or OpenMemory MCP) - **Enhanced memory extraction** with individual fact storage and smart updates - **Semantic memory search** with relevance threshold filtering and live results - Action item extraction @@ -38,13 +38,13 @@ cd backends/advanced - **Authentication**: Admin email/password setup - **Transcription Provider**: Choose Deepgram, Mistral, or Offline (Parakeet) - **LLM Provider**: Choose OpenAI or Ollama for memory extraction -- **Memory Provider**: Choose Friend-Lite Native or OpenMemory MCP +- **Memory Provider**: Choose Chronicle Native or OpenMemory MCP - **Optional Services**: Speaker Recognition and other extras - **Network Configuration**: Ports and host settings **Example flow:** ``` -๐Ÿš€ Friend-Lite Interactive Setup +๐Ÿš€ Chronicle Interactive Setup =============================================== โ–บ Authentication Setup @@ -126,13 +126,13 @@ ADMIN_EMAIL=admin@example.com **Memory Provider Configuration:** ```bash # Memory Provider (Choose One) -# Option 1: Friend-Lite Native (Default - Recommended) -MEMORY_PROVIDER=friend_lite +# Option 1: Chronicle Native (Default - Recommended) +MEMORY_PROVIDER=chronicle # Option 2: OpenMemory MCP (Cross-client compatibility) # MEMORY_PROVIDER=openmemory_mcp # OPENMEMORY_MCP_URL=http://host.docker.internal:8765 -# OPENMEMORY_CLIENT_NAME=friend_lite +# OPENMEMORY_CLIENT_NAME=chronicle # OPENMEMORY_USER_ID=openmemory ``` @@ -325,8 +325,8 @@ curl -X POST "http://localhost:8000/api/process-audio-files" \ ### Memory & Intelligence #### Pluggable Memory System -- **Two memory providers**: Choose between Friend-Lite native or OpenMemory MCP -- **Friend-Lite Provider**: Full control with custom extraction, individual fact storage, smart deduplication +- **Two memory providers**: Choose between Chronicle native or OpenMemory MCP +- **Chronicle Provider**: Full control with custom extraction, individual fact storage, smart deduplication - **OpenMemory MCP Provider**: Cross-client compatibility (Claude Desktop, Cursor, Windsurf), professional processing #### Enhanced Memory Processing @@ -482,7 +482,7 @@ tailscale ip -4 ## Data Architecture -The friend-lite backend uses a **user-centric data architecture**: +The chronicle backend uses a **user-centric data architecture**: - **All memories are keyed by database user_id** (not client_id) - **Client information is stored in metadata** for reference and debugging @@ -495,12 +495,12 @@ For detailed information, see [User Data Architecture](user-data-architecture.md ### Choosing a Memory Provider -Friend-Lite offers two memory backends: +Chronicle offers two memory backends: -#### 1. Friend-Lite Native +#### 1. Chronicle Native ```bash # In your .env file -MEMORY_PROVIDER=friend_lite +MEMORY_PROVIDER=chronicle LLM_PROVIDER=openai OPENAI_API_KEY=your-openai-key-here ``` @@ -519,7 +519,7 @@ OPENAI_API_KEY=your-openai-key-here cd extras/openmemory-mcp docker compose up -d -# Then configure Friend-Lite +# Then configure Chronicle MEMORY_PROVIDER=openmemory_mcp OPENMEMORY_MCP_URL=http://host.docker.internal:8765 ``` diff --git a/Docs/init-system.md b/Docs/init-system.md index fb9c1763..98d7c49a 100644 --- a/Docs/init-system.md +++ b/Docs/init-system.md @@ -1,4 +1,4 @@ -# Friend-Lite Initialization System +# Chronicle Initialization System ## Quick Links @@ -10,14 +10,14 @@ ## Overview -Friend-Lite uses a unified initialization system with clean separation of concerns: +Chronicle uses a unified initialization system with clean separation of concerns: - **Configuration** (`wizard.py`) - Set up service configurations, API keys, and .env files - **Service Management** (`services.py`) - Start, stop, and manage running services The root orchestrator handles service selection and delegates configuration to individual service scripts. In general, setup scripts only configure and do not start services automatically. Exceptions: `extras/asr-services` and `extras/openmemory-mcp` are startup scripts. This prevents unnecessary resource usage and gives you control over when services actually run. -> **New to Friend-Lite?** Most users should start with the [Quick Start Guide](../quickstart.md) instead of this detailed reference. +> **New to Chronicle?** Most users should start with the [Quick Start Guide](../quickstart.md) instead of this detailed reference. ## Architecture @@ -133,7 +133,7 @@ Services use `host.docker.internal` for inter-container communication: ## Service Management -Friend-Lite now separates **configuration** from **service lifecycle management**: +Chronicle now separates **configuration** from **service lifecycle management**: ### Unified Service Management Use the `services.py` script for all service operations: diff --git a/Docs/ports-and-access.md b/Docs/ports-and-access.md index f93137b7..67c0fd28 100644 --- a/Docs/ports-and-access.md +++ b/Docs/ports-and-access.md @@ -1,11 +1,11 @@ -# Friend-Lite Port Configuration & User Journey +# Chronicle Port Configuration & User Journey ## User Journey: Git Clone to Running Services ### 1. Clone & Setup ```bash git clone -cd friend-lite +cd chronicle # Configure all services uv run --with-requirements setup-requirements.txt python init.py diff --git a/Makefile b/Makefile index 3d03a180..9c4dca6a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # ======================================== -# Friend-Lite Management System +# Chronicle Management System # ======================================== -# Central management interface for Friend-Lite project +# Central management interface for Chronicle project # Handles configuration, deployment, and maintenance tasks # Load environment variables from .env file @@ -25,7 +25,7 @@ K8S_SCRIPTS_DIR := $(SCRIPTS_DIR)/k8s .DEFAULT_GOAL := menu menu: ## Show interactive menu (default) - @echo "๐ŸŽฏ Friend-Lite Management System" + @echo "๐ŸŽฏ Chronicle Management System" @echo "================================" @echo @echo "๐Ÿ“‹ Quick Actions:" @@ -59,7 +59,7 @@ menu: ## Show interactive menu (default) @echo @echo "๐Ÿ”„ Mycelia Sync:" @echo " mycelia-sync-status ๐Ÿ“Š Show Mycelia OAuth sync status" - @echo " mycelia-sync-all ๐Ÿ”„ Sync all Friend-Lite users to Mycelia" + @echo " mycelia-sync-all ๐Ÿ”„ Sync all Chronicle users to Mycelia" @echo " mycelia-sync-user ๐Ÿ‘ค Sync specific user (EMAIL=user@example.com)" @echo " mycelia-check-orphans ๐Ÿ” Find orphaned Mycelia objects" @echo " mycelia-reassign-orphans โ™ป๏ธ Reassign orphans (EMAIL=admin@example.com)" @@ -75,7 +75,7 @@ menu: ## Show interactive menu (default) @echo "๐Ÿ’ก Tip: Run 'make help' for detailed help on any target" help: ## Show detailed help for all targets - @echo "๐ŸŽฏ Friend-Lite Management System - Detailed Help" + @echo "๐ŸŽฏ Chronicle Management System - Detailed Help" @echo "================================================" @echo @echo "๐Ÿ—๏ธ KUBERNETES SETUP:" @@ -110,9 +110,9 @@ help: ## Show detailed help for all targets @echo @echo "๐Ÿ”„ MYCELIA SYNC:" @echo " mycelia-sync-status Show Mycelia OAuth sync status for all users" - @echo " mycelia-sync-all Sync all Friend-Lite users to Mycelia OAuth" + @echo " mycelia-sync-all Sync all Chronicle users to Mycelia OAuth" @echo " mycelia-sync-user Sync specific user (EMAIL=user@example.com)" - @echo " mycelia-check-orphans Find Mycelia objects without Friend-Lite owner" + @echo " mycelia-check-orphans Find Mycelia objects without Chronicle owner" @echo " mycelia-reassign-orphans Reassign orphaned objects (EMAIL=admin@example.com)" @echo @echo "๐Ÿงช ROBOT FRAMEWORK TESTING:" @@ -158,7 +158,7 @@ setup-dev: ## Setup development environment (git hooks, pre-commit) setup-k8s: ## Initial Kubernetes setup (registry + infrastructure) @echo "๐Ÿ—๏ธ Starting Kubernetes initial setup..." - @echo "This will set up the complete infrastructure for Friend-Lite" + @echo "This will set up the complete infrastructure for Chronicle" @echo @echo "๐Ÿ“‹ Setup includes:" @echo " โ€ข Insecure registry configuration" @@ -230,10 +230,10 @@ config-k8s: ## Generate Kubernetes configuration files (ConfigMap/Secret only - @kubectl apply -f k8s-manifests/configmap.yaml -n $(APPLICATION_NAMESPACE) 2>/dev/null || echo "โš ๏ธ ConfigMap not applied (cluster not available?)" @kubectl apply -f k8s-manifests/secrets.yaml -n $(APPLICATION_NAMESPACE) 2>/dev/null || echo "โš ๏ธ Secret not applied (cluster not available?)" @echo "๐Ÿ“ฆ Copying ConfigMap and Secret to speech namespace..." - @kubectl get configmap friend-lite-config -n $(APPLICATION_NAMESPACE) -o yaml | \ + @kubectl get configmap chronicle-config -n $(APPLICATION_NAMESPACE) -o yaml | \ sed -e '/namespace:/d' -e '/resourceVersion:/d' -e '/uid:/d' -e '/creationTimestamp:/d' | \ kubectl apply -n speech -f - 2>/dev/null || echo "โš ๏ธ ConfigMap not copied to speech namespace" - @kubectl get secret friend-lite-secrets -n $(APPLICATION_NAMESPACE) -o yaml | \ + @kubectl get secret chronicle-secrets -n $(APPLICATION_NAMESPACE) -o yaml | \ sed -e '/namespace:/d' -e '/resourceVersion:/d' -e '/uid:/d' -e '/creationTimestamp:/d' | \ kubectl apply -n speech -f - 2>/dev/null || echo "โš ๏ธ Secret not copied to speech namespace" @echo "โœ… Kubernetes configuration files generated" @@ -353,13 +353,13 @@ audio-manage: ## Interactive audio file management mycelia-sync-status: ## Show Mycelia OAuth sync status for all users @echo "๐Ÿ“Š Checking Mycelia OAuth sync status..." - @cd backends/advanced && uv run python scripts/sync_friendlite_mycelia.py --status + @cd backends/advanced && uv run python scripts/sync_chronicle_mycelia.py --status -mycelia-sync-all: ## Sync all Friend-Lite users to Mycelia OAuth - @echo "๐Ÿ”„ Syncing all Friend-Lite users to Mycelia OAuth..." +mycelia-sync-all: ## Sync all Chronicle users to Mycelia OAuth + @echo "๐Ÿ”„ Syncing all Chronicle users to Mycelia OAuth..." @echo "โš ๏ธ This will create OAuth credentials for users without them" @read -p "Continue? (y/N): " confirm && [ "$$confirm" = "y" ] || exit 1 - @cd backends/advanced && uv run python scripts/sync_friendlite_mycelia.py --sync-all + @cd backends/advanced && uv run python scripts/sync_chronicle_mycelia.py --sync-all mycelia-sync-user: ## Sync specific user to Mycelia OAuth (usage: make mycelia-sync-user EMAIL=user@example.com) @echo "๐Ÿ‘ค Syncing specific user to Mycelia OAuth..." @@ -367,11 +367,11 @@ mycelia-sync-user: ## Sync specific user to Mycelia OAuth (usage: make mycelia-s echo "โŒ EMAIL parameter is required. Usage: make mycelia-sync-user EMAIL=user@example.com"; \ exit 1; \ fi - @cd backends/advanced && uv run python scripts/sync_friendlite_mycelia.py --email $(EMAIL) + @cd backends/advanced && uv run python scripts/sync_chronicle_mycelia.py --email $(EMAIL) -mycelia-check-orphans: ## Find Mycelia objects without Friend-Lite owner +mycelia-check-orphans: ## Find Mycelia objects without Chronicle owner @echo "๐Ÿ” Checking for orphaned Mycelia objects..." - @cd backends/advanced && uv run python scripts/sync_friendlite_mycelia.py --check-orphans + @cd backends/advanced && uv run python scripts/sync_chronicle_mycelia.py --check-orphans mycelia-reassign-orphans: ## Reassign orphaned objects to user (usage: make mycelia-reassign-orphans EMAIL=admin@example.com) @echo "โ™ป๏ธ Reassigning orphaned Mycelia objects..." @@ -381,7 +381,7 @@ mycelia-reassign-orphans: ## Reassign orphaned objects to user (usage: make myce fi @echo "โš ๏ธ This will reassign all orphaned objects to: $(EMAIL)" @read -p "Continue? (y/N): " confirm && [ "$$confirm" = "y" ] || exit 1 - @cd backends/advanced && uv run python scripts/sync_friendlite_mycelia.py --reassign-orphans --target-email $(EMAIL) + @cd backends/advanced && uv run python scripts/sync_chronicle_mycelia.py --reassign-orphans --target-email $(EMAIL) # ======================================== # TESTING TARGETS diff --git a/README-K8S.md b/README-K8S.md index 3e282a33..0e8358c1 100644 --- a/README-K8S.md +++ b/README-K8S.md @@ -1,6 +1,6 @@ -# Friend-Lite Kubernetes Setup Guide +# Chronicle Kubernetes Setup Guide -This guide walks you through setting up Friend-Lite from scratch on a fresh Ubuntu system, including MicroK8s installation, Docker registry configuration, and deployment via Skaffold. +This guide walks you through setting up Chronicle from scratch on a fresh Ubuntu system, including MicroK8s installation, Docker registry configuration, and deployment via Skaffold. ## System Architecture @@ -245,7 +245,7 @@ This guide walks you through setting up Friend-Lite from scratch on a fresh Ubun ### **Directory Structure** ``` -friend-lite/ +chronicle/ โ”œโ”€โ”€ scripts/ # Kubernetes deployment and management scripts โ”‚ โ”œโ”€โ”€ deploy-all-services.sh # Deploy all services โ”‚ โ”œโ”€โ”€ cluster-status.sh # Check cluster health @@ -267,7 +267,7 @@ friend-lite/ 1. **Clone Repository** ```bash # Clone Friend-Lite repository with submodules - git clone --recursive https://github.com/yourusername/friend-lite.git + git clone --recursive https://github.com/chronicle-ai/chronicle.git cd friend-lite # If you already cloned without --recursive, initialize submodules: @@ -392,7 +392,7 @@ The following scripts are available in the `scripts/` folder to simplify common ./scripts/cluster-status.sh # Check status of specific namespace -./scripts/cluster-status.sh friend-lite +./scripts/cluster-status.sh chronicle ``` ### **Setup Scripts** @@ -487,14 +487,14 @@ This directory contains standalone Kubernetes manifests that are not managed by 3. **Verify Deployment** ```bash # Check all resources - kubectl get all -n friend-lite + kubectl get all -n chronicle kubectl get all -n root # Check Ingress - kubectl get ingress -n friend-lite + kubectl get ingress -n chronicle # Check services - kubectl get svc -n friend-lite + kubectl get svc -n chronicle ``` ## Multi-Node Cluster Management @@ -635,14 +635,14 @@ spec: 1. **Check Application Health** ```bash # Check backend health - curl -k https://friend-lite.192-168-1-42.nip.io:32623/health + curl -k https://chronicle.192-168-1-42.nip.io:32623/health # Check WebUI - curl -k https://friend-lite.192-168-1-42.nip.io:32623/ + curl -k https://chronicle.192-168-1-42.nip.io:32623/ ``` 2. **Access WebUI** - - Open browser to: `https://friend-lite.192-168-1-42.nip.io:32623/` + - Open browser to: `https://chronicle.192-168-1-42.nip.io:32623/` - Accept self-signed certificate warning - Create admin user account - Test audio recording functionality @@ -681,7 +681,7 @@ spec: kubectl get pods -n ingress-nginx # Check Ingress configuration (run on build machine) - kubectl describe ingress -n friend-lite + kubectl describe ingress -n chronicle ``` 4. **Build Issues** @@ -734,20 +734,20 @@ spec: ```bash # View logs (run on build machine) -kubectl logs -n friend-lite deployment/advanced-backend -kubectl logs -n friend-lite deployment/webui +kubectl logs -n chronicle deployment/advanced-backend +kubectl logs -n chronicle deployment/webui # Port forward for debugging (run on build machine) -kubectl port-forward -n friend-lite svc/advanced-backend 8000:8000 -kubectl port-forward -n friend-lite svc/webui 8080:80 +kubectl port-forward -n chronicle svc/advanced-backend 8000:8000 +kubectl port-forward -n chronicle svc/webui 8080:80 # Check resource usage (run on build machine) -kubectl top pods -n friend-lite +kubectl top pods -n chronicle kubectl top nodes # Restart deployments (run on build machine) -kubectl rollout restart deployment/advanced-backend -n friend-lite -kubectl rollout restart deployment/webui -n friend-lite +kubectl rollout restart deployment/advanced-backend -n chronicle +kubectl rollout restart deployment/webui -n chronicle ``` ## Maintenance @@ -778,7 +778,7 @@ kubectl rollout restart deployment/webui -n friend-lite cp skaffold.env skaffold.env.backup # Backup Kubernetes manifests (run on build machine) - kubectl get all -n friend-lite -o yaml > friend-lite-backup.yaml + kubectl get all -n chronicle -o yaml > chronicle-backup.yaml kubectl get all -n root -o yaml > infrastructure-backup.yaml ``` @@ -796,7 +796,7 @@ chmod +x init.sh ./init.sh ``` -This will guide you through setting up Friend-Lite using Docker Compose instead of Kubernetes. +This will guide you through setting up Chronicle using Docker Compose instead of Kubernetes. ## Speaker Recognition Deployment diff --git a/README.md b/README.md index 0a43076b..34027891 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Friend-Lite +# Chronicle Self-hostable AI system that captures audio/video data from OMI devices and other sources to generate memories, action items, and contextual insights about your conversations and daily interactions. diff --git a/app/README.md b/app/README.md index 6d3272f9..d73dd748 100644 --- a/app/README.md +++ b/app/README.md @@ -1,6 +1,6 @@ -# Friend-Lite Mobile App +# Chronicle Mobile App -React Native mobile application for connecting OMI devices and streaming audio to Friend-Lite backends. Supports cross-platform deployment on iOS and Android with Bluetooth integration. +React Native mobile application for connecting OMI devices and streaming audio to Chronicle backends. Supports cross-platform deployment on iOS and Android with Bluetooth integration. ## Features @@ -64,7 +64,7 @@ npx expo prebuild --clean cd ios && pod install && cd .. # Open in Xcode -open ios/friendlite.xcworkspace +open ios/chronicle.xcworkspace ``` Build and run from Xcode interface. @@ -154,7 +154,7 @@ Backend URL: wss://[ngrok-subdomain].ngrok.io/ws_pcm ## Phone Audio Streaming (NEW) ### Overview -Stream audio directly from your phone's microphone to Friend-Lite backend, bypassing Bluetooth devices. This feature provides a direct audio input method for users who want to use their phone as the audio source. +Stream audio directly from your phone's microphone to Chronicle backend, bypassing Bluetooth devices. This feature provides a direct audio input method for users who want to use their phone as the audio source. ### Features - **Direct Microphone Access**: Use phone's built-in microphone @@ -166,7 +166,7 @@ Stream audio directly from your phone's microphone to Friend-Lite backend, bypas ### Setup & Usage #### Enable Phone Audio Streaming -1. **Open Friend-Lite app** +1. **Open Chronicle app** 2. **Configure Backend Connection** (see Backend Configuration section) 3. **Grant Microphone Permissions** when prompted 4. **Tap "Stream Phone Audio" button** in main interface @@ -175,7 +175,7 @@ Stream audio directly from your phone's microphone to Friend-Lite backend, bypas #### Requirements - **iOS**: iOS 13+ with microphone permissions - **Android**: Android API 21+ with microphone permissions -- **Network**: Stable connection to Friend-Lite backend +- **Network**: Stable connection to Chronicle backend - **Backend**: Advanced backend running with `/ws_pcm` endpoint #### Switching Audio Sources @@ -197,8 +197,8 @@ Stream audio directly from your phone's microphone to Friend-Lite backend, bypas - **Restart Recording**: Stop and restart phone audio streaming #### Permission Issues -- **iOS**: Settings > Privacy & Security > Microphone > Friend-Lite -- **Android**: Settings > Apps > Friend-Lite > Permissions > Microphone +- **iOS**: Settings > Privacy & Security > Microphone > Chronicle +- **Android**: Settings > Apps > Chronicle > Permissions > Microphone #### No Audio Level Visualization - **Restart App**: Close and reopen the application @@ -210,7 +210,7 @@ Stream audio directly from your phone's microphone to Friend-Lite backend, bypas ### Device Connection 1. **Enable Bluetooth** on your mobile device -2. **Open Friend-Lite app** +2. **Open Chronicle app** 3. **Pair OMI device**: - Go to Device Settings - Scan for nearby OMI devices diff --git a/app/app.json b/app/app.json index 9acdac77..c2446e12 100644 --- a/app/app.json +++ b/app/app.json @@ -1,7 +1,7 @@ { "expo": { - "name": "friend-lite-app", - "slug": "friend-lite-app", + "name": "chronicle-app", + "slug": "chronicle-app", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", @@ -17,9 +17,9 @@ ], "ios": { "supportsTablet": true, - "bundleIdentifier": "com.cupbearer5517.friendlite", + "bundleIdentifier": "com.cupbearer5517.chronicle", "infoPlist": { - "NSMicrophoneUsageDescription": "Friend-Lite needs access to your microphone to stream audio to the backend for processing." + "NSMicrophoneUsageDescription": "Chronicle needs access to your microphone to stream audio to the backend for processing." } }, "android": { @@ -27,7 +27,7 @@ "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#ffffff" }, - "package": "com.cupbearer5517.friendlite", + "package": "com.cupbearer5517.chronicle", "permissions": [ "android.permission.BLUETOOTH", "android.permission.BLUETOOTH_ADMIN", diff --git a/app/app/components/DeviceDetails.tsx b/app/app/components/DeviceDetails.tsx index ebf204c3..3bd22b4a 100644 --- a/app/app/components/DeviceDetails.tsx +++ b/app/app/components/DeviceDetails.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { View, Text, TouchableOpacity, StyleSheet, TextInput } from 'react-native'; -import { BleAudioCodec } from 'friend-lite-react-native'; +import { BleAudioCodec } from 'chronicle-react-native'; interface DeviceDetailsProps { // Device Info diff --git a/app/app/components/DeviceListItem.tsx b/app/app/components/DeviceListItem.tsx index a8083035..3da559de 100644 --- a/app/app/components/DeviceListItem.tsx +++ b/app/app/components/DeviceListItem.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; -import { OmiDevice } from 'friend-lite-react-native'; +import { OmiDevice } from 'chronicle-react-native'; interface DeviceListItemProps { device: OmiDevice; diff --git a/app/app/hooks/useAudioListener.ts b/app/app/hooks/useAudioListener.ts index 391ed125..1dcf225e 100644 --- a/app/app/hooks/useAudioListener.ts +++ b/app/app/hooks/useAudioListener.ts @@ -1,6 +1,6 @@ import { useState, useRef, useCallback, useEffect } from 'react'; import { Alert } from 'react-native'; -import { OmiConnection } from 'friend-lite-react-native'; +import { OmiConnection } from 'chronicle-react-native'; import { Subscription, ConnectionPriority } from 'react-native-ble-plx'; // OmiConnection might use this type for subscriptions interface UseAudioListener { diff --git a/app/app/hooks/useDeviceConnection.ts b/app/app/hooks/useDeviceConnection.ts index e729169e..964e4d4e 100644 --- a/app/app/hooks/useDeviceConnection.ts +++ b/app/app/hooks/useDeviceConnection.ts @@ -1,6 +1,6 @@ import { useState, useCallback } from 'react'; import { Alert } from 'react-native'; -import { OmiConnection, BleAudioCodec, OmiDevice } from 'friend-lite-react-native'; +import { OmiConnection, BleAudioCodec, OmiDevice } from 'chronicle-react-native'; interface UseDeviceConnection { connectedDevice: OmiDevice | null; diff --git a/app/app/hooks/useDeviceScanning.ts b/app/app/hooks/useDeviceScanning.ts index d7780266..f4c16ff3 100644 --- a/app/app/hooks/useDeviceScanning.ts +++ b/app/app/hooks/useDeviceScanning.ts @@ -1,6 +1,6 @@ import { useState, useEffect, useCallback, useRef } from 'react'; import { BleManager, State as BluetoothState } from 'react-native-ble-plx'; -import { OmiConnection, OmiDevice } from 'friend-lite-react-native'; // Assuming this is the correct import for Omi types +import { OmiConnection, OmiDevice } from 'chronicle-react-native'; // Assuming this is the correct import for Omi types interface UseDeviceScanning { devices: OmiDevice[]; diff --git a/app/app/index.tsx b/app/app/index.tsx index 8bb1234a..2b20cb7b 100644 --- a/app/app/index.tsx +++ b/app/app/index.tsx @@ -1,6 +1,6 @@ import React, { useRef, useCallback, useEffect, useState } from 'react'; import { StyleSheet, Text, View, SafeAreaView, ScrollView, Platform, FlatList, ActivityIndicator, Alert, Switch, Button, TouchableOpacity, KeyboardAvoidingView } from 'react-native'; -import { OmiConnection } from 'friend-lite-react-native'; // OmiDevice also comes from here +import { OmiConnection } from 'chronicle-react-native'; // OmiDevice also comes from here import { State as BluetoothState } from 'react-native-ble-plx'; // Import State from ble-plx // Hooks @@ -521,7 +521,7 @@ export default function App() { contentContainerStyle={styles.content} keyboardShouldPersistTaps="handled" > - Friend Lite + Chronicle {/* Backend Connection - moved to top */} **Note**: This documentation covers the modern React interface located in `./webui/`. The legacy Streamlit interface has been moved to `src/_webui_original/` for reference. diff --git a/backends/advanced/Docs/architecture.md b/backends/advanced/Docs/architecture.md index 8211cb32..d5edb6a3 100644 --- a/backends/advanced/Docs/architecture.md +++ b/backends/advanced/Docs/architecture.md @@ -1,11 +1,11 @@ -# Friend-Lite Backend Architecture +# Chronicle Backend Architecture > ๐Ÿ“– **Prerequisite**: Read [quickstart.md](./quickstart.md) first for basic system understanding. ## System Overview -Friend-Lite is a comprehensive real-time conversation processing system that captures audio streams, performs speech-to-text transcription, and extracts memories. The system features a FastAPI backend with WebSocket audio streaming, versioned transcript and memory processing, a React web dashboard with search capabilities, and user authentication with role-based access control. +Chronicle is a comprehensive real-time conversation processing system that captures audio streams, performs speech-to-text transcription, and extracts memories. The system features a FastAPI backend with WebSocket audio streaming, versioned transcript and memory processing, a React web dashboard with search capabilities, and user authentication with role-based access control. **Core Implementation**: The complete system is implemented in `src/advanced_omi_backend/main.py` with supporting services in dedicated modules, using a modular router/controller architecture pattern. @@ -1049,7 +1049,7 @@ src/advanced_omi_backend/ "memory_versions": [ { "version_id": "version_def", - "provider": "friend_lite", + "provider": "chronicle", "created_at": "2025-01-15T10:32:00Z", "memory_count": 5 } diff --git a/backends/advanced/Docs/auth.md b/backends/advanced/Docs/auth.md index 4a3f7267..2aa7d254 100644 --- a/backends/advanced/Docs/auth.md +++ b/backends/advanced/Docs/auth.md @@ -2,7 +2,7 @@ ## Overview -Friend-Lite uses a comprehensive authentication system built on `fastapi-users` with support for multiple authentication methods including JWT tokens and cookies. The system provides secure user management with proper data isolation and role-based access control using MongoDB ObjectIds for user identification. +Chronicle uses a comprehensive authentication system built on `fastapi-users` with support for multiple authentication methods including JWT tokens and cookies. The system provides secure user management with proper data isolation and role-based access control using MongoDB ObjectIds for user identification. ## Architecture Components @@ -269,7 +269,7 @@ echo $ADMIN_PASSWORD ### Debug Commands ```bash # Check user database -docker exec -it mongo-container mongosh friend-lite +docker exec -it mongo-container mongosh chronicle # View authentication logs docker compose logs friend-backend | grep -i auth diff --git a/backends/advanced/Docs/memories.md b/backends/advanced/Docs/memories.md index 06aa3f60..b2887dc9 100644 --- a/backends/advanced/Docs/memories.md +++ b/backends/advanced/Docs/memories.md @@ -2,7 +2,7 @@ > ๐Ÿ“– **Prerequisite**: Read [quickstart.md](./quickstart.md) first for system overview. -This document explains how to configure and customize the memory service in the friend-lite backend. +This document explains how to configure and customize the memory service in the chronicle backend. **Code References**: - **Main Implementation**: `src/memory/memory_service.py` @@ -65,7 +65,7 @@ OLLAMA_BASE_URL=http://192.168.0.110:11434 QDRANT_BASE_URL=localhost # Mem0 Organization Settings (optional) -MEM0_ORGANIZATION_ID=friend-lite-org +MEM0_ORGANIZATION_ID=chronicle-org MEM0_PROJECT_ID=audio-conversations MEM0_APP_ID=omi-backend @@ -391,7 +391,7 @@ process_memory.add( "timestamp": 1720616655, "conversation_context": "audio_transcription", "device_type": "audio_recording", - "organization_id": "friend-lite-org", + "organization_id": "chronicle-org", "project_id": "audio-conversations", "app_id": "omi-backend" } @@ -583,7 +583,7 @@ The memory service exposes these endpoints with enhanced search capabilities: - **Vector-based**: Uses embeddings for contextual understanding beyond keyword matching **Memory Count API**: -- **Friend-Lite Provider**: Native Qdrant count API provides accurate total counts +- **Chronicle Provider**: Native Qdrant count API provides accurate total counts - **OpenMemory MCP Provider**: Count support varies by OpenMemory implementation - **Response Format**: `{"memories": [...], "total_count": 42}` when supported diff --git a/backends/advanced/Docs/quickstart.md b/backends/advanced/Docs/quickstart.md index 523218bc..fc5a77b7 100644 --- a/backends/advanced/Docs/quickstart.md +++ b/backends/advanced/Docs/quickstart.md @@ -1,14 +1,14 @@ -# Friend-Lite Backend Quickstart Guide +# Chronicle Backend Quickstart Guide -> ๐Ÿ“– **New to friend-lite?** This is your starting point! After reading this, continue with [architecture.md](./architecture.md) for technical details. +> ๐Ÿ“– **New to chronicle?** This is your starting point! After reading this, continue with [architecture.md](./architecture.md) for technical details. ## Overview -Friend-Lite is an eco-system of services to support "AI wearable" agents/functionality. +Chronicle is an eco-system of services to support "AI wearable" agents/functionality. At the moment, the basic functionalities are: - Audio capture (via WebSocket, from OMI device, files, or a laptop) - Audio transcription -- **Advanced memory system** with pluggable providers (Friend-Lite native or OpenMemory MCP) +- **Advanced memory system** with pluggable providers (Chronicle native or OpenMemory MCP) - **Enhanced memory extraction** with individual fact storage and smart updates - **Semantic memory search** with relevance threshold filtering and live results - Action item extraction @@ -36,13 +36,13 @@ cd backends/advanced - **Authentication**: Admin email/password setup - **Transcription Provider**: Choose Deepgram, Mistral, or Offline (Parakeet) - **LLM Provider**: Choose OpenAI or Ollama for memory extraction -- **Memory Provider**: Choose Friend-Lite Native or OpenMemory MCP +- **Memory Provider**: Choose Chronicle Native or OpenMemory MCP - **Optional Services**: Speaker Recognition and other extras - **Network Configuration**: Ports and host settings **Example flow:** ``` -๐Ÿš€ Friend-Lite Interactive Setup +๐Ÿš€ Chronicle Interactive Setup =============================================== โ–บ Authentication Setup @@ -124,13 +124,13 @@ ADMIN_EMAIL=admin@example.com **Memory Provider Configuration:** ```bash # Memory Provider (Choose One) -# Option 1: Friend-Lite Native (Default - Recommended) -MEMORY_PROVIDER=friend_lite +# Option 1: Chronicle Native (Default - Recommended) +MEMORY_PROVIDER=chronicle # Option 2: OpenMemory MCP (Cross-client compatibility) # MEMORY_PROVIDER=openmemory_mcp # OPENMEMORY_MCP_URL=http://host.docker.internal:8765 -# OPENMEMORY_CLIENT_NAME=friend_lite +# OPENMEMORY_CLIENT_NAME=chronicle # OPENMEMORY_USER_ID=openmemory ``` @@ -323,8 +323,8 @@ curl -X POST "http://localhost:8000/api/audio/upload" \ ### Memory & Intelligence #### Pluggable Memory System -- **Two memory providers**: Choose between Friend-Lite native or OpenMemory MCP -- **Friend-Lite Provider**: Full control with custom extraction, individual fact storage, smart deduplication +- **Two memory providers**: Choose between Chronicle native or OpenMemory MCP +- **Chronicle Provider**: Full control with custom extraction, individual fact storage, smart deduplication - **OpenMemory MCP Provider**: Cross-client compatibility (Claude Desktop, Cursor, Windsurf), professional processing #### Enhanced Memory Processing @@ -480,7 +480,7 @@ tailscale ip -4 ## Data Architecture -The friend-lite backend uses a **user-centric data architecture**: +The chronicle backend uses a **user-centric data architecture**: - **All memories are keyed by database user_id** (not client_id) - **Client information is stored in metadata** for reference and debugging @@ -493,12 +493,12 @@ For detailed information, see [User Data Architecture](user-data-architecture.md ### Choosing a Memory Provider -Friend-Lite offers two memory backends: +Chronicle offers two memory backends: -#### 1. Friend-Lite Native +#### 1. Chronicle Native ```bash # In your .env file -MEMORY_PROVIDER=friend_lite +MEMORY_PROVIDER=chronicle LLM_PROVIDER=openai OPENAI_API_KEY=your-openai-key-here ``` @@ -517,7 +517,7 @@ OPENAI_API_KEY=your-openai-key-here cd extras/openmemory-mcp docker compose up -d -# Then configure Friend-Lite +# Then configure Chronicle MEMORY_PROVIDER=openmemory_mcp OPENMEMORY_MCP_URL=http://host.docker.internal:8765 ``` diff --git a/backends/advanced/docker-compose-test.yml b/backends/advanced/docker-compose-test.yml index c68465a8..f72ca54d 100644 --- a/backends/advanced/docker-compose-test.yml +++ b/backends/advanced/docker-compose-test.yml @@ -3,7 +3,7 @@ # Uses different ports to avoid conflicts with development environment services: - friend-backend-test: + chronicle-backend-test: build: context: . dockerfile: Dockerfile @@ -36,7 +36,7 @@ services: - TRANSCRIPTION_PROVIDER=${TRANSCRIPTION_PROVIDER:-deepgram} # - PARAKEET_ASR_URL=${PARAKEET_ASR_URL} # Memory provider configuration - - MEMORY_PROVIDER=${MEMORY_PROVIDER:-friend_lite} + - MEMORY_PROVIDER=${MEMORY_PROVIDER:-chronicle} - OPENMEMORY_MCP_URL=${OPENMEMORY_MCP_URL:-http://host.docker.internal:8765} - OPENMEMORY_USER_ID=${OPENMEMORY_USER_ID:-openmemory} - MYCELIA_URL=http://mycelia-backend-test:5173 @@ -76,7 +76,7 @@ services: ports: - "3001:80" # Avoid conflict with dev on 3000 depends_on: - friend-backend-test: + chronicle-backend-test: condition: service_healthy mongo-test: condition: service_healthy @@ -146,7 +146,7 @@ services: - ADMIN_PASSWORD=test-admin-password-123 - ADMIN_EMAIL=test-admin@example.com - TRANSCRIPTION_PROVIDER=${TRANSCRIPTION_PROVIDER:-deepgram} - - MEMORY_PROVIDER=${MEMORY_PROVIDER:-friend_lite} + - MEMORY_PROVIDER=${MEMORY_PROVIDER:-chronicle} - OPENMEMORY_MCP_URL=${OPENMEMORY_MCP_URL:-http://host.docker.internal:8765} - OPENMEMORY_USER_ID=${OPENMEMORY_USER_ID:-openmemory} - MYCELIA_URL=http://mycelia-backend-test:5173 @@ -158,7 +158,7 @@ services: # Wait for audio queue to drain before timing out (test mode) - WAIT_FOR_AUDIO_QUEUE_DRAIN=true depends_on: - friend-backend-test: + chronicle-backend-test: condition: service_healthy mongo-test: condition: service_healthy @@ -169,58 +169,58 @@ services: restart: unless-stopped # Mycelia - AI memory and timeline service (test environment) - mycelia-backend-test: - build: - context: ../../extras/mycelia/backend - dockerfile: Dockerfile.simple - ports: - - "5100:5173" # Test backend port - environment: - # Shared JWT secret for Friend-Lite authentication (test key) - - JWT_SECRET=test-jwt-signing-key-for-integration-tests - - SECRET_KEY=test-jwt-signing-key-for-integration-tests - # MongoDB connection (test database) - - MONGO_URL=mongodb://mongo-test:27017 - - MONGO_DB=mycelia_test - - DATABASE_NAME=mycelia_test - # Redis connection (ioredis uses individual host/port, not URL) - - REDIS_HOST=redis-test - - REDIS_PORT=6379 - volumes: - - ../../extras/mycelia/backend/app:/app/app # Mount source for development - depends_on: - mongo-test: - condition: service_healthy - redis-test: - condition: service_started - healthcheck: - test: ["CMD", "deno", "eval", "fetch('http://localhost:5173/health').then(r => r.ok ? Deno.exit(0) : Deno.exit(1))"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 5s - restart: unless-stopped - profiles: - - mycelia + # mycelia-backend-test: + # build: + # context: ../../extras/mycelia/backend + # dockerfile: Dockerfile.simple + # ports: + # - "5100:5173" # Test backend port + # environment: + # # Shared JWT secret for Chronicle authentication (test key) + # - JWT_SECRET=test-jwt-signing-key-for-integration-tests + # - SECRET_KEY=test-jwt-signing-key-for-integration-tests + # # MongoDB connection (test database) + # - MONGO_URL=mongodb://mongo-test:27017 + # - MONGO_DB=mycelia_test + # - DATABASE_NAME=mycelia_test + # # Redis connection (ioredis uses individual host/port, not URL) + # - REDIS_HOST=redis-test + # - REDIS_PORT=6379 + # volumes: + # - ../../extras/mycelia/backend/app:/app/app # Mount source for development + # depends_on: + # mongo-test: + # condition: service_healthy + # redis-test: + # condition: service_started + # healthcheck: + # test: ["CMD", "deno", "eval", "fetch('http://localhost:5173/health').then(r => r.ok ? Deno.exit(0) : Deno.exit(1))"] + # interval: 30s + # timeout: 10s + # retries: 3 + # start_period: 5s + # restart: unless-stopped + # profiles: + # - mycelia - mycelia-frontend-test: - build: - context: ../../extras/mycelia - dockerfile: frontend/Dockerfile.simple - args: - - VITE_API_URL=http://localhost:5100 - ports: - - "3002:8080" # Nginx serves on 8080 internally - environment: - - VITE_API_URL=http://localhost:5100 - volumes: - - ../../extras/mycelia/frontend/src:/app/src # Mount source for development - depends_on: - mycelia-backend-test: - condition: service_healthy - restart: unless-stopped - profiles: - - mycelia + # mycelia-frontend-test: + # build: + # context: ../../extras/mycelia + # dockerfile: frontend/Dockerfile.simple + # args: + # - VITE_API_URL=http://localhost:5100 + # ports: + # - "3002:8080" # Nginx serves on 8080 internally + # environment: + # - VITE_API_URL=http://localhost:5100 + # volumes: + # - ../../extras/mycelia/frontend/src:/app/src # Mount source for development + # depends_on: + # mycelia-backend-test: + # condition: service_healthy + # restart: unless-stopped + # profiles: + # - mycelia # caddy: # image: caddy:2-alpine @@ -234,7 +234,7 @@ services: # depends_on: # webui-test: # condition: service_started - # friend-backend-test: + # chronicle-backend-test: # condition: service_healthy # restart: unless-stopped diff --git a/backends/advanced/docker-compose.yml b/backends/advanced/docker-compose.yml index d9d58dca..ea2f936b 100644 --- a/backends/advanced/docker-compose.yml +++ b/backends/advanced/docker-compose.yml @@ -1,5 +1,5 @@ services: - friend-backend: + chronicle-backend: build: context: . dockerfile: Dockerfile @@ -52,7 +52,7 @@ services: restart: unless-stopped # Unified Worker Container - # No CUDA needed for friend-backend and workers, workers only orchestrate jobs and call external services + # No CUDA needed for chronicle-backend and workers, workers only orchestrate jobs and call external services # Runs all workers in a single container for efficiency: # - 3 RQ workers (transcription, memory, default queues) # - 1 Audio stream worker (Redis Streams consumer - must be single to maintain sequential chunks) @@ -102,7 +102,7 @@ services: # - "${WEBUI_PORT:-3010}:80" - 3010:80 depends_on: - friend-backend: + chronicle-backend: condition: service_healthy restart: unless-stopped @@ -119,7 +119,7 @@ services: - caddy_data:/data - caddy_config:/config depends_on: - friend-backend: + chronicle-backend: condition: service_healthy restart: unless-stopped profiles: @@ -138,7 +138,7 @@ services: - ./webui/src:/app/src - ./webui/public:/app/public depends_on: - friend-backend: + chronicle-backend: condition: service_healthy profiles: - dev @@ -216,7 +216,7 @@ services: # UNCOMMENT OUT FOR LOCAL DEMO - EXPOSES to internet # ngrok: # image: ngrok/ngrok:latest - # depends_on: [friend-backend, proxy] + # depends_on: [chronicle-backend, proxy] # ports: # - "4040:4040" # Ngrok web interface # environment: diff --git a/backends/advanced/init-https.sh b/backends/advanced/init-https.sh index 8cca1ba1..cfeebf61 100755 --- a/backends/advanced/init-https.sh +++ b/backends/advanced/init-https.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -# Initialize Friend-Lite Advanced Backend with HTTPS proxy +# Initialize Chronicle Advanced Backend with HTTPS proxy # Usage: ./init.sh if [ $# -ne 1 ]; then @@ -23,7 +23,7 @@ if ! echo "$TAILSCALE_IP" | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{ exit 1 fi -echo "๐Ÿš€ Initializing Friend-Lite Advanced Backend with Tailscale IP: $TAILSCALE_IP" +echo "๐Ÿš€ Initializing Chronicle Advanced Backend with Tailscale IP: $TAILSCALE_IP" echo "" # Check if nginx.conf.template exists @@ -98,7 +98,7 @@ echo " ๐Ÿ“ฑ Navigate to Live Record page" echo " ๐ŸŽค Microphone access will work over HTTPS" echo "" echo "๐Ÿ”ง Services included:" -echo " - Friend-Lite Backend: Internal (proxied through nginx)" +echo " - Chronicle Backend: Internal (proxied through nginx)" echo " - Web Dashboard: https://localhost/ or https://$TAILSCALE_IP/" echo " - WebSocket Audio: wss://localhost/ws_pcm or wss://$TAILSCALE_IP/ws_pcm" echo "" diff --git a/backends/advanced/init.py b/backends/advanced/init.py index 76d27aea..773ea11e 100644 --- a/backends/advanced/init.py +++ b/backends/advanced/init.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -Friend-Lite Advanced Backend Interactive Setup Script +Chronicle Advanced Backend Interactive Setup Script Interactive configuration for all services and API keys """ @@ -22,7 +22,7 @@ from rich.text import Text -class FriendLiteSetup: +class ChronicleSetup: def __init__(self, args=None): self.console = Console() self.config: Dict[str, Any] = {} @@ -265,26 +265,26 @@ def setup_memory(self): self.print_section("Memory Storage Configuration") choices = { - "1": "Friend-Lite Native (Qdrant + custom extraction)", + "1": "Chronicle Native (Qdrant + custom extraction)", "2": "OpenMemory MCP (cross-client compatible, external server)" } choice = self.prompt_choice("Choose your memory storage backend:", choices, "1") if choice == "1": - self.config["MEMORY_PROVIDER"] = "friend_lite" - self.console.print("[blue][INFO][/blue] Friend-Lite Native memory provider selected") + self.config["MEMORY_PROVIDER"] = "chronicle" + self.console.print("[blue][INFO][/blue] Chronicle Native memory provider selected") qdrant_url = self.prompt_value("Qdrant URL", "qdrant") self.config["QDRANT_BASE_URL"] = qdrant_url - self.console.print("[green][SUCCESS][/green] Friend-Lite memory provider configured") + self.console.print("[green][SUCCESS][/green] Chronicle memory provider configured") elif choice == "2": self.config["MEMORY_PROVIDER"] = "openmemory_mcp" self.console.print("[blue][INFO][/blue] OpenMemory MCP selected") mcp_url = self.prompt_value("OpenMemory MCP server URL", "http://host.docker.internal:8765") - client_name = self.prompt_value("OpenMemory client name", "friend_lite") + client_name = self.prompt_value("OpenMemory client name", "chronicle") user_id = self.prompt_value("OpenMemory user ID", "openmemory") self.config["OPENMEMORY_MCP_URL"] = mcp_url @@ -473,7 +473,7 @@ def show_summary(self): self.console.print(f"โœ… Admin Account: {self.config.get('ADMIN_EMAIL', 'Not configured')}") self.console.print(f"โœ… Transcription: {self.config.get('TRANSCRIPTION_PROVIDER', 'Not configured')}") self.console.print(f"โœ… LLM Provider: {self.config.get('LLM_PROVIDER', 'Not configured')}") - self.console.print(f"โœ… Memory Provider: {self.config.get('MEMORY_PROVIDER', 'friend_lite')}") + self.console.print(f"โœ… Memory Provider: {self.config.get('MEMORY_PROVIDER', 'chronicle')}") # Auto-determine URLs based on HTTPS configuration if self.config.get('HTTPS_ENABLED') == 'true': server_ip = self.config.get('SERVER_IP', 'localhost') @@ -523,8 +523,8 @@ def show_next_steps(self): def run(self): """Run the complete setup process""" - self.print_header("๐Ÿš€ Friend-Lite Interactive Setup") - self.console.print("This wizard will help you configure Friend-Lite with all necessary services.") + self.print_header("๐Ÿš€ Chronicle Interactive Setup") + self.console.print("This wizard will help you configure Chronicle with all necessary services.") self.console.print("We'll ask for your API keys and preferences step by step.") self.console.print() @@ -569,7 +569,7 @@ def run(self): def main(): """Main entry point""" - parser = argparse.ArgumentParser(description="Friend-Lite Advanced Backend Setup") + parser = argparse.ArgumentParser(description="Chronicle Advanced Backend Setup") parser.add_argument("--speaker-service-url", help="Speaker Recognition service URL (default: prompt user)") parser.add_argument("--parakeet-asr-url", @@ -581,7 +581,7 @@ def main(): args = parser.parse_args() - setup = FriendLiteSetup(args) + setup = ChronicleSetup(args) setup.run() diff --git a/backends/advanced/scripts/create_mycelia_api_key.py b/backends/advanced/scripts/create_mycelia_api_key.py index b12d81ed..1e4bcb90 100755 --- a/backends/advanced/scripts/create_mycelia_api_key.py +++ b/backends/advanced/scripts/create_mycelia_api_key.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Create a proper Mycelia API key (not OAuth client) for Friend-Lite user.""" +"""Create a proper Mycelia API key (not OAuth client) for Chronicle user.""" import base64 import os @@ -72,7 +72,7 @@ def main(): "hashedKey": hashed_key, # Note: hashedKey, not hash! "salt": base64.b64encode(salt).decode('utf-8'), # Store as base64 like Mycelia "owner": USER_ID, - "name": "Friend-Lite Integration", + "name": "Chronicle Integration", "policies": [ { "resource": "**", diff --git a/backends/advanced/scripts/sync_friendlite_mycelia.py b/backends/advanced/scripts/sync_friendlite_mycelia.py index c7051f2c..3849a5a9 100644 --- a/backends/advanced/scripts/sync_friendlite_mycelia.py +++ b/backends/advanced/scripts/sync_friendlite_mycelia.py @@ -1,25 +1,25 @@ #!/usr/bin/env python3 """ -Sync Friend-Lite users with Mycelia OAuth credentials. +Sync Chronicle users with Mycelia OAuth credentials. -This script helps migrate existing Friend-Lite installations to use Mycelia, -or sync existing Mycelia installations with Friend-Lite users. +This script helps migrate existing Chronicle installations to use Mycelia, +or sync existing Mycelia installations with Chronicle users. Usage: # Dry run (preview changes) - python scripts/sync_friendlite_mycelia.py --dry-run + python scripts/sync_chronicle_mycelia.py --dry-run # Sync all users - python scripts/sync_friendlite_mycelia.py --sync-all + python scripts/sync_chronicle_mycelia.py --sync-all # Sync specific user - python scripts/sync_friendlite_mycelia.py --email admin@example.com + python scripts/sync_chronicle_mycelia.py --email admin@example.com # Check for orphaned Mycelia objects - python scripts/sync_friendlite_mycelia.py --check-orphans + python scripts/sync_chronicle_mycelia.py --check-orphans # Reassign orphaned objects to a user - python scripts/sync_friendlite_mycelia.py --reassign-orphans --target-email admin@example.com + python scripts/sync_chronicle_mycelia.py --reassign-orphans --target-email admin@example.com Environment Variables: MONGODB_URI or MONGO_URL - MongoDB connection string @@ -41,18 +41,18 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) -class FriendLiteMyceliaSync: - """Sync Friend-Lite users with Mycelia OAuth credentials.""" +class ChronicleMyceliaSync: + """Sync Chronicle users with Mycelia OAuth credentials.""" - def __init__(self, mongo_url: str, mycelia_db: str, friendlite_db: str): + def __init__(self, mongo_url: str, mycelia_db: str, chronicle_db: str): self.mongo_url = mongo_url self.mycelia_db = mycelia_db - self.friendlite_db = friendlite_db + self.chronicle_db = chronicle_db self.client = MongoClient(mongo_url) print(f"๐Ÿ“Š Connected to MongoDB:") print(f" URL: {mongo_url}") - print(f" Friend-Lite DB: {friendlite_db}") + print(f" Chronicle DB: {chronicle_db}") print(f" Mycelia DB: {mycelia_db}\n") def _hash_api_key_with_salt(self, api_key: str, salt: bytes) -> str: @@ -62,9 +62,9 @@ def _hash_api_key_with_salt(self, api_key: str, salt: bytes) -> str: h.update(api_key.encode('utf-8')) return base64.b64encode(h.digest()).decode('utf-8') - def get_all_friendlite_users(self) -> List[Dict]: - """Get all users from Friend-Lite database.""" - db = self.client[self.friendlite_db] + def get_all_chronicle_users(self) -> List[Dict]: + """Get all users from Chronicle database.""" + db = self.client[self.chronicle_db] users = list(db["users"].find({})) return users @@ -84,7 +84,7 @@ def get_mycelia_api_key_for_user(self, user_id: str) -> Optional[Dict]: return api_key def create_mycelia_api_key(self, user_id: str, user_email: str, dry_run: bool = False) -> Tuple[str, str]: - """Create a Mycelia API key for a Friend-Lite user.""" + """Create a Mycelia API key for a Chronicle user.""" # Generate API key random_part = secrets.token_urlsafe(32) api_key = f"mycelia_{random_part}" @@ -96,7 +96,7 @@ def create_mycelia_api_key(self, user_id: str, user_email: str, dry_run: bool = "hashedKey": hashed_key, "salt": base64.b64encode(salt).decode('utf-8'), "owner": user_id, - "name": f"Friend-Lite Auto ({user_email})", + "name": f"Chronicle Auto ({user_email})", "policies": [{"resource": "**", "action": "*", "effect": "allow"}], "openPrefix": open_prefix, "createdAt": datetime.utcnow(), @@ -111,8 +111,8 @@ def create_mycelia_api_key(self, user_id: str, user_email: str, dry_run: bool = result = db["api_keys"].insert_one(api_key_doc) client_id = str(result.inserted_id) - # Update Friend-Lite user document - fl_db = self.client[self.friendlite_db] + # Update Chronicle user document + fl_db = self.client[self.chronicle_db] fl_db["users"].update_one( {"_id": ObjectId(user_id)}, { @@ -156,13 +156,13 @@ def sync_user(self, user: Dict, dry_run: bool = False) -> bool: return False def sync_all_users(self, dry_run: bool = False): - """Sync all Friend-Lite users to Mycelia OAuth.""" - users = self.get_all_friendlite_users() + """Sync all Chronicle users to Mycelia OAuth.""" + users = self.get_all_chronicle_users() print(f"{'='*80}") print(f"SYNC ALL USERS") print(f"{'='*80}") - print(f"Found {len(users)} Friend-Lite users\n") + print(f"Found {len(users)} Chronicle users\n") if dry_run: print("๐Ÿ” DRY RUN MODE - No changes will be made\n") @@ -180,8 +180,8 @@ def sync_all_users(self, dry_run: bool = False): print(f"{'='*80}\n") def check_orphaned_objects(self): - """Find Mycelia objects with userId not matching any Friend-Lite user.""" - users = self.get_all_friendlite_users() + """Find Mycelia objects with userId not matching any Chronicle user.""" + users = self.get_all_chronicle_users() user_ids = {str(user["_id"]) for user in users} objects = self.get_all_mycelia_objects() @@ -189,7 +189,7 @@ def check_orphaned_objects(self): print(f"{'='*80}") print(f"ORPHANED OBJECTS CHECK") print(f"{'='*80}") - print(f"Friend-Lite users: {len(user_ids)}") + print(f"Chronicle users: {len(user_ids)}") print(f"Mycelia objects: {len(objects)}\n") orphaned = [] @@ -229,20 +229,20 @@ def check_orphaned_objects(self): return orphaned def reassign_orphaned_objects(self, target_email: str, dry_run: bool = False): - """Reassign all orphaned objects to a specific Friend-Lite user.""" + """Reassign all orphaned objects to a specific Chronicle user.""" # Get target user - fl_db = self.client[self.friendlite_db] + fl_db = self.client[self.chronicle_db] target_user = fl_db["users"].find_one({"email": target_email}) if not target_user: - print(f"โœ— User with email '{target_email}' not found in Friend-Lite") + print(f"โœ— User with email '{target_email}' not found in Chronicle") return target_user_id = str(target_user["_id"]) print(f"Target user: {target_email} (ID: {target_user_id})\n") # Find orphaned objects - users = self.get_all_friendlite_users() + users = self.get_all_chronicle_users() user_ids = {str(user["_id"]) for user in users} objects = self.get_all_mycelia_objects() @@ -291,7 +291,7 @@ def reassign_orphaned_objects(self, target_email: str, dry_run: bool = False): def display_sync_status(self): """Display current sync status.""" - users = self.get_all_friendlite_users() + users = self.get_all_chronicle_users() print(f"{'='*80}") print(f"SYNC STATUS") @@ -326,13 +326,13 @@ def display_sync_status(self): def main(): parser = argparse.ArgumentParser( - description="Sync Friend-Lite users with Mycelia OAuth credentials", + description="Sync Chronicle users with Mycelia OAuth credentials", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=__doc__ ) parser.add_argument("--dry-run", action="store_true", help="Preview changes without making them") - parser.add_argument("--sync-all", action="store_true", help="Sync all Friend-Lite users") + parser.add_argument("--sync-all", action="store_true", help="Sync all Chronicle users") parser.add_argument("--email", type=str, help="Sync specific user by email") parser.add_argument("--check-orphans", action="store_true", help="Check for orphaned Mycelia objects") parser.add_argument("--reassign-orphans", action="store_true", help="Reassign orphaned objects to target user") @@ -346,14 +346,14 @@ def main(): # Extract database name from MONGODB_URI if present if "/" in mongo_url and mongo_url.count("/") >= 3: - friendlite_db = mongo_url.split("/")[-1].split("?")[0] or "friend-lite" + chronicle_db = mongo_url.split("/")[-1].split("?")[0] or "chronicle" else: - friendlite_db = "friend-lite" + chronicle_db = "chronicle" mycelia_db = os.getenv("MYCELIA_DB", os.getenv("DATABASE_NAME", "mycelia")) # Create sync service - sync = FriendLiteMyceliaSync(mongo_url, mycelia_db, friendlite_db) + sync = ChronicleMyceliaSync(mongo_url, mycelia_db, chronicle_db) # Execute requested action if args.status: @@ -361,7 +361,7 @@ def main(): elif args.sync_all: sync.sync_all_users(dry_run=args.dry_run) elif args.email: - fl_db = sync.client[friendlite_db] + fl_db = sync.client[chronicle_db] user = fl_db["users"].find_one({"email": args.email}) if user: sync.sync_user(user, dry_run=args.dry_run) diff --git a/backends/advanced/setup-https.sh b/backends/advanced/setup-https.sh index 51f98fe9..e0f733df 100755 --- a/backends/advanced/setup-https.sh +++ b/backends/advanced/setup-https.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -# Friend-Lite Advanced Backend Initialization Script +# Chronicle Advanced Backend Initialization Script # Comprehensive setup for all configuration files and optional services # Colors for output @@ -73,8 +73,8 @@ if [ ! -f "pyproject.toml" ] || [ ! -d "src" ]; then exit 1 fi -print_header "Friend-Lite Advanced Backend Initialization" -echo "This script will help you set up the Friend-Lite backend with all necessary configurations." +print_header "Chronicle Advanced Backend Initialization" +echo "This script will help you set up the Chronicle backend with all necessary configurations." echo "" # Function to prompt yes/no diff --git a/backends/advanced/src/advanced_omi_backend/app_config.py b/backends/advanced/src/advanced_omi_backend/app_config.py index 4bef6593..fcab2d12 100644 --- a/backends/advanced/src/advanced_omi_backend/app_config.py +++ b/backends/advanced/src/advanced_omi_backend/app_config.py @@ -1,5 +1,5 @@ """ -Application configuration for Friend-Lite backend. +Application configuration for Chronicle backend. Centralizes all application-level configuration including database connections, service configurations, and environment variables that were previously in main.py. @@ -67,7 +67,7 @@ def __init__(self): # External Services Configuration self.qdrant_base_url = os.getenv("QDRANT_BASE_URL", "qdrant") self.qdrant_port = os.getenv("QDRANT_PORT", "6333") - self.memory_provider = os.getenv("MEMORY_PROVIDER", "friend_lite").lower() + self.memory_provider = os.getenv("MEMORY_PROVIDER", "chronicle").lower() # Redis Configuration self.redis_url = os.getenv("REDIS_URL", "redis://localhost:6379/0") @@ -84,7 +84,7 @@ def __init__(self): self.max_workers = os.cpu_count() or 4 # Memory service configuration - self.memory_service_supports_threshold = self.memory_provider == "friend_lite" + self.memory_service_supports_threshold = self.memory_provider == "chronicle" # Global configuration instance diff --git a/backends/advanced/src/advanced_omi_backend/app_factory.py b/backends/advanced/src/advanced_omi_backend/app_factory.py index 65b1adbf..7ccda184 100644 --- a/backends/advanced/src/advanced_omi_backend/app_factory.py +++ b/backends/advanced/src/advanced_omi_backend/app_factory.py @@ -1,5 +1,5 @@ """ -Application factory for Friend-Lite backend. +Application factory for Chronicle backend. Creates and configures the FastAPI application with all routers, middleware, and service initializations. diff --git a/backends/advanced/src/advanced_omi_backend/auth.py b/backends/advanced/src/advanced_omi_backend/auth.py index d06e9e68..b0b7ffc1 100644 --- a/backends/advanced/src/advanced_omi_backend/auth.py +++ b/backends/advanced/src/advanced_omi_backend/auth.py @@ -120,13 +120,15 @@ def generate_jwt_for_user(user_id: str, user_email: str) -> str: >>> token = generate_jwt_for_user("507f1f77bcf86cd799439011", "user@example.com") >>> # Use token to call Mycelia API """ - # Create JWT payload matching Friend-Lite's standard format + + + # Create JWT payload matching Chronicle's standard format payload = { "sub": user_id, # Subject = user ID "email": user_email, - "iss": "friend-lite", # Issuer - "aud": "friend-lite", # Audience - "exp": datetime.utcnow() + timedelta(seconds=JWT_LIFETIME_SECONDS), + "iss": "chronicle", # Issuer + "aud": "chronicle", # Audience + "exp": datetime.utcnow() + timedelta(hours=24), # 24 hour expiration "iat": datetime.utcnow(), # Issued at } diff --git a/backends/advanced/src/advanced_omi_backend/chat_service.py b/backends/advanced/src/advanced_omi_backend/chat_service.py index 4ec5ecff..1cd1a2e3 100644 --- a/backends/advanced/src/advanced_omi_backend/chat_service.py +++ b/backends/advanced/src/advanced_omi_backend/chat_service.py @@ -1,5 +1,5 @@ """ -Chat service implementation for Friend-Lite with memory integration. +Chat service implementation for Chronicle with memory integration. This module provides: - Chat session management with MongoDB persistence diff --git a/backends/advanced/src/advanced_omi_backend/clients/__init__.py b/backends/advanced/src/advanced_omi_backend/clients/__init__.py index 099f3c45..70c41823 100644 --- a/backends/advanced/src/advanced_omi_backend/clients/__init__.py +++ b/backends/advanced/src/advanced_omi_backend/clients/__init__.py @@ -1,4 +1,4 @@ -"""Client implementations for Friend-Lite backend. +"""Client implementations for Chronicle backend. This module provides reusable client implementations that can be used for: - Integration testing diff --git a/backends/advanced/src/advanced_omi_backend/config.py b/backends/advanced/src/advanced_omi_backend/config.py index 4fe83d60..2b07a8d4 100644 --- a/backends/advanced/src/advanced_omi_backend/config.py +++ b/backends/advanced/src/advanced_omi_backend/config.py @@ -1,5 +1,5 @@ """ -Configuration management for Friend-Lite backend. +Configuration management for Chronicle backend. Currently contains diarization settings because they were used in multiple places causing circular imports. Other configurations can be moved here as needed. diff --git a/backends/advanced/src/advanced_omi_backend/controllers/system_controller.py b/backends/advanced/src/advanced_omi_backend/controllers/system_controller.py index 9341cc59..27b2810f 100644 --- a/backends/advanced/src/advanced_omi_backend/controllers/system_controller.py +++ b/backends/advanced/src/advanced_omi_backend/controllers/system_controller.py @@ -24,13 +24,13 @@ async def get_current_metrics(): """Get current system metrics.""" try: # Get memory provider configuration - memory_provider = os.getenv("MEMORY_PROVIDER", "friend_lite").lower() + memory_provider = os.getenv("MEMORY_PROVIDER", "chronicle").lower() # Get basic system metrics metrics = { "timestamp": int(time.time()), "memory_provider": memory_provider, - "memory_provider_supports_threshold": memory_provider == "friend_lite", + "memory_provider_supports_threshold": memory_provider == "chronicle", } return metrics @@ -470,10 +470,10 @@ async def delete_all_user_memories(user: User): async def get_memory_provider(): """Get current memory provider configuration.""" try: - current_provider = os.getenv("MEMORY_PROVIDER", "friend_lite").lower() + current_provider = os.getenv("MEMORY_PROVIDER", "chronicle").lower() # Get available providers - available_providers = ["friend_lite", "openmemory_mcp", "mycelia"] + available_providers = ["chronicle", "openmemory_mcp", "mycelia"] return { "current_provider": current_provider, @@ -493,7 +493,7 @@ async def set_memory_provider(provider: str): try: # Validate provider provider = provider.lower().strip() - valid_providers = ["friend_lite", "openmemory_mcp", "mycelia"] + valid_providers = ["chronicle", "openmemory_mcp", "mycelia"] if provider not in valid_providers: return JSONResponse( diff --git a/backends/advanced/src/advanced_omi_backend/controllers/websocket_controller.py b/backends/advanced/src/advanced_omi_backend/controllers/websocket_controller.py index a4338f2b..e138a6e5 100644 --- a/backends/advanced/src/advanced_omi_backend/controllers/websocket_controller.py +++ b/backends/advanced/src/advanced_omi_backend/controllers/websocket_controller.py @@ -1,6 +1,6 @@ """ -WebSocket controller for Friend-Lite backend. +WebSocket controller for Chronicle backend. This module handles WebSocket connections for audio streaming. """ diff --git a/backends/advanced/src/advanced_omi_backend/database.py b/backends/advanced/src/advanced_omi_backend/database.py index 822878e5..ae7650b0 100644 --- a/backends/advanced/src/advanced_omi_backend/database.py +++ b/backends/advanced/src/advanced_omi_backend/database.py @@ -1,5 +1,5 @@ """ -Database configuration and utilities for the Friend-Lite backend. +Database configuration and utilities for the Chronicle backend. This module provides centralized database access to avoid duplication across main.py and router modules. diff --git a/backends/advanced/src/advanced_omi_backend/middleware/app_middleware.py b/backends/advanced/src/advanced_omi_backend/middleware/app_middleware.py index be2f2705..eafeffec 100644 --- a/backends/advanced/src/advanced_omi_backend/middleware/app_middleware.py +++ b/backends/advanced/src/advanced_omi_backend/middleware/app_middleware.py @@ -1,5 +1,5 @@ """ -Middleware configuration for Friend-Lite backend. +Middleware configuration for Chronicle backend. Centralizes CORS configuration and global exception handlers. """ diff --git a/backends/advanced/src/advanced_omi_backend/models/__init__.py b/backends/advanced/src/advanced_omi_backend/models/__init__.py index 52c63c20..a19fa0db 100644 --- a/backends/advanced/src/advanced_omi_backend/models/__init__.py +++ b/backends/advanced/src/advanced_omi_backend/models/__init__.py @@ -1,8 +1,8 @@ """ -Models package for Friend-Lite backend. +Models package for Chronicle backend. This package contains Pydantic models that define the structure and validation -for all data entities in the Friend-Lite system. +for all data entities in the Chronicle system. """ # Models can be imported directly from their files diff --git a/backends/advanced/src/advanced_omi_backend/models/audio_file.py b/backends/advanced/src/advanced_omi_backend/models/audio_file.py index de1c6f3f..00060037 100644 --- a/backends/advanced/src/advanced_omi_backend/models/audio_file.py +++ b/backends/advanced/src/advanced_omi_backend/models/audio_file.py @@ -1,5 +1,5 @@ """ -AudioFile models for Friend-Lite backend. +AudioFile models for Chronicle backend. This module contains the Beanie Document model for audio_chunks collection, which stores ALL audio files (both with and without speech). This is the diff --git a/backends/advanced/src/advanced_omi_backend/models/conversation.py b/backends/advanced/src/advanced_omi_backend/models/conversation.py index 55c31244..87dc731a 100644 --- a/backends/advanced/src/advanced_omi_backend/models/conversation.py +++ b/backends/advanced/src/advanced_omi_backend/models/conversation.py @@ -1,5 +1,5 @@ """ -Conversation models for Friend-Lite backend. +Conversation models for Chronicle backend. This module contains Beanie Document and Pydantic models for conversations, transcript versions, and memory versions. @@ -28,7 +28,7 @@ class TranscriptProvider(str, Enum): class MemoryProvider(str, Enum): """Supported memory providers.""" - FRIEND_LITE = "friend_lite" + CHRONICLE = "chronicle" OPENMEMORY_MCP = "openmemory_mcp" MYCELIA = "mycelia" diff --git a/backends/advanced/src/advanced_omi_backend/routers/api_router.py b/backends/advanced/src/advanced_omi_backend/routers/api_router.py index a510d396..528713c0 100644 --- a/backends/advanced/src/advanced_omi_backend/routers/api_router.py +++ b/backends/advanced/src/advanced_omi_backend/routers/api_router.py @@ -1,5 +1,5 @@ """ -Main API router for Friend-Lite backend. +Main API router for Chronicle backend. This module aggregates all the functional router modules and provides a single entry point for the API endpoints. diff --git a/backends/advanced/src/advanced_omi_backend/routers/modules/__init__.py b/backends/advanced/src/advanced_omi_backend/routers/modules/__init__.py index 371fd38d..a5669b06 100644 --- a/backends/advanced/src/advanced_omi_backend/routers/modules/__init__.py +++ b/backends/advanced/src/advanced_omi_backend/routers/modules/__init__.py @@ -1,5 +1,5 @@ """ -Router modules for Friend-Lite API. +Router modules for Chronicle API. This package contains organized router modules for different functional areas: - user_routes: User management and authentication diff --git a/backends/advanced/src/advanced_omi_backend/routers/modules/chat_routes.py b/backends/advanced/src/advanced_omi_backend/routers/modules/chat_routes.py index a1fea4fc..d0c64904 100644 --- a/backends/advanced/src/advanced_omi_backend/routers/modules/chat_routes.py +++ b/backends/advanced/src/advanced_omi_backend/routers/modules/chat_routes.py @@ -1,5 +1,5 @@ """ -Chat API routes for Friend-Lite with streaming support and memory integration. +Chat API routes for Chronicle with streaming support and memory integration. This module provides: - RESTful chat session management endpoints diff --git a/backends/advanced/src/advanced_omi_backend/routers/modules/client_routes.py b/backends/advanced/src/advanced_omi_backend/routers/modules/client_routes.py index 191ca39f..821ad52a 100644 --- a/backends/advanced/src/advanced_omi_backend/routers/modules/client_routes.py +++ b/backends/advanced/src/advanced_omi_backend/routers/modules/client_routes.py @@ -1,5 +1,5 @@ """ -Client management routes for Friend-Lite API. +Client management routes for Chronicle API. Handles active client monitoring and management. """ diff --git a/backends/advanced/src/advanced_omi_backend/routers/modules/conversation_routes.py b/backends/advanced/src/advanced_omi_backend/routers/modules/conversation_routes.py index e2b76f7d..8da0f5b0 100644 --- a/backends/advanced/src/advanced_omi_backend/routers/modules/conversation_routes.py +++ b/backends/advanced/src/advanced_omi_backend/routers/modules/conversation_routes.py @@ -1,5 +1,5 @@ """ -Conversation management routes for Friend-Lite API. +Conversation management routes for Chronicle API. Handles conversation CRUD operations, audio processing, and transcript management. """ diff --git a/backends/advanced/src/advanced_omi_backend/routers/modules/health_routes.py b/backends/advanced/src/advanced_omi_backend/routers/modules/health_routes.py index 06e0da1e..24865f90 100644 --- a/backends/advanced/src/advanced_omi_backend/routers/modules/health_routes.py +++ b/backends/advanced/src/advanced_omi_backend/routers/modules/health_routes.py @@ -1,5 +1,5 @@ """ -Health check routes for Friend-Lite backend. +Health check routes for Chronicle backend. This module provides health check endpoints for monitoring the application's status. """ @@ -118,7 +118,7 @@ async def health_check(): critical_services_healthy = True # Get configuration once at the start - memory_provider = os.getenv("MEMORY_PROVIDER", "friend_lite") + memory_provider = os.getenv("MEMORY_PROVIDER", "chronicle") speaker_service_url = os.getenv("SPEAKER_SERVICE_URL") openmemory_mcp_url = os.getenv("OPENMEMORY_MCP_URL") @@ -230,38 +230,38 @@ async def health_check(): overall_healthy = False # Check memory service (provider-dependent) - if memory_provider == "friend_lite": + if memory_provider == "chronicle": try: - # Test Friend-Lite memory service connection with timeout + # Test Chronicle memory service connection with timeout test_success = await asyncio.wait_for(memory_service.test_connection(), timeout=8.0) if test_success: health_status["services"]["memory_service"] = { - "status": "โœ… Friend-Lite Memory Connected", + "status": "โœ… Chronicle Memory Connected", "healthy": True, - "provider": "friend_lite", + "provider": "chronicle", "critical": False, } else: health_status["services"]["memory_service"] = { - "status": "โš ๏ธ Friend-Lite Memory Test Failed", + "status": "โš ๏ธ Chronicle Memory Test Failed", "healthy": False, - "provider": "friend_lite", + "provider": "chronicle", "critical": False, } overall_healthy = False except asyncio.TimeoutError: health_status["services"]["memory_service"] = { - "status": "โš ๏ธ Friend-Lite Memory Timeout (8s) - Check Qdrant", + "status": "โš ๏ธ Chronicle Memory Timeout (8s) - Check Qdrant", "healthy": False, - "provider": "friend_lite", + "provider": "chronicle", "critical": False, } overall_healthy = False except Exception as e: health_status["services"]["memory_service"] = { - "status": f"โš ๏ธ Friend-Lite Memory Failed: {str(e)}", + "status": f"โš ๏ธ Chronicle Memory Failed: {str(e)}", "healthy": False, - "provider": "friend_lite", + "provider": "chronicle", "critical": False, } overall_healthy = False diff --git a/backends/advanced/src/advanced_omi_backend/routers/modules/memory_routes.py b/backends/advanced/src/advanced_omi_backend/routers/modules/memory_routes.py index 93ad0f6b..d0be9528 100644 --- a/backends/advanced/src/advanced_omi_backend/routers/modules/memory_routes.py +++ b/backends/advanced/src/advanced_omi_backend/routers/modules/memory_routes.py @@ -1,5 +1,5 @@ """ -Memory management routes for Friend-Lite API. +Memory management routes for Chronicle API. Handles memory CRUD operations, search, and debug functionality. """ diff --git a/backends/advanced/src/advanced_omi_backend/routers/modules/system_routes.py b/backends/advanced/src/advanced_omi_backend/routers/modules/system_routes.py index 10587b5c..e51c036c 100644 --- a/backends/advanced/src/advanced_omi_backend/routers/modules/system_routes.py +++ b/backends/advanced/src/advanced_omi_backend/routers/modules/system_routes.py @@ -1,5 +1,5 @@ """ -System and utility routes for Friend-Lite API. +System and utility routes for Chronicle API. Handles metrics, auth config, and other system utilities. """ diff --git a/backends/advanced/src/advanced_omi_backend/routers/modules/user_routes.py b/backends/advanced/src/advanced_omi_backend/routers/modules/user_routes.py index 808b8185..12ed5c63 100644 --- a/backends/advanced/src/advanced_omi_backend/routers/modules/user_routes.py +++ b/backends/advanced/src/advanced_omi_backend/routers/modules/user_routes.py @@ -1,5 +1,5 @@ """ -User management routes for Friend-Lite API. +User management routes for Chronicle API. Handles user CRUD operations and admin user management. """ diff --git a/backends/advanced/src/advanced_omi_backend/routers/modules/websocket_routes.py b/backends/advanced/src/advanced_omi_backend/routers/modules/websocket_routes.py index 454cabb9..d9754a87 100644 --- a/backends/advanced/src/advanced_omi_backend/routers/modules/websocket_routes.py +++ b/backends/advanced/src/advanced_omi_backend/routers/modules/websocket_routes.py @@ -1,5 +1,5 @@ """ -WebSocket routes for Friend-Lite backend. +WebSocket routes for Chronicle backend. This module handles WebSocket connections for audio streaming. """ diff --git a/backends/advanced/src/advanced_omi_backend/services/__init__.py b/backends/advanced/src/advanced_omi_backend/services/__init__.py index 81d3c535..d656f34c 100644 --- a/backends/advanced/src/advanced_omi_backend/services/__init__.py +++ b/backends/advanced/src/advanced_omi_backend/services/__init__.py @@ -1,5 +1,5 @@ """ -Services module for Friend-Lite backend. +Services module for Chronicle backend. This module contains business logic services and their provider implementations. """ diff --git a/backends/advanced/src/advanced_omi_backend/services/memory/__init__.py b/backends/advanced/src/advanced_omi_backend/services/memory/__init__.py index c2413ff2..1b777028 100644 --- a/backends/advanced/src/advanced_omi_backend/services/memory/__init__.py +++ b/backends/advanced/src/advanced_omi_backend/services/memory/__init__.py @@ -1,7 +1,7 @@ """Memory service package. This package provides memory management functionality with support for -multiple memory providers (Friend-Lite, Mycelia, OpenMemory MCP). +multiple memory providers (Chronicle, Mycelia, OpenMemory MCP). The memory service handles extraction, storage, and retrieval of memories from user conversations and interactions. @@ -10,7 +10,7 @@ - base.py: Abstract base classes and interfaces - config.py: Configuration management - service_factory.py: Provider selection and instantiation -- providers/friend_lite.py: Friend-Lite native provider (LLM + Qdrant) +- providers/chronicle.py: Chronicle native provider (LLM + Qdrant) - providers/mycelia.py: Mycelia backend provider - providers/openmemory_mcp.py: OpenMemory MCP provider - providers/llm_providers.py: LLM implementations (OpenAI, Ollama) diff --git a/backends/advanced/src/advanced_omi_backend/services/memory/config.py b/backends/advanced/src/advanced_omi_backend/services/memory/config.py index 3946deae..7560d88f 100644 --- a/backends/advanced/src/advanced_omi_backend/services/memory/config.py +++ b/backends/advanced/src/advanced_omi_backend/services/memory/config.py @@ -34,7 +34,7 @@ class VectorStoreProvider(Enum): class MemoryProvider(Enum): """Supported memory service providers.""" - FRIEND_LITE = "friend_lite" # Default sophisticated implementation + CHRONICLE = "chronicle" # Default sophisticated implementation OPENMEMORY_MCP = "openmemory_mcp" # OpenMemory MCP backend MYCELIA = "mycelia" # Mycelia memory backend @@ -42,7 +42,7 @@ class MemoryProvider(Enum): @dataclass class MemoryConfig: """Configuration for memory service.""" - memory_provider: MemoryProvider = MemoryProvider.FRIEND_LITE + memory_provider: MemoryProvider = MemoryProvider.CHRONICLE llm_provider: LLMProvider = LLMProvider.OPENAI vector_store_provider: VectorStoreProvider = VectorStoreProvider.QDRANT llm_config: Dict[str, Any] = None @@ -111,7 +111,7 @@ def create_qdrant_config( def create_openmemory_config( server_url: str = "http://localhost:8765", - client_name: str = "friend_lite", + client_name: str = "chronicle", user_id: str = "default", timeout: int = 30 ) -> Dict[str, Any]: @@ -145,7 +145,7 @@ def build_memory_config_from_env() -> MemoryConfig: """Build memory configuration from environment variables and YAML config.""" try: # Determine memory provider - memory_provider = os.getenv("MEMORY_PROVIDER", "friend_lite").lower() + memory_provider = os.getenv("MEMORY_PROVIDER", "chronicle").lower() if memory_provider not in [p.value for p in MemoryProvider]: raise ValueError(f"Unsupported memory provider: {memory_provider}") @@ -155,7 +155,7 @@ def build_memory_config_from_env() -> MemoryConfig: if memory_provider_enum == MemoryProvider.OPENMEMORY_MCP: openmemory_config = create_openmemory_config( server_url=os.getenv("OPENMEMORY_MCP_URL", "http://localhost:8765"), - client_name=os.getenv("OPENMEMORY_CLIENT_NAME", "friend_lite"), + client_name=os.getenv("OPENMEMORY_CLIENT_NAME", "chronicle"), user_id=os.getenv("OPENMEMORY_USER_ID", "default"), timeout=int(os.getenv("OPENMEMORY_TIMEOUT", "30")) ) @@ -199,7 +199,7 @@ def build_memory_config_from_env() -> MemoryConfig: timeout_seconds=int(os.getenv("MYCELIA_TIMEOUT", "30")) ) - # For Friend-Lite provider, use existing complex configuration + # For Chronicle provider, use existing complex configuration # Import config loader from advanced_omi_backend.memory_config_loader import get_config_loader @@ -282,7 +282,7 @@ def build_memory_config_from_env() -> MemoryConfig: extraction_enabled = config_loader.is_memory_extraction_enabled() extraction_prompt = config_loader.get_memory_prompt() if extraction_enabled else None - memory_logger.info(f"๐Ÿ”ง Memory config: Provider=Friend-Lite, LLM={llm_provider}, VectorStore={vector_store_provider}, Extraction={extraction_enabled}") + memory_logger.info(f"๐Ÿ”ง Memory config: Provider=Chronicle, LLM={llm_provider}, VectorStore={vector_store_provider}, Extraction={extraction_enabled}") return MemoryConfig( memory_provider=memory_provider_enum, diff --git a/backends/advanced/src/advanced_omi_backend/services/memory/providers/__init__.py b/backends/advanced/src/advanced_omi_backend/services/memory/providers/__init__.py index 43d438cf..3a71f7cf 100644 --- a/backends/advanced/src/advanced_omi_backend/services/memory/providers/__init__.py +++ b/backends/advanced/src/advanced_omi_backend/services/memory/providers/__init__.py @@ -1,7 +1,7 @@ """Memory service provider implementations. This package contains all memory service provider implementations: -- friend_lite: Friend-Lite native implementation with LLM + vector store +- chronicle: Chronicle native implementation with LLM + vector store - openmemory_mcp: OpenMemory MCP backend integration - mycelia: Mycelia backend integration - llm_providers: LLM provider implementations (OpenAI, Ollama) @@ -9,7 +9,7 @@ - mcp_client: MCP client utilities """ -from .friend_lite import MemoryService as FriendLiteMemoryService +from .chronicle import MemoryService as ChronicleMemoryService from .openmemory_mcp import OpenMemoryMCPService from .mycelia import MyceliaMemoryService from .llm_providers import OpenAIProvider @@ -17,7 +17,7 @@ from .mcp_client import MCPClient, MCPError __all__ = [ - "FriendLiteMemoryService", + "ChronicleMemoryService", "OpenMemoryMCPService", "MyceliaMemoryService", "OpenAIProvider", diff --git a/backends/advanced/src/advanced_omi_backend/services/memory/providers/friend_lite.py b/backends/advanced/src/advanced_omi_backend/services/memory/providers/chronicle.py similarity index 100% rename from backends/advanced/src/advanced_omi_backend/services/memory/providers/friend_lite.py rename to backends/advanced/src/advanced_omi_backend/services/memory/providers/chronicle.py diff --git a/backends/advanced/src/advanced_omi_backend/services/memory/providers/mcp_client.py b/backends/advanced/src/advanced_omi_backend/services/memory/providers/mcp_client.py index c0b9deaf..971c41f3 100644 --- a/backends/advanced/src/advanced_omi_backend/services/memory/providers/mcp_client.py +++ b/backends/advanced/src/advanced_omi_backend/services/memory/providers/mcp_client.py @@ -28,7 +28,7 @@ class MCPClient: client: HTTP client instance """ - def __init__(self, server_url: str, client_name: str = "friend_lite", user_id: str = "default", user_email: str = "", timeout: int = 30): + def __init__(self, server_url: str, client_name: str = "chronicle", user_id: str = "default", user_email: str = "", timeout: int = 30): """Initialize client for OpenMemory. Args: @@ -127,7 +127,17 @@ async def add_memories(self, text: str) -> List[str]: response = await self.client.post( f"{self.server_url}/api/v1/memories/", - json=payload + json={ + "user_id": self.user_id, + "text": text, + "app": self.client_name, # Use app name (OpenMemory accepts name or UUID) + "metadata": { + "source": "chronicle", + "client": self.client_name, + "user_email": self.user_email + }, + "infer": True + } ) response_body = response.text[:500] if response.status_code != 200 else "..." @@ -220,7 +230,7 @@ async def search_memory(self, query: str, limit: int = 10) -> List[Dict[str, Any else: memories = [] - # Format memories for Friend-Lite + # Format memories for Chronicle formatted_memories = [] for memory in memories: formatted_memories.append({ @@ -374,7 +384,7 @@ async def get_memory(self, memory_id: str) -> Optional[Dict[str, Any]]: response.raise_for_status() result = response.json() - # Format memory for Friend-Lite + # Format memory for Chronicle if isinstance(result, dict): return { "id": result.get("id", memory_id), diff --git a/backends/advanced/src/advanced_omi_backend/services/memory/providers/mycelia.py b/backends/advanced/src/advanced_omi_backend/services/memory/providers/mycelia.py index a4d271bb..6f9df0ba 100644 --- a/backends/advanced/src/advanced_omi_backend/services/memory/providers/mycelia.py +++ b/backends/advanced/src/advanced_omi_backend/services/memory/providers/mycelia.py @@ -52,7 +52,7 @@ class MyceliaMemoryService(MemoryServiceBase): """Memory service implementation using Mycelia backend. This class implements the MemoryServiceBase interface by delegating memory - operations to a Mycelia server using JWT authentication from Friend-Lite. + operations to a Mycelia server using JWT authentication from Chronicle. Args: api_url: Mycelia API endpoint URL @@ -196,7 +196,7 @@ async def _call_resource(self, action: str, jwt_token: str, **params) -> Dict[st Args: action: Action to perform (create, list, get, delete, etc.) - jwt_token: User's JWT token from Friend-Lite + jwt_token: User's JWT token from Chronicle **params: Additional parameters for the action Returns: @@ -246,7 +246,7 @@ async def _extract_memories_via_llm( return [] try: - # Get OpenAI client using Friend-Lite's utility + # Get OpenAI client using Chronicle's utility client = _get_openai_client( api_key=self.llm_config.get("api_key"), base_url=self.llm_config.get("base_url", "https://api.openai.com/v1"), @@ -304,7 +304,7 @@ async def _extract_temporal_entity_via_llm( return None try: - # Get OpenAI client using Friend-Lite's utility + # Get OpenAI client using Chronicle's utility client = _get_openai_client( api_key=self.llm_config.get("api_key"), base_url=self.llm_config.get("base_url", "https://api.openai.com/v1"), diff --git a/backends/advanced/src/advanced_omi_backend/services/memory/providers/openmemory_mcp.py b/backends/advanced/src/advanced_omi_backend/services/memory/providers/openmemory_mcp.py index 970806a9..2fe34164 100644 --- a/backends/advanced/src/advanced_omi_backend/services/memory/providers/openmemory_mcp.py +++ b/backends/advanced/src/advanced_omi_backend/services/memory/providers/openmemory_mcp.py @@ -2,7 +2,7 @@ This module provides a concrete implementation of the MemoryServiceBase interface that uses OpenMemory MCP as the backend for all memory operations. It maintains -compatibility with the existing Friend-Lite memory service API while leveraging +compatibility with the existing Chronicle memory service API while leveraging OpenMemory's standardized memory management capabilities. """ @@ -20,10 +20,10 @@ class OpenMemoryMCPService(MemoryServiceBase): """Memory service implementation using OpenMemory MCP as backend. - + This class implements the MemoryServiceBase interface by delegating memory operations to an OpenMemory MCP server. It handles the translation between - Friend-Lite's memory service API and the standardized MCP operations. + Chronicle's memory service API and the standardized MCP operations. Key features: - Maintains compatibility with existing MemoryServiceBase interface @@ -63,7 +63,7 @@ def __init__( """ super().__init__() self.server_url = server_url or os.getenv("OPENMEMORY_MCP_URL", "http://localhost:8765") - self.client_name = client_name or os.getenv("OPENMEMORY_CLIENT_NAME", "friend_lite") + self.client_name = client_name or os.getenv("OPENMEMORY_CLIENT_NAME", "chronicle") self.user_id = user_id or os.getenv("OPENMEMORY_USER_ID", "default") self.timeout = int(timeout or os.getenv("OPENMEMORY_TIMEOUT", "30")) self.mcp_client: Optional[MCPClient] = None @@ -146,10 +146,8 @@ async def add_memory( # OpenMemory will auto-create users if they don't exist original_user_id = self.mcp_client.user_id original_user_email = self.mcp_client.user_email - - # Update MCP client with Friend-Lite user details - self.mcp_client.user_id = user_id - self.mcp_client.user_email = user_email + self.mcp_client.user_id = user_id # Use the actual Chronicle user's ID + self.mcp_client.user_email = user_email # Use the actual user's email try: # Thin client approach: Send raw transcript to OpenMemory MCP server @@ -209,7 +207,7 @@ async def search_memories( # Update MCP client user context for this search operation original_user_id = self.mcp_client.user_id - self.mcp_client.user_id = user_id + self.mcp_client.user_id = user_id # Use the actual Chronicle user's ID try: results = await self.mcp_client.search_memory( @@ -259,7 +257,7 @@ async def get_all_memories( # Update MCP client user context for this operation original_user_id = self.mcp_client.user_id - self.mcp_client.user_id = user_id # Use the actual Friend-Lite user's ID + self.mcp_client.user_id = user_id # Use the actual Chronicle user's ID try: results = await self.mcp_client.list_memories(limit=limit) @@ -299,7 +297,7 @@ async def get_memory(self, memory_id: str, user_id: Optional[str] = None) -> Opt # Update MCP client user context for this operation original_user_id = self.mcp_client.user_id - self.mcp_client.user_id = user_id or self.user_id # Use the actual Friend-Lite user's ID + self.mcp_client.user_id = user_id or self.user_id # Use the actual Chronicle user's ID try: result = await self.mcp_client.get_memory(memory_id) @@ -346,7 +344,7 @@ async def update_memory( # Update MCP client user context for this operation original_user_id = self.mcp_client.user_id - self.mcp_client.user_id = user_id or self.user_id # Use the actual Friend-Lite user's ID + self.mcp_client.user_id = user_id or self.user_id # Use the actual Chronicle user's ID try: success = await self.mcp_client.update_memory( diff --git a/backends/advanced/src/advanced_omi_backend/services/memory/service_factory.py b/backends/advanced/src/advanced_omi_backend/services/memory/service_factory.py index 37922186..dc57dbe9 100644 --- a/backends/advanced/src/advanced_omi_backend/services/memory/service_factory.py +++ b/backends/advanced/src/advanced_omi_backend/services/memory/service_factory.py @@ -1,7 +1,7 @@ """Memory service factory for creating appropriate memory service instances. This module provides a factory pattern for instantiating memory services -based on configuration. It supports both the sophisticated Friend-Lite +based on configuration. It supports both the sophisticated Chronicle implementation and the OpenMemory MCP backend. """ @@ -36,10 +36,10 @@ def create_memory_service(config: MemoryConfig) -> MemoryServiceBase: """ memory_logger.info(f"๐Ÿง  Creating memory service with provider: {config.memory_provider.value}") - if config.memory_provider == MemoryProvider.FRIEND_LITE: - # Use the sophisticated Friend-Lite implementation - from .providers.friend_lite import MemoryService as FriendLiteMemoryService - return FriendLiteMemoryService(config) + if config.memory_provider == MemoryProvider.CHRONICLE: + # Use the sophisticated Chronicle implementation + from .providers.chronicle import MemoryService as ChronicleMemoryService + return ChronicleMemoryService(config) elif config.memory_provider == MemoryProvider.OPENMEMORY_MCP: # Use OpenMemory MCP implementation @@ -156,7 +156,7 @@ def get_service_info() -> dict: # Try to determine provider from service type if "OpenMemoryMCP" in info["service_type"]: info["memory_provider"] = "openmemory_mcp" - elif "FriendLite" in info["service_type"] or "MemoryService" in info["service_type"]: - info["memory_provider"] = "friend_lite" + elif "Chronicle" in info["service_type"] or "MemoryService" in info["service_type"]: + info["memory_provider"] = "chronicle" return info \ No newline at end of file diff --git a/backends/advanced/src/advanced_omi_backend/services/mycelia_sync.py b/backends/advanced/src/advanced_omi_backend/services/mycelia_sync.py index 5b1a64b6..84011068 100644 --- a/backends/advanced/src/advanced_omi_backend/services/mycelia_sync.py +++ b/backends/advanced/src/advanced_omi_backend/services/mycelia_sync.py @@ -1,9 +1,9 @@ """ Mycelia OAuth Synchronization Service. -This module synchronizes Friend-Lite users with Mycelia OAuth API keys, +This module synchronizes Chronicle users with Mycelia OAuth API keys, ensuring that when users access Mycelia directly, they use credentials -that map to their Friend-Lite user ID. +that map to their Chronicle user ID. """ import base64 @@ -21,7 +21,7 @@ class MyceliaSyncService: - """Synchronize Friend-Lite users with Mycelia OAuth API keys.""" + """Synchronize Chronicle users with Mycelia OAuth API keys.""" def __init__(self): """Initialize the sync service.""" @@ -35,17 +35,15 @@ def __init__(self): # Test environment uses mycelia_test, production uses mycelia self.mycelia_db = os.getenv("MYCELIA_DB", os.getenv("DATABASE_NAME", "mycelia")) - # Friend-Lite database - extract from MONGODB_URI or use default - # Test env: test_db, Production: friend-lite + # Chronicle database - extract from MONGODB_URI or use default + # Test env: test_db, Production: chronicle if "/" in self.mongo_url and self.mongo_url.count("/") >= 3: # Extract database name from mongodb://host:port/database - self.friendlite_db = self.mongo_url.split("/")[-1].split("?")[0] or "friend-lite" + self.chronicle_db = self.mongo_url.split("/")[-1].split("?")[0] or "chronicle" else: - self.friendlite_db = "friend-lite" + self.chronicle_db = "chronicle" - logger.info( - f"MyceliaSyncService initialized: {self.mongo_url}, Mycelia DB: {self.mycelia_db}, Friend-Lite DB: {self.friendlite_db}" - ) + logger.info(f"MyceliaSyncService initialized: {self.mongo_url}, Mycelia DB: {self.mycelia_db}, Chronicle DB: {self.chronicle_db}") def _hash_api_key_with_salt(self, api_key: str, salt: bytes) -> str: """Hash API key with salt (matches Mycelia's implementation).""" @@ -56,10 +54,10 @@ def _hash_api_key_with_salt(self, api_key: str, salt: bytes) -> str: def _create_mycelia_api_key(self, user_id: str, user_email: str) -> Tuple[str, str]: """ - Create a Mycelia API key for a Friend-Lite user. + Create a Mycelia API key for a Chronicle user. Args: - user_id: Friend-Lite user ID (MongoDB ObjectId as string) + user_id: Chronicle user ID (MongoDB ObjectId as string) user_email: User email address Returns: @@ -84,9 +82,11 @@ def _create_mycelia_api_key(self, user_id: str, user_email: str) -> Tuple[str, s api_keys_collection = db["api_keys"] # Check if user already has an active API key - existing = api_keys_collection.find_one( - {"owner": user_id, "isActive": True, "name": f"Friend-Lite Auto ({user_email})"} - ) + existing = api_keys_collection.find_one({ + "owner": user_id, + "isActive": True, + "name": f"Chronicle Auto ({user_email})" + }) if existing: logger.info(f"User {user_email} already has Mycelia API key: {existing['_id']}") @@ -97,10 +97,16 @@ def _create_mycelia_api_key(self, user_id: str, user_email: str) -> Tuple[str, s # Create new API key document api_key_doc = { "hashedKey": hashed_key, - "salt": base64.b64encode(salt).decode("utf-8"), - "owner": user_id, # CRITICAL: owner = Friend-Lite user ID - "name": f"Friend-Lite Auto ({user_email})", - "policies": [{"resource": "**", "action": "*", "effect": "allow"}], + "salt": base64.b64encode(salt).decode('utf-8'), + "owner": user_id, # CRITICAL: owner = Chronicle user ID + "name": f"Chronicle Auto ({user_email})", + "policies": [ + { + "resource": "**", + "action": "*", + "effect": "allow" + } + ], "openPrefix": open_prefix, "createdAt": datetime.utcnow(), "isActive": True, @@ -116,10 +122,10 @@ def _create_mycelia_api_key(self, user_id: str, user_email: str) -> Tuple[str, s def sync_user_to_mycelia(self, user_id: str, user_email: str) -> Optional[Tuple[str, str]]: """ - Sync a Friend-Lite user to Mycelia OAuth. + Sync a Chronicle user to Mycelia OAuth. Args: - user_id: Friend-Lite user ID + user_id: Chronicle user ID user_email: User email Returns: @@ -129,10 +135,10 @@ def sync_user_to_mycelia(self, user_id: str, user_email: str) -> Optional[Tuple[ # Create Mycelia API key client_id, api_key = self._create_mycelia_api_key(user_id, user_email) - # Store credentials in Friend-Lite user document (if new key was created) + # Store credentials in Chronicle user document (if new key was created) if api_key: client = MongoClient(self.mongo_url) - db = client[self.friendlite_db] + db = client[self.chronicle_db] users_collection = db["users"] users_collection.update_one( @@ -171,9 +177,9 @@ def sync_admin_user(self) -> Optional[Tuple[str, str]]: logger.warning("ADMIN_EMAIL not set, skipping Mycelia sync") return None - # Get admin user from Friend-Lite database + # Get admin user from Chronicle database client = MongoClient(self.mongo_url) - db = client[self.friendlite_db] + db = client[self.chronicle_db] users_collection = db["users"] admin_user = users_collection.find_one({"email": admin_email}) @@ -229,7 +235,7 @@ async def sync_admin_on_startup(): logger.info("๐Ÿ”„ Starting Mycelia OAuth synchronization...") # Check if Mycelia sync is enabled - memory_provider = os.getenv("MEMORY_PROVIDER", "friend_lite") + memory_provider = os.getenv("MEMORY_PROVIDER", "chronicle") if memory_provider != "mycelia": logger.info("Mycelia sync skipped (MEMORY_PROVIDER != mycelia)") return diff --git a/backends/advanced/src/advanced_omi_backend/workers/conversation_jobs.py b/backends/advanced/src/advanced_omi_backend/workers/conversation_jobs.py index 1d4bd985..0059c816 100644 --- a/backends/advanced/src/advanced_omi_backend/workers/conversation_jobs.py +++ b/backends/advanced/src/advanced_omi_backend/workers/conversation_jobs.py @@ -405,10 +405,15 @@ async def open_conversation_job( ) # Determine end reason based on how we exited the loop - # Check session completion_reason from Redis + # Check session completion_reason from Redis (set by WebSocket controller on disconnect) completion_reason = await redis_client.hget(session_key, "completion_reason") completion_reason_str = completion_reason.decode() if completion_reason else None + # Determine end_reason with proper precedence: + # 1. websocket_disconnect (explicit disconnect from client) + # 2. inactivity_timeout (no speech for SPEECH_INACTIVITY_THRESHOLD_SECONDS) + # 3. max_duration (conversation exceeded max runtime) + # 4. user_stopped (user manually stopped recording) if completion_reason_str == "websocket_disconnect": end_reason = "websocket_disconnect" elif timeout_triggered: diff --git a/backends/advanced/src/advanced_omi_backend/workers/memory_jobs.py b/backends/advanced/src/advanced_omi_backend/workers/memory_jobs.py index 439cdf4c..31dba573 100644 --- a/backends/advanced/src/advanced_omi_backend/workers/memory_jobs.py +++ b/backends/advanced/src/advanced_omi_backend/workers/memory_jobs.py @@ -28,7 +28,7 @@ async def process_memory_job(conversation_id: str, *, redis_client=None) -> Dict V2 Architecture: 1. Extracts memories from conversation transcript 2. Checks primary speakers filter if configured - 3. Uses configured memory provider (friend_lite or openmemory_mcp) + 3. Uses configured memory provider (chronicle or openmemory_mcp) 4. Stores memory references in conversation document Note: Listening jobs are restarted by open_conversation_job (not here). @@ -145,7 +145,7 @@ async def process_memory_job(conversation_id: str, *, redis_client=None) -> Dict transcript_version_id = conversation_model.active_transcript_version or "unknown" # Determine memory provider from memory service - memory_provider = conversation_model.MemoryProvider.FRIEND_LITE # Default + memory_provider = conversation_model.MemoryProvider.CHRONICLE # Default try: memory_service_obj = get_memory_service() provider_name = memory_service_obj.__class__.__name__ diff --git a/backends/advanced/ssl/generate-ssl.sh b/backends/advanced/ssl/generate-ssl.sh index efc5d8c2..b0fd4b3d 100755 --- a/backends/advanced/ssl/generate-ssl.sh +++ b/backends/advanced/ssl/generate-ssl.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -# Generate self-signed SSL certificate for Friend-Lite Advanced Backend +# Generate self-signed SSL certificate for Chronicle Advanced Backend # Supports localhost, IP addresses, and domain names SERVER_ADDRESS="$1" diff --git a/backends/advanced/start-k8s.sh b/backends/advanced/start-k8s.sh index 487b82c8..a2f3d817 100755 --- a/backends/advanced/start-k8s.sh +++ b/backends/advanced/start-k8s.sh @@ -1,11 +1,11 @@ #!/bin/bash -# Friend-Lite Backend Kubernetes Startup Script +# Chronicle Backend Kubernetes Startup Script # Starts both the FastAPI backend and RQ workers for K8s deployment set -e -echo "๐Ÿš€ Starting Friend-Lite Backend (Kubernetes)..." +echo "๐Ÿš€ Starting Chronicle Backend (Kubernetes)..." # Debug environment variables echo "๐Ÿ” Environment check:" diff --git a/backends/advanced/start-workers.sh b/backends/advanced/start-workers.sh index 2e39848d..f62b5a42 100755 --- a/backends/advanced/start-workers.sh +++ b/backends/advanced/start-workers.sh @@ -4,7 +4,7 @@ set -e -echo "๐Ÿš€ Starting Friend-Lite Workers..." +echo "๐Ÿš€ Starting Chronicle Workers..." # Clean up any stale worker registrations from previous runs echo "๐Ÿงน Cleaning up stale worker registrations from Redis..." diff --git a/backends/advanced/start.sh b/backends/advanced/start.sh index 51946672..40fa4abf 100755 --- a/backends/advanced/start.sh +++ b/backends/advanced/start.sh @@ -1,11 +1,11 @@ #!/bin/bash -# Friend-Lite Backend Startup Script +# Chronicle Backend Startup Script # Starts both the FastAPI backend and RQ workers set -e -echo "๐Ÿš€ Starting Friend-Lite Backend..." +echo "๐Ÿš€ Starting Chronicle Backend..." # Function to handle shutdown shutdown() { diff --git a/backends/advanced/tests/test_conversation_models.py b/backends/advanced/tests/test_conversation_models.py index 197fddee..e4387c89 100644 --- a/backends/advanced/tests/test_conversation_models.py +++ b/backends/advanced/tests/test_conversation_models.py @@ -92,7 +92,7 @@ def test_memory_version_model(self): version_id="mem-v1", memory_count=5, transcript_version_id="trans-v1", - provider=MemoryProvider.FRIEND_LITE, + provider=MemoryProvider.CHRONICLE, model="gpt-4o-mini", created_at=datetime.now(), processing_time_seconds=45.2, @@ -102,7 +102,7 @@ def test_memory_version_model(self): assert version.version_id == "mem-v1" assert version.memory_count == 5 assert version.transcript_version_id == "trans-v1" - assert version.provider == MemoryProvider.FRIEND_LITE + assert version.provider == MemoryProvider.CHRONICLE assert version.model == "gpt-4o-mini" assert version.processing_time_seconds == 45.2 assert version.metadata["extraction_quality"] == "high" @@ -151,7 +151,7 @@ def test_add_memory_version(self): version_id="m1", memory_count=3, transcript_version_id="v1", - provider=MemoryProvider.FRIEND_LITE, + provider=MemoryProvider.CHRONICLE, model="gpt-4o-mini", processing_time_seconds=30.0 ) @@ -198,7 +198,7 @@ def test_active_version_properties(self): # Add versions segments = [SpeakerSegment(start=0.0, end=5.0, text="Test", speaker="Speaker A")] conversation.add_transcript_version("v1", "Test", segments, TranscriptProvider.DEEPGRAM) - conversation.add_memory_version("m1", 2, "v1", MemoryProvider.FRIEND_LITE) + conversation.add_memory_version("m1", 2, "v1", MemoryProvider.CHRONICLE) # Should return active versions active_transcript = conversation.active_transcript @@ -217,7 +217,7 @@ def test_provider_enums(self): assert TranscriptProvider.PARAKEET == "parakeet" # Test MemoryProvider enum - assert MemoryProvider.FRIEND_LITE == "friend_lite" + assert MemoryProvider.CHRONICLE == "chronicle" assert MemoryProvider.OPENMEMORY_MCP == "openmemory_mcp" def test_conversation_model_dump(self): @@ -227,7 +227,7 @@ def test_conversation_model_dump(self): # Add some versions segments = [SpeakerSegment(start=0.0, end=5.0, text="Test", speaker="Speaker A")] conversation.add_transcript_version("v1", "Test", segments, TranscriptProvider.DEEPGRAM) - conversation.add_memory_version("m1", 2, "v1", MemoryProvider.FRIEND_LITE) + conversation.add_memory_version("m1", 2, "v1", MemoryProvider.CHRONICLE) # Test model_dump() works conv_dict = conversation.model_dump() diff --git a/backends/advanced/tests/test_integration.py b/backends/advanced/tests/test_integration.py index a4422d4c..a8086d1b 100644 --- a/backends/advanced/tests/test_integration.py +++ b/backends/advanced/tests/test_integration.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -End-to-end integration test for Friend-Lite backend with unified transcription support. +End-to-end integration test for Chronicle backend with unified transcription support. This test validates the complete audio processing pipeline using isolated test environment: 1. Service startup with docker-compose-test.yml (isolated ports and databases) @@ -954,7 +954,7 @@ def validate_memory_extraction(self, upload_response: dict): client_memories = self.wait_for_memory_processing(memory_job_id, client_id) # Check if we're using OpenMemory MCP provider - memory_provider = os.environ.get("MEMORY_PROVIDER", "friend_lite") + memory_provider = os.environ.get("MEMORY_PROVIDER", "chronicle") if not client_memories: if memory_provider == "openmemory_mcp": diff --git a/backends/advanced/upload_files.py b/backends/advanced/upload_files.py index 44ca0e26..ead58e74 100755 --- a/backends/advanced/upload_files.py +++ b/backends/advanced/upload_files.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -Upload audio files to the Friend-Lite backend for processing. +Upload audio files to the Chronicle backend for processing. """ import argparse @@ -376,7 +376,7 @@ def poll_job_status(job_id: str, token: str, base_url: str, total_files: int) -> def parse_args(): """Parse command line arguments.""" - parser = argparse.ArgumentParser(description="Upload audio files to Friend-Lite backend") + parser = argparse.ArgumentParser(description="Upload audio files to Chronicle backend") parser.add_argument( "files", nargs="*", @@ -394,7 +394,7 @@ def main(): """Main function to orchestrate the upload process.""" args = parse_args() - logger.info("Friend-Lite Audio File Upload Tool") + logger.info("Chronicle Audio File Upload Tool") logger.info("=" * 40) # Load environment variables diff --git a/backends/advanced/webui/README.md b/backends/advanced/webui/README.md index f093f66b..303b2780 100644 --- a/backends/advanced/webui/README.md +++ b/backends/advanced/webui/README.md @@ -1,6 +1,6 @@ -# Friend-Lite Web Dashboard +# Chronicle Web Dashboard -A modern React-based web interface for the Friend-Lite AI-powered personal audio system. +A modern React-based web interface for the Chronicle AI-powered personal audio system. ## Features diff --git a/backends/advanced/webui/package-lock.json b/backends/advanced/webui/package-lock.json index 39cfba6b..4582a222 100644 --- a/backends/advanced/webui/package-lock.json +++ b/backends/advanced/webui/package-lock.json @@ -1,11 +1,11 @@ { - "name": "friend-lite-webui", + "name": "chronicle-webui", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "friend-lite-webui", + "name": "chronicle-webui", "version": "0.1.0", "dependencies": { "axios": "^1.6.2", @@ -20,7 +20,6 @@ }, "devDependencies": { "@types/d3": "^7.4.3", - "@types/frappe-gantt": "^0.9.0", "@types/react": "^18.2.43", "@types/react-dom": "^18.2.17", "@types/react-vertical-timeline-component": "^3.3.6", @@ -32,7 +31,7 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.5", "postcss": "^8.4.32", - "sass-embedded": "^1.83.0", + "sass-embedded": "^1.80.7", "tailwindcss": "^3.3.0", "typescript": "^5.2.2", "vite": "^5.0.8" @@ -1991,13 +1990,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/frappe-gantt": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@types/frappe-gantt/-/frappe-gantt-0.9.0.tgz", - "integrity": "sha512-n00ElvRvJ1/+HkJwt57yjnTtAM7FcH/pEV9LbRCy3+hR39TY6l0mQuy4o909uxvw97aCNhQjNh8J8xACKJ2G3w==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/geojson": { "version": "7946.0.16", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", @@ -5252,9 +5244,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.95.1.tgz", - "integrity": "sha512-uPoDh5NIEZV4Dp5GBodkmNY9tSQfXY02pmCcUo+FR1P+x953HGkpw+vV28D4IqYB6f8webZtwoSaZaiPtpTeMg==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.93.3.tgz", + "integrity": "sha512-elOcIZRTM76dvxNAjqYrucTSI0teAF/L2Lv0s6f6b7FOwcwIuA357bIE871580AjHJuSvLIRUosgV+lIWx6Rgg==", "dev": true, "license": "MIT", "optional": true, @@ -5274,9 +5266,9 @@ } }, "node_modules/sass-embedded": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.95.1.tgz", - "integrity": "sha512-l086+s40Z0qP7ckj4T+rI/7tZcwAfcKCG9ah9A808yINWOxZFv0kO0u/UHhR4G9Aimeyax/JNvqh8RE7z1wngg==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.93.3.tgz", + "integrity": "sha512-+VUy01yfDqNmIVMd/LLKl2TTtY0ovZN0rTonh+FhKr65mFwIYgU9WzgIZKS7U9/SPCQvWTsTGx9jyt+qRm/XFw==", "dev": true, "license": "MIT", "dependencies": { @@ -5296,30 +5288,30 @@ "node": ">=16.0.0" }, "optionalDependencies": { - "sass-embedded-all-unknown": "1.95.1", - "sass-embedded-android-arm": "1.95.1", - "sass-embedded-android-arm64": "1.95.1", - "sass-embedded-android-riscv64": "1.95.1", - "sass-embedded-android-x64": "1.95.1", - "sass-embedded-darwin-arm64": "1.95.1", - "sass-embedded-darwin-x64": "1.95.1", - "sass-embedded-linux-arm": "1.95.1", - "sass-embedded-linux-arm64": "1.95.1", - "sass-embedded-linux-musl-arm": "1.95.1", - "sass-embedded-linux-musl-arm64": "1.95.1", - "sass-embedded-linux-musl-riscv64": "1.95.1", - "sass-embedded-linux-musl-x64": "1.95.1", - "sass-embedded-linux-riscv64": "1.95.1", - "sass-embedded-linux-x64": "1.95.1", - "sass-embedded-unknown-all": "1.95.1", - "sass-embedded-win32-arm64": "1.95.1", - "sass-embedded-win32-x64": "1.95.1" + "sass-embedded-all-unknown": "1.93.3", + "sass-embedded-android-arm": "1.93.3", + "sass-embedded-android-arm64": "1.93.3", + "sass-embedded-android-riscv64": "1.93.3", + "sass-embedded-android-x64": "1.93.3", + "sass-embedded-darwin-arm64": "1.93.3", + "sass-embedded-darwin-x64": "1.93.3", + "sass-embedded-linux-arm": "1.93.3", + "sass-embedded-linux-arm64": "1.93.3", + "sass-embedded-linux-musl-arm": "1.93.3", + "sass-embedded-linux-musl-arm64": "1.93.3", + "sass-embedded-linux-musl-riscv64": "1.93.3", + "sass-embedded-linux-musl-x64": "1.93.3", + "sass-embedded-linux-riscv64": "1.93.3", + "sass-embedded-linux-x64": "1.93.3", + "sass-embedded-unknown-all": "1.93.3", + "sass-embedded-win32-arm64": "1.93.3", + "sass-embedded-win32-x64": "1.93.3" } }, "node_modules/sass-embedded-all-unknown": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-all-unknown/-/sass-embedded-all-unknown-1.95.1.tgz", - "integrity": "sha512-ObGM3xSHEK2fu89GusvAdk1hId3D1R03CyQ6/AVTFSrcBFav1a3aWUmBWtImzf5LsVzliRnlAPPS6+rT/Ghb1A==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-all-unknown/-/sass-embedded-all-unknown-1.93.3.tgz", + "integrity": "sha512-3okGgnE41eg+CPLtAPletu6nQ4N0ij7AeW+Sl5Km4j29XcmqZQeFwYjHe1AlKTEgLi/UAONk1O8i8/lupeKMbw==", "cpu": [ "!arm", "!arm64", @@ -5330,13 +5322,13 @@ "license": "MIT", "optional": true, "dependencies": { - "sass": "1.95.1" + "sass": "1.93.3" } }, "node_modules/sass-embedded-android-arm": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.95.1.tgz", - "integrity": "sha512-siaN1TVEjhBP4QJ5UlDBRhyKmMbFhbdcyHj0B4hIuNcinuVprP6tH1NT0NkHvkXh2egBmTvjzZgJ1ySsCB32JA==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.93.3.tgz", + "integrity": "sha512-8xOw9bywfOD6Wv24BgCmgjkk6tMrsOTTHcb28KDxeJtFtoxiUyMbxo0vChpPAfp2Hyg2tFFKS60s0s4JYk+Raw==", "cpu": [ "arm" ], @@ -5351,9 +5343,9 @@ } }, "node_modules/sass-embedded-android-arm64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.95.1.tgz", - "integrity": "sha512-E+3vZXhUOVHFiSITH2g53/ynxTG4zz8vTVrXGAKkZQwSe6aCO22uc1Pah23F3jOrDNF/YLrsyp82T/CIIczK3w==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.93.3.tgz", + "integrity": "sha512-uqUl3Kt1IqdGVAcAdbmC+NwuUJy8tM+2ZnB7/zrt6WxWVShVCRdFnWR9LT8HJr7eJN7AU8kSXxaVX/gedanPsg==", "cpu": [ "arm64" ], @@ -5368,9 +5360,9 @@ } }, "node_modules/sass-embedded-android-riscv64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.95.1.tgz", - "integrity": "sha512-UcPcr5JXVtInD+/XE+2DhwPsALUdRAHyippnnAP6MtdaT3+AnqqvzSVy9Gb6SKyeqEk4YxPmIlQpZCVODDT4eA==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.93.3.tgz", + "integrity": "sha512-2jNJDmo+3qLocjWqYbXiBDnfgwrUeZgZFHJIwAefU7Fn66Ot7rsXl+XPwlokaCbTpj7eMFIqsRAZ/uDueXNCJg==", "cpu": [ "riscv64" ], @@ -5385,9 +5377,9 @@ } }, "node_modules/sass-embedded-android-x64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.95.1.tgz", - "integrity": "sha512-sW/TO+B0Wq9VDTa7YiO74DW4iF9jEYds+9yslaHtc69r/Ch+Zj+ZB6HeJysfmen91zn5CLJDGrnTSrIk+/COfQ==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.93.3.tgz", + "integrity": "sha512-y0RoAU6ZenQFcjM9PjQd3cRqRTjqwSbtWLL/p68y2oFyh0QGN0+LQ826fc0ZvU/AbqCsAizkqjzOn6cRZJxTTQ==", "cpu": [ "x64" ], @@ -5402,9 +5394,9 @@ } }, "node_modules/sass-embedded-darwin-arm64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.95.1.tgz", - "integrity": "sha512-SWTCwszlBzjin35T2OiGZSDRbC/sqg5Mjepih18lelELrz14eB9LcFTZeiqDfdnwx6qQqPWj2VufCpExr8jElA==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.93.3.tgz", + "integrity": "sha512-7zb/hpdMOdKteK17BOyyypemglVURd1Hdz6QGsggy60aUFfptTLQftLRg8r/xh1RbQAUKWFbYTNaM47J9yPxYg==", "cpu": [ "arm64" ], @@ -5419,9 +5411,9 @@ } }, "node_modules/sass-embedded-darwin-x64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.95.1.tgz", - "integrity": "sha512-0GZEgkE1e8E2h97lUtwgZbKHrJYmRE/KhWQBHv6ZueAto8DJcAFNFrIQiQoRJjraE6QTaw6ahSvc1YJ7gL4OQA==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.93.3.tgz", + "integrity": "sha512-Ek1Vp8ZDQEe327Lz0b7h3hjvWH3u9XjJiQzveq74RPpJQ2q6d9LfWpjiRRohM4qK6o4XOHw1X10OMWPXJtdtWg==", "cpu": [ "x64" ], @@ -5436,9 +5428,9 @@ } }, "node_modules/sass-embedded-linux-arm": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.95.1.tgz", - "integrity": "sha512-zUAm/rztm5Uyy+DSs408VJg404siVgUuZyqId4tFwkPNC5WRKu25Z8bFMriyGaE4YfEqbNwFV07C16mJoGeVOA==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.93.3.tgz", + "integrity": "sha512-yeiv2y+dp8B4wNpd3+JsHYD0mvpXSfov7IGyQ1tMIR40qv+ROkRqYiqQvAOXf76Qwh4Y9OaYZtLpnsPjfeq6mA==", "cpu": [ "arm" ], @@ -5453,9 +5445,9 @@ } }, "node_modules/sass-embedded-linux-arm64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.95.1.tgz", - "integrity": "sha512-MQxa+qVX7Os2rMpJ/AvhWup+1cS0JieQgCfi9cz1Zckn4zaUhg35+m2FQhfKvzv4afeW5bubTMOQeTRMQujbXw==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.93.3.tgz", + "integrity": "sha512-RBrHWgfd8Dd8w4fbmdRVXRrhh8oBAPyeWDTKAWw8ZEmuXfVl4ytjDuyxaVilh6rR1xTRTNpbaA/YWApBlLrrNw==", "cpu": [ "arm64" ], @@ -5470,9 +5462,9 @@ } }, "node_modules/sass-embedded-linux-musl-arm": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.95.1.tgz", - "integrity": "sha512-gNdaGmM3nZ0jkFNmyXWyNlXZPdaMP+7n5Mk3yGFGShqRt/6T/bHh5SkyNnU2ZdP1z7R9poPItJhULrZJ42ETeA==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.93.3.tgz", + "integrity": "sha512-fU0fwAwbp7sBE3h5DVU5UPzvaLg7a4yONfFWkkcCp6ZrOiPuGRHXXYriWQ0TUnWy4wE+svsVuWhwWgvlb/tkKg==", "cpu": [ "arm" ], @@ -5487,9 +5479,9 @@ } }, "node_modules/sass-embedded-linux-musl-arm64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.95.1.tgz", - "integrity": "sha512-8lD5vHGzBjBRCMIr9CXCyjmy8Q1q+H4ygcYCIm/aPNYhrm9uPOzJfs8hv9kDRgRAASFkcPGlFw8tDH4QqiJ5wg==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.93.3.tgz", + "integrity": "sha512-PS829l+eUng+9W4PFclXGb4uA2+965NHV3/Sa5U7qTywjeeUUYTZg70dJHSqvhrBEfCc2XJABeW3adLJbyQYkw==", "cpu": [ "arm64" ], @@ -5504,9 +5496,9 @@ } }, "node_modules/sass-embedded-linux-musl-riscv64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.95.1.tgz", - "integrity": "sha512-WjKfHxnFc/jOL5QtmgYuiWCc4616V15DkpE+7z41JWEawRXku6w++w7AR+Zx/jbz93FZ/AsZp27IS3XUt80u3Q==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.93.3.tgz", + "integrity": "sha512-cK1oBY+FWQquaIGEeQ5H74KTO8cWsSWwXb/WaildOO9U6wmUypTgUYKQ0o5o/29nZbWWlM1PHuwVYTSnT23Jjg==", "cpu": [ "riscv64" ], @@ -5521,9 +5513,9 @@ } }, "node_modules/sass-embedded-linux-musl-x64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.95.1.tgz", - "integrity": "sha512-3U6994SRUUmC8mPvSG/vNLUo2ZcGv3jHuPoBywTbJhGQI8gq0hef1MY8TU5mvtj9DhQYlah6MYktM4YrOQgqcQ==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.93.3.tgz", + "integrity": "sha512-A7wkrsHu2/I4Zpa0NMuPGkWDVV7QGGytxGyUq3opSXgAexHo/vBPlGoDXoRlSdex0cV+aTMRPjoGIfdmNlHwyg==", "cpu": [ "x64" ], @@ -5538,9 +5530,9 @@ } }, "node_modules/sass-embedded-linux-riscv64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.95.1.tgz", - "integrity": "sha512-CJ0tEEQnfpJEMCQrdubLsmuVc/c66EgaCAO0ZgSJ/KpxBKF3O1lHN6e1UErRf6VO0rh8ExAOh75po12Vu849Og==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.93.3.tgz", + "integrity": "sha512-vWkW1+HTF5qcaHa6hO80gx/QfB6GGjJUP0xLbnAoY4pwEnw5ulGv6RM8qYr8IDhWfVt/KH+lhJ2ZFxnJareisQ==", "cpu": [ "riscv64" ], @@ -5555,9 +5547,9 @@ } }, "node_modules/sass-embedded-linux-x64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.95.1.tgz", - "integrity": "sha512-nGnzrEpZZOsGOwrRVyX4t15M8ijZWhc4e4lLpOqaPm+lv23HFncfY05WxU5bRj0KAknrkeTM2IX/6veP2aeUdA==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.93.3.tgz", + "integrity": "sha512-k6uFxs+e5jSuk1Y0niCwuq42F9ZC5UEP7P+RIOurIm8w/5QFa0+YqeW+BPWEW5M1FqVOsNZH3qGn4ahqvAEjPA==", "cpu": [ "x64" ], @@ -5572,9 +5564,9 @@ } }, "node_modules/sass-embedded-unknown-all": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-unknown-all/-/sass-embedded-unknown-all-1.95.1.tgz", - "integrity": "sha512-bhywAcadVQoCotD4gVmyMBi2SENPvyLFPrXf33VK5mY487Nf/g5SgGCUuGmfTsbns4NBwbwR7PA/1fnJmeMtdA==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-unknown-all/-/sass-embedded-unknown-all-1.93.3.tgz", + "integrity": "sha512-o5wj2rLpXH0C+GJKt/VpWp6AnMsCCbfFmnMAttcrsa+U3yrs/guhZ3x55KAqqUsE8F47e3frbsDL+1OuQM5DAA==", "dev": true, "license": "MIT", "optional": true, @@ -5585,13 +5577,13 @@ "!win32" ], "dependencies": { - "sass": "1.95.1" + "sass": "1.93.3" } }, "node_modules/sass-embedded-win32-arm64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.95.1.tgz", - "integrity": "sha512-RWWODCthWdMVODoq98lyIk9R56mgGJ4TFUjD9LSCe7fAYD/tiTkUabE4AUzkZqknQSYr0n0Q2uy7POSDIKvhVg==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.93.3.tgz", + "integrity": "sha512-0dOfT9moy9YmBolodwYYXtLwNr4jL4HQC9rBfv6mVrD7ud8ue2kDbn+GVzj1hEJxvEexVSmDCf7MHUTLcGs9xQ==", "cpu": [ "arm64" ], @@ -5606,9 +5598,9 @@ } }, "node_modules/sass-embedded-win32-x64": { - "version": "1.95.1", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.95.1.tgz", - "integrity": "sha512-jotHgOQnCb1XdjK0fhsyuhsfox7Y5EkrOc4h2caEpRcNCnsPTBZHqhuc8Lnw8HbKIhwKYkqWhexkjgz62MShhg==", + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.93.3.tgz", + "integrity": "sha512-wHFVfxiS9hU/sNk7KReD+lJWRp3R0SLQEX4zfOnRP2zlvI2X4IQR5aZr9GNcuMP6TmNpX0nQPZTegS8+h9RrEg==", "cpu": [ "x64" ], diff --git a/backends/advanced/webui/package.json b/backends/advanced/webui/package.json index 120bbe9c..aa33d177 100644 --- a/backends/advanced/webui/package.json +++ b/backends/advanced/webui/package.json @@ -1,5 +1,5 @@ { - "name": "friend-lite-webui", + "name": "chronicle-webui", "private": true, "version": "0.1.0", "type": "module", @@ -34,7 +34,7 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.5", "postcss": "^8.4.32", - "sass-embedded": "^1.83.0", + "sass-embedded": "^1.80.7", "tailwindcss": "^3.3.0", "typescript": "^5.2.2", "vite": "^5.0.8" diff --git a/backends/advanced/webui/src/components/layout/Layout.tsx b/backends/advanced/webui/src/components/layout/Layout.tsx index f4caf629..5995f823 100644 --- a/backends/advanced/webui/src/components/layout/Layout.tsx +++ b/backends/advanced/webui/src/components/layout/Layout.tsx @@ -31,7 +31,7 @@ export default function Layout() {

- Friend-Lite Dashboard + Chronicle Dashboard

@@ -102,7 +102,7 @@ export default function Layout() {
- ๐ŸŽต Friend-Lite Dashboard v1.0 | AI-powered personal audio system + ๐ŸŽต Chronicle Dashboard v1.0 | AI-powered personal audio system
diff --git a/backends/advanced/webui/src/pages/LoginPage.tsx b/backends/advanced/webui/src/pages/LoginPage.tsx index 717bb61d..7093e73a 100644 --- a/backends/advanced/webui/src/pages/LoginPage.tsx +++ b/backends/advanced/webui/src/pages/LoginPage.tsx @@ -58,7 +58,7 @@ export default function LoginPage() {

- Friend-Lite Dashboard + Chronicle Dashboard

Sign in to your account diff --git a/backends/advanced/webui/src/pages/Memories.tsx b/backends/advanced/webui/src/pages/Memories.tsx index 0c4973b6..732d1683 100644 --- a/backends/advanced/webui/src/pages/Memories.tsx +++ b/backends/advanced/webui/src/pages/Memories.tsx @@ -258,7 +258,7 @@ export default function Memories() { {memoryProvider && (

- Provider: {memoryProvider === 'friend_lite' ? 'Friend-Lite' : memoryProvider === 'openmemory_mcp' ? 'OpenMemory MCP' : memoryProvider} + Provider: {memoryProvider === 'chronicle' ? 'Chronicle' : memoryProvider === 'openmemory_mcp' ? 'OpenMemory MCP' : memoryProvider}

)} @@ -313,7 +313,7 @@ export default function Memories() { - {/* Initial Search Threshold Slider - Show for Friend-Lite provider */} + {/* Initial Search Threshold Slider - Show for Chronicle provider */} {memoryProviderSupportsThreshold && (
diff --git a/backends/advanced/webui/src/pages/MemoriesRouter.tsx b/backends/advanced/webui/src/pages/MemoriesRouter.tsx index b39663f9..fe6285e9 100644 --- a/backends/advanced/webui/src/pages/MemoriesRouter.tsx +++ b/backends/advanced/webui/src/pages/MemoriesRouter.tsx @@ -4,7 +4,7 @@ import Memories from './Memories' /** * Memories page wrapper that stores JWT for cross-origin Mycelia access. - * Always displays Friend-Lite native Memories component (backend proxies to provider). + * Always displays Chronicle native Memories component (backend proxies to provider). */ export default function MemoriesRouter() { const { token } = useAuth() @@ -17,6 +17,6 @@ export default function MemoriesRouter() { }, [token]) // Always show the native Memories page (works for all providers) - // Friend-Lite backend will proxy to Mycelia when needed + // Chronicle backend will proxy to Mycelia when needed return } diff --git a/backends/advanced/webui/src/pages/System.tsx b/backends/advanced/webui/src/pages/System.tsx index c722ada9..5c52e057 100644 --- a/backends/advanced/webui/src/pages/System.tsx +++ b/backends/advanced/webui/src/pages/System.tsx @@ -359,7 +359,7 @@ export default function System() { > {availableProviders.map((provider) => ( diff --git a/backends/advanced/webui/tsconfig.json b/backends/advanced/webui/tsconfig.json index 7a7611e4..7355a7c8 100644 --- a/backends/advanced/webui/tsconfig.json +++ b/backends/advanced/webui/tsconfig.json @@ -16,6 +16,7 @@ /* Linting */ "strict": true, + "noImplicitAny": false, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true diff --git a/backends/charts/advanced-backend/Chart.yaml b/backends/charts/advanced-backend/Chart.yaml index 01aad364..c70e0509 100644 --- a/backends/charts/advanced-backend/Chart.yaml +++ b/backends/charts/advanced-backend/Chart.yaml @@ -1,10 +1,10 @@ apiVersion: v2 name: advanced-backend -description: Friend-lite Advanced Backend Service +description: Chronicle Advanced Backend Service version: 0.1.0 appVersion: "1.0" keywords: - - friend-lite + - chronicle - backend - ai sources: diff --git a/backends/charts/advanced-backend/templates/deployment.yaml b/backends/charts/advanced-backend/templates/deployment.yaml index 4082bd65..0e40a7fb 100644 --- a/backends/charts/advanced-backend/templates/deployment.yaml +++ b/backends/charts/advanced-backend/templates/deployment.yaml @@ -25,9 +25,9 @@ spec: protocol: TCP envFrom: - configMapRef: - name: friend-lite-config + name: chronicle-config - secretRef: - name: friend-lite-secrets + name: chronicle-secrets env: # Override specific values from Kubernetes/Helm if needed {{- range $key, $value := .Values.env }} @@ -70,9 +70,9 @@ spec: command: ["./start-workers.sh"] envFrom: - configMapRef: - name: friend-lite-config + name: chronicle-config - secretRef: - name: friend-lite-secrets + name: chronicle-secrets env: {{- range $key, $value := .Values.env }} - name: {{ $key }} diff --git a/backends/charts/advanced-backend/templates/workers-deployment.yaml b/backends/charts/advanced-backend/templates/workers-deployment.yaml index effcc10d..22751d31 100644 --- a/backends/charts/advanced-backend/templates/workers-deployment.yaml +++ b/backends/charts/advanced-backend/templates/workers-deployment.yaml @@ -24,9 +24,9 @@ spec: command: ["./start-workers.sh"] envFrom: - configMapRef: - name: friend-lite-config + name: chronicle-config - secretRef: - name: friend-lite-secrets + name: chronicle-secrets env: # Override specific values from Kubernetes/Helm if needed {{- range $key, $value := .Values.env }} diff --git a/backends/charts/advanced-backend/values.yaml b/backends/charts/advanced-backend/values.yaml index 8827a62d..a3a2812f 100644 --- a/backends/charts/advanced-backend/values.yaml +++ b/backends/charts/advanced-backend/values.yaml @@ -55,9 +55,9 @@ ingress: # hosts: defined in ingress-values.yaml and overridden by Skaffold # tls: - # - secretName: friend-lite-tls + # - secretName: chronicle-tls # hosts: - # - friend-lite.192-168-1-42.nip.io + # - chronicle.192-168-1-42.nip.io resources: limits: diff --git a/backends/charts/webui/Chart.yaml b/backends/charts/webui/Chart.yaml index cc3b2d32..869eba76 100644 --- a/backends/charts/webui/Chart.yaml +++ b/backends/charts/webui/Chart.yaml @@ -1,10 +1,10 @@ apiVersion: v2 name: webui -description: Friend-lite WebUI +description: Chronicle WebUI version: 0.1.0 appVersion: "1.0" keywords: - - friend-lite + - chronicle - webui - frontend sources: diff --git a/backends/charts/webui/templates/deployment.yaml b/backends/charts/webui/templates/deployment.yaml index a1358e2e..6d57204c 100644 --- a/backends/charts/webui/templates/deployment.yaml +++ b/backends/charts/webui/templates/deployment.yaml @@ -24,9 +24,9 @@ spec: protocol: TCP envFrom: - configMapRef: - name: friend-lite-config + name: chronicle-config - secretRef: - name: friend-lite-secrets + name: chronicle-secrets env: {{- range $key, $value := .Values.env }} - name: {{ $key }} diff --git a/backends/charts/webui/values.yaml b/backends/charts/webui/values.yaml index c56229e4..1dce6ab4 100644 --- a/backends/charts/webui/values.yaml +++ b/backends/charts/webui/values.yaml @@ -38,7 +38,7 @@ ingress: - host: external.example.com # Overridden by Skaffold setValueTemplates paths: *commonPaths # tls: - # - secretName: friend-lite-tls + # - secretName: chronicle-tls # hosts: # - webui.example.com diff --git a/extras/asr-services/README.md b/extras/asr-services/README.md index b235b659..670d33b5 100644 --- a/extras/asr-services/README.md +++ b/extras/asr-services/README.md @@ -1,6 +1,6 @@ # ASR Services -Offline Automatic Speech Recognition (ASR) services for Friend-Lite using the Wyoming protocol. +Offline Automatic Speech Recognition (ASR) services for Chronicle using the Wyoming protocol. ## Overview @@ -100,7 +100,7 @@ services: ## Integration -### With Friend-Lite Backend +### With Chronicle Backend The ASR services integrate as fallback transcription when Deepgram is unavailable: ```bash # Backend configuration diff --git a/extras/asr-services/quickstart.md b/extras/asr-services/quickstart.md index 1fed4c12..994d17bc 100644 --- a/extras/asr-services/quickstart.md +++ b/extras/asr-services/quickstart.md @@ -40,8 +40,8 @@ python client.py --host localhost --port 8765 --audio test.wav python client.py --host localhost --port 8765 --microphone ``` -### Integration with Friend-Lite -Set the offline ASR URI in your Friend-Lite backend: +### Integration with Chronicle +Set the offline ASR URI in your Chronicle backend: ```bash # In your .env file OFFLINE_ASR_TCP_URI=tcp://localhost:8765 @@ -55,7 +55,7 @@ OFFLINE_ASR_TCP_URI=tcp://localhost:8765 ## Next Steps -1. **Configure Backend**: Update Friend-Lite to use offline ASR as fallback +1. **Configure Backend**: Update Chronicle to use offline ASR as fallback 2. **Test Integration**: Verify transcription works when Deepgram is unavailable 3. **Performance Tuning**: Monitor CPU/memory usage and adjust as needed 4. **Production Deploy**: Scale services based on load requirements diff --git a/extras/asr-services/tests/test_parakeet_service.py b/extras/asr-services/tests/test_parakeet_service.py index 0fd3462d..4c94af12 100644 --- a/extras/asr-services/tests/test_parakeet_service.py +++ b/extras/asr-services/tests/test_parakeet_service.py @@ -13,7 +13,7 @@ Run with: # Run the test (service management is automatic) - cd /home/ankush/workspaces/friend-lite/extras/asr-services + cd /home/ankush/workspaces/chronicle/extras/asr-services uv run pytest tests/test_parakeet_service.py -v -s """ diff --git a/extras/havpe-relay/README.md b/extras/havpe-relay/README.md index 5ab061e3..2793b36d 100644 --- a/extras/havpe-relay/README.md +++ b/extras/havpe-relay/README.md @@ -161,4 +161,4 @@ You can test the relay using the provided test listener (if needed): ## License -This project is part of the friend-lite ecosystem. +This project is part of the chronicle ecosystem. diff --git a/extras/havpe-relay/main.py b/extras/havpe-relay/main.py index 4494bb00..eac6d58b 100644 --- a/extras/havpe-relay/main.py +++ b/extras/havpe-relay/main.py @@ -526,7 +526,7 @@ async def main(): # Print startup banner with authentication info logger.info("๐ŸŽต ========================================") - logger.info("๐ŸŽต Friend-Lite HAVPE Relay with Authentication") + logger.info("๐ŸŽต Chronicle HAVPE Relay with Authentication") logger.info("๐ŸŽต ========================================") logger.info(f"๐ŸŽง ESP32 Server: {args.host}:{args.port}") logger.info(f"๐Ÿ“ก Backend API: {BACKEND_URL}") diff --git a/extras/local-omi-bt/connect-omi.py b/extras/local-omi-bt/connect-omi.py index a689bb4b..302a17d7 100644 --- a/extras/local-omi-bt/connect-omi.py +++ b/extras/local-omi-bt/connect-omi.py @@ -10,8 +10,8 @@ from bleak.backends.device import BLEDevice from dotenv import load_dotenv, set_key from easy_audio_interfaces.filesystem import RollingFileSink -from friend_lite.bluetooth import listen_to_omi, print_devices -from friend_lite.decoder import OmiOpusDecoder +from chronicle.bluetooth import listen_to_omi, print_devices +from chronicle.decoder import OmiOpusDecoder from wyoming.audio import AudioChunk # Setup logging @@ -49,7 +49,7 @@ async def as_audio_chunks(it) -> AsyncGenerator[AudioChunk, None]: async for data in it: yield AudioChunk(audio=data, rate=16000, width=2, channels=1) -# Add this to friend-lite sdk +# Add this to chronicle sdk async def list_devices(prefix: str = "OMI") -> list[BLEDevice]: devices = await BleakScanner.discover() filtered_devices = [] diff --git a/extras/openmemory-mcp/README.md b/extras/openmemory-mcp/README.md index 82d033e0..940a33e5 100644 --- a/extras/openmemory-mcp/README.md +++ b/extras/openmemory-mcp/README.md @@ -1,6 +1,6 @@ # OpenMemory MCP Service -This directory contains a local deployment of the OpenMemory MCP (Model Context Protocol) server, which can be used as an alternative memory provider for Friend-Lite. +This directory contains a local deployment of the OpenMemory MCP (Model Context Protocol) server, which can be used as an alternative memory provider for Chronicle. ## What is OpenMemory MCP? @@ -30,9 +30,9 @@ cp .env.template .env ./run.sh --with-ui ``` -### 3. Configure Friend-Lite +### 3. Configure Chronicle -In your Friend-Lite backend `.env` file: +In your Chronicle backend `.env` file: ```bash # Use OpenMemory MCP instead of built-in memory processing @@ -52,7 +52,7 @@ The deployment includes: 2. **Qdrant Vector Database** (port 6334) - Stores memory embeddings - Enables semantic search - - Isolated from main Friend-Lite Qdrant + - Isolated from main Chronicle Qdrant 3. **OpenMemory UI** (port 3001, optional) - Web interface for memory management @@ -69,16 +69,16 @@ The deployment includes: - **UI** (if enabled): http://localhost:3001 -## How It Works with Friend-Lite +## How It Works with Chronicle -When configured with `MEMORY_PROVIDER=openmemory_mcp`, Friend-Lite will: +When configured with `MEMORY_PROVIDER=openmemory_mcp`, Chronicle will: 1. Send raw conversation transcripts to OpenMemory MCP 2. OpenMemory extracts memories using OpenAI 3. Memories are stored in the dedicated Qdrant instance -4. Friend-Lite can search memories via the MCP protocol +4. Chronicle can search memories via the MCP protocol -This replaces Friend-Lite's built-in memory processing with OpenMemory's implementation. +This replaces Chronicle's built-in memory processing with OpenMemory's implementation. ## Managing Services @@ -98,7 +98,7 @@ docker compose restart ## Testing -### Standalone Test (No Friend-Lite Dependencies) +### Standalone Test (No Chronicle Dependencies) Test the OpenMemory MCP server directly: @@ -117,9 +117,9 @@ This test verifies: - Memory deletion - MCP protocol endpoints -### Integration Test (With Friend-Lite) +### Integration Test (With Chronicle) -Test the integration between Friend-Lite and OpenMemory MCP: +Test the integration between Chronicle and OpenMemory MCP: ```bash # From backends/advanced directory @@ -134,7 +134,7 @@ This test verifies: - MCP client functionality - OpenMemoryMCPService implementation - Service factory integration -- Memory operations through Friend-Lite interface +- Memory operations through Chronicle interface ## Troubleshooting @@ -143,35 +143,35 @@ This test verifies: If ports are already in use, edit `docker-compose.yml`: - Change `8765:8765` to another port for MCP server - Change `6334:6333` to another port for Qdrant -- Update Friend-Lite's `OPENMEMORY_MCP_URL` accordingly +- Update Chronicle's `OPENMEMORY_MCP_URL` accordingly ### Memory Not Working 1. Check OpenMemory logs: `docker compose logs openmemory-mcp` 2. Verify OPENAI_API_KEY is set correctly -3. Ensure Friend-Lite backend is configured with correct URL +3. Ensure Chronicle backend is configured with correct URL 4. Test MCP endpoint: `curl http://localhost:8765/api/v1/memories?user_id=test` ### Connection Issues -- Ensure containers are on same network if running Friend-Lite in Docker +- Ensure containers are on same network if running Chronicle in Docker - Use `host.docker.internal` instead of `localhost` when connecting from Docker containers ## Advanced Configuration ### Using with Docker Network -If Friend-Lite backend is also running in Docker: +If Chronicle backend is also running in Docker: ```yaml -# In Friend-Lite docker-compose.yml +# In Chronicle docker-compose.yml networks: default: external: name: openmemory-mcp_openmemory-network ``` -Then use container names in Friend-Lite .env: +Then use container names in Chronicle .env: ```bash OPENMEMORY_MCP_URL=http://openmemory-mcp:8765 ``` @@ -184,4 +184,4 @@ OpenMemory uses OpenAI by default. To use different models, you would need to mo - [OpenMemory Documentation](https://docs.mem0.ai/open-memory/introduction) - [MCP Protocol Spec](https://github.com/mem0ai/mem0/tree/main/openmemory) -- [Friend-Lite Memory Docs](../../backends/advanced/MEMORY_PROVIDERS.md) \ No newline at end of file +- [Chronicle Memory Docs](../../backends/advanced/MEMORY_PROVIDERS.md) \ No newline at end of file diff --git a/extras/openmemory-mcp/run.sh b/extras/openmemory-mcp/run.sh index 1cc0bf21..1092207a 100755 --- a/extras/openmemory-mcp/run.sh +++ b/extras/openmemory-mcp/run.sh @@ -2,7 +2,7 @@ set -e -echo "๐Ÿš€ Starting OpenMemory MCP installation for Friend-Lite..." +echo "๐Ÿš€ Starting OpenMemory MCP installation for Chronicle..." # Set environment variables OPENAI_API_KEY="${OPENAI_API_KEY:-}" @@ -64,9 +64,9 @@ if docker ps | grep -q openmemory-mcp; then curl -s http://localhost:8765/openapi.json | jq '.paths | keys[]' fi echo "" - echo "๐Ÿ“š Integration with Friend-Lite:" - echo " Set MEMORY_PROVIDER=openmemory_mcp in your Friend-Lite .env" - echo " Set OPENMEMORY_MCP_URL=http://localhost:8765 in your Friend-Lite .env" + echo "๐Ÿ“š Integration with Chronicle:" + echo " Set MEMORY_PROVIDER=openmemory_mcp in your Chronicle .env" + echo " Set OPENMEMORY_MCP_URL=http://localhost:8765 in your Chronicle .env" echo "" echo "๐Ÿ” Check logs: docker compose logs -f" echo "๐Ÿ›‘ Stop services: docker compose down" diff --git a/extras/openmemory-mcp/test_standalone.py b/extras/openmemory-mcp/test_standalone.py index 58f011a4..08720f4e 100755 --- a/extras/openmemory-mcp/test_standalone.py +++ b/extras/openmemory-mcp/test_standalone.py @@ -2,7 +2,7 @@ """Standalone test script for OpenMemory MCP server. This script tests the OpenMemory MCP server directly using its REST API, -without any dependencies on Friend-Lite backend code. +without any dependencies on Chronicle backend code. """ import asyncio diff --git a/extras/speaker-omni-experimental/README.md b/extras/speaker-omni-experimental/README.md index 0f0d34c7..5c7e3a30 100644 --- a/extras/speaker-omni-experimental/README.md +++ b/extras/speaker-omni-experimental/README.md @@ -355,7 +355,7 @@ Approximate processing times (7B model on RTX 4090): ## ๐Ÿ”ฎ Integration Path -This experimental system can be integrated with the existing Friend-Lite backend: +This experimental system can be integrated with the existing Chronicle backend: 1. **Standalone Testing**: Use this directory for initial family testing 2. **API Wrapper**: Create FastAPI endpoint similar to traditional speaker service @@ -372,7 +372,7 @@ This experimental system can be integrated with the existing Friend-Lite backend ## ๐Ÿ”— Related Files - `../speaker-recognition/`: Traditional PyAnnote-based system -- `../../backends/advanced-backend/`: Main Friend-Lite backend +- `../../backends/advanced-backend/`: Main Chronicle backend - `../../extras/test-audios/`: Sample audio files for testing ## ๐Ÿ“ Development Notes @@ -394,4 +394,4 @@ This is an experimental system. Feedback and improvements welcome: ## ๐Ÿ“„ License -Part of the Friend-Lite project. See main repository license. \ No newline at end of file +Part of the Chronicle project. See main repository license. \ No newline at end of file diff --git a/extras/speaker-recognition/charts/templates/speaker-deployment.yaml b/extras/speaker-recognition/charts/templates/speaker-deployment.yaml index 94417297..d77f6204 100644 --- a/extras/speaker-recognition/charts/templates/speaker-deployment.yaml +++ b/extras/speaker-recognition/charts/templates/speaker-deployment.yaml @@ -34,7 +34,7 @@ spec: protocol: TCP envFrom: - configMapRef: - name: friend-lite-config + name: chronicle-config - secretRef: name: {{ .Values.secrets.name | default (printf "%s-secrets" .Release.Name) }} env: diff --git a/extras/speaker-recognition/charts/templates/webui-deployment.yaml b/extras/speaker-recognition/charts/templates/webui-deployment.yaml index aca7f872..ab8ba3e5 100644 --- a/extras/speaker-recognition/charts/templates/webui-deployment.yaml +++ b/extras/speaker-recognition/charts/templates/webui-deployment.yaml @@ -28,9 +28,9 @@ spec: protocol: TCP envFrom: - configMapRef: - name: friend-lite-config + name: chronicle-config - secretRef: - name: friend-lite-secrets + name: chronicle-secrets env: {{- range $key, $value := .Values.webui.env }} - name: {{ $key }} diff --git a/extras/speaker-recognition/charts/values.yaml b/extras/speaker-recognition/charts/values.yaml index a1ea8f34..afccf104 100644 --- a/extras/speaker-recognition/charts/values.yaml +++ b/extras/speaker-recognition/charts/values.yaml @@ -94,6 +94,6 @@ secrets: hfToken: "" deepgramApiKey: "" # Fixed secret name to prevent regeneration - uses existing secret from Makefile - name: "friend-lite-secrets" + name: "chronicle-secrets" # Don't create the secret, use existing one from Makefile create: false \ No newline at end of file diff --git a/extras/speaker-recognition/init.py b/extras/speaker-recognition/init.py index 8d1dd547..8267e35b 100755 --- a/extras/speaker-recognition/init.py +++ b/extras/speaker-recognition/init.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -Friend-Lite Speaker Recognition Setup Script +Chronicle Speaker Recognition Setup Script Interactive configuration for speaker recognition service """ diff --git a/extras/speaker-recognition/quickstart.md b/extras/speaker-recognition/quickstart.md index c594069a..47a99f56 100644 --- a/extras/speaker-recognition/quickstart.md +++ b/extras/speaker-recognition/quickstart.md @@ -47,7 +47,7 @@ docker compose up --build -d **Important**: Accept the SSL certificate warning when prompted. Self-signed certificates are used for local development. -**Note**: Speaker Recognition runs on port 8444 (HTTPS) and 8081 (HTTP) to avoid conflicts with the main Friend-Lite backend which uses the standard ports 443/80. +**Note**: Speaker Recognition runs on port 8444 (HTTPS) and 8081 (HTTP) to avoid conflicts with the main Chronicle backend which uses the standard ports 443/80. **Need to customize other settings?** Copy `.env.template` to `.env` and modify: ```bash diff --git a/extras/speaker-recognition/src/simple_speaker_recognition/__init__.py b/extras/speaker-recognition/src/simple_speaker_recognition/__init__.py index bb656b8f..c2893e0f 100644 --- a/extras/speaker-recognition/src/simple_speaker_recognition/__init__.py +++ b/extras/speaker-recognition/src/simple_speaker_recognition/__init__.py @@ -18,7 +18,7 @@ """ __version__ = "0.1.0" -__author__ = "Friend-Lite Team" +__author__ = "Chronicle Team" # Import core classes for convenience from .core.audio_backend import AudioBackend diff --git a/extras/speaker-recognition/ssl/generate-ssl.sh b/extras/speaker-recognition/ssl/generate-ssl.sh index c1e832c5..6ef71bd8 100755 --- a/extras/speaker-recognition/ssl/generate-ssl.sh +++ b/extras/speaker-recognition/ssl/generate-ssl.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -# Generate self-signed SSL certificate for Friend-Lite Advanced Backend +# Generate self-signed SSL certificate for Chronicle Advanced Backend # Supports localhost, IP addresses, and domain names SERVER_ADDRESS="$1" diff --git a/extras/speaker-recognition/tests/test_speaker_service_integration.py b/extras/speaker-recognition/tests/test_speaker_service_integration.py index 5d8872da..58e55b61 100644 --- a/extras/speaker-recognition/tests/test_speaker_service_integration.py +++ b/extras/speaker-recognition/tests/test_speaker_service_integration.py @@ -34,7 +34,7 @@ CLEANUP_CONTAINERS = os.environ.get("CLEANUP_CONTAINERS", "true").lower() == "true" REBUILD = os.environ.get("REBUILD", "false").lower() == "true" -REPO_ROOT = Path(__file__).resolve().parents[3] # Go up to friend-lite root +REPO_ROOT = Path(__file__).resolve().parents[3] # Go up to chronicle root SPEAKER_DIR = REPO_ROOT / "extras" / "speaker-recognition" TEST_ASSETS_DIR = SPEAKER_DIR / "tests" / "assets" diff --git a/k8s-manifests/cross-namespace-rbac.yaml b/k8s-manifests/cross-namespace-rbac.yaml index 6beb54c6..632cbf2f 100644 --- a/k8s-manifests/cross-namespace-rbac.yaml +++ b/k8s-manifests/cross-namespace-rbac.yaml @@ -6,16 +6,16 @@ metadata: name: speech-config-reader namespace: speech --- -# Role in friend-lite namespace to read ConfigMap/Secret +# Role in chronicle namespace to read ConfigMap/Secret apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: config-reader - namespace: friend-lite + namespace: chronicle rules: - apiGroups: [""] resources: ["configmaps", "secrets"] - resourceNames: ["friend-lite-config", "friend-lite-secrets"] + resourceNames: ["chronicle-config", "chronicle-secrets"] verbs: ["get", "list"] --- # RoleBinding to allow speech service account to read config @@ -23,7 +23,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: speech-config-access - namespace: friend-lite + namespace: chronicle subjects: - kind: ServiceAccount name: speech-config-reader diff --git a/quickstart.md b/quickstart.md index 8d7897f2..2f77e3fc 100644 --- a/quickstart.md +++ b/quickstart.md @@ -1,10 +1,10 @@ -# Friend-Lite Quick Start +# Chronicle Quick Start ## What You're Building (Complete Beginners Start Here!) You're setting up your own personal AI that: - **Runs on your home computer** - processes audio, stores memories, runs AI models -- **Connects to your phone** - where you use the Friend-Lite app and OMI device +- **Connects to your phone** - where you use the Chronicle app and OMI device - **Works everywhere** - your phone can access your home AI from anywhere Think of it like having Siri/Alexa, but it's **your own AI** running on **your hardware** with **your data**. @@ -13,12 +13,12 @@ Think of it like having Siri/Alexa, but it's **your own AI** running on **your h ### On Your Home Computer - **Docker** - Runs all the AI services (like having multiple apps in containers) -- **Friend-Lite Backend** - The main AI brain (transcription, memory, processing) +- **Chronicle Backend** - The main AI brain (transcription, memory, processing) - **Tailscale** - Creates secure tunnel so your phone can reach home ### On Your Phone - **Tailscale** - Connects securely to your home computer -- **Friend-Lite Mobile App** - Interface for your OMI device and conversations +- **Chronicle Mobile App** - Interface for your OMI device and conversations ### AI Services (Choose Your Path) @@ -101,14 +101,14 @@ The setup wizard will automatically download and configure: *Note: First-time setup will download AI models (this can take time and storage space)* -## Step 3: Download and Setup Friend-Lite +## Step 3: Download and Setup Chronicle ### On Your Home Computer **Download the code:** ```bash -git clone --recursive https://github.com/AnkushMalaker/friend-lite.git -cd friend-lite +git clone https://github.com/chronicle-ai/chronicle.git +cd chronicle ``` *The `--recursive` flag downloads the Mycelia submodule (see note below)* @@ -207,26 +207,26 @@ Before connecting your phone, make sure everything works: *Your browser will warn about "unsafe certificate" - click "Advanced" โ†’ "Proceed anyway"* -2. You should see the Friend-Lite dashboard +2. You should see the Chronicle dashboard 3. Click "Live Recording" in the sidebar 4. Test your microphone - record a short clip 5. Check that it gets transcribed and appears in "Conversations" 6. **Only proceed to phone setup when this works perfectly!** -## Step 5: Install Friend-Lite on Your Phone +## Step 5: Install Chronicle on Your Phone **No development setup needed - just download and install!** ### Android Users -1. Go to [GitHub Releases](https://github.com/AnkushMalaker/friend-lite/releases) -2. Find the latest release and download `friend-lite-android.apk` +1. Go to [GitHub Releases](https://github.com/AnkushMalaker/chronicle/releases) +2. Find the latest release and download `chronicle-android.apk` 3. Install APK on your phone: - Enable "Install from unknown sources" in Android settings - Tap the downloaded APK file to install ### iPhone Users -1. Go to [GitHub Releases](https://github.com/AnkushMalaker/friend-lite/releases) -2. Find the latest release and download `friend-lite-ios.ipa` +1. Go to [GitHub Releases](https://github.com/AnkushMalaker/chronicle/releases) +2. Find the latest release and download `chronicle-ios.ipa` 3. Install using sideloading tool: - **AltStore** (recommended): [altstore.io](https://altstore.io) - **Sideloadly**: [sideloadly.io](https://sideloadly.io) @@ -235,7 +235,7 @@ Before connecting your phone, make sure everything works: ### Configure the App 1. **First**: Make sure Tailscale is running on your phone -2. Open Friend-Lite app +2. Open Chronicle app 3. Go to Settings โ†’ Backend Configuration 4. Enter Backend URL: `https://[your-tailscale-ip]` @@ -250,7 +250,7 @@ Before connecting your phone, make sure everything works: ## Step 6: Connect Your OMI Device 1. Turn on your OMI/Friend device (make sure it's charged) -2. Open Friend-Lite app on your phone +2. Open Chronicle app on your phone 3. Go to "Devices" tab โ†’ "Add New Device" 4. Follow Bluetooth pairing instructions 5. Once connected, start a conversation! diff --git a/run-test.sh b/run-test.sh index fce082e5..ebc39a07 100755 --- a/run-test.sh +++ b/run-test.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Friend-Lite Local Test Runner +# Chronicle Local Test Runner # Runs the same tests as GitHub CI but configured for local development # Usage: ./run-test.sh [advanced-backend|speaker-recognition|all] @@ -63,12 +63,12 @@ run_speaker_recognition_tests() { } # Main execution -print_info "Friend-Lite Local Test Runner" +print_info "Chronicle Local Test Runner" print_info "==============================" # Check if we're in the right directory if [ ! -f "CLAUDE.md" ]; then - print_error "Please run this script from the friend-lite root directory" + print_error "Please run this script from the chronicle root directory" exit 1 fi diff --git a/scripts/generate-k8s-configs.py b/scripts/generate-k8s-configs.py index 9b800fff..2eea45aa 100755 --- a/scripts/generate-k8s-configs.py +++ b/scripts/generate-k8s-configs.py @@ -12,7 +12,7 @@ from env_utils import get_resolved_env_vars, classify_secrets -def generate_k8s_manifests(namespace: str = "friend-lite"): +def generate_k8s_manifests(namespace: str = "chronicle"): """Generate Kubernetes ConfigMap and Secret manifests""" print(f"Generating Kubernetes ConfigMap and Secret for namespace {namespace}...") @@ -30,10 +30,10 @@ def generate_k8s_manifests(namespace: str = "friend-lite"): f.write("apiVersion: v1\n") f.write("kind: ConfigMap\n") f.write("metadata:\n") - f.write(f" name: friend-lite-config\n") + f.write(f" name: chronicle-config\n") f.write(f" namespace: {namespace}\n") f.write(" labels:\n") - f.write(" app.kubernetes.io/name: friend-lite\n") + f.write(" app.kubernetes.io/name: chronicle\n") f.write(" app.kubernetes.io/component: config\n") f.write("data:\n") @@ -50,10 +50,10 @@ def generate_k8s_manifests(namespace: str = "friend-lite"): f.write("kind: Secret\n") f.write("type: Opaque\n") f.write("metadata:\n") - f.write(f" name: friend-lite-secrets\n") + f.write(f" name: chronicle-secrets\n") f.write(f" namespace: {namespace}\n") f.write(" labels:\n") - f.write(" app.kubernetes.io/name: friend-lite\n") + f.write(" app.kubernetes.io/name: chronicle\n") f.write(" app.kubernetes.io/component: secrets\n") f.write("data:\n") @@ -74,7 +74,7 @@ def generate_k8s_manifests(namespace: str = "friend-lite"): def main(): """Main entry point""" - namespace = sys.argv[1] if len(sys.argv) > 1 else "friend-lite" + namespace = sys.argv[1] if len(sys.argv) > 1 else "chronicle" generate_k8s_manifests(namespace) if __name__ == "__main__": diff --git a/scripts/k8s/cluster-status.sh b/scripts/k8s/cluster-status.sh index 9733066f..8f3cb644 100644 --- a/scripts/k8s/cluster-status.sh +++ b/scripts/k8s/cluster-status.sh @@ -5,7 +5,7 @@ # # Usage: ./scripts/cluster-status.sh [namespace] # Example: ./scripts/cluster-status.sh -# Example: ./scripts/cluster-status.sh friend-lite +# Example: ./scripts/cluster-status.sh chronicle set -e diff --git a/scripts/k8s/load-env.sh b/scripts/k8s/load-env.sh index 97f873eb..a9ab113f 100644 --- a/scripts/k8s/load-env.sh +++ b/scripts/k8s/load-env.sh @@ -31,7 +31,7 @@ load_config_env() { export SPEAKER_NODE="${SPEAKER_NODE:-}" export CONTAINER_REGISTRY="${CONTAINER_REGISTRY:-localhost:32000}" export INFRASTRUCTURE_NAMESPACE="${INFRASTRUCTURE_NAMESPACE:-root}" - export APPLICATION_NAMESPACE="${APPLICATION_NAMESPACE:-friend-lite}" + export APPLICATION_NAMESPACE="${APPLICATION_NAMESPACE:-chronicle}" export STORAGE_CLASS="${STORAGE_CLASS:-openebs-hostpath}" } diff --git a/scripts/manage-audio-files.sh b/scripts/manage-audio-files.sh index 981d38cf..f02547f1 100755 --- a/scripts/manage-audio-files.sh +++ b/scripts/manage-audio-files.sh @@ -5,7 +5,7 @@ set -e -NAMESPACE="friend-lite" +NAMESPACE="chronicle" POD_NAME="" AUDIO_CHUNKS_DIR="/app/data/audio_chunks" DATA_DIR="/app/data" diff --git a/services.py b/services.py index a3d734d4..ba5fed2f 100755 --- a/services.py +++ b/services.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -Friend-Lite Service Management +Chronicle Service Management Start, stop, and manage configured services """ @@ -265,7 +265,7 @@ def show_status(): console.print("\n๐Ÿ’ก [dim]Use 'python services.py start --all' to start all configured services[/dim]") def main(): - parser = argparse.ArgumentParser(description="Friend-Lite Service Management") + parser = argparse.ArgumentParser(description="Chronicle Service Management") subparsers = parser.add_subparsers(dest='command', help='Available commands') # Start command diff --git a/skaffold.yaml b/skaffold.yaml index f40d4407..279566ce 100644 --- a/skaffold.yaml +++ b/skaffold.yaml @@ -1,7 +1,7 @@ apiVersion: skaffold/v4beta13 kind: Config metadata: - name: friend-lite + name: chronicle build: tagPolicy: dateTime: @@ -149,7 +149,7 @@ profiles: image.repository: "{{.IMAGE_REPO_advanced_backend}}" image.tag: "{{.IMAGE_TAG_advanced_backend}}" # Override specific Kubernetes-specific values (not in env file) - env.MONGODB_URI: "mongodb://mongodb.{{.INFRASTRUCTURE_NAMESPACE}}.svc.cluster.local:27017/friend-lite" + env.MONGODB_URI: "mongodb://mongodb.{{.INFRASTRUCTURE_NAMESPACE}}.svc.cluster.local:27017/chronicle" env.QDRANT_BASE_URL: "qdrant.{{.INFRASTRUCTURE_NAMESPACE}}.svc.cluster.local" env.REDIS_URL: "redis://redis-master.{{.INFRASTRUCTURE_NAMESPACE}}.svc.cluster.local:6379/0" persistence.storageClass: "openebs-hostpath" diff --git a/status.py b/status.py index 1ae9a353..babf6cb7 100644 --- a/status.py +++ b/status.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -Friend-Lite Health Status Checker +Chronicle Health Status Checker Show runtime health status of all services """ @@ -162,7 +162,7 @@ def get_service_health(service_name: str) -> Dict[str, Any]: def show_quick_status(): """Show quick status overview""" - console.print("\n๐Ÿฅ [bold]Friend-Lite Health Status[/bold]\n") + console.print("\n๐Ÿฅ [bold]Chronicle Health Status[/bold]\n") table = Table(title="Service Status Overview") table.add_column("Service", style="cyan", no_wrap=True) @@ -215,7 +215,7 @@ def show_quick_status(): def show_detailed_status(): """Show detailed status with backend health breakdown""" - console.print("\n๐Ÿฅ [bold]Friend-Lite Detailed Health Status[/bold]\n") + console.print("\n๐Ÿฅ [bold]Chronicle Detailed Health Status[/bold]\n") # Get all service statuses for service_name, service_info in SERVICES.items(): @@ -320,7 +320,7 @@ def show_json_status(): def main(): parser = argparse.ArgumentParser( - description="Friend-Lite Health Status Checker", + description="Chronicle Health Status Checker", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: diff --git a/tests/.env.test b/tests/.env.test index 4317e347..974dcee2 100644 --- a/tests/.env.test +++ b/tests/.env.test @@ -11,4 +11,14 @@ ADMIN_PASSWORD=test-admin-password-123 # Test configuration TEST_TIMEOUT=120 -TEST_DEVICE_NAME=robot-test \ No newline at end of file +TEST_DEVICE_NAME=robot-test + +MEMORY_PROVIDER=chronicle + +# Docker container names (test environment) +BACKEND_CONTAINER=advanced-chronicle-backend-test-1 +WORKERS_CONTAINER=advanced-workers-test-1 +MONGO_CONTAINER=advanced-mongo-test-1 +REDIS_CONTAINER=advanced-redis-test-1 +QDRANT_CONTAINER=advanced-qdrant-test-1 +WEBUI_CONTAINER=advanced-webui-test-1 \ No newline at end of file diff --git a/tests/Makefile b/tests/Makefile index ac370508..707743e4 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,4 @@ -# Friend-Lite Test Makefile +# Chronicle Test Makefile # Shortcuts for running tests .PHONY: help all clean @@ -8,7 +8,7 @@ OUTPUTDIR ?= results TEST_DIR = endpoints integration infrastructure help: - @echo "Friend-Lite Test Targets:" + @echo "Chronicle Test Targets:" @echo "" @echo "Running Tests:" @echo " make all - Run all tests" diff --git a/tests/README.md b/tests/README.md index 1a6c7480..a16a0281 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,6 +1,6 @@ -# Friend-Lite API Tests +# Chronicle API Tests -Comprehensive Robot Framework test suite for the Friend-Lite advanced backend API endpoints. +Comprehensive Robot Framework test suite for the Chronicle advanced backend API endpoints. ## Quick Start @@ -87,7 +87,7 @@ If you already have the backend running, you can use the Makefile directly: ## Running Tests ### Prerequisites -1. Friend-Lite backend running at `http://localhost:8001` (or set `API_URL` in `.env`) +1. Chronicle backend running at `http://localhost:8001` (or set `API_URL` in `.env`) 2. Admin user credentials configured in `.env` 3. Robot Framework and RequestsLibrary installed diff --git a/tests/TESTING_USER_GUIDE.md b/tests/TESTING_USER_GUIDE.md index e2b3b8ad..d1ebbd9d 100644 --- a/tests/TESTING_USER_GUIDE.md +++ b/tests/TESTING_USER_GUIDE.md @@ -1,6 +1,6 @@ # Robot Framework Testing User Guide -A beginner-friendly guide to setting up VSCode for Robot Framework testing, running tests, and creating new tests for the Friend-Lite project. +A beginner-friendly guide to setting up VSCode for Robot Framework testing, running tests, and creating new tests for the Chronicle project. ## Table of Contents - [VSCode Setup](#vscode-setup) diff --git a/tests/browser/browser_auth.robot b/tests/browser/browser_auth.robot index 430f9fcc..90820c71 100644 --- a/tests/browser/browser_auth.robot +++ b/tests/browser/browser_auth.robot @@ -25,7 +25,7 @@ Test Browser Can Access Login Page Fill Text id=password ${ADMIN_PASSWORD} Click button[type="submit"] # Verify that we are logged in by checking for the presence of the dashboard - Get Element text=Friend-Lite Dashboard + Get Element text=Chronicle Dashboard Log Successfully accessed login page and logged in INFO diff --git a/tests/infrastructure/infra_tests.robot b/tests/infrastructure/infra_tests.robot index f5429988..48b1a057 100644 --- a/tests/infrastructure/infra_tests.robot +++ b/tests/infrastructure/infra_tests.robot @@ -262,7 +262,8 @@ WebSocket Disconnect Conversation End Reason Test Send Audio Chunks To Stream ${stream_id} ${TEST_AUDIO_FILE} num_chunks=200 # Wait for conversation job to be created and conversation_id to be populated - ${conv_jobs}= Wait Until Keyword Succeeds 30s 2s + # Transcription + speech analysis takes time (30-60s with queue) + ${conv_jobs}= Wait Until Keyword Succeeds 60s 3s ... Job Type Exists For Client open_conversation ${device_name} # Wait for conversation_id in job meta (created asynchronously) @@ -287,3 +288,4 @@ WebSocket Disconnect Conversation End Reason Test Should Not Be Equal ${conversation}[completed_at] ${None} [Teardown] Run Keyword And Ignore Error Close Audio Stream ${stream_id} + diff --git a/tests/libs/audio_stream_library.py b/tests/libs/audio_stream_library.py index 7c2ddcee..25399175 100644 --- a/tests/libs/audio_stream_library.py +++ b/tests/libs/audio_stream_library.py @@ -103,6 +103,34 @@ def send_audio_chunks( ) +def send_audio_stop_event(stream_id: str) -> None: + """Send audio-stop event without closing the WebSocket connection. + + This is used to test the user_stopped end_reason scenario where + the user manually stops recording but the connection remains open. + """ + session = _manager._sessions.get(stream_id) + if not session: + raise ValueError(f"Stream {stream_id} not found") + + import asyncio + + async def _send_stop(): + try: + await session.client.send_audio_stop() + session.audio_stopped = True + except Exception as e: + session.error = str(e) + raise + + # Run in the stream's event loop + future = asyncio.run_coroutine_threadsafe(_send_stop(), session.loop) + future.result(timeout=5) # Wait for audio-stop to be sent + + if session.error: + raise RuntimeError(f"Failed to send audio-stop: {session.error}") + + def stop_audio_stream(stream_id: str) -> int: """Stop an audio stream and close the connection.""" return _manager.stop_stream(stream_id) diff --git a/tests/resources/websocket_keywords.robot b/tests/resources/websocket_keywords.robot index 25b8499c..f1ee54b4 100644 --- a/tests/resources/websocket_keywords.robot +++ b/tests/resources/websocket_keywords.robot @@ -89,6 +89,15 @@ Send Audio Chunks To Stream Log Sent ${chunks_sent} chunks to stream ${stream_id} RETURN ${chunks_sent} +Send Audio Stop Event + [Documentation] Send audio-stop event without closing the WebSocket + ... This simulates a user manually stopping recording + [Arguments] ${stream_id} + + # Call the Python library method directly + Send Audio Stop Event ${stream_id} + Log Sent audio-stop event to stream ${stream_id} + Close Audio Stream [Documentation] Stop an audio stream and close the connection [Arguments] ${stream_id} diff --git a/tests/setup/setup_keywords.robot b/tests/setup/setup_keywords.robot index e3809c1c..3fe7bd17 100644 --- a/tests/setup/setup_keywords.robot +++ b/tests/setup/setup_keywords.robot @@ -106,7 +106,7 @@ Start Docker Services # Clean up any stopped/stuck containers first Run Process docker compose -f ${compose_file} down -v cwd=${working_dir} shell=True - Run Process docker rm -f advanced-mongo-test-1 advanced-redis-test-1 advanced-qdrant-test-1 advanced-friend-backend-test-1 advanced-workers-test-1 shell=True + Run Process docker rm -f ${MONGO_CONTAINER} ${REDIS_CONTAINER} ${QDRANT_CONTAINER} ${BACKEND_CONTAINER} ${WORKERS_CONTAINER} ${WEBUI_CONTAINER} shell=True # Start containers IF ${build} diff --git a/tests/setup/test_env.py b/tests/setup/test_env.py index a333f476..51589fd2 100644 --- a/tests/setup/test_env.py +++ b/tests/setup/test_env.py @@ -69,4 +69,4 @@ REDIS_CONTAINER = f"{COMPOSE_PROJECT_NAME}-redis-test-1" BACKEND_CONTAINER = f"{COMPOSE_PROJECT_NAME}-friend-backend-test-1" MONGO_CONTAINER = f"{COMPOSE_PROJECT_NAME}-mongo-test-1" -QDRANT_CONTAINER = f"{COMPOSE_PROJECT_NAME}-qdrant-test-1" \ No newline at end of file +QDRANT_CONTAINER = f"{COMPOSE_PROJECT_NAME}-qdrant-test-1" diff --git a/tests/setup/test_manager_keywords.robot b/tests/setup/test_manager_keywords.robot index a7ad5783..65506551 100644 --- a/tests/setup/test_manager_keywords.robot +++ b/tests/setup/test_manager_keywords.robot @@ -34,14 +34,16 @@ Clear Test Databases Log To Console Clearing test databases and audio files... # Clear MongoDB collections but preserve admin user and fixtures - Run Process docker exec advanced-mongo-test-1 mongosh test_db --eval "db.users.deleteMany({'email': {\\$ne:'${ADMIN_EMAIL}'}})" shell=True + Run Process docker exec ${MONGO_CONTAINER} mongosh test_db --eval "db.users.deleteMany({'email': {\\$ne:'${ADMIN_EMAIL}'}})" shell=True - # Clear conversations and audio_chunks except those tagged as fixtures - Run Process docker exec advanced-mongo-test-1 mongosh test_db --eval "db.conversations.deleteMany({\\$or: [{'is_fixture': {\\$exists: false}}, {'is_fixture': false}]})" shell=True - Run Process docker exec advanced-mongo-test-1 mongosh test_db --eval "db.audio_chunks.deleteMany({\\$or: [{'is_fixture': {\\$exists: false}}, {'is_fixture': false}]})" shell=True + # Clear conversations except those tagged as fixtures + Run Process docker exec ${MONGO_CONTAINER} mongosh test_db --eval "db.conversations.deleteMany({\\$or: [{'is_fixture': {\\$exists: false}}, {'is_fixture': false}]})" shell=True + + # Clear job references from remaining conversations to prevent "No such job" errors + Run Process docker exec ${MONGO_CONTAINER} mongosh test_db --eval "db.conversations.updateMany({}, {\\$unset: {'transcription_job_id': '', 'speaker_job_id': '', 'memory_job_id': ''}})" shell=True # Count fixtures for logging - ${result}= Run Process docker exec advanced-mongo-test-1 mongosh test_db --eval "db.conversations.countDocuments({'is_fixture': true})" --quiet shell=True + ${result}= Run Process docker exec ${MONGO_CONTAINER} mongosh test_db --eval "db.conversations.countDocuments({'is_fixture': true})" --quiet shell=True ${fixture_count}= Strip String ${result.stdout} IF '${fixture_count}' != '0' @@ -51,7 +53,7 @@ Clear Test Databases END # Clear admin user's registered_clients dict to prevent client_id counter increments - Run Process docker exec advanced-mongo-test-1 mongosh test_db --eval "db.users.updateOne({'email':'${ADMIN_EMAIL}'}, {\\$set: {'registered_clients': {}}})" shell=True + Run Process docker exec ${MONGO_CONTAINER} mongosh test_db --eval "db.users.updateOne({'email':'${ADMIN_EMAIL}'}, {\\$set: {'registered_clients': {}}})" shell=True # Clear Qdrant collections # Note: Fixture memories will be lost here unless we implement Qdrant metadata filtering @@ -65,13 +67,13 @@ Clear Test Databases Log To Console Audio files cleared (fixtures/ subfolder preserved) # Clear container audio files (except fixtures subfolder) - Run Process bash -c docker exec advanced-friend-backend-test-1 find /app/audio_chunks -maxdepth 1 -name "*.wav" -delete || true shell=True - Run Process bash -c docker exec advanced-friend-backend-test-1 find /app/debug_dir -name "*" -type f -delete || true shell=True + Run Process bash -c docker exec ${BACKEND_CONTAINER} find /app/audio_chunks -maxdepth 1 -name "*.wav" -delete || true shell=True + Run Process bash -c docker exec ${BACKEND_CONTAINER} find /app/debug_dir -name "*" -type f -delete || true shell=True # Clear Redis queues and job registries (preserve worker registrations, failed and completed jobs) # Delete all rq:* keys except worker registrations (rq:worker:*), failed jobs (rq:failed:*), and completed jobs (rq:finished:*) ${redis_clear_script}= Set Variable redis-cli --scan --pattern "rq:*" | grep -Ev "^rq:(worker|failed|finished)" | xargs -r redis-cli DEL; redis-cli --scan --pattern "audio:*" | xargs -r redis-cli DEL; redis-cli --scan --pattern "consumer:*" | xargs -r redis-cli DEL - Run Process docker exec advanced-redis-test-1 sh -c ${redis_clear_script} shell=True + Run Process docker exec ${REDIS_CONTAINER} sh -c ${redis_clear_script} shell=True Log To Console Redis queues and job registries cleared (worker registrations preserved) Clear All Test Data @@ -79,9 +81,8 @@ Clear All Test Data Log To Console Clearing ALL test data including admin user and fixtures... # Wipe all MongoDB collections - Run Process docker exec advanced-mongo-test-1 mongosh test_db --eval "db.users.deleteMany({})" shell=True - Run Process docker exec advanced-mongo-test-1 mongosh test_db --eval "db.conversations.deleteMany({})" shell=True - Run Process docker exec advanced-mongo-test-1 mongosh test_db --eval "db.audio_chunks.deleteMany({})" shell=True + Run Process docker exec ${MONGO_CONTAINER} mongosh test_db --eval "db.users.deleteMany({})" shell=True + Run Process docker exec ${MONGO_CONTAINER} mongosh test_db --eval "db.conversations.deleteMany({})" shell=True Log To Console MongoDB completely cleared # Clear Qdrant @@ -93,7 +94,7 @@ Clear All Test Data Run Process bash -c rm -rf ${EXECDIR}/backends/advanced/data/test_debug_dir/* || true shell=True # Clear all Redis data - Run Process docker exec advanced-redis-test-1 redis-cli FLUSHALL shell=True + Run Process docker exec ${REDIS_CONTAINER} redis-cli FLUSHALL shell=True Log To Console All test data cleared @@ -125,13 +126,9 @@ Create Fixture Conversation Should Not Be Empty ${transcript} Fixture conversation has no transcript # Tag this conversation as a fixture in MongoDB so cleanup preserves it - ${result}= Run Process docker exec advanced-mongo-test-1 mongosh test_db --eval "db.conversations.updateOne({'conversation_id': '${conversation_id}'}, {\\$set: {'is_fixture': true}})" shell=True + ${result}= Run Process docker exec ${MONGO_CONTAINER} mongosh test_db --eval "db.conversations.updateOne({'conversation_id': '${conversation_id}'}, {\\$set: {'is_fixture': true}})" shell=True Should Be Equal As Integers ${result.rc} 0 Failed to tag conversation as fixture: ${result.stderr} - # Also tag audio_chunks - ${result2}= Run Process docker exec advanced-mongo-test-1 mongosh test_db --eval "db.audio_chunks.updateMany({'conversation_id': '${conversation_id}'}, {\\$set: {'is_fixture': true}})" shell=True - Should Be Equal As Integers ${result2.rc} 0 Failed to tag audio chunks as fixture: ${result2.stderr} - Log To Console โœ“ Audio files stored in fixtures/ subfolder ${transcript_len}= Get Length ${transcript} diff --git a/tests/tags.md b/tests/tags.md index e41874f5..6ddb6fba 100644 --- a/tests/tags.md +++ b/tests/tags.md @@ -1,10 +1,10 @@ # Robot Framework Test Tags Reference -This document defines the standard tags used across the Friend-Lite test suite. +This document defines the standard tags used across the Chronicle test suite. ## Simplified Tag Set -Friend-Lite uses a **minimal, focused tag set** for test organization. Only 11 tags are permitted. +Chronicle uses a **minimal, focused tag set** for test organization. Only 11 tags are permitted. ## Tag Format diff --git a/wizard.py b/wizard.py index 25ef890f..6e6ad6cb 100755 --- a/wizard.py +++ b/wizard.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -Friend-Lite Root Setup Orchestrator +Chronicle Root Setup Orchestrator Handles service selection and delegation only - no configuration duplication """ @@ -100,7 +100,7 @@ def check_service_exists(service_name, service_config): def select_services(): """Let user select which services to setup""" - console.print("๐Ÿš€ [bold cyan]Friend-Lite Service Setup[/bold cyan]") + console.print("๐Ÿš€ [bold cyan]Chronicle Service Setup[/bold cyan]") console.print("Select which services to configure:\n") selected = [] @@ -302,7 +302,7 @@ def setup_git_hooks(): def main(): """Main orchestration logic""" - console.print("๐ŸŽ‰ [bold green]Welcome to Friend-Lite![/bold green]\n") + console.print("๐ŸŽ‰ [bold green]Welcome to Chronicle![/bold green]\n") # Setup git hooks first setup_git_hooks() @@ -411,7 +411,7 @@ def main(): console.print("4. Stop services when done:") console.print(" [cyan]uv run --with-requirements setup-requirements.txt python services.py stop --all[/cyan]") - console.print(f"\n๐Ÿš€ [bold]Enjoy Friend-Lite![/bold]") + console.print(f"\n๐Ÿš€ [bold]Enjoy Chronicle![/bold]") # Show individual service usage console.print(f"\n๐Ÿ’ก [dim]Tip: You can also setup services individually:[/dim]") From 9439656430861ffcc2e8d9f5a280144e7871000e Mon Sep 17 00:00:00 2001 From: Stu Alexandere Date: Thu, 11 Dec 2025 14:18:28 +0000 Subject: [PATCH 2/3] changed mobile app package to friend-lite for the moment --- app/app.json | 10 +++++----- app/app/components/DeviceDetails.tsx | 2 +- app/app/components/DeviceListItem.tsx | 2 +- app/app/hooks/useAudioListener.ts | 2 +- app/app/hooks/useDeviceConnection.ts | 2 +- app/app/hooks/useDeviceScanning.ts | 2 +- app/app/index.tsx | 4 ++-- app/package.json | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/app.json b/app/app.json index c2446e12..66fbb8c2 100644 --- a/app/app.json +++ b/app/app.json @@ -1,7 +1,7 @@ { "expo": { - "name": "chronicle-app", - "slug": "chronicle-app", + "name": "friend-lite-app", + "slug": "friend-lite-app", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", @@ -17,9 +17,9 @@ ], "ios": { "supportsTablet": true, - "bundleIdentifier": "com.cupbearer5517.chronicle", + "bundleIdentifier": "com.cupbearer5517.friendlite", "infoPlist": { - "NSMicrophoneUsageDescription": "Chronicle needs access to your microphone to stream audio to the backend for processing." + "NSMicrophoneUsageDescription": "Friend Lite needs access to your microphone to stream audio to the backend for processing." } }, "android": { @@ -27,7 +27,7 @@ "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#ffffff" }, - "package": "com.cupbearer5517.chronicle", + "package": "com.cupbearer5517.friendlite", "permissions": [ "android.permission.BLUETOOTH", "android.permission.BLUETOOTH_ADMIN", diff --git a/app/app/components/DeviceDetails.tsx b/app/app/components/DeviceDetails.tsx index 3bd22b4a..ebf204c3 100644 --- a/app/app/components/DeviceDetails.tsx +++ b/app/app/components/DeviceDetails.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { View, Text, TouchableOpacity, StyleSheet, TextInput } from 'react-native'; -import { BleAudioCodec } from 'chronicle-react-native'; +import { BleAudioCodec } from 'friend-lite-react-native'; interface DeviceDetailsProps { // Device Info diff --git a/app/app/components/DeviceListItem.tsx b/app/app/components/DeviceListItem.tsx index 3da559de..a8083035 100644 --- a/app/app/components/DeviceListItem.tsx +++ b/app/app/components/DeviceListItem.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; -import { OmiDevice } from 'chronicle-react-native'; +import { OmiDevice } from 'friend-lite-react-native'; interface DeviceListItemProps { device: OmiDevice; diff --git a/app/app/hooks/useAudioListener.ts b/app/app/hooks/useAudioListener.ts index 1dcf225e..391ed125 100644 --- a/app/app/hooks/useAudioListener.ts +++ b/app/app/hooks/useAudioListener.ts @@ -1,6 +1,6 @@ import { useState, useRef, useCallback, useEffect } from 'react'; import { Alert } from 'react-native'; -import { OmiConnection } from 'chronicle-react-native'; +import { OmiConnection } from 'friend-lite-react-native'; import { Subscription, ConnectionPriority } from 'react-native-ble-plx'; // OmiConnection might use this type for subscriptions interface UseAudioListener { diff --git a/app/app/hooks/useDeviceConnection.ts b/app/app/hooks/useDeviceConnection.ts index 964e4d4e..e729169e 100644 --- a/app/app/hooks/useDeviceConnection.ts +++ b/app/app/hooks/useDeviceConnection.ts @@ -1,6 +1,6 @@ import { useState, useCallback } from 'react'; import { Alert } from 'react-native'; -import { OmiConnection, BleAudioCodec, OmiDevice } from 'chronicle-react-native'; +import { OmiConnection, BleAudioCodec, OmiDevice } from 'friend-lite-react-native'; interface UseDeviceConnection { connectedDevice: OmiDevice | null; diff --git a/app/app/hooks/useDeviceScanning.ts b/app/app/hooks/useDeviceScanning.ts index f4c16ff3..d7780266 100644 --- a/app/app/hooks/useDeviceScanning.ts +++ b/app/app/hooks/useDeviceScanning.ts @@ -1,6 +1,6 @@ import { useState, useEffect, useCallback, useRef } from 'react'; import { BleManager, State as BluetoothState } from 'react-native-ble-plx'; -import { OmiConnection, OmiDevice } from 'chronicle-react-native'; // Assuming this is the correct import for Omi types +import { OmiConnection, OmiDevice } from 'friend-lite-react-native'; // Assuming this is the correct import for Omi types interface UseDeviceScanning { devices: OmiDevice[]; diff --git a/app/app/index.tsx b/app/app/index.tsx index 2b20cb7b..8bb1234a 100644 --- a/app/app/index.tsx +++ b/app/app/index.tsx @@ -1,6 +1,6 @@ import React, { useRef, useCallback, useEffect, useState } from 'react'; import { StyleSheet, Text, View, SafeAreaView, ScrollView, Platform, FlatList, ActivityIndicator, Alert, Switch, Button, TouchableOpacity, KeyboardAvoidingView } from 'react-native'; -import { OmiConnection } from 'chronicle-react-native'; // OmiDevice also comes from here +import { OmiConnection } from 'friend-lite-react-native'; // OmiDevice also comes from here import { State as BluetoothState } from 'react-native-ble-plx'; // Import State from ble-plx // Hooks @@ -521,7 +521,7 @@ export default function App() { contentContainerStyle={styles.content} keyboardShouldPersistTaps="handled" > - Chronicle + Friend Lite {/* Backend Connection - moved to top */} Date: Thu, 11 Dec 2025 15:13:37 +0000 Subject: [PATCH 3/3] rabbit aI fixes --- backends/advanced/.env.template | 8 ++++---- .../src/advanced_omi_backend/models/conversation.py | 1 + .../src/advanced_omi_backend/services/memory/config.py | 8 +++++++- .../services/memory/service_factory.py | 4 +++- .../src/advanced_omi_backend/services/mycelia_sync.py | 2 +- backends/advanced/webui/package-lock.json | 8 ++++++++ 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/backends/advanced/.env.template b/backends/advanced/.env.template index 60d2c99e..e9f1e3bf 100644 --- a/backends/advanced/.env.template +++ b/backends/advanced/.env.template @@ -99,9 +99,9 @@ QDRANT_BASE_URL=qdrant # MEMORY PROVIDER CONFIGURATION # ======================================== -# Memory Provider: "friend_lite" (default), "openmemory_mcp", or "mycelia" +# Memory Provider: "chronicle" (default), "openmemory_mcp", or "mycelia" # -# Friend-Lite (default): In-house memory system with full control +# Chronicle (default): In-house memory system with full control # - Custom LLM-powered extraction with individual fact storage # - Smart deduplication and memory updates (ADD/UPDATE/DELETE) # - Direct Qdrant vector storage @@ -121,7 +121,7 @@ QDRANT_BASE_URL=qdrant # - Requires Mycelia server setup (extras/mycelia) # # See MEMORY_PROVIDERS.md for detailed comparison -MEMORY_PROVIDER=friend_lite +MEMORY_PROVIDER=chronicle # ---------------------------------------- # OpenMemory MCP Configuration @@ -131,7 +131,7 @@ MEMORY_PROVIDER=friend_lite # cd extras/openmemory-mcp && docker compose up -d # # OPENMEMORY_MCP_URL=http://host.docker.internal:8765 -# OPENMEMORY_CLIENT_NAME=friend_lite +# OPENMEMORY_CLIENT_NAME=chronicle # OPENMEMORY_USER_ID=openmemory # OPENMEMORY_TIMEOUT=30 diff --git a/backends/advanced/src/advanced_omi_backend/models/conversation.py b/backends/advanced/src/advanced_omi_backend/models/conversation.py index 87dc731a..01dd5d96 100644 --- a/backends/advanced/src/advanced_omi_backend/models/conversation.py +++ b/backends/advanced/src/advanced_omi_backend/models/conversation.py @@ -31,6 +31,7 @@ class MemoryProvider(str, Enum): CHRONICLE = "chronicle" OPENMEMORY_MCP = "openmemory_mcp" MYCELIA = "mycelia" + FRIEND_LITE = "friend_lite" # Legacy value class ConversationStatus(str, Enum): """Conversation processing status.""" diff --git a/backends/advanced/src/advanced_omi_backend/services/memory/config.py b/backends/advanced/src/advanced_omi_backend/services/memory/config.py index 7560d88f..f3943f29 100644 --- a/backends/advanced/src/advanced_omi_backend/services/memory/config.py +++ b/backends/advanced/src/advanced_omi_backend/services/memory/config.py @@ -146,9 +146,15 @@ def build_memory_config_from_env() -> MemoryConfig: try: # Determine memory provider memory_provider = os.getenv("MEMORY_PROVIDER", "chronicle").lower() + + # Map legacy provider names to current names + if memory_provider in ("friend-lite", "friend_lite"): + memory_logger.info(f"๐Ÿ”ง Mapping legacy provider '{memory_provider}' to 'chronicle'") + memory_provider = "chronicle" + if memory_provider not in [p.value for p in MemoryProvider]: raise ValueError(f"Unsupported memory provider: {memory_provider}") - + memory_provider_enum = MemoryProvider(memory_provider) # For OpenMemory MCP, configuration is much simpler diff --git a/backends/advanced/src/advanced_omi_backend/services/memory/service_factory.py b/backends/advanced/src/advanced_omi_backend/services/memory/service_factory.py index dc57dbe9..5607d8ff 100644 --- a/backends/advanced/src/advanced_omi_backend/services/memory/service_factory.py +++ b/backends/advanced/src/advanced_omi_backend/services/memory/service_factory.py @@ -156,7 +156,9 @@ def get_service_info() -> dict: # Try to determine provider from service type if "OpenMemoryMCP" in info["service_type"]: info["memory_provider"] = "openmemory_mcp" - elif "Chronicle" in info["service_type"] or "MemoryService" in info["service_type"]: + elif info["service_type"] == "ChronicleMemoryService": info["memory_provider"] = "chronicle" + elif info["service_type"] == "MyceliaMemoryService": + info["memory_provider"] = "mycelia" return info \ No newline at end of file diff --git a/backends/advanced/src/advanced_omi_backend/services/mycelia_sync.py b/backends/advanced/src/advanced_omi_backend/services/mycelia_sync.py index 84011068..87f3b944 100644 --- a/backends/advanced/src/advanced_omi_backend/services/mycelia_sync.py +++ b/backends/advanced/src/advanced_omi_backend/services/mycelia_sync.py @@ -235,7 +235,7 @@ async def sync_admin_on_startup(): logger.info("๐Ÿ”„ Starting Mycelia OAuth synchronization...") # Check if Mycelia sync is enabled - memory_provider = os.getenv("MEMORY_PROVIDER", "chronicle") + memory_provider = os.getenv("MEMORY_PROVIDER", "chronicle").lower() if memory_provider != "mycelia": logger.info("Mycelia sync skipped (MEMORY_PROVIDER != mycelia)") return diff --git a/backends/advanced/webui/package-lock.json b/backends/advanced/webui/package-lock.json index 4582a222..7cf02b1a 100644 --- a/backends/advanced/webui/package-lock.json +++ b/backends/advanced/webui/package-lock.json @@ -20,6 +20,7 @@ }, "devDependencies": { "@types/d3": "^7.4.3", + "@types/frappe-gantt": "^0.9.0", "@types/react": "^18.2.43", "@types/react-dom": "^18.2.17", "@types/react-vertical-timeline-component": "^3.3.6", @@ -1990,6 +1991,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/frappe-gantt": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@types/frappe-gantt/-/frappe-gantt-0.9.0.tgz", + "integrity": "sha512-n00ElvRvJ1/+HkJwt57yjnTtAM7FcH/pEV9LbRCy3+hR39TY6l0mQuy4o909uxvw97aCNhQjNh8J8xACKJ2G3w==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/geojson": { "version": "7946.0.16", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",