- Add chat_message table for message-level analytics with usage JSON field
- Add migration to backfill from existing chats
- Add /analytics endpoints: summary, models, users, daily
- Support hourly/daily granularity for time-series data
- Fill missing days/hours in date range
## Summary
Eliminates redundant database query in update_memory_by_id_and_user_id. Previously, after modifying the memory object, it called get_memory_by_id which opened a new session and queried again.
## Changes
models/memories.py update_memory_by_id_and_user_id:
- Replace self.get_memory_by_id(id) with db.refresh(memory)
- Return the same memory object that was already modified
## Performance Impact
Before: 2 queries (get + get_memory_by_id)
After: 1 query + refresh on same session
This fix restores and extends the username/email search functionality across workspace pages that was originally added in PR #14002. The issue was that:
1. The backend search functions for Models and Knowledge only searched `User.name` and `User.email`, but not `User.username`
2. The Functions admin page lacked user search entirely
Changes made:
Added User.username to backend search conditions for Models and Knowledge pages
Added complete user search (name, email, username) to the Functions admin page client-side filter
## Summary
Fixed N+1 query pattern in the `/api/v1/users` endpoint where groups were being fetched for each user individually.
### Problem
The `GET /api/v1/users` endpoint called `Groups.get_groups_by_member_id()` for each user, resulting in:
- 1 query for users
- N queries for groups (one per user)
### Solution
Added a new `Groups.get_groups_by_member_ids()` method that fetches groups for multiple users in a single query using SQL `IN` clause and `JOIN`.
### Changes
- **[groups.py](open_webui/models/groups.py)**: Added `get_groups_by_member_ids()` method
- **[users.py](open_webui/routers/users.py)**: Updated endpoint to use bulk method
### Result
- Before: 1 + N queries
- After: 2 queries total (1 for users, 1 for all groups)
* feat: Add read-only access support for Tools
- Backend: Add write_access field to ToolAccessResponse
- Backend: Update /tools/list to return tools with write_access
- Frontend: Display Read Only badge in Tools list
- Frontend: Disable inputs and save button when no write access
- Frontend: Add readOnly prop to CodeEditor component
* Update Tools.svelte
* fix: Return write_access from getToolById endpoint
fix: Return write_access from getToolById endpoint
- Use ToolAccessResponse instead of raw dict
- Remove inefficient getToolList call in edit page
* refactor: Rename write_access to disabled in ToolkitEditor
- Rename prop from write_access to disabled
- Invert logic where needed
- Update edit page to pass disabled instead of write_access
* rem
* Update +page.svelte
* fix
* Update ToolkitEditor.svelte
* Update CodeEditor.svelte
* Update ToolkitEditor.svelte
* feat: Add read-only access support for Models
- Backend: Add write_access field to ModelAccessResponse
- Backend: Update /models/list to return ModelAccessListResponse
- Frontend: Display Read Only badge in Models list
- Frontend: Disable inputs and save button when no write access
- Frontend: Hide action buttons for read-only models
* fix: Handle ModelAccessListResponse format in getModels API
- Backend returns {items, total} instead of {data}
- Update getModels API to handle both formats for backward compatibility
* fix: Show read-only shared models in workspace list
- Backend: Change search_models permission from 'write' to 'read' to include shared models
- Backend: Keep user_id filter to only show owned/shared models (not all public)
- Frontend: Handle ModelAccessListResponse format in getModels API
* fix: Align Read Only badge inline with model name
* fix: Correct badge placement and fix syntax error
* fix: Resolve badge truncation in Models list
- Add w-full to flex container for proper spacing
- Wrap Badge in div to prevent truncation
- Match Knowledge.svelte badge pattern
* fix: Align Read Only badge with Knowledge.svelte pattern
- Match Knowledge.svelte structure for badge placement
- Actions only show when write_access or admin
- Remove w-full from container to prevent right-overflow
* fix: Return write_access from getModelById endpoint
fix: Return write_access from getModelById endpoint
- Use ModelAccessResponse instead of raw dict
- Remove inefficient getModels call in edit page
* revert
* fix
* fix
* fix