mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
When new users sign up, check if they previously filled out the Tally beta application form and, if so, pre-populate their CoPilotUnderstanding with business data extracted from that form. This gives the CoPilot (Otto) immediate context about the user on their very first chat interaction. ### Changes 🏗️ - **`backend/util/settings.py`**: Added `tally_api_key` to `Secrets` class - **`backend/.env.default`**: Added `TALLY_API_KEY=` env var entry - **`backend/data/tally.py`** (new): Core Tally integration module - Redis-cached email index of form submissions (1h TTL) with incremental refresh via `startDate` - Paginated Tally API fetching with Bearer token auth - Email matching (case-insensitive) against submission data - LLM extraction (gpt-4o-mini via OpenRouter) of `BusinessUnderstandingInput` fields - Fire-and-forget orchestrator that is idempotent and never raises - **`backend/api/features/v1.py`**: Added background task in `get_or_create_user_route` to trigger Tally lookup on login (skips if understanding already exists) - **`backend/data/tally_test.py`** (new): 15 unit tests covering index building, email case-insensitivity, cache hit/miss, format helpers, idempotency, graceful degradation, and error resilience ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] All 15 unit tests pass (`poetry run pytest backend/data/tally_test.py --noconftest -xvs`) - [x] Lint clean (`poetry run ruff check` on changed files) - [x] Type check clean (`poetry run pyright` on new files) - [ ] Manual: Set `TALLY_API_KEY` in `.env`, create a new user, verify CoPilotUnderstanding is populated - [ ] Manual: Verify user creation succeeds when Tally API key is missing or API is down #### For configuration changes: - [x] `.env.default` is updated or already compatible with my changes - [x] `docker-compose.yml` is updated or already compatible with my changes - [x] I have included a list of my configuration changes in the PR description (under **Changes**) - Added `TALLY_API_KEY=` to `.env.default` (optional, empty by default — feature is a no-op without it) <!-- greptile_comment --> <details><summary><h3>Greptile Summary</h3></summary> This PR adds a Tally form integration that pre-populates `CoPilotUnderstanding` for new users by matching their signup email against cached Tally beta application form submissions, then using an LLM (gpt-4o-mini via OpenRouter) to extract structured business data. - **New module `tally.py`** implements Redis-cached email indexing of Tally form submissions with incremental refresh, email matching, LLM extraction, and an idempotent fire-and-forget orchestrator - **`v1.py`** adds a background task on the `get_or_create_user_route` to trigger Tally lookup on every login (idempotency check is inside the called function) - **`settings.py` / `.env.default`** adds `tally_api_key` as an optional secret — feature is a no-op without it - **`tally_test.py`** adds 15 unit tests with thorough mocking coverage - **Bug: TTL mismatch** — `_LAST_FETCH_TTL` (2h) > `_INDEX_TTL` (1h) creates a window where incremental refresh loses all previously indexed emails because the base index has expired but `last_fetch` persists. This will cause silent data loss for users whose form submissions were indexed before the cache expiry - **Bug: `str.format()` on LLM prompt** — form data containing `{` or `}` will crash the prompt formatting, silently preventing understanding population for those users </details> <details><summary><h3>Confidence Score: 2/5</h3></summary> - This PR has two logic bugs that will cause silent data loss in production — recommend fixing before merge. - The TTL mismatch between `_LAST_FETCH_TTL` and `_INDEX_TTL` will intermittently cause incomplete caches, silently dropping users from the email index. The `str.format()` issue will cause failures for any form submission containing curly braces. Both bugs are caught by the top-level exception handler, so they won't crash the service, but they will silently prevent the feature from working correctly for affected users. The overall architecture is sound and well-tested for normal paths. - `autogpt_platform/backend/backend/data/tally.py` — contains both the TTL mismatch bug in `_refresh_cache` and the `str.format()` issue in `extract_business_understanding` </details> <details><summary><h3>Sequence Diagram</h3></summary> ```mermaid sequenceDiagram participant User participant API as v1.py (get_or_create_user_route) participant Tally as tally.py (populate_understanding_from_tally) participant DB as Database (understanding) participant Redis participant TallyAPI as Tally API participant LLM as OpenRouter (gpt-4o-mini) User->>API: POST /auth/user (JWT) API->>API: get_or_create_user(user_data) API-->>User: Return user (immediate) API->>Tally: asyncio.create_task(populate_understanding_from_tally) Tally->>DB: get_business_understanding(user_id) alt Understanding exists DB-->>Tally: existing understanding Note over Tally: Skip (idempotent) else No understanding DB-->>Tally: None Tally->>Tally: Check tally_api_key configured Tally->>Redis: Check cached email index alt Cache hit Redis-->>Tally: email_index + questions else Cache miss Redis-->>Tally: None Tally->>TallyAPI: GET /forms/{id}/submissions (paginated) TallyAPI-->>Tally: submissions + questions Tally->>Tally: Build email index Tally->>Redis: Cache index (1h TTL) end Tally->>Tally: Lookup email in index alt Email found Tally->>Tally: format_submission_for_llm() Tally->>LLM: Extract BusinessUnderstandingInput LLM-->>Tally: JSON structured data Tally->>DB: upsert_business_understanding(user_id, input) end end ``` </details> <sub>Last reviewed commit: 92d2da4</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment --> --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Otto (AGPT) <otto@agpt.co> Co-authored-by: Reinier van der Leer <pwuts@agpt.co>
198 lines
6.2 KiB
Plaintext
198 lines
6.2 KiB
Plaintext
# Backend Configuration
|
|
# This file contains environment variables that MUST be set for the AutoGPT platform
|
|
# Variables with working defaults in settings.py are not included here
|
|
|
|
## ===== REQUIRED DATABASE CONFIGURATION ===== ##
|
|
# PostgreSQL Database Connection
|
|
DB_USER=postgres
|
|
DB_PASS=your-super-secret-and-long-postgres-password
|
|
DB_NAME=postgres
|
|
DB_PORT=5432
|
|
DB_HOST=localhost
|
|
DB_CONNECTION_LIMIT=12
|
|
DB_CONNECT_TIMEOUT=60
|
|
DB_POOL_TIMEOUT=300
|
|
DB_SCHEMA=platform
|
|
DATABASE_URL="postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}?schema=${DB_SCHEMA}&connect_timeout=${DB_CONNECT_TIMEOUT}"
|
|
DIRECT_URL="postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}?schema=${DB_SCHEMA}&connect_timeout=${DB_CONNECT_TIMEOUT}"
|
|
PRISMA_SCHEMA="postgres/schema.prisma"
|
|
|
|
## ===== REQUIRED SERVICE CREDENTIALS ===== ##
|
|
# Redis Configuration
|
|
REDIS_HOST=localhost
|
|
REDIS_PORT=6379
|
|
# REDIS_PASSWORD=
|
|
|
|
# RabbitMQ Credentials
|
|
RABBITMQ_DEFAULT_USER=rabbitmq_user_default
|
|
RABBITMQ_DEFAULT_PASS=k0VMxyIJF9S35f3x2uaw5IWAl6Y536O7
|
|
|
|
# Supabase Authentication
|
|
SUPABASE_URL=http://localhost:8000
|
|
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q
|
|
JWT_VERIFY_KEY=your-super-secret-jwt-token-with-at-least-32-characters-long
|
|
|
|
## ===== REQUIRED SECURITY KEYS ===== ##
|
|
# Generate using: from cryptography.fernet import Fernet;Fernet.generate_key().decode()
|
|
ENCRYPTION_KEY=dvziYgz0KSK8FENhju0ZYi8-fRTfAdlz6YLhdB_jhNw=
|
|
UNSUBSCRIBE_SECRET_KEY=HlP8ivStJjmbf6NKi78m_3FnOogut0t5ckzjsIqeaio=
|
|
|
|
## ===== IMPORTANT OPTIONAL CONFIGURATION ===== ##
|
|
# Platform URLs (set these for webhooks and OAuth to work)
|
|
PLATFORM_BASE_URL=http://localhost:8000
|
|
FRONTEND_BASE_URL=http://localhost:3000
|
|
|
|
# Media Storage (required for marketplace and library functionality)
|
|
MEDIA_GCS_BUCKET_NAME=
|
|
|
|
## ===== API KEYS AND OAUTH CREDENTIALS ===== ##
|
|
# All API keys below are optional - only add what you need
|
|
|
|
# AI/LLM Services
|
|
OPENAI_API_KEY=
|
|
ANTHROPIC_API_KEY=
|
|
GROQ_API_KEY=
|
|
LLAMA_API_KEY=
|
|
AIML_API_KEY=
|
|
V0_API_KEY=
|
|
OPEN_ROUTER_API_KEY=
|
|
NVIDIA_API_KEY=
|
|
|
|
# Langfuse Prompt Management
|
|
# Used for managing the CoPilot system prompt externally
|
|
# Get credentials from https://cloud.langfuse.com or your self-hosted instance
|
|
LANGFUSE_PUBLIC_KEY=
|
|
LANGFUSE_SECRET_KEY=
|
|
LANGFUSE_HOST=https://cloud.langfuse.com
|
|
|
|
# OAuth Credentials
|
|
# For the OAuth callback URL, use <your_frontend_url>/auth/integrations/oauth_callback,
|
|
# e.g. http://localhost:3000/auth/integrations/oauth_callback
|
|
|
|
# GitHub OAuth App server credentials - https://github.com/settings/developers
|
|
GITHUB_CLIENT_ID=
|
|
GITHUB_CLIENT_SECRET=
|
|
|
|
# Notion OAuth App server credentials - https://developers.notion.com/docs/authorization
|
|
# Configure a public integration
|
|
NOTION_CLIENT_ID=
|
|
NOTION_CLIENT_SECRET=
|
|
|
|
# Google OAuth App server credentials - https://console.cloud.google.com/apis/credentials, and enable gmail api and set scopes
|
|
# https://console.cloud.google.com/apis/credentials/consent ?project=<your_project_id>
|
|
# You'll need to add/enable the following scopes (minimum):
|
|
# https://console.developers.google.com/apis/api/gmail.googleapis.com/overview ?project=<your_project_id>
|
|
# https://console.cloud.google.com/apis/library/sheets.googleapis.com/ ?project=<your_project_id>
|
|
GOOGLE_CLIENT_ID=
|
|
GOOGLE_CLIENT_SECRET=
|
|
|
|
# Twitter (X) OAuth 2.0 with PKCE Configuration
|
|
# 1. Create a Twitter Developer Account:
|
|
# - Visit https://developer.x.com/en and sign up
|
|
# 2. Set up your application:
|
|
# - Navigate to Developer Portal > Projects > Create Project
|
|
# - Add a new app to your project
|
|
# 3. Configure app settings:
|
|
# - App Permissions: Read + Write + Direct Messages
|
|
# - App Type: Web App, Automated App or Bot
|
|
# - OAuth 2.0 Callback URL: http://localhost:3000/auth/integrations/oauth_callback
|
|
# - Save your Client ID and Client Secret below
|
|
TWITTER_CLIENT_ID=
|
|
TWITTER_CLIENT_SECRET=
|
|
|
|
# Linear App
|
|
# Make a new workspace for your OAuth APP -- trust me
|
|
# https://linear.app/settings/api/applications/new
|
|
# Callback URL: http://localhost:3000/auth/integrations/oauth_callback
|
|
LINEAR_API_KEY=
|
|
# Linear project and team IDs for the feature request tracker.
|
|
# Find these in your Linear workspace URL: linear.app/<workspace>/project/<project-id>
|
|
# and in team settings. Used by the chat copilot to file and search feature requests.
|
|
LINEAR_FEATURE_REQUEST_PROJECT_ID=
|
|
LINEAR_FEATURE_REQUEST_TEAM_ID=
|
|
LINEAR_CLIENT_ID=
|
|
LINEAR_CLIENT_SECRET=
|
|
|
|
# To obtain Todoist API credentials:
|
|
# 1. Create a Todoist account at todoist.com
|
|
# 2. Visit the Developer Console: https://developer.todoist.com/appconsole.html
|
|
# 3. Click "Create new app"
|
|
# 4. Once created, copy your Client ID and Client Secret below
|
|
TODOIST_CLIENT_ID=
|
|
TODOIST_CLIENT_SECRET=
|
|
|
|
NOTION_CLIENT_ID=
|
|
NOTION_CLIENT_SECRET=
|
|
|
|
# Discord OAuth App credentials
|
|
# 1. Go to https://discord.com/developers/applications
|
|
# 2. Create a new application
|
|
# 3. Go to OAuth2 section and add redirect URI: http://localhost:3000/auth/integrations/oauth_callback
|
|
# 4. Copy Client ID and Client Secret below
|
|
DISCORD_CLIENT_ID=
|
|
DISCORD_CLIENT_SECRET=
|
|
|
|
REDDIT_CLIENT_ID=
|
|
REDDIT_CLIENT_SECRET=
|
|
|
|
# Payment Processing
|
|
STRIPE_API_KEY=
|
|
STRIPE_WEBHOOK_SECRET=
|
|
|
|
# Email Service (for sending notifications and confirmations)
|
|
POSTMARK_SERVER_API_TOKEN=
|
|
POSTMARK_SENDER_EMAIL=invalid@invalid.com
|
|
POSTMARK_WEBHOOK_TOKEN=
|
|
|
|
# Error Tracking
|
|
SENTRY_DSN=
|
|
|
|
# Feature Flags
|
|
LAUNCH_DARKLY_SDK_KEY=
|
|
|
|
# Content Generation & Media
|
|
DID_API_KEY=
|
|
FAL_API_KEY=
|
|
IDEOGRAM_API_KEY=
|
|
REPLICATE_API_KEY=
|
|
REVID_API_KEY=
|
|
SCREENSHOTONE_API_KEY=
|
|
UNREAL_SPEECH_API_KEY=
|
|
ELEVENLABS_API_KEY=
|
|
|
|
# Data & Search Services
|
|
E2B_API_KEY=
|
|
EXA_API_KEY=
|
|
JINA_API_KEY=
|
|
MEM0_API_KEY=
|
|
OPENWEATHERMAP_API_KEY=
|
|
GOOGLE_MAPS_API_KEY=
|
|
|
|
# Communication Services
|
|
DISCORD_BOT_TOKEN=
|
|
MEDIUM_API_KEY=
|
|
MEDIUM_AUTHOR_ID=
|
|
SMTP_SERVER=
|
|
SMTP_PORT=
|
|
SMTP_USERNAME=
|
|
SMTP_PASSWORD=
|
|
|
|
# Business & Marketing Tools
|
|
APOLLO_API_KEY=
|
|
ENRICHLAYER_API_KEY=
|
|
AYRSHARE_API_KEY=
|
|
AYRSHARE_JWT_KEY=
|
|
SMARTLEAD_API_KEY=
|
|
ZEROBOUNCE_API_KEY=
|
|
|
|
# PostHog Analytics
|
|
# Get API key from https://posthog.com - Project Settings > Project API Key
|
|
POSTHOG_API_KEY=
|
|
POSTHOG_HOST=https://eu.i.posthog.com
|
|
|
|
# Tally Form Integration (pre-populate business understanding on signup)
|
|
TALLY_API_KEY=
|
|
|
|
# Other Services
|
|
AUTOMOD_API_KEY=
|