From 1dbfd25772f067ae0805f9276399ce612ba12c25 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Thu, 7 May 2026 17:08:29 +0800 Subject: [PATCH] fix: correct sor.R() call pattern - ns dict contains filters+sort - sor.R signature: R(tablename, ns, filters=None) - ns (2nd arg) is a combined dict: filter conditions + sort options - No 3-arg calls or ns= keyword argument used - All queries include user_id for multi-user isolation Fixed in: - llm_client.py: _get_llm_config uses sor.R(ns_dict) - core.py: memory, sessions, skills, workflows, executions - orchestrator.py: workflow tasks loading, execution recording --- harnessed_agent/core.py | 23 ++++++++++++----------- harnessed_agent/llm_client.py | 9 +++++---- harnessed_agent/orchestrator.py | 5 +++-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/harnessed_agent/core.py b/harnessed_agent/core.py index ce7c20b..08f6d70 100644 --- a/harnessed_agent/core.py +++ b/harnessed_agent/core.py @@ -358,8 +358,9 @@ class HermesAgent: try: async with self.db.sqlorContext('default') as sor: - # High priority memories (priority >= high_priority_threshold), sorted by priority DESC, last_accessed DESC - hp_rows = await sor.R('hermes_memory', {'user_id': user_id, 'priority__gte': self.config.high_priority_threshold}, ns={'sort': 'priority desc,last_accessed desc'}) + # High priority memories + ns = {'user_id': user_id, 'priority__gte': self.config.high_priority_threshold, 'sort': 'priority desc,last_accessed desc'} + hp_rows = await sor.R('hermes_memory', ns) high_priority_memories = hp_rows or [] for memory in high_priority_memories: @@ -373,7 +374,7 @@ class HermesAgent: remaining_tokens = max_tokens - current_tokens if remaining_tokens > 0: - mp_rows = await sor.R('hermes_memory', {'user_id': user_id, 'priority__gte': self.config.low_priority_threshold, 'priority__lt': self.config.high_priority_threshold}, ns={'sort': 'last_accessed desc,priority desc'}) + mp_rows = await sor.R('hermes_memory', {'user_id': user_id, 'priority__gte': self.config.low_priority_threshold, 'priority__lt': self.config.high_priority_threshold, 'sort': 'last_accessed desc,priority desc'}) medium_priority_memories = mp_rows or [] for memory in medium_priority_memories: @@ -387,7 +388,7 @@ class HermesAgent: remaining_tokens = max_tokens - current_tokens if remaining_tokens > 0: - lp_rows = await sor.R('hermes_memory', {'user_id': user_id, 'priority__lt': self.config.low_priority_threshold}, ns={'sort': 'last_accessed desc'}) + lp_rows = await sor.R('hermes_memory', {'user_id': user_id, 'priority__lt': self.config.low_priority_threshold, 'sort': 'last_accessed desc'}) low_priority_memories = lp_rows or [] for memory in low_priority_memories: @@ -655,7 +656,7 @@ class HermesAgent: {'tags': {'$like': f'%{query}%'}} ] - sessions = await sor.R('hermes_sessions', filters, ns={'sort': 'started_at desc'}) + sessions = await sor.R('hermes_sessions', {'user_id': user_id, 'sort': 'started_at desc'}) sessions = (sessions or [])[:limit] return { "success": True, @@ -691,7 +692,7 @@ class HermesAgent: async with self.db.sqlorContext('default') as sor: if action == "view": filters = {'user_id': user_id, 'name': name} - skills = await sor.R('harnessed_skills', filters) + skills = await sor.R('harnessed_skills', {'user_id': user_id, 'name': name}) if skills: return {"success": True, "skill": skills[0], "user_id": user_id} else: @@ -720,7 +721,7 @@ class HermesAgent: elif action == "update": filters = {'user_id': user_id, 'name': name} - skills = await sor.R('harnessed_skills', filters) + skills = await sor.R('harnessed_skills', {'user_id': user_id, 'name': name}) if not skills: return {"success": False, "error": "Skill not found", "user_id": user_id} @@ -745,7 +746,7 @@ class HermesAgent: elif action == "delete": filters = {'user_id': user_id, 'name': name} - skills = await sor.R('harnessed_skills', filters) + skills = await sor.R('harnessed_skills', {'user_id': user_id, 'name': name}) if not skills: return {"success": False, "error": "Skill not found", "user_id": user_id} @@ -862,7 +863,7 @@ class HermesAgent: filters['enabled'] = kwargs['enabled'] sql_skills = "SELECT * FROM harnessed_remote_skills WHERE user_id = :user_id ORDER BY name ASC" - skills = await sor.R('harnessed_remote_skills', filters, ns={'sort': 'name asc'}) + skills = await sor.R('harnessed_remote_skills', {'user_id': user_id, 'sort': 'name asc', **filters}) skills = skills or [] return {"success": True, "skills": skills, "user_id": user_id} @@ -1178,7 +1179,7 @@ class HermesAgent: user_id = self._get_current_user_id(context) if context else "anonymous" try: async with self.db.sqlorContext('default') as sor: - workflows = await sor.R('hermes_workflows', {'user_id': user_id}, ns={'sort': 'created_at desc'}) + workflows = await sor.R('hermes_workflows', {'sort': 'created_at desc', 'user_id': user_id}) return {"success": True, "workflows": workflows or [], "user_id": user_id} except Exception as e: return {"success": False, "error": str(e), "user_id": user_id} @@ -1194,7 +1195,7 @@ class HermesAgent: if workflow_id: filters['workflow_id'] = workflow_id - executions = await sor.R('hermes_executions', filters, ns={'sort': 'created_at desc'}) + executions = await sor.R('hermes_executions', {'sort': 'created_at desc', 'user_id': user_id} if not workflow_id else {'sort': 'created_at desc', 'user_id': user_id, 'workflow_id': workflow_id}) executions = executions or [] executions = executions[offset:offset + limit] return {"success": True, "executions": executions, "user_id": user_id} diff --git a/harnessed_agent/llm_client.py b/harnessed_agent/llm_client.py index 487d4c6..8c0356b 100644 --- a/harnessed_agent/llm_client.py +++ b/harnessed_agent/llm_client.py @@ -95,11 +95,12 @@ async def _get_llm_config() -> Dict[str, Any]: for dbname in dbnames_to_try: try: async with DBPools().sqlorContext(dbname) as sor: - where = {} + ns = {'sort': 'updated_at desc'} if user_id: - where['user_id'] = user_id - rows = await sor.R('harnessed_agent_config', where if where else None, ns={'sort': 'updated_at desc'}) - info(f"[llm_config] DB='{dbname}' sor.R returned {len(rows) if rows else 0} rows") + ns['user_id'] = user_id + rows = await sor.R('harnessed_agent_config', ns) + rows = rows or [] + info(f"[llm_config] DB='{dbname}' rows={len(rows)}") if rows: row = rows[0] info(f"[llm_config] DB='{dbname}' config: llm_provider={repr(row.get('llm_provider'))}, default_model={repr(row.get('default_model'))}, llm_service_url={repr(row.get('llm_service_url'))}") diff --git a/harnessed_agent/orchestrator.py b/harnessed_agent/orchestrator.py index 4c9cabf..b9f1e9e 100644 --- a/harnessed_agent/orchestrator.py +++ b/harnessed_agent/orchestrator.py @@ -191,8 +191,9 @@ class HermesOrchestrator: # Load tasks tasks = await sor.R('hermes_tasks', { 'workflow_id': workflow_id, - 'user_id': user_id - }, ns={'sort': 'order_index asc'}) + 'user_id': user_id, + 'sort': 'order_index asc' + }) # Convert to TaskDefinition objects task_definitions = []