Add Consensus Tool for Multi-Model Perspective Gathering (#67)
* WIP Refactor resolving mode_names, should be done once at MCP call boundary Pass around model context instead Consensus tool allows one to get a consensus from multiple models, optionally assigning one a 'for' or 'against' stance to find nuanced responses. * Deduplication of model resolution, model_context should be available before reaching deeper parts of the code Improved abstraction when building conversations Throw programmer errors early * Guardrails Support for `model:option` format at MCP boundary so future tools can use additional options if needed instead of handling this only for consensus Model name now supports an optional ":option" for future use * Simplified async flow * Improved model for request to support natural language Simplified async flow * Improved model for request to support natural language Simplified async flow * Fix consensus tool async/sync patterns to match codebase standards CRITICAL FIXES: - Converted _get_consensus_responses from async to sync (matches other tools) - Converted store_conversation_turn from async to sync (add_turn is synchronous) - Removed unnecessary asyncio imports and sleep calls - Fixed ClosedResourceError in MCP protocol during long consensus operations PATTERN ALIGNMENT: - Consensus tool now follows same sync patterns as all other tools - Only execute() and prepare_prompt() are async (base class requirement) - All internal operations are synchronous like analyze, chat, debug, etc. TESTING: - MCP simulation test now passes: consensus_stance ✅ - Two-model consensus works correctly in ~35 seconds - Unknown stance handling defaults to neutral with warnings - All 9 unit tests pass (100% success rate) The consensus tool async patterns were anomalous in the codebase. This fix aligns it with the established synchronous patterns used by all other tools while maintaining full functionality. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Fixed call order and added new test * Cleanup dead comments Docs for the new tool Improved tests --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
9b98df650b
commit
95556ba9ea
@@ -136,18 +136,23 @@ class Calculator:
|
||||
|
||||
self.logger.debug(f"Calling MCP tool {tool_name} with proper initialization")
|
||||
|
||||
# Execute the command
|
||||
# Execute the command with proper handling for async responses
|
||||
# For consensus tool and other long-running tools, we need to ensure
|
||||
# the subprocess doesn't close prematurely
|
||||
result = subprocess.run(
|
||||
docker_cmd,
|
||||
input=input_data,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
timeout=3600, # 1 hour timeout
|
||||
check=False, # Don't raise on non-zero exit code
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
self.logger.error(f"Docker exec failed: {result.stderr}")
|
||||
return None, None
|
||||
self.logger.error(f"Docker exec failed with return code {result.returncode}")
|
||||
self.logger.error(f"Stderr: {result.stderr}")
|
||||
# Still try to parse stdout as the response might have been written before the error
|
||||
self.logger.debug(f"Attempting to parse stdout despite error: {result.stdout[:500]}")
|
||||
|
||||
# Parse the response - look for the tool call response
|
||||
response_data = self._parse_mcp_response(result.stdout, expected_id=2)
|
||||
@@ -191,7 +196,10 @@ class Calculator:
|
||||
|
||||
# If we get here, log all responses for debugging
|
||||
self.logger.warning(f"No valid tool call response found for ID {expected_id}")
|
||||
self.logger.debug(f"Full stdout: {stdout}")
|
||||
self.logger.warning(f"Full stdout: {stdout}")
|
||||
self.logger.warning(f"Total stdout lines: {len(lines)}")
|
||||
for i, line in enumerate(lines[:10]): # Log first 10 lines
|
||||
self.logger.warning(f"Line {i}: {line[:100]}...")
|
||||
return None
|
||||
|
||||
except json.JSONDecodeError as e:
|
||||
|
||||
Reference in New Issue
Block a user