Context-Based Timeout Configuration
Overview
The Aitana backend uses a context-aware timeout system that adjusts processing time limits based on where the request originates. This ensures optimal performance for user-facing operations while allowing extended processing for background tasks.
Context Types
1. UI Context (context="ui")
- Timeout: 60 seconds
- Use Case: Interactive web interface
- Characteristics:
- Fast response required for user experience
- Suitable for simple queries and small documents
- Default for all web frontend requests
2. API Context (context="api")
- Timeout: 300 seconds (5 minutes)
- Use Case: Batch processing, CLI tools, automated workflows
- Characteristics:
- Extended processing for large documents
- Suitable for complex extraction tasks
- Used by Aitana CLI batch-extract command
3. Email Context (context="email")
- Timeout: 300 seconds (5 minutes)
- Use Case: Email processing, webhook handlers
- Characteristics:
- Background processing without user waiting
- Suitable for document attachments
- Used by email integration system
4. Background Context (context="background")
- Timeout: 300 seconds (5 minutes)
- Use Case: Scheduled tasks, async processing
- Characteristics:
- No user interaction required
- Suitable for batch operations
- Used by background workers
Implementation Details
GenAI Client Configuration
The timeout is configured in backend/genai_client.py:
def get_genai_client(context="ui"):
"""Create GenAI client with context-aware timeout"""
if context in ["api", "email", "background"]:
timeout_ms = 300000 # 5 minutes
else: # ui or default
timeout_ms = 60000 # 1 minute
return genai.Client(
request_options=RequestOptions(
timeout=timeout_ms
)
)
Context Flow Through System
- Entry Point - Context is specified at request entry:
# CLI/Batch processing process_assistant_request(context="api") # Web UI process_assistant_request(context="ui") # Email handler process_assistant_request(context="email") - VAC Service - Context propagates through service layer:
async def vac_stream(**kwargs): request_context = kwargs.get("context", "ui") # Pass to model calls - Model Layer - Context reaches AI model configuration:
async def stream_smart(..., context="ui"): # Configure model timeout based on context - Tool Execution - Tools inherit context from parent:
async def file_browser_tool(..., context="ui"): # Tool timeout matches context
Usage Examples
CLI Batch Processing (5-minute timeout)
from assistant_utils import process_assistant_request
result = await process_assistant_request(
assistant_id="my-assistant",
user_input="Extract data from large PDF",
context="api", # 5-minute timeout
documents=[{"uri": "gs://bucket/large-file.pdf"}]
)
Web UI Request (60-second timeout)
# Flask/FastAPI endpoint
@app.post("/vac/assistant/{assistant_id}")
async def assistant_endpoint(request):
# Default context="ui" for web requests
result = await process_assistant_request(
assistant_id=assistant_id,
user_input=request.question,
context="ui" # 60-second timeout
)
Email Processing (5-minute timeout)
# Email webhook handler
async def process_email_attachment(attachment):
result = await process_assistant_request(
assistant_id="email-processor",
user_input="Process attachment",
context="email", # 5-minute timeout
documents=[attachment]
)
Performance Implications
UI Context (60 seconds)
Pros:
- Fast feedback to users
- Prevents browser timeouts
- Better perceived performance
Cons:
- May fail on large documents
- Complex queries might timeout
- Limited processing capability
API Context (5 minutes)
Pros:
- Handles large documents
- Complex extraction possible
- Better success rate
Cons:
- Longer wait times
- Higher resource usage
- Not suitable for interactive UI
Troubleshooting
Common Issues
1. DEADLINE_EXCEEDED Errors
Symptom: 503 The model is overloaded. Please try again later.
Cause: Processing exceeded context timeout
Solutions:
- For large files, use API context instead of UI
- Reduce document size or complexity
- Simplify extraction prompts
- Use batch processing with smaller chunks
2. Wrong Context Used
Symptom: Batch processing timing out at 60 seconds
Cause: Context parameter not passed through call chain
Solution: Ensure context is passed at every level:
# ✅ Correct
await process_assistant_request(
...,
context="api"
)
# ❌ Wrong (defaults to "ui")
await process_assistant_request(
...
# Missing context parameter
)
3. Context Lost in Tool Chain
Symptom: Tools timeout despite API context
Cause: Tool doesn’t propagate context
Solution: Pass context to all tool calls:
async def my_tool(..., context="ui"):
# Use context in nested calls
await another_tool(..., context=context)
Best Practices
1. Choose Appropriate Context
- Interactive operations: Use UI context
- Batch processing: Use API context
- Background jobs: Use background context
- Email/webhooks: Use email context
2. Document Size Guidelines
| Document Size | Recommended Context | Processing Time | |————–|——————-|—————-| | < 1MB | UI | < 30 seconds | | 1-10MB | UI/API | 30-120 seconds | | 10-50MB | API | 2-5 minutes | | > 50MB | API + chunking | 5+ minutes |
3. Prompt Complexity Guidelines
| Prompt Type | Recommended Context | Example | |————|——————-|———| | Simple extraction | UI | “Extract title and date” | | Structured extraction | UI/API | “Extract all obligations with schema” | | Complex analysis | API | “Analyze legal implications and risks” | | Multi-document | API | “Compare these 5 contracts” |
4. Error Handling
Always handle timeout errors gracefully:
try:
result = await process_assistant_request(
...,
context="ui"
)
except DeadlineExceeded:
# Retry with longer timeout
result = await process_assistant_request(
...,
context="api"
)
Configuration
Environment Variables
# Optional: Override default timeouts (milliseconds)
GENAI_UI_TIMEOUT_MS=60000
GENAI_API_TIMEOUT_MS=300000
GENAI_EMAIL_TIMEOUT_MS=300000
GENAI_BACKGROUND_TIMEOUT_MS=300000
Dynamic Context Selection
def get_optimal_context(file_size_mb, prompt_complexity):
"""Dynamically select context based on workload"""
if file_size_mb < 1 and prompt_complexity == "simple":
return "ui"
elif file_size_mb < 10:
return "ui" if prompt_complexity == "simple" else "api"
else:
return "api"
Migration Guide
Updating Existing Code
- Identify timeout issues - Look for DEADLINE_EXCEEDED errors
- Add context parameter - Update function signatures
- Pass context through - Ensure propagation through call chain
- Test with large files - Verify 5-minute timeout works
Example Migration
# Before (60-second timeout)
async def process_documents(files):
for file in files:
result = await process_assistant_request(
user_input="Extract data",
documents=[file]
)
# After (5-minute timeout)
async def process_documents(files, context="api"):
for file in files:
result = await process_assistant_request(
user_input="Extract data",
documents=[file],
context=context # Pass context
)