diff --git a/src/fabledassistant/routes/chat.py b/src/fabledassistant/routes/chat.py index 36d495f..a25253e 100644 --- a/src/fabledassistant/routes/chat.py +++ b/src/fabledassistant/routes/chat.py @@ -40,6 +40,7 @@ async def list_conversations_route(): uid = get_current_user_id() limit = min(request.args.get("limit", 50, type=int), 500) offset = request.args.get("offset", 0, type=int) + conv_type = request.args.get("type", "chat") # Apply retention policy before returning list retention_str = await get_setting(uid, "chat_retention_days", "90") try: @@ -48,7 +49,7 @@ async def list_conversations_route(): retention_days = 90 if retention_days > 0: await cleanup_old_conversations(uid, retention_days) - conversations, total = await list_conversations(uid, limit=limit, offset=offset) + conversations, total = await list_conversations(uid, limit=limit, offset=offset, conv_type=conv_type) return jsonify({ "conversations": conversations, "total": total, diff --git a/src/fabledassistant/services/chat.py b/src/fabledassistant/services/chat.py index c4e3617..e244ca9 100644 --- a/src/fabledassistant/services/chat.py +++ b/src/fabledassistant/services/chat.py @@ -46,12 +46,13 @@ async def get_conversation( async def list_conversations( - user_id: int, limit: int = 50, offset: int = 0 + user_id: int, limit: int = 50, offset: int = 0, conv_type: str = "chat" ) -> tuple[list[dict], int]: async with async_session() as session: total = await session.scalar( select(func.count(Conversation.id)).where( - Conversation.user_id == user_id + Conversation.user_id == user_id, + Conversation.conversation_type == conv_type, ) ) or 0 @@ -65,7 +66,7 @@ async def list_conversations( result = await session.execute( select(Conversation, msg_count.label("message_count")) - .where(Conversation.user_id == user_id) + .where(Conversation.user_id == user_id, Conversation.conversation_type == conv_type) .order_by(Conversation.updated_at.desc()) .limit(limit) .offset(offset) @@ -78,6 +79,8 @@ async def list_conversations( "id": conv.id, "title": conv.title, "model": conv.model, + "conversation_type": conv.conversation_type, + "briefing_date": conv.briefing_date.isoformat() if conv.briefing_date else None, "message_count": row[1], "created_at": conv.created_at.isoformat(), "updated_at": conv.updated_at.isoformat(), diff --git a/src/fabledassistant/services/tools.py b/src/fabledassistant/services/tools.py index 54050d8..97efdd5 100644 --- a/src/fabledassistant/services/tools.py +++ b/src/fabledassistant/services/tools.py @@ -478,6 +478,51 @@ _CORE_TOOLS = [ }, }, }, + { + "type": "function", + "function": { + "name": "get_weather", + "description": ( + "Get the current 7-day weather forecast for the user's configured locations. " + "Returns temperature, precipitation, and conditions for each day. " + "Also reports any changes since the last forecast was fetched." + ), + "parameters": { + "type": "object", + "properties": { + "location_key": { + "type": "string", + "description": "Which location to focus on: 'home', 'work', or 'all'. Defaults to 'all'.", + } + }, + "required": [], + }, + }, + }, + { + "type": "function", + "function": { + "name": "get_rss_items", + "description": ( + "Get recent items from the user's RSS feeds (news, blogs, Reddit, podcasts). " + "Returns titles, URLs, and summaries of recent posts." + ), + "parameters": { + "type": "object", + "properties": { + "limit": { + "type": "integer", + "description": "Number of items to return (default 15, max 50)", + }, + "category": { + "type": "string", + "description": "Filter by feed category (e.g. 'news', 'tech'). Omit for all.", + }, + }, + "required": [], + }, + }, + }, ] # CalDAV tools — only included when user has CalDAV configured @@ -1568,6 +1613,20 @@ async def execute_tool(user_id: int, tool_name: str, arguments: dict) -> dict: return {"success": False, "error": str(e)} return {"success": True, "log": log.to_dict(), "task": note.title} + elif tool_name == "get_weather": + from fabledassistant.services.weather import get_cached_weather + location_key = arguments.get("location_key", "all") + locations = await get_cached_weather(user_id) + if location_key != "all": + locations = [loc for loc in locations if loc["location_key"] == location_key] + return {"data": {"locations": locations}} + + elif tool_name == "get_rss_items": + from fabledassistant.services.rss import get_recent_items + limit = min(int(arguments.get("limit", 15)), 50) + items = await get_recent_items(user_id, limit=limit) + return {"data": {"items": items, "count": len(items)}} + else: return {"success": False, "error": f"Unknown tool: {tool_name}"}