Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
da462ae
application/pdf export to mime map
pocucan-ds Jul 16, 2025
5f6b8a6
impersonation feature for client.
pocucan-ds Jul 16, 2025
38ffe8b
remove impersonation at class level and define it at instance level.
pocucan-ds Jul 18, 2025
466fe37
updated tests
pocucan-ds Jul 18, 2025
5dd7fe4
impersonation same loop
pocucan-ds Jul 18, 2025
238f8fd
updated environment variables.
pocucan-ds Jul 18, 2025
4524989
impersonation support changelog
pocucan-ds Jul 18, 2025
f3e5255
Merge branch 'main' into extension/source/googledrive/impersonator
pocucan-ds Jul 18, 2025
6a65354
updated how to and formatted.
pocucan-ds Jul 18, 2025
4041158
Merge branch 'extension/source/googledrive/impersonator' of https://g…
pocucan-ds Jul 18, 2025
20df7d2
updated for ruff
pocucan-ds Jul 18, 2025
54da82b
updated signature
pocucan-ds Jul 18, 2025
da272a8
Add impersonation attributes to GoogleDriveSource and update tests fo…
maxpill Jul 21, 2025
7f095c1
Merge branch 'main' into feat/gdrive-impersonator
maxpill Jul 21, 2025
55c3f34
Add GoogleDriveExportFormat enum and update MIME type handling in Goo…
maxpill Jul 24, 2025
43e507d
feat: force tool calling support (#751)
GlockPL Aug 6, 2025
5de31a6
Merge branch 'main' into feat/gdrive-impersonator
maxpill Aug 6, 2025
ca72a0f
Merge branch 'feat/gdrive-impersonator' of https://github.com/deepsen…
maxpill Aug 8, 2025
9290b3e
feat: force tool calling support (#751)
GlockPL Aug 6, 2025
c5b3f73
feat: add PydanticAI agents support (#755)
akotyla Aug 6, 2025
4e60aeb
feat: Autogenerate TS types (#727)
jakubduda-dsai Aug 7, 2025
f267d39
fix: prompt consumes same iterator twice (#768)
ds-sebastianchwilczynski Aug 7, 2025
14b1e77
feat(ui): page title & favicon customization (#767)
dazy-ds Aug 7, 2025
d74a13b
feat(google_drive): enhance impersonation capabilities with class-lev…
maxpill Aug 11, 2025
d2d5537
Merge branch 'main' into feat/gdrive-impersonator
maxpill Aug 11, 2025
ac54d78
fix(google_drive): remove redundant comment in credentials file path
maxpill Aug 11, 2025
84e4f7f
Merge branch 'feat/gdrive-impersonator' of https://github.com/deepsen…
maxpill Aug 11, 2025
6309afc
feat(google_drive): add class method for default impersonation target
maxpill Aug 11, 2025
a7352a9
Merge branch 'develop' of https://github.com/deepsense-ai/ragbits int…
maxpill Aug 12, 2025
04ad536
feat: Optional parallel batches execution in ragbits.evaluate.Evaluat…
vladimir-kivi-ds Aug 14, 2025
6cfb38c
feat(auth): Backend authentication into the chat (#761)
GlockPL Aug 14, 2025
67fbd71
feat(lazy-loading): Decreasing the time needed to start the app (#753)
GlockPL Aug 18, 2025
f7c920a
feat(ui): initial auth plugin (#763)
dazy-ds Aug 19, 2025
6316196
Merge branch 'develop' into feat/gdrive-impersonator
GlockPL Aug 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/shared-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ jobs:
env:
GOOGLE_DRIVE_CLIENTID_JSON: ${{ secrets.GOOGLE_DRIVE_CLIENTID_JSON }}
GOOGLE_SOURCE_UNIT_TEST_FOLDER: ${{ secrets.GOOGLE_SOURCE_UNIT_TEST_FOLDER }}
GOOGLE_DRIVE_TARGET_EMAIL: ${{ secrets.GOOGLE_DRIVE_TARGET_EMAIL }}

- name: Test Report
uses: mikepenz/action-junit-report@v4
Expand Down
8 changes: 8 additions & 0 deletions docs/how-to/agents/define_and_use_agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ The result is an [AgentResult][ragbits.agents.AgentResult], which includes the m

You can find the complete code example in the Ragbits repository [here](https://github.com/deepsense-ai/ragbits/blob/main/examples/agents/tool_use.py).

## Tool choice
To control what tool is used at first call you could use `tool_choice` parameter. There are the following options:
- "auto": let model decide if tool call is needed
- "none": do not call tool
- "required: enforce tool usage (model decides which one)
- Callable: one of provided tools


## Conversation history
[`Agent`][ragbits.agents.Agent]s can retain conversation context across multiple interactions by enabling the `keep_history` flag when initializing the agent. This is useful when you want the agent to understand follow-up questions without needing the user to repeat earlier details.

Expand Down
44 changes: 44 additions & 0 deletions docs/how-to/sources/google-drive.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,50 @@ async def process_drive_documents():
asyncio.run(process_drive_documents())
```

## Impersonating Google Accounts

You can configure your Google service account to impersonate other users in your Google Workspace domain. This is useful when you need to access files or perform actions on behalf of specific users.

### Step 1: Enable Domain-Wide Delegation

1. **Sign in to the [Google Admin Console](https://admin.google.com/) as a Super Admin.**
2. Navigate to:
**Security > Access and data control > API controls > MANAGE DOMAIN WIDE DELEGATION**
3. Add a new API client or edit an existing one, and include the following OAuth scopes:
- `https://www.googleapis.com/auth/cloud-platform`
- `https://www.googleapis.com/auth/drive`
4. Click **Authorize** or **Save** to apply the changes.

### Step 2: Impersonate a User in Your Code

After configuring domain-wide delegation, you can specify a target user to impersonate when using the `GoogleDriveSource` in your code.

```python
from ragbits.core.sources.google_drive import GoogleDriveSource

target_email = "[email protected]"
credentials_file = "service-account-key.json"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd put link to the part about creating this credential_file here.

This how-to is very long and I believe someone may forgot what this credential file is all about long ago. Or if they come directly to this place, they're cooked


# Set the path to your service account key file
GoogleDriveSource.set_credentials_file_path(credentials_file)

# Option 1: Set default impersonation for all instances (class-level)
GoogleDriveSource.set_default_impersonation_target(target_email)

# Option 2: Set impersonation for specific instances
sources = await GoogleDriveSource.from_uri("folder_id/**", impersonate_target_email=target_email)

# Option 3: Set impersonation on individual instances
source = GoogleDriveSource(file_id="...", file_name="...", mime_type="...")
source.set_impersonation_target(target_email)
```

**Note:**
- The `target_email` must be a valid user in your Google Workspace domain.
- Ensure your service account has been granted domain-wide delegation as described above.

This setup allows your service account to act on behalf of the specified user, enabling access to their Google Drive files and resources as permitted by the assigned scopes.

## Troubleshooting

### Common Issues
Expand Down
2 changes: 1 addition & 1 deletion examples/agents/tool_use.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ async def main() -> None:
tools=[get_weather],
default_options=AgentOptions(max_total_tokens=500, max_turns=5),
)
response = await agent.run(WeatherPromptInput(location="Paris"))
response = await agent.run(WeatherPromptInput(location="Paris"), tool_choice=get_weather)
print(response)


Expand Down
215 changes: 215 additions & 0 deletions examples/chat/README_authenticated.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# Authenticated Chat Example

This example demonstrates how to create a chat interface with user authentication using Ragbits Chat.

## Features

- 🔐 **User Authentication**: Login/logout with username/password
- 👤 **Role-based Access**: Different user roles (admin, moderator, user) with specific capabilities
- 🛡️ **Secure Sessions**: Session-based authentication with Bearer tokens
- 📊 **Personalized Responses**: User-specific chat responses based on profile and roles
- 🔄 **Live Updates**: Role-specific live updates during processing
- 📚 **User Context**: Reference documents with user profile information
- 🎨 **UI Customization**: Custom welcome messages, headers, and branding
- 📝 **Feedback System**: Like/dislike forms with custom Pydantic models
- ⚙️ **User Settings**: Configurable user preferences (e.g., language selection)

## Files

- `authenticated_chat.py` - Main authenticated chat implementation
- `README_authenticated.md` - This documentation

## Quick Start

### 1. Start the Server

#### Full Authentication Support (Recommended)
```bash
# From the examples/chat directory - includes login/logout endpoints
uv run python authenticated_chat.py
```

#### Alternative Methods
```bash
# From project root
python examples/chat/authenticated_chat.py

# Via CLI with authentication support
uv run ragbits api run examples.chat.authenticated_chat:MyAuthenticatedChat --auth examples.chat.authenticated_chat:get_auth_backend
```

The server will start at `http://127.0.0.1:8000` with a web interface.

**Note**: When using the CLI, include the `--auth` flag with the authentication backend factory function to enable full authentication features including login/logout endpoints.

### 2. Test Users

The example includes these test users:

| Username | Password | Roles | Description |
|-----------|-----------|--------------------------|---------------------|
| `admin` | `admin123` | admin, moderator, user | System administrator |
| `moderator` | `mod123` | moderator, user | Community moderator |
| `alice` | `alice123` | user | Regular user |
| `bob` | `bob123` | user | Regular user |

### 3. Authentication Workflow

#### Web Interface
1. Open `http://127.0.0.1:8000` in your browser
2. Use the login form with any test user credentials
3. Start chatting after successful authentication

#### API Endpoints
1. **Login**: `POST /api/auth/login`
```json
{
"username": "admin",
"password": "admin123"
}
```

2. **Chat**: `POST /api/chat` (with Bearer token)
```bash
Authorization: Bearer <session_id>
```

3. **Logout**: `POST /api/auth/logout`
```json
{
"session_id": "<session_id>"
}
```

## Testing

You can test the authentication functionality using:

### Web Interface Testing
1. Start the server: `python examples/chat/authenticated_chat.py`
2. Open `http://127.0.0.1:8000` in your browser
3. Use the login form with any of the test user credentials
4. Test different roles and their specific features

### API Testing with curl
```bash
# Login
curl -X POST http://127.0.0.1:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "admin123"}'

# Chat (replace <session_id> with the session_id from login response)
curl -X POST http://127.0.0.1:8000/api/chat \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <session_id>" \
-d '{"message": "Hello!"}'

# Logout
curl -X POST http://127.0.0.1:8000/api/auth/logout \
-H "Content-Type: application/json" \
-d '{"session_id": "<session_id>"}'
```

## Example Chat Interactions

### As Admin User
```
💬 You: What admin features are available?
🤖 Bot: As an administrator, you have full system access including:
- User management and permissions
- System configuration and monitoring
- Content moderation capabilities
- Administrative dashboards and reports
```

### As Regular User
```
💬 You: Tell me about my profile
🤖 Bot: Hello Alice Johnson! You're logged in as 'alice' with user role.
Your profile shows you're part of the Marketing department.
```

## Architecture
### ListAuthBackend
- In-memory user storage with hashed passwords
- Session management with expiration
- User roles and metadata support
- Suitable for development and small deployments

### Role-based Features
- **Admin**: Full system access, admin-specific live updates, special admin profile images
- **Moderator**: Content moderation features with policy checks and content guidelines
- **User**: Standard chat features with personalized responses and user-specific context

## Customization

### Adding New Users
Edit the `get_auth_backend()` factory function in `authenticated_chat.py`:

```python
users = [
{
"username": "newuser",
"password": "newpass123",
"email": "[email protected]",
"full_name": "New User",
"roles": ["user"],
"metadata": {"department": "Engineering"}
}
]
```


### Role-specific Responses
Modify the `chat()` method to customize responses based on user roles:

```python
# Get user info from context
user_info = context.state.get("authenticated_user") if context else None
user_roles = user_info.roles if user_info else []

if "admin" in user_roles:
yield self.create_text_response("🔧 Admin-specific content...")
elif "moderator" in user_roles:
yield self.create_text_response("🛡️ Moderator-specific content...")
```

### UI Customization

The example demonstrates UI customization features:

```python
from ragbits.chat.interface.ui_customization import HeaderCustomization, UICustomization

ui_customization = UICustomization(
header=HeaderCustomization(
title="🔐 Authenticated Ragbits Chat",
subtitle="by deepsense.ai - Secure Chat Experience",
logo="🛡️"
),
welcome_message="🔐 **Welcome to Authenticated Ragbits Chat!**\n\n..."
)
```

### Feedback Configuration

Custom feedback forms using Pydantic models:

```python
from ragbits.chat.interface.forms import FeedbackConfig

feedback_config = FeedbackConfig(
like_enabled=True,
like_form=LikeFormExample, # Custom Pydantic model
dislike_enabled=True,
dislike_form=DislikeFormExample, # Custom Pydantic model
)
```

## Security Notes

- Passwords are hashed using bcrypt in `ListAuthBackend`
- Sessions have configurable expiration times
- Bearer tokens are used for API authentication
- CORS is configured for web interface access
- State signatures prevent tampering with conversation state
Loading
Loading