feat: Add Loki MCP server scaffold, fix adapter blocking, upgrade model
- Scaffold mcp_servers/loki/ with config and async HTTP client - Fix Slack/Telegram adapters to use non-blocking connections - Upgrade default model to claude-sonnet-4-6 - Improve Agent SDK message collection for empty ResultMessage cases - Add Message-ID to email summaries, increase body truncation limit - Fix .gitignore inline comments that broke sensitive file exclusions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,13 +3,13 @@
|
||||
Supports two modes for Claude:
|
||||
1. Agent SDK (v0.1.36+) - DEFAULT - Uses query() API with Max subscription
|
||||
- Set USE_AGENT_SDK=true (default)
|
||||
- Model: claude-sonnet-4-5-20250929 (default for all operations)
|
||||
- Model: claude-sonnet-4-6 (default for all operations)
|
||||
- All tools are MCP-based (no API key needed)
|
||||
- Tools registered via mcp_tools.py MCP server
|
||||
- Flat-rate subscription cost
|
||||
|
||||
2. Direct API (pay-per-token) - Set USE_DIRECT_API=true
|
||||
- Model: claude-sonnet-4-5-20250929
|
||||
- Model: claude-sonnet-4-6
|
||||
- Requires ANTHROPIC_API_KEY in .env
|
||||
- Uses traditional tool definitions from tools.py
|
||||
"""
|
||||
@@ -60,8 +60,8 @@ _USE_AGENT_SDK = os.getenv("USE_AGENT_SDK", "true").lower() == "true"
|
||||
|
||||
# Default models by provider
|
||||
_DEFAULT_MODELS = {
|
||||
"claude": "claude-sonnet-4-5-20250929",
|
||||
"claude_agent_sdk": "claude-sonnet-4-5-20250929",
|
||||
"claude": "claude-sonnet-4-6",
|
||||
"claude_agent_sdk": "claude-sonnet-4-6",
|
||||
"glm": "glm-4-plus",
|
||||
}
|
||||
|
||||
@@ -147,9 +147,9 @@ class LLMInterface:
|
||||
# Set model based on mode
|
||||
if provider == "claude":
|
||||
if self.mode == "agent_sdk":
|
||||
self.model = _DEFAULT_MODELS.get("claude_agent_sdk", "claude-sonnet-4-5-20250929")
|
||||
self.model = _DEFAULT_MODELS.get("claude_agent_sdk", "claude-sonnet-4-6")
|
||||
else:
|
||||
self.model = _DEFAULT_MODELS.get(provider, "claude-sonnet-4-5-20250929")
|
||||
self.model = _DEFAULT_MODELS.get(provider, "claude-sonnet-4-6")
|
||||
else:
|
||||
self.model = _DEFAULT_MODELS.get(provider, "")
|
||||
|
||||
@@ -505,6 +505,7 @@ class LLMInterface:
|
||||
|
||||
# --- 4. Consume messages until we get a ResultMessage. ---
|
||||
result_text = ""
|
||||
assistant_messages = [] # Collect assistant responses
|
||||
message_count = 0
|
||||
async for data in query_obj.receive_messages():
|
||||
message = parse_message(data)
|
||||
@@ -514,14 +515,29 @@ class LLMInterface:
|
||||
message_type = type(message).__name__
|
||||
logger.debug(f"[LLM] Received message #{message_count}: {message_type}")
|
||||
|
||||
# Collect text from AssistantMessage objects
|
||||
if isinstance(message, AssistantMessage):
|
||||
if hasattr(message, 'content') and message.content:
|
||||
# Extract text from content blocks
|
||||
if isinstance(message.content, str):
|
||||
assistant_messages.append(message.content)
|
||||
elif isinstance(message.content, list):
|
||||
for block in message.content:
|
||||
if hasattr(block, 'type') and block.type == 'text':
|
||||
if hasattr(block, 'text'):
|
||||
assistant_messages.append(block.text)
|
||||
|
||||
if isinstance(message, ResultMessage):
|
||||
result_text = message.result or ""
|
||||
# Use ResultMessage.result if available, otherwise use collected assistant messages
|
||||
result_text = message.result or "\n".join(assistant_messages)
|
||||
logger.info(
|
||||
"[LLM] Agent SDK result received after %d messages: cost=$%.4f, turns=%s",
|
||||
message_count,
|
||||
getattr(message, "total_cost_usd", 0),
|
||||
getattr(message, "num_turns", "?"),
|
||||
)
|
||||
if not message.result and assistant_messages:
|
||||
logger.debug(f"[LLM] ResultMessage.result was empty, using {len(assistant_messages)} collected assistant messages")
|
||||
break
|
||||
|
||||
# Log non-result messages to detect loops
|
||||
|
||||
Reference in New Issue
Block a user