From bba394be38461fd7dea7c4ac051f2a38ec87ad1f Mon Sep 17 00:00:00 2001 From: chiguyong Date: Wed, 10 Jun 2026 19:21:40 +0800 Subject: [PATCH] fix(marketplace): address code review findings - Fix str.format() crash when user input contains curly braces - Fix Layer 2 passing str to find_best_agent (expects list[str]) - Fix AlignmentGuard fail-open on LLM audit failure (now fail-closed) - Fix _config_reload_lock not initialized in create_app() - Fix evolve_soul redundant reflector.reflect() call (reuse existing reflection) - Fix test mocks using AsyncMock for sync find_best_agent method - Remove unused _COMPLEXITY_CLASSIFY_PROMPT constant --- src/agentkit/chat/skill_routing.py | 23 +++++++++++------------ src/agentkit/evolution/lifecycle.py | 11 ++++++----- src/agentkit/quality/alignment.py | 6 +++++- src/agentkit/server/app.py | 1 + tests/integration/test_marketplace_e2e.py | 4 ++-- tests/unit/test_cost_aware_router.py | 4 ++-- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/agentkit/chat/skill_routing.py b/src/agentkit/chat/skill_routing.py index 8eec811..937a07a 100644 --- a/src/agentkit/chat/skill_routing.py +++ b/src/agentkit/chat/skill_routing.py @@ -186,16 +186,6 @@ _CHAT_MODE_RE = re.compile( re.IGNORECASE, ) -_COMPLEXITY_CLASSIFY_PROMPT = ( - "Assess the complexity of the following user request on a scale of 0.0 to 1.0.\n" - "0.0 = trivial greeting / simple chat\n" - "0.3 = single-skill task (e.g. search, translate)\n" - "0.7 = multi-step or cross-domain task (e.g. market research + competitor analysis)\n" - "1.0 = highly complex, multi-agent collaboration needed\n\n" - 'User request: "{content}"\n\n' - 'Respond ONLY with a JSON object: {{"complexity": }}' -) - class CostAwareRouter: """三层成本感知路由器。 @@ -251,7 +241,13 @@ class CostAwareRouter: if self._llm_gateway is None: return 0.5 - prompt = _COMPLEXITY_CLASSIFY_PROMPT.format(content=content) + prompt = ( + 'You are a complexity classifier. Rate the complexity of the user request on a scale of 0.0 to 1.0.\n' + '0.0 = trivial greeting, 0.3 = simple question, 0.5 = moderate task, ' + '0.7 = complex multi-step task, 1.0 = very complex research task.\n\n' + f'User request: "{content}"\n\n' + 'Respond ONLY with a JSON object: {"complexity": }' + ) try: response = await self._llm_gateway.chat( messages=[{"role": "user", "content": prompt}], @@ -283,7 +279,10 @@ class CostAwareRouter: """Layer 2: 高复杂度任务通过 org_context.find_best_agent 路由。""" if self._org_context is not None and hasattr(self._org_context, "find_best_agent"): try: - best_agent = await self._org_context.find_best_agent(content) + # Extract capability-like keywords from content for matching + # find_best_agent expects list[str] of required capabilities + content_words = [w for w in content.split() if len(w) > 2][:5] + best_agent = self._org_context.find_best_agent(required_capabilities=content_words) if best_agent is not None: agent_name = best_agent if isinstance(best_agent, str) else getattr(best_agent, "name", str(best_agent)) result = SkillRoutingResult( diff --git a/src/agentkit/evolution/lifecycle.py b/src/agentkit/evolution/lifecycle.py index 17268ef..582d82b 100644 --- a/src/agentkit/evolution/lifecycle.py +++ b/src/agentkit/evolution/lifecycle.py @@ -149,7 +149,7 @@ class EvolutionMixin: # Step 2: Soul 进化检查 if memory_store is not None: - await self.evolve_soul(task, result, memory_store) + await self.evolve_soul(task, result, memory_store, reflection=reflection) # Step 3: 如果有改进建议,触发 Prompt 优化 if not reflection.suggestions: @@ -378,6 +378,7 @@ class EvolutionMixin: task: TaskMessage, result: TaskResult, memory_store: MemoryStore | None = None, + reflection: Reflection | None = None, ) -> bool: """Check if soul should be updated based on accumulated reflections. @@ -389,10 +390,10 @@ class EvolutionMixin: if memory_store is None: return False - if self._reflector is None: - return False - - reflection = await self._reflector.reflect(task, result) + if reflection is None: + if self._reflector is None: + return False + reflection = await self._reflector.reflect(task, result) # 只关注低质量且有建议的反思 if reflection.quality_score >= 0.5: diff --git a/src/agentkit/quality/alignment.py b/src/agentkit/quality/alignment.py index a2b0642..66b82de 100644 --- a/src/agentkit/quality/alignment.py +++ b/src/agentkit/quality/alignment.py @@ -159,7 +159,11 @@ class AlignmentGuard: ) except Exception as e: logger.warning(f"LLM audit failed: {e}") - return AlignmentCheckResult(passed=True, checked_by="rule") + return AlignmentCheckResult( + passed=False, + violations=[f"LLM audit unavailable: {e}"], + checked_by="rule", + ) def record_interaction(self, session_id: str) -> CascadeAlert | None: """记录一次 agent 间交互,超过阈值返回 CascadeAlert""" diff --git a/src/agentkit/server/app.py b/src/agentkit/server/app.py index 1b3934a..9f47bc4 100644 --- a/src/agentkit/server/app.py +++ b/src/agentkit/server/app.py @@ -487,6 +487,7 @@ def create_app( app.state.runner = BackgroundRunner(task_store=app.state.task_store) app.state.server_config = server_config app.state.api_key = effective_api_key + app.state._config_reload_lock = asyncio.Lock() # Initialize session manager for Chat mode from agentkit.session.manager import SessionManager diff --git a/tests/integration/test_marketplace_e2e.py b/tests/integration/test_marketplace_e2e.py index 7e8b3a0..fb5026d 100644 --- a/tests/integration/test_marketplace_e2e.py +++ b/tests/integration/test_marketplace_e2e.py @@ -111,7 +111,7 @@ class TestCapabilityMatching: )) # Mock find_best_agent to return the research agent - org_context.find_best_agent = AsyncMock( + org_context.find_best_agent = MagicMock( return_value=org_context.get_agent_profile("research_agent") ) @@ -515,7 +515,7 @@ class TestFullPipeline: skills=["market_analysis"], current_load=0, )) - org_context.find_best_agent = AsyncMock( + org_context.find_best_agent = MagicMock( return_value=org_context.get_agent_profile("analyst") ) diff --git a/tests/unit/test_cost_aware_router.py b/tests/unit/test_cost_aware_router.py index 06c6832..3f0326f 100644 --- a/tests/unit/test_cost_aware_router.py +++ b/tests/unit/test_cost_aware_router.py @@ -267,7 +267,7 @@ class TestLayer2CapabilityMatching: """'做市场调研+竞品分析' 复杂度 > 0.7,触发能力匹配""" gateway = _make_llm_gateway(json.dumps({"complexity": 0.85})) org_context = MagicMock() - org_context.find_best_agent = AsyncMock(return_value="market-researcher") + org_context.find_best_agent = MagicMock(return_value="market-researcher") router = CostAwareRouter(llm_gateway=gateway, model="default", org_context=org_context) result = await router.route( @@ -289,7 +289,7 @@ class TestLayer2CapabilityMatching: agent_obj = MagicMock() agent_obj.name = "analyst-agent" org_context = MagicMock() - org_context.find_best_agent = AsyncMock(return_value=agent_obj) + org_context.find_best_agent = MagicMock(return_value=agent_obj) router = CostAwareRouter(llm_gateway=gateway, model="default", org_context=org_context) result = await router.route(