Merge branch 'main' into fix-logger
This commit is contained in:
commit
6f76044395
4 changed files with 122 additions and 200 deletions
|
|
@ -5,6 +5,7 @@ from config.settings import (
|
||||||
LANGFLOW_CHAT_FLOW_ID,
|
LANGFLOW_CHAT_FLOW_ID,
|
||||||
LANGFLOW_INGEST_FLOW_ID,
|
LANGFLOW_INGEST_FLOW_ID,
|
||||||
LANGFLOW_PUBLIC_URL,
|
LANGFLOW_PUBLIC_URL,
|
||||||
|
clients,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
@ -36,15 +37,9 @@ async def get_settings(request, session_manager):
|
||||||
# Fetch ingestion flow configuration to get actual component defaults
|
# Fetch ingestion flow configuration to get actual component defaults
|
||||||
if LANGFLOW_INGEST_FLOW_ID:
|
if LANGFLOW_INGEST_FLOW_ID:
|
||||||
try:
|
try:
|
||||||
from config.settings import generate_langflow_api_key
|
response = await clients.langflow_request(
|
||||||
import httpx
|
"GET",
|
||||||
|
f"/api/v1/flows/{LANGFLOW_INGEST_FLOW_ID}"
|
||||||
api_key = await generate_langflow_api_key()
|
|
||||||
if api_key:
|
|
||||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
|
||||||
response = await client.get(
|
|
||||||
f"{LANGFLOW_URL}/api/v1/flows/{LANGFLOW_INGEST_FLOW_ID}",
|
|
||||||
headers={"x-api-key": api_key},
|
|
||||||
)
|
)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
flow_data = response.json()
|
flow_data = response.json()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
from config.settings import NUDGES_FLOW_ID, LANGFLOW_URL, LANGFLOW_CHAT_FLOW_ID, LANGFLOW_INGEST_FLOW_ID
|
from config.settings import NUDGES_FLOW_ID, LANGFLOW_URL, LANGFLOW_CHAT_FLOW_ID, LANGFLOW_INGEST_FLOW_ID, clients
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import aiohttp
|
|
||||||
from utils.logging_config import get_logger
|
from utils.logging_config import get_logger
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
@ -71,23 +70,16 @@ class FlowsService:
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
raise ValueError(f"Invalid JSON in flow file {flow_file}: {e}")
|
raise ValueError(f"Invalid JSON in flow file {flow_file}: {e}")
|
||||||
|
|
||||||
# Get API key for Langflow
|
# Make PATCH request to Langflow API to update the flow using shared client
|
||||||
from config.settings import LANGFLOW_KEY
|
|
||||||
if not LANGFLOW_KEY:
|
|
||||||
raise ValueError("LANGFLOW_KEY is required for flow reset")
|
|
||||||
|
|
||||||
# Make PATCH request to Langflow API to update the flow
|
|
||||||
url = f"{LANGFLOW_URL}/api/v1/flows/{flow_id}"
|
|
||||||
headers = {
|
|
||||||
"x-api-key": LANGFLOW_KEY,
|
|
||||||
"Content-Type": "application/json"
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with aiohttp.ClientSession() as session:
|
response = await clients.langflow_request(
|
||||||
async with session.patch(url, json=flow_data, headers=headers) as response:
|
"PATCH",
|
||||||
if response.status == 200:
|
f"/api/v1/flows/{flow_id}",
|
||||||
result = await response.json()
|
json=flow_data
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
result = response.json()
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Successfully reset {flow_type} flow",
|
f"Successfully reset {flow_type} flow",
|
||||||
flow_id=flow_id,
|
flow_id=flow_id,
|
||||||
|
|
@ -100,25 +92,19 @@ class FlowsService:
|
||||||
"flow_type": flow_type
|
"flow_type": flow_type
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
error_text = await response.text()
|
error_text = response.text
|
||||||
logger.error(
|
logger.error(
|
||||||
f"Failed to reset {flow_type} flow",
|
f"Failed to reset {flow_type} flow",
|
||||||
status_code=response.status,
|
status_code=response.status_code,
|
||||||
error=error_text
|
error=error_text
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
"success": False,
|
"success": False,
|
||||||
"error": f"Failed to reset flow: HTTP {response.status} - {error_text}"
|
"error": f"Failed to reset flow: HTTP {response.status_code} - {error_text}"
|
||||||
}
|
|
||||||
except aiohttp.ClientError as e:
|
|
||||||
logger.error(f"Network error while resetting {flow_type} flow", error=str(e))
|
|
||||||
return {
|
|
||||||
"success": False,
|
|
||||||
"error": f"Network error: {str(e)}"
|
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Unexpected error while resetting {flow_type} flow", error=str(e))
|
logger.error(f"Error while resetting {flow_type} flow", error=str(e))
|
||||||
return {
|
return {
|
||||||
"success": False,
|
"success": False,
|
||||||
"error": f"Unexpected error: {str(e)}"
|
"error": f"Error: {str(e)}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,109 +1,50 @@
|
||||||
"""
|
"""
|
||||||
Langflow Message History Service
|
Langflow Message History Service
|
||||||
Simplified service that retrieves message history from Langflow using a single token
|
Simplified service that retrieves message history from Langflow using shared client infrastructure
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import httpx
|
|
||||||
from typing import List, Dict, Optional, Any
|
from typing import List, Dict, Optional, Any
|
||||||
|
|
||||||
from config.settings import LANGFLOW_URL, LANGFLOW_SUPERUSER, LANGFLOW_SUPERUSER_PASSWORD
|
from config.settings import clients
|
||||||
from utils.logging_config import get_logger
|
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
|
||||||
|
|
||||||
class LangflowHistoryService:
|
class LangflowHistoryService:
|
||||||
"""Simplified service to retrieve message history from Langflow"""
|
"""Simplified service to retrieve message history from Langflow"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.langflow_url = LANGFLOW_URL
|
pass
|
||||||
self.auth_token = None
|
|
||||||
|
|
||||||
async def _authenticate(self) -> Optional[str]:
|
|
||||||
"""Authenticate with Langflow and get access token"""
|
|
||||||
if self.auth_token:
|
|
||||||
return self.auth_token
|
|
||||||
|
|
||||||
if not all([LANGFLOW_SUPERUSER, LANGFLOW_SUPERUSER_PASSWORD]):
|
|
||||||
logger.error("Missing Langflow credentials")
|
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
|
||||||
login_data = {
|
|
||||||
"username": LANGFLOW_SUPERUSER,
|
|
||||||
"password": LANGFLOW_SUPERUSER_PASSWORD
|
|
||||||
}
|
|
||||||
|
|
||||||
async with httpx.AsyncClient() as client:
|
|
||||||
response = await client.post(
|
|
||||||
f"{self.langflow_url.rstrip('/')}/api/v1/login",
|
|
||||||
data=login_data,
|
|
||||||
headers={"Content-Type": "application/x-www-form-urlencoded"}
|
|
||||||
)
|
|
||||||
|
|
||||||
if response.status_code == 200:
|
|
||||||
result = response.json()
|
|
||||||
self.auth_token = result.get('access_token')
|
|
||||||
logger.debug(f"Successfully authenticated with Langflow for history retrieval")
|
|
||||||
return self.auth_token
|
|
||||||
else:
|
|
||||||
logger.error(f"Langflow authentication failed: {response.status_code}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Error authenticating with Langflow: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def get_user_sessions(self, user_id: str, flow_id: Optional[str] = None) -> List[str]:
|
async def get_user_sessions(self, user_id: str, flow_id: Optional[str] = None) -> List[str]:
|
||||||
"""Get all session IDs for a user's conversations
|
"""Get all session IDs for a user's conversations"""
|
||||||
|
|
||||||
Since we use one Langflow token, we get all sessions and filter by user_id locally
|
|
||||||
"""
|
|
||||||
token = await self._authenticate()
|
|
||||||
if not token:
|
|
||||||
return []
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
headers = {"Authorization": f"Bearer {token}"}
|
|
||||||
params = {}
|
params = {}
|
||||||
|
|
||||||
if flow_id:
|
if flow_id:
|
||||||
params["flow_id"] = flow_id
|
params["flow_id"] = flow_id
|
||||||
|
|
||||||
async with httpx.AsyncClient() as client:
|
response = await clients.langflow_request(
|
||||||
response = await client.get(
|
"GET",
|
||||||
f"{self.langflow_url.rstrip('/')}/api/v1/monitor/messages/sessions",
|
"/api/v1/monitor/messages/sessions",
|
||||||
headers=headers,
|
|
||||||
params=params
|
params=params
|
||||||
)
|
)
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
session_ids = response.json()
|
session_ids = response.json()
|
||||||
logger.debug(f"Found {len(session_ids)} total sessions from Langflow")
|
print(f"Found {len(session_ids)} total sessions from Langflow")
|
||||||
|
|
||||||
# Since we use a single Langflow instance, return all sessions
|
|
||||||
# Session filtering is handled by user_id at the application level
|
|
||||||
return session_ids
|
return session_ids
|
||||||
else:
|
else:
|
||||||
logger.error(f"Failed to get sessions: {response.status_code} - {response.text}")
|
print(f"Failed to get sessions: {response.status_code} - {response.text}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error getting user sessions: {e}")
|
print(f"Error getting user sessions: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
async def get_session_messages(self, user_id: str, session_id: str) -> List[Dict[str, Any]]:
|
async def get_session_messages(self, user_id: str, session_id: str) -> List[Dict[str, Any]]:
|
||||||
"""Get all messages for a specific session"""
|
"""Get all messages for a specific session"""
|
||||||
token = await self._authenticate()
|
|
||||||
if not token:
|
|
||||||
return []
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
headers = {"Authorization": f"Bearer {token}"}
|
response = await clients.langflow_request(
|
||||||
|
"GET",
|
||||||
async with httpx.AsyncClient() as client:
|
"/api/v1/monitor/messages",
|
||||||
response = await client.get(
|
|
||||||
f"{self.langflow_url.rstrip('/')}/api/v1/monitor/messages",
|
|
||||||
headers=headers,
|
|
||||||
params={
|
params={
|
||||||
"session_id": session_id,
|
"session_id": session_id,
|
||||||
"order_by": "timestamp"
|
"order_by": "timestamp"
|
||||||
|
|
@ -115,11 +56,11 @@ class LangflowHistoryService:
|
||||||
# Convert to OpenRAG format
|
# Convert to OpenRAG format
|
||||||
return self._convert_langflow_messages(messages)
|
return self._convert_langflow_messages(messages)
|
||||||
else:
|
else:
|
||||||
logger.error(f"Failed to get messages for session {session_id}: {response.status_code}")
|
print(f"Failed to get messages for session {session_id}: {response.status_code}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error getting session messages: {e}")
|
print(f"Error getting session messages: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def _convert_langflow_messages(self, langflow_messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
def _convert_langflow_messages(self, langflow_messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
||||||
|
|
@ -173,7 +114,7 @@ class LangflowHistoryService:
|
||||||
converted_messages.append(converted_msg)
|
converted_messages.append(converted_msg)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error converting message: {e}")
|
print(f"Error converting message: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return converted_messages
|
return converted_messages
|
||||||
|
|
@ -218,7 +159,7 @@ class LangflowHistoryService:
|
||||||
}
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error getting user conversation history: {e}")
|
print(f"Error getting user conversation history: {e}")
|
||||||
return {
|
return {
|
||||||
"error": str(e),
|
"error": str(e),
|
||||||
"conversations": []
|
"conversations": []
|
||||||
|
|
|
||||||
4
uv.lock
generated
4
uv.lock
generated
|
|
@ -1,5 +1,5 @@
|
||||||
version = 1
|
version = 1
|
||||||
revision = 3
|
revision = 2
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
resolution-markers = [
|
resolution-markers = [
|
||||||
"sys_platform == 'darwin'",
|
"sys_platform == 'darwin'",
|
||||||
|
|
@ -1405,7 +1405,7 @@ wheels = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openrag"
|
name = "openrag"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "agentd" },
|
{ name = "agentd" },
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue