name: Send Message SDK Tests on: pull_request_target: branches: [main] # TODO: uncomment before merge types: [labeled] paths: - 'letta/**' jobs: send-messages: # Only run when the "safe to test" label is applied if: contains(github.event.pull_request.labels.*.name, 'safe to test') runs-on: ubuntu-latest timeout-minutes: 15 strategy: fail-fast: false matrix: config_file: - "openai-gpt-4o-mini.json" - "azure-gpt-4o-mini.json" - "claude-3-5-sonnet.json" - "claude-4-sonnet-extended.json" - "claude-3-7-sonnet-extended.json" - "gemini-pro.json" - "gemini-vertex.json" services: qdrant: image: qdrant/qdrant ports: - 6333:6333 postgres: image: pgvector/pgvector:pg17 ports: - 5432:5432 env: POSTGRES_HOST_AUTH_METHOD: trust POSTGRES_DB: postgres POSTGRES_USER: postgres options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 redis: image: redis:7 ports: - 6379:6379 options: >- --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 5s --health-retries 10 steps: # Ensure secrets don't leak - name: Configure git to hide secrets run: | git config --global core.logAllRefUpdates false git config --global log.hideCredentials true - name: Set up secret masking run: | # Automatically mask any environment variable ending with _KEY for var in $(env | grep '_KEY=' | cut -d= -f1); do value="${!var}" if [[ -n "$value" ]]; then # Mask the full value echo "::add-mask::$value" # Also mask partial values (first and last several characters) # This helps when only parts of keys appear in logs if [[ ${#value} -gt 8 ]]; then echo "::add-mask::${value:0:8}" echo "::add-mask::${value:(-8)}" fi # Also mask with common formatting changes # Some logs might add quotes or other characters echo "::add-mask::\"$value\"" echo "::add-mask::$value\"" echo "::add-mask::\"$value" echo "Masked secret: $var (length: ${#value})" fi done # Check out base repository code, not the PR's code (for security) - name: Checkout base repository uses: actions/checkout@v4 # No ref specified means it uses base branch # Only extract relevant files from the PR (for security, specifically prevent modification of workflow files) - name: Extract PR schema files run: | # Fetch PR without checking it out git fetch origin pull/${{ github.event.pull_request.number }}/head:pr-${{ github.event.pull_request.number }} # Extract ONLY the schema files git checkout pr-${{ github.event.pull_request.number }} -- letta/ - name: Set up python 3.12 id: setup-python uses: actions/setup-python@v5 with: python-version: 3.12 - name: Install uv uses: astral-sh/setup-uv@v4 with: version: "latest" - name: Load cached venv id: cached-uv-dependencies uses: actions/cache@v4 with: path: .venv key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/uv.lock') }} restore-keys: | venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}- - name: Install dependencies if: steps.cached-uv-dependencies.outputs.cache-hit != 'true' shell: bash run: uv sync --extra dev --extra postgres --extra external-tools --extra cloud-tool-sandbox --extra google - name: Install letta packages run: | uv run pip install --upgrade letta-client letta - name: Migrate database env: LETTA_PG_PORT: 5432 LETTA_PG_USER: postgres LETTA_PG_PASSWORD: postgres LETTA_PG_DB: postgres LETTA_PG_HOST: localhost run: | psql -h localhost -U postgres -d postgres -c 'CREATE EXTENSION vector' uv run alembic upgrade head - name: Run integration tests for ${{ matrix.config_file }} env: LLM_CONFIG_FILE: ${{ matrix.config_file }} LETTA_PG_PORT: 5432 LETTA_PG_USER: postgres LETTA_PG_PASSWORD: postgres LETTA_PG_DB: postgres LETTA_PG_HOST: localhost LETTA_REDIS_HOST: localhost LETTA_REDIS_PORT: 6379 LETTA_SERVER_PASS: test_server_token OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} AZURE_API_KEY: ${{ secrets.AZURE_API_KEY }} AZURE_BASE_URL: ${{ secrets.AZURE_BASE_URL }} GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} COMPOSIO_API_KEY: ${{ secrets.COMPOSIO_API_KEY }} DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} GOOGLE_CLOUD_PROJECT: ${{ secrets.GOOGLE_CLOUD_PROJECT }} GOOGLE_CLOUD_LOCATION: ${{ secrets.GOOGLE_CLOUD_LOCATION }} LETTA_GEMINI_FORCE_MINIMUM_THINKING_BUDGET: true run: | uv run pytest \ -s -vv \ tests/integration_test_send_message.py \ --maxfail=1 --durations=10