fix(init): remove leftover conflict markers and duplicate code

Cleaned up 426 lines of dead code and unresolved conflict markers
(<<<<<<< HEAD, =======, >>>>>>>) left over from rebase.
File reduced from 1102 to 676 lines.
This commit is contained in:
yumoqing 2026-04-25 22:10:38 +08:00
parent e03d27edd9
commit 4df2f72758

View File

@ -18,437 +18,11 @@ from datetime import datetime
# Import sqlor database module # Import sqlor database module
from sqlor.dbpools import get_sor_context from sqlor.dbpools import get_sor_context
>>>>>>> f741c58 (feat(hermes-web-cli): refactor user context, settings, services and sessions management)
# Import database table definitions and CRUD operations # Import database table definitions and CRUD operations
from .db_tables import TABLE_DEFINITIONS from .db_tables import TABLE_DEFINITIONS
from .crud_ops import SERVICES_CRUD, SESSIONS_CRUD, SETTINGS_CRUD from .crud_ops import SERVICES_CRUD, SESSIONS_CRUD, SETTINGS_CRUD
def load_hermes_web_cli(): def load_hermes_web_cli():
<<<<<<< HEAD
"""Initialize and load the hermes-web-cli module.
This function is called by Sage system during module loading.
It registers all module functions with the ServerEnv instance
so they can be called directly from .ui and .dspy files.
"""
from ahserver.serverenv import ServerEnv
# Get the ServerEnv instance
env = ServerEnv()
# Register all module functions with ServerEnv
env.get_setting = get_setting
env.save_setting = save_setting
env.get_all_services = get_all_services
env.create_service = create_service
env.delete_service = delete_service
env.get_service_by_id = get_service_by_id
env.test_service_connection = test_service_connection
env.create_session = create_session
env.send_message_to_service = send_message_to_service
env.get_session_messages = get_session_messages
env.get_active_sessions = get_active_sessions
env.get_recent_sessions = get_recent_sessions
env.get_session_by_id = get_session_by_id
env.validate_service_url = validate_service_url
env.generate_session_id = generate_session_id
return True
# Database operations using sqlor-database-module
async def get_all_services_old(userid: str) -> List[Dict]:
"""Get all registered Hermes services for the current user from database."""
try:
# Query services table with user_id filter using sqlor-database-module
env = ServerEnv()
async with get_sor_context(env, 'hermes-web-cli') as sor:
sql_template = SERVICES_CRUD['operations']['read_all']['sql_template']
recs = await sor.sqlExe(sql_template, {'user_id': user_id})
# Convert datetime objects to ISO format strings for JSON serialization
result = []
for rec in recs:
service_dict = dict(rec)
if 'created_at' in service_dict and service_dict['created_at']:
service_dict['created_at'] = service_dict['created_at'].isoformat()
if 'updated_at' in service_dict and service_dict['updated_at']:
service_dict['updated_at'] = service_dict['updated_at'].isoformat()
result.append(service_dict)
return result
except Exception as e:
print(f"Error getting services: {str(e)}")
# Return empty list on error
return []
except Exception as e:
print(f"Error getting services: {e}")
return []
async def create_service(userid: str, name: str, url: str, description: str = "", apikey: str = "") -> str:
"""Create a new Hermes service registration for the current user."""
try:
# Validate service URL
if not await validate_service_url(url):
raise ValueError("Invalid service URL")
service_id = getID()
# Save to database using sqlor-database-module
env = ServerEnv()
async with get_sor_context(env, 'hermes-web-cli') as sor:
sql_template = SERVICES_CRUD['operations']['create']['sql_template']
await sor.sqlExe(sql_template, {
'id': service_id,
'user_id': user_id,
'name': name,
'service_url': url,
'description': description,
'status': 'active'
})
return service_id
except Exception as e:
print(f"Error creating service: {str(e)}")
raise
async def delete_service(userid: str, service_id: str) -> bool:
"""Delete a Hermes service registration (only if owned by current user)."""
try:
# Verify service belongs to current user before deletion
service = await get_service_by_id(service_id)
if not service:
return False
if service.get("user_id") != user_id:
print(f"Permission denied: Service {service_id} does not belong to user {user_id}")
return False
# Delete from database using sqlor-database-module
env = ServerEnv()
async with get_sor_context(env, 'hermes-web-cli') as sor:
sql_template = SERVICES_CRUD['operations']['delete']['sql_template']
await sor.sqlExe(sql_template, {
'service_id': service_id,
'user_id': user_id
})
# Also delete associated sessions
env = ServerEnv()
dbname = env.get_module_dbname()
async with db.sqlorContext(dbname) as sor:
await sor.sqlExe("""
DELETE FROM sessions
WHERE service_id = ${service_id}$ AND user_id = ${user_id}$
""", {
'service_id': service_id,
'user_id': user_id
})
return True
except Exception as e:
print(f"Error deleting service: {str(e)}")
return False
async def get_service_by_id(userid: str, service_id: str) -> Optional[Dict]:
"""Get service configuration by ID (only if owned by current user)."""
try:
# Query database directly with user_id filter for security
env = ServerEnv()
async with get_sor_context(env, 'hermes-web-cli') as sor:
sql_template = SERVICES_CRUD['operations']['read_by_id']['sql_template']
recs = await sor.sqlExe(sql_template, {
'service_id': service_id,
'user_id': user_id
})
if len(recs) > 0:
service_dict = dict(recs[0])
if 'created_at' in service_dict and service_dict['created_at']:
service_dict['created_at'] = service_dict['created_at'].isoformat()
if 'updated_at' in service_dict and service_dict['updated_at']:
service_dict['updated_at'] = service_dict['updated_at'].isoformat()
return service_dict
return None
except Exception as e:
print(f"Error getting service: {str(e)}")
return None
# Service connection testing
async def test_service_connection(service_id: str) -> Tuple[bool, str]:
"""Test connection to a Hermes service endpoint.
Args:
service_id: The ID of the service to test
Returns:
Tuple[bool, str]: (is_connected, status_message)
"""
try:
# Get service configuration (verify it belongs to current user)
service = await get_service_by_id(service_id)
if not service:
return False, "Service not found or access denied"
url = service["service_url"]
apikey = service.get("apikey", "")
# Prepare headers
headers = {}
if apikey:
headers["Authorization"] = f"Bearer {apikey}"
# Test the /health endpoint or similar
timeout = aiohttp.ClientTimeout(total=10)
async with aiohttp.ClientSession(timeout=timeout) as session:
async with session.get(f"{url.rstrip('/')}/health", headers=headers) as response:
if response.status == 200:
return True, "Connected"
else:
return False, f"HTTP {response.status}"
except asyncio.TimeoutError:
return False, "Connection timeout"
except aiohttp.ClientConnectorError:
return False, "Connection refused"
except Exception as e:
return False, f"Error: {str(e)}"
# Session management
async def create_session(service_id: str, user_id: str, user_message: str = "") -> str:
"""Create a new session with a Hermes service."""
try:
# Get service configuration (verify it belongs to current user)
service = await get_service_by_id(service_id)
if not service:
raise ValueError(f"Service {service_id} not found or access denied")
service_url = service["service_url"]
apikey = service.get("apikey", "")
# Prepare headers
headers = {
"Content-Type": "application/json"
}
# Add Authorization header if API key is provided
if apikey:
headers["Authorization"] = f"Bearer {apikey}"
# Call remote service API to create session
timeout = aiohttp.ClientTimeout(total=30)
async with aiohttp.ClientSession(timeout=timeout) as session:
async with session.post(
f"{service_url.rstrip('/')}/api/v1/sessions",
json={
"user_id": user_id,
"initial_message": user_message if user_message else None
},
headers=headers
) as response:
response.raise_for_status()
result = await response.json()
# Get the session ID from the remote service
remote_session_id = result.get("session_id", "")
if not remote_session_id:
raise ValueError("Remote service did not return a session ID")
# Create local session record in database
env = ServerEnv()
async with get_sor_context(env, 'hermes-web-cli') as sor:
sql_template = SESSIONS_CRUD['operations']['create']['sql_template']
await sor.sqlExe(sql_template, {
'session_id': remote_session_id,
'user_id': user_id,
'service_id': service_id,
'session_name': None,
'service_name': service.get("name", "Unknown Service")
})
# Return the session ID from the remote service
return remote_session_id
except Exception as e:
print(f"Error creating session: {str(e)}")
raise
async def send_message_to_service(userid: str, service_id: str, session_id: str, message: str) -> Dict:
"""Send a message to a Hermes service and get response (only if session owned by current user)."""
try:
# Verify session belongs to current user before sending message
session = await get_session_by_id(session_id)
if not session:
raise ValueError(f"Session {session_id} not found or access denied for user {user_id}")
service = await get_service_by_id(userid, service_id)
if not service:
raise ValueError(f"Service {service_id} not found or access denied for user {user_id}")
service_url = service["service_url"]
apikey = service.get("apikey", "")
# Prepare headers
headers = {
"Content-Type": "application/json"
}
# Add Authorization header if API key is provided
if apikey:
headers["Authorization"] = f"Bearer {apikey}"
# Call remote service API
timeout = aiohttp.ClientTimeout(total=30)
async with aiohttp.ClientSession(timeout=timeout) as session:
async with session.post(
f"{service_url.rstrip('/')}/api/chat",
json={
"session_id": session_id,
"message": message
},
headers=headers
) as response:
response.raise_for_status()
return await response.json()
except Exception as e:
print(f"Error sending message: {e}")
raise
async def get_session_messages(userid: str, session_id: str) -> List[Dict]:
"""Get all messages for a session (only if session owned by current user)."""
try:
# Verify session belongs to current user before getting messages
session = await get_session_by_id(session_id)
if not session:
print(f"Session {session_id} not found or access denied for user {user_id}")
return []
# Get the associated service
service = await get_service_by_id(userid, session['service_id'])
if not service:
print(f"Service for session {session_id} not found or access denied")
return []
service_url = service["service_url"]
apikey = service.get("apikey", "")
# Prepare headers
headers = {
"Content-Type": "application/json"
}
# Add Authorization header if API key is provided
if apikey:
headers["Authorization"] = f"Bearer {apikey}"
# Call remote service API to get messages
timeout = aiohttp.ClientTimeout(total=30)
async with aiohttp.ClientSession(timeout=timeout) as session:
async with session.get(
f"{service_url.rstrip('/')}/api/v1/sessions/{session_id}/messages",
headers=headers
) as response:
response.raise_for_status()
messages = await response.json()
# Update session last_active timestamp and message count in local database
env = ServerEnv()
async with get_sor_context(env, 'hermes-web-cli') as sor:
await sor.sqlExe("""
UPDATE sessions
SET last_active = CURRENT_TIMESTAMP,
message_count = ${message_count}$
WHERE session_id = ${session_id}$ AND user_id = ${user_id}$
""", {
'session_id': session_id,
'user_id': user_id,
'message_count': len(messages)
})
return messages
except Exception as e:
print(f"Error getting session messages: {str(e)}")
return []
# Active sessions management
async def get_active_sessions(userid: str) -> List[Dict]:
"""Get all active sessions for the current user from database."""
try:
# Query the sessions table for active sessions belonging to current user using sqlor-database-module
env = ServerEnv()
async with get_sor_context(env, 'hermes-web-cli') as sor:
sql_template = SESSIONS_CRUD['operations']['read_active']['sql_template']
recs = await sor.sqlExe(sql_template, {'user_id': user_id})
# Convert datetime objects to ISO format strings for JSON serialization
result = []
for rec in recs:
session_dict = dict(rec)
if 'created_at' in session_dict and session_dict['created_at']:
session_dict['created_at'] = session_dict['created_at'].isoformat()
if 'last_active' in session_dict and session_dict['last_active']:
session_dict['last_active'] = session_dict['last_active'].isoformat()
result.append(session_dict)
return result
except Exception as e:
print(f"Error getting active sessions: {str(e)}")
return []
async def get_recent_sessions(userid: str, limit: int = 5) -> List[Dict]:
"""Get recent sessions for the current user from database, ordered by creation time (most recent first)."""
try:
# Query the sessions table for recent sessions belonging to current user using sqlor-database-module
env = ServerEnv()
async with get_sor_context(env, 'hermes-web-cli') as sor:
sql_template = SESSIONS_CRUD['operations']['read_recent']['sql_template']
recs = await sor.sqlExe(sql_template, {'user_id': user_id, 'limit': limit})
# Convert datetime objects to ISO format strings for JSON serialization
result = []
for rec in recs:
session_dict = dict(rec)
if 'created_at' in session_dict and session_dict['created_at']:
session_dict['created_at'] = session_dict['created_at'].isoformat()
if 'last_active' in session_dict and session_dict['last_active']:
session_dict['last_active'] = session_dict['last_active'].isoformat()
result.append(session_dict)
return result
except Exception as e:
print(f"Error getting recent sessions: {str(e)}")
return []
async def get_session_by_id(userid, session_id: str) -> Optional[Dict]:
"""Get session details by session ID (only if owned by current user)."""
try:
# Query database directly with user_id filter for security
env = ServerEnv()
async with get_sor_context(env, 'hermes-web-cli') as sor:
sql_template = SESSIONS_CRUD['operations']['read_by_id']['sql_template']
recs = await sor.sqlExe(sql_template, {
'session_id': session_id,
'user_id': user_id
})
if len(recs) > 0:
session_dict = dict(recs[0])
if 'created_at' in session_dict and session_dict['created_at']:
session_dict['created_at'] = session_dict['created_at'].isoformat()
if 'last_active' in session_dict and session_dict['last_active']:
session_dict['last_active'] = session_dict['last_active'].isoformat()
return session_dict
return None
except Exception as e:
print(f"Error getting session by ID: {str(e)}")
return None
=======
"""Initialize and load the hermes-web-cli module. """Initialize and load the hermes-web-cli module.
This function is called by Sage system during module loading. This function is called by Sage system during module loading.