Skip to content

Commit 0bc569a

Browse files
authored
Merge branch 'main' into stu/name-change
2 parents 21e2a5c + dededcd commit 0bc569a

19 files changed

Lines changed: 149 additions & 304 deletions

File tree

‎backends/advanced/docker-compose-ci.yml‎

Lines changed: 0 additions & 192 deletions
This file was deleted.

‎backends/advanced/docker-compose-test.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ services:
2424
# Import API keys from environment
2525
- DEEPGRAM_API_KEY=${DEEPGRAM_API_KEY}
2626
- OPENAI_API_KEY=${OPENAI_API_KEY}
27+
- OPENAI_BASE_URL=https://api.openai.com/v1
2728
# LLM provider configuration (required for memory service)
2829
- LLM_PROVIDER=${LLM_PROVIDER:-openai}
2930
- OPENAI_MODEL=${OPENAI_MODEL:-gpt-4o-mini}

‎backends/advanced/src/advanced_omi_backend/app_config.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ class AppConfig:
2828
def __init__(self):
2929
# MongoDB Configuration
3030
self.mongodb_uri = os.getenv("MONGODB_URI", "mongodb://mongo:27017")
31+
self.mongodb_database = os.getenv("MONGODB_DATABASE", "friend-lite")
3132
self.mongo_client = AsyncIOMotorClient(self.mongodb_uri)
32-
self.db = self.mongo_client.get_default_database("chronicle")
33+
self.db = self.mongo_client.get_default_database(self.mongodb_database)
3334
self.users_col = self.db["users"]
3435
self.speakers_col = self.db["speakers"]
3536

‎backends/advanced/src/advanced_omi_backend/database.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
# MongoDB Configuration
1616
MONGODB_URI = os.getenv("MONGODB_URI", "mongodb://mongo:27017")
17+
MONGODB_DATABASE = os.getenv("MONGODB_DATABASE", "friend-lite")
18+
1719
mongo_client = AsyncIOMotorClient(
1820
MONGODB_URI,
1921
maxPoolSize=50, # Increased pool size for concurrent operations
@@ -22,7 +24,7 @@
2224
serverSelectionTimeoutMS=5000, # Fail fast if server unavailable
2325
socketTimeoutMS=20000, # 20 second timeout for operations
2426
)
25-
db = mongo_client.get_default_database("chronicle")
27+
db = mongo_client.get_default_database(MONGODB_DATABASE)
2628

2729
# Collection references (for non-Beanie collections)
2830
users_col = db["users"]

‎backends/advanced/src/advanced_omi_backend/models/job.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,12 @@ async def _ensure_beanie_initialized():
4343
mongodb_uri = os.getenv("MONGODB_URI", "mongodb://localhost:27017")
4444

4545
# Create MongoDB client
46+
mongodb_database = os.getenv("MONGODB_DATABASE", "friend-lite")
4647
client = AsyncIOMotorClient(mongodb_uri)
4748
try:
48-
database = client.get_default_database("chronicle")
49+
database = client.get_default_database(mongodb_database)
4950
except ConfigurationError:
50-
database = client["chronicle"]
51+
database = client[mongodb_database]
5152
raise
5253
_beanie_initialized = True
5354
# Initialize Beanie

‎backends/advanced/src/advanced_omi_backend/services/memory/providers/mcp_client.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,20 @@ async def add_memories(self, text: str) -> List[str]:
111111

112112
# Use REST API endpoint for creating memories
113113
# The 'app' field can be either app name (string) or app UUID
114+
payload = {
115+
"user_id": self.user_id,
116+
"text": text,
117+
"app": self.client_name, # Use app name (OpenMemory accepts name or UUID)
118+
"metadata": {
119+
"source": "friend_lite",
120+
"client": self.client_name,
121+
"user_email": self.user_email
122+
},
123+
"infer": True
124+
}
125+
126+
memory_logger.info(f"POSTing memory to {self.server_url}/api/v1/memories/ with payload={payload}")
127+
114128
response = await self.client.post(
115129
f"{self.server_url}/api/v1/memories/",
116130
json={
@@ -125,6 +139,10 @@ async def add_memories(self, text: str) -> List[str]:
125139
"infer": True
126140
}
127141
)
142+
143+
response_body = response.text[:500] if response.status_code != 200 else "..."
144+
memory_logger.info(f"OpenMemory response: status={response.status_code}, body={response_body}, headers={dict(response.headers)}")
145+
128146
response.raise_for_status()
129147

130148
result = response.json()

‎backends/advanced/src/advanced_omi_backend/services/memory/providers/openmemory_mcp.py‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,21 @@ async def add_memory(
142142
memory_logger.info(f"Skipping empty transcript for {source_id}")
143143
return True, []
144144

145-
# Update MCP client user context for this operation
145+
# Pass Friend-Lite user details to OpenMemory for proper user tracking
146+
# OpenMemory will auto-create users if they don't exist
146147
original_user_id = self.mcp_client.user_id
147148
original_user_email = self.mcp_client.user_email
148-
self.mcp_client.user_id = user_id # Use the actual Chronicle user's ID
149-
self.mcp_client.user_email = user_email # Use the actual user's email
149+
150+
# Update MCP client with Friend-Lite user details
151+
self.mcp_client.user_id = user_id
152+
self.mcp_client.user_email = user_email
150153

151154
try:
152155
# Thin client approach: Send raw transcript to OpenMemory MCP server
153156
# OpenMemory handles: extraction, deduplication, vector storage, ACL
154157
enriched_transcript = f"[Source: {source_id}, Client: {client_id}] {transcript}"
155158

156-
memory_logger.info(f"Delegating memory processing to OpenMemory MCP for user {user_id}, source {source_id}")
159+
memory_logger.info(f"Delegating memory processing to OpenMemory for user {user_id} (email: {user_email}), source {source_id}")
157160
memory_ids = await self.mcp_client.add_memories(text=enriched_transcript)
158161

159162
finally:
@@ -204,7 +207,7 @@ async def search_memories(
204207
if not self._initialized:
205208
await self.initialize()
206209

207-
# Update MCP client user context for this operation
210+
# Update MCP client user context for this search operation
208211
original_user_id = self.mcp_client.user_id
209212
self.mcp_client.user_id = user_id # Use the actual Chronicle user's ID
210213

@@ -231,7 +234,7 @@ async def search_memories(
231234
memory_logger.error(f"Search memories failed: {e}")
232235
return []
233236
finally:
234-
# Restore original user_id
237+
# Restore original user context
235238
self.mcp_client.user_id = original_user_id
236239

237240
async def get_all_memories(

‎backends/advanced/webui/src/App.tsx‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ import { ErrorBoundary, PageErrorBoundary } from './components/ErrorBoundary'
1818

1919
function App() {
2020
console.log('🚀 Full App restored with working login!')
21-
21+
22+
// Get base path from Vite config (e.g., "/prod/" for path-based routing)
23+
const basename = import.meta.env.BASE_URL
24+
2225
return (
2326
<ErrorBoundary>
2427
<ThemeProvider>
2528
<AuthProvider>
26-
<Router future={{ v7_startTransition: true, v7_relativeSplatPath: true }}>
29+
<Router basename={basename} future={{ v7_startTransition: true, v7_relativeSplatPath: true }}>
2730
<Routes>
2831
<Route path="/login" element={<LoginPage />} />
2932
<Route path="/" element={

‎backends/advanced/webui/src/contexts/AuthContext.tsx‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createContext, useContext, useState, useEffect, ReactNode } from 'react'
22
import { authApi } from '../services/api'
3+
import { getStorageKey } from '../utils/storage'
34

45
interface User {
56
id: string
@@ -21,7 +22,7 @@ const AuthContext = createContext<AuthContextType | undefined>(undefined)
2122

2223
export function AuthProvider({ children }: { children: ReactNode }) {
2324
const [user, setUser] = useState<User | null>(null)
24-
const [token, setToken] = useState<string | null>(localStorage.getItem('token'))
25+
const [token, setToken] = useState<string | null>(localStorage.getItem(getStorageKey('token')))
2526
const [isLoading, setIsLoading] = useState(true)
2627

2728
// Check if user is admin
@@ -30,7 +31,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
3031
useEffect(() => {
3132
const initAuth = async () => {
3233
console.log('🔐 AuthContext: Initializing authentication...')
33-
const savedToken = localStorage.getItem('token')
34+
const savedToken = localStorage.getItem(getStorageKey('token'))
3435
console.log('🔐 AuthContext: Saved token exists:', !!savedToken)
3536

3637
if (savedToken) {
@@ -44,7 +45,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
4445
} catch (error) {
4546
console.error('❌ AuthContext: Token verification failed:', error)
4647
// Token is invalid, clear it
47-
localStorage.removeItem('token')
48+
localStorage.removeItem(getStorageKey('token'))
4849
setToken(null)
4950
setUser(null)
5051
}
@@ -64,9 +65,9 @@ export function AuthProvider({ children }: { children: ReactNode }) {
6465

6566
const { access_token } = response.data
6667
setToken(access_token)
67-
localStorage.setItem('token', access_token)
68+
localStorage.setItem(getStorageKey('token'), access_token)
6869
// Store JWT for Mycelia auto-login (enables seamless access to Mycelia frontend)
69-
localStorage.setItem('mycelia_jwt_token', access_token)
70+
localStorage.setItem(getStorageKey('mycelia_jwt_token'), access_token)
7071

7172
// Get user info
7273
const userResponse = await authApi.getMe()
@@ -100,8 +101,8 @@ export function AuthProvider({ children }: { children: ReactNode }) {
100101
const logout = () => {
101102
setUser(null)
102103
setToken(null)
103-
localStorage.removeItem('token')
104-
localStorage.removeItem('mycelia_jwt_token')
104+
localStorage.removeItem(getStorageKey('token'))
105+
localStorage.removeItem(getStorageKey('mycelia_jwt_token'))
105106
}
106107

107108
return (

0 commit comments

Comments
 (0)