Enhance AI resolver and debugging output
- Added logging for AI response content in workspace.py to aid in debugging, including previews of responses and handling of empty responses. - Refactored the AI resolver's merge function for clarity and improved error logging, ensuring consistent error messages are printed to stderr. - Updated the maximum turns for AI responses to streamline the merge process.
This commit is contained in:
@@ -598,16 +598,15 @@ def create_claude_resolver() -> AIResolver:
|
|||||||
"""
|
"""
|
||||||
Create an AIResolver configured to use Claude via the Agent SDK.
|
Create an AIResolver configured to use Claude via the Agent SDK.
|
||||||
|
|
||||||
Uses the same SDK pattern as the rest of the auto-claude framework,
|
Uses the same OAuth token pattern as the rest of the auto-claude framework.
|
||||||
ensuring consistent authentication and rate limits.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Configured AIResolver
|
Configured AIResolver
|
||||||
"""
|
"""
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
# Check for OAuth token (required for Claude Agent SDK)
|
|
||||||
oauth_token = os.environ.get("CLAUDE_CODE_OAUTH_TOKEN")
|
oauth_token = os.environ.get("CLAUDE_CODE_OAUTH_TOKEN")
|
||||||
if not oauth_token:
|
if not oauth_token:
|
||||||
logger.warning("CLAUDE_CODE_OAUTH_TOKEN not set, AI resolution unavailable")
|
logger.warning("CLAUDE_CODE_OAUTH_TOKEN not set, AI resolution unavailable")
|
||||||
@@ -622,43 +621,43 @@ def create_claude_resolver() -> AIResolver:
|
|||||||
def call_claude(system: str, user: str) -> str:
|
def call_claude(system: str, user: str) -> str:
|
||||||
"""Call Claude using the Agent SDK for merge resolution."""
|
"""Call Claude using the Agent SDK for merge resolution."""
|
||||||
|
|
||||||
async def _run_merge_agent() -> str:
|
async def _run_merge() -> str:
|
||||||
# Create a focused client for merge resolution (no tools needed)
|
# Create a minimal client for merge resolution
|
||||||
client = ClaudeSDKClient(
|
client = ClaudeSDKClient(
|
||||||
options=ClaudeAgentOptions(
|
options=ClaudeAgentOptions(
|
||||||
model="sonnet", # Fast and capable for merges
|
model="sonnet",
|
||||||
system_prompt=system,
|
system_prompt=system,
|
||||||
allowed_tools=[], # No tools needed for merge resolution
|
allowed_tools=[], # No tools needed for merge
|
||||||
max_turns=3, # Should complete in 1 turn, allow a few for safety
|
max_turns=1,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with client:
|
# Use the same pattern as qa/reviewer.py - NO context manager
|
||||||
await client.query(user)
|
await client.query(user)
|
||||||
|
|
||||||
response_text = ""
|
response_text = ""
|
||||||
async for msg in client.receive_response():
|
async for msg in client.receive_response():
|
||||||
msg_type = type(msg).__name__
|
msg_type = type(msg).__name__
|
||||||
if msg_type == "AssistantMessage" and hasattr(msg, "content"):
|
if msg_type == "AssistantMessage" and hasattr(msg, "content"):
|
||||||
for block in msg.content:
|
for block in msg.content:
|
||||||
block_type = type(block).__name__
|
if hasattr(block, "text"):
|
||||||
if block_type == "TextBlock" and hasattr(block, "text"):
|
response_text += block.text
|
||||||
response_text += block.text
|
|
||||||
|
|
||||||
return response_text
|
logger.info(f"AI merge response: {len(response_text)} chars")
|
||||||
|
return response_text
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Claude SDK call failed: {e}")
|
logger.error(f"Claude SDK call failed: {e}")
|
||||||
import sys
|
print(f" [ERROR] Claude SDK error: {e}", file=sys.stderr)
|
||||||
print(f"Claude SDK error: {e}", file=sys.stderr)
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
# Run the async function synchronously
|
|
||||||
try:
|
try:
|
||||||
return asyncio.run(_run_merge_agent())
|
return asyncio.run(_run_merge())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"asyncio.run failed: {e}")
|
logger.error(f"asyncio.run failed: {e}")
|
||||||
|
print(f" [ERROR] asyncio error: {e}", file=sys.stderr)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
logger.info("Using Claude Agent SDK for merge resolution")
|
||||||
return AIResolver(ai_call_fn=call_claude)
|
return AIResolver(ai_call_fn=call_claude)
|
||||||
|
|||||||
@@ -1868,6 +1868,13 @@ def _merge_file_with_ai(
|
|||||||
debug_detailed(MODULE, "AI response received",
|
debug_detailed(MODULE, "AI response received",
|
||||||
response_length=len(response) if response else 0)
|
response_length=len(response) if response else 0)
|
||||||
|
|
||||||
|
# Log response content for debugging (truncated)
|
||||||
|
if response:
|
||||||
|
preview = response[:200] if len(response) > 200 else response
|
||||||
|
print(f" [DEBUG] AI response preview: {repr(preview)}", file=sys.stderr)
|
||||||
|
else:
|
||||||
|
print(f" [DEBUG] AI response was empty", file=sys.stderr)
|
||||||
|
|
||||||
# Extract code from response
|
# Extract code from response
|
||||||
merged = resolver._extract_code_block(response, language)
|
merged = resolver._extract_code_block(response, language)
|
||||||
if not merged:
|
if not merged:
|
||||||
|
|||||||
Reference in New Issue
Block a user