Files
journal_organizer/conversation/response_generator.py
T
windyboy f7e54692a9 Initial project setup: Obsidian intelligent journal organizer
- Add core agent architecture with Command + Skill pattern
- Implement Claude API integration for content analysis
- Add Obsidian REST API integration for vault operations
- Create conversational interface (v2.0) with natural language processing
- Add comprehensive configuration management and validation
- Include project documentation and developer guides
- Set up testing framework with unit, integration, and property tests
- Add Kiro specs for Claude API configuration and code quality improvements
- Configure project steering files for development guidelines
2025-12-31 17:55:10 +08:00

235 lines
6.9 KiB
Python

"""
响应生成模块
使用 Claude 生成自然语言响应
"""
import logging
from typing import Dict, Any, Optional, List
from ..dependency_manager import get_dependency_manager
# Try to import anthropic with graceful degradation
dependency_manager = get_dependency_manager()
Anthropic = dependency_manager.get_class_from_module('anthropic', 'Anthropic')
class ResponseGenerator:
"""响应生成器,使用 Claude 生成自然语言响应"""
def __init__(self, config: Optional[Dict[str, Any]] = None) -> None:
"""
初始化响应生成器
Args:
config: 配置字典
"""
self.config: Dict[str, Any] = config or {}
self.logger: logging.Logger = logging.getLogger("ResponseGenerator")
# Initialize Anthropic client with dependency checking
if Anthropic is not None:
try:
self.client: Optional[Anthropic] = Anthropic()
except Exception as e:
self.logger.error(f"Failed to initialize Anthropic client: {e}")
self.client = None
else:
self.client = None
self.logger.warning("Anthropic library not available - AI response generation disabled")
async def generate_success_response(
self, command: str, result: Any, user_message: str
) -> str:
"""
生成成功响应
Args:
command: 执行的命令
result: 命令执行结果
user_message: 原始用户消息
Returns:
生成的响应文本
"""
prompt: str = self._build_success_prompt(command, result, user_message)
return await self._generate_response(prompt)
async def generate_error_response(
self, command: str, error: str, user_message: str
) -> str:
"""
生成错误响应
Args:
command: 执行的命令
error: 错误信息
user_message: 原始用户消息
Returns:
生成的响应文本
"""
prompt: str = self._build_error_prompt(command, error, user_message)
return await self._generate_response(prompt)
async def generate_clarification_response(self, question: str) -> str:
"""
生成澄清问题的响应
Args:
question: 澄清问题
Returns:
生成的响应文本
"""
return question
async def generate_welcome_message(self) -> str:
"""
生成欢迎消息
Returns:
欢迎消息
"""
return "👋 欢迎使用 Obsidian 日记整理助手!我可以帮您整理日记、分析内容、导出总结等。请告诉我您想要做什么?"
async def generate_suggestions(
self, context: Optional[Dict[str, Any]] = None
) -> List[str]:
"""
生成智能建议
Args:
context: 上下文信息
Returns:
建议列表
"""
suggestions: List[str] = ["整理今天的日记", "分析本周的主题", "导出月度总结", "查看最近的经验"]
# 可以根据上下文生成更个性化的建议
if context:
# 例如,如果是周五,建议生成周总结
from datetime import datetime
if datetime.now().weekday() == 4: # 周五
suggestions.insert(0, "生成本周总结")
return suggestions
def _build_success_prompt(
self, command: str, result: Any, user_message: str
) -> str:
"""
构建成功响应的提示
Args:
command: 执行的命令
result: 命令执行结果
user_message: 原始用户消息
Returns:
提示文本
"""
result_str: str = self._format_result(result)
prompt: str = f"""你是一个友好的 Obsidian 日记整理助手。
用户问: "{user_message}"
你已经成功执行了 "{command}" 命令。
执行结果:
{result_str}
请用友好、自然的语言总结结果。保持回复简洁(1-3 句话)。
如果有重要的数据或统计信息,请突出显示。
示例回复:
- "✓ 已成功整理您今天的日记。提取了 5 条经验、3 条待办事项和 2 个问题。"
- "✓ 分析完成!本周的主题主要集中在项目管理和技术学习两个方面。"
"""
return prompt
def _build_error_prompt(self, command: str, error: str, user_message: str) -> str:
"""
构建错误响应的提示
Args:
command: 执行的命令
error: 错误信息
user_message: 原始用户消息
Returns:
提示文本
"""
prompt: str = f"""你是一个友好的 Obsidian 日记整理助手。
用户问: "{user_message}"
执行 "{command}" 命令时出现了错误:
{error}
请用友好、有帮助的语言解释错误,并建议可能的解决方案。保持回复简洁(1-2 句话)。
示例回复:
- "✗ 抱歉,找不到该日期的日记。请检查日期格式是否正确(YYYY-MM-DD)。"
- "✗ 执行过程中出现了问题。请稍后重试,或检查您的配置设置。"
"""
return prompt
def _format_result(self, result: Any) -> str:
"""
格式化结果
Args:
result: 结果对象
Returns:
格式化的结果字符串
"""
if isinstance(result, dict):
lines: List[str] = []
for key, value in result.items():
if isinstance(value, (list, dict)):
lines.append(f"- {key}: {len(value)} 项")
else:
lines.append(f"- {key}: {value}")
return "\n".join(lines)
elif isinstance(result, list):
return "\n".join([f"- {item}" for item in result])
else:
return str(result)
async def _generate_response(self, prompt: str) -> str:
"""
使用 Claude 生成响应
Args:
prompt: 提示文本
Returns:
生成的响应
"""
# Check if Claude is available
if self.client is None:
self.logger.warning("Claude client not available, using fallback response")
return "✓ 操作已完成。(注意:AI 响应生成功能暂时不可用)"
try:
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=300,
messages=[{"role": "user", "content": prompt}],
)
response_text: str = response.content[0].text.strip()
self.logger.debug(f"生成响应: {response_text[:100]}...")
return response_text
except Exception as e:
self.logger.error(f"生成响应失败: {str(e)}")
return "✓ 操作已完成。(注意:AI 响应生成遇到问题,请检查网络连接和 API 配置)"