# Alexa Suno Skill - Technical Overview

## Project Summary

This is an Alexa skill that integrates Suno's music generation capabilities into the Alexa voice platform. Users can generate music through voice commands, browse their Suno library, and play content on Alexa-enabled devices. The skill is built as an AWS Lambda function that acts as a bridge between Alexa's voice interface and Suno's OAuth API endpoints.

## Key Technologies

- **Runtime**: Python 3.x (AWS Lambda)
- **Cloud Provider**: AWS (Lambda, CloudWatch Logs)
- **External Services**: 
  - Suno (music generation via OAuth API)
  - Redis KV Store (for repeat/loop state persistence)

## Architecture Overview

```
                      Studio API       Modal SSE
                             ↑            ↑
User → Alexa Device → Alexa Platform → AWS Lambda → Studio API
           ↓                              ↓
      CloudFront                       Redis KV Store
      or Modal (for streaming)
```

The skill follows a request-response pattern where:
1. Users speak commands to their Alexa device
2. Alexa converts voice to structured JSON directives
3. Lambda function processes directives and calls Suno API
4. Responses are formatted for Alexa's audio/visual rendering

## Core Components

### 1. Lambda Function (`lambda_function.py`)
- Main entry point handling all Alexa directives
- Routes requests to appropriate handlers based on namespace/name
- Manages error handling and response formatting
- Implements artificial delays for better UX during content generation

### 2. Suno Integration (`suno.py`)
- Wraps Suno's OAuth API endpoints
- Handles authentication, API calls, and SSE (Server-Sent Events) streams
- Key endpoints:
  - `/api/v2/external/oauth/generate` - Create new songs
  - `/api/v2/external/oauth/clips` - Get clip details
  - `/api/v2/external/oauth/search` - Search user library
  - `/alexa/skill-account-linked` - Account linking notification

### 3. Error Models (`error_models.py`)
- Custom exception hierarchy for skill-specific errors
- Maps Suno API errors to Alexa error responses
- Handles content filtering, rate limits, auth failures

### 4. Supporting Modules
- `constants.py` - API URLs, timeouts, genre lists
- `instrumental_determinator.py` - Pattern matching for vocal/instrumental detection
- `anodyne.py` - Title generation for untitled tracks

#### Instrumental Detection (`instrumental_determinator.py`)
The `song_is_vocal()` function uses keyword-based pattern matching to determine user intent:

**Detection Strategy**:
- Weighted scoring system with context-aware analysis
- Position-based weighting (early mentions weighted higher)
- Negation handling ("not instrumental", "no vocals")
- Contradictory phrase detection ("instrumental but with vocals")

**Decision Logic**:
- Returns `False` for instrumental requests
- Returns `True` for vocal requests (default)

## Key Features

### Music Generation
- Users can request songs with prompts like "make a jazz song about rain"
- Supports both vocal and instrumental tracks (auto-detected from prompt)
- Removes "on suno" phrases from prompts before generation
- Uses SSE to get real-time generation status and metadata

### Library Management
- Search user's Suno library by keywords or genres
- Browse all songs with "show my songs" 
- Play specific tracks or entire library
- Support for explicit content filtering

### Playback Controls
- Next/Previous navigation through user's library
- Repeat mode (single track looping)
- Loop mode (playlist looping - temporarily mapped to repeat due to Alexa limitations!!)
- Real-time playback event logging

### Account Management  
- OAuth-based account linking between Alexa and Suno
- Catalog sync on account link (up to 2500 personal catalog entities per user)
- Support for incremental catalog updates via Update API
- Self-healing mechanism for catalog sync with previousSyncToken tracking
- Sync status responses: ASYNC_UPDATE, NO_UPDATE, NO_CONTENT

## Technical Implementation Details

### Request Processing Flow
1. **Directive Reception**: Lambda receives JSON directive from Alexa
2. **Message ID Tracking**: Each request gets unique ID for log correlation
3. **Handler Routing**: Pattern matching determines appropriate handler
4. **API Orchestration**: Handler calls Suno API with timeout management
5. **Response Formatting**: Results formatted per Alexa interface specs
6. **Error Handling**: Exceptions mapped to appropriate Alexa errors

### Time Management
- Global handler timeout: 4.5 seconds
- Dynamic SSE timeouts based on remaining budget
- Artificial delays for generation UX (min 3.5s execution time)
- Separate tracking of real vs. full processing time

### State Persistence
- Repeat/loop status stored in Redis via separate Lambda
- Queue ID used as key for state lookup
- Fire-and-forget writes, synchronous reads

### Content Resolution
- Supports resolvedEntities for track identification  
- Falls back to search when entity resolution fails
- Handles both playable and displayable content requests

## API Integration Notes

### Suno API Characteristics
- OAuth 2.0 implementation with custom extensions
- Requires bearer token authentication with scopes
- Returns clips in reverse chronological order
- SSE streams for real-time updates during generation
- Rate limiting with 429 responses
- Content moderation with specific error messages

### Backend API Endpoints (studio-api)

#### OAuth Flow
- `GET /api/v2/external/oauth/authorize` - OAuth authorization endpoint
- `POST /api/v2/external/oauth/generate-code` - Generate auth code after Clerk authentication
- `GET /api/v2/external/oauth/client-info` - Get OAuth client application info
- `POST /api/v2/external/oauth/token` - Standard OAuth token endpoint

#### Music Generation
- `POST /api/v2/external/oauth/generate` - Generate songs with `generate_music` scope
  - Rate limit: 10/minute per user
  - Supports instrumental mode, tags, and custom models
  - Returns list of clips with IDs and metadata
  - Handles moderation failures and insufficient credits (402)

#### Content Access
- `GET /api/v2/external/oauth/clips` - Get clips by IDs with `read_music` scope
  - Rate limit: 100/minute per user
  - Returns clip details including URLs and metadata
  - Filters out error clips with sanitized messages

- `GET /api/v2/external/oauth/search-user-clips` - Search/paginate user clips
  - Supports before_id/after_id pagination
  - Returns up to 50 clips per request
  - Ordered by creation date

- `POST /api/v2/external/oauth/search` - Full library search
  - Rate limit: 20/minute per user
  - Uses compound search functionality

#### Alexa-Specific Endpoints
- `POST /api/v2/external/oauth/alexa/skill-account-linked` - Handle account linking
  - Manages catalog sync with Alexa Music Service
  - Returns sync tokens and update status
  - Handles NO_CONTENT case for empty libraries

- `POST /api/v2/external/oauth/alexa/song-created` - Add new song to Alexa catalog
  - Rate limit: 30/minute per user
  - Updates catalog incrementally
  - Creates AlexaUserInfo if needed

- `GET /api/v2/external/oauth/alexa-user-info` - Get Alexa user metadata
  - Requires `read_profile` scope
  - Returns AlexaUserInfo model

### OAuth Scopes
- `read_profile` - Access user profile information
- `read_music` - Access user's music library
- `generate_music` - Create new music

### Alexa Interface Requirements
- Responses must include proper namespace/name
- PlayQueue items need enable/disable controls  
- Media search supports ranked selection criteria
- Displayable content uses groups for organization
- Error responses require specific error codes

### Alexa Media Search V3.0 Support
**Note**: The skill currently implements V2.0. V3.0 capabilities include:
- Complex query predicates (UNION, INTERSECTION, NOT, SIMILAR)
- Multiple entity resolutions per attribute
- Natural language selection criteria
- Skill manifest declaration of supported attributes and predicates
- Matched criteria reporting in responses

## Deployment & Operations

### Environment Setup
- Deployed as AWS Lambda function
- Requires OAuth client credentials (stored in Suno backend)
- Redis Lambda ARN configured for KV store access
- CloudWatch Logs for monitoring and debugging

### Key Scripts
- `config_sso.sh` - Configure AWS SSO
- `deploy_lambda.sh` - Package and deploy Lambda function
- `tail.sh` - Monitor CloudWatch logs in real-time
- `get_manifest.sh` / `update_manifest.sh` - Manage Alexa skill manifest

### Testing
- `uv run test_lambda.py` - Unit tests for Lambda handlers
- `uv run test_instrumental_determinator.py` - Test instrumental detection

## Deployment and Operations Guide

This section details the key scripts used for configuring the development environment and deploying the Lambda function.

### `config_sso.sh`

This script configures your local AWS CLI to authenticate via AWS IAM Identity Center (formerly SSO), which is required for deploying and managing the Lambda function.

**Usage:**
```bash
./config_sso.sh <aws-region>
# Example: ./config_sso.sh us-east-1
```

**Functionality:**
1.  **Takes Region**: Requires the target AWS region (e.g., `us-east-1`) as an argument.
2.  **Creates Profile**: Sets up a named AWS profile (e.g., `suno-east-1`) with the correct SSO configuration (`start_url`, `account_id`, `role_name`, etc.).
3.  **Initiates Login**: Triggers the `aws sso login` command, which opens a browser window for you to authorize the device.
4.  **Sets Default Profile**: Upon successful login, it exports the `AWS_PROFILE` environment variable for the current terminal session and adds this command to your `~/.bashrc` and `~/.zshrc` files to make the setting persistent.

### `deploy_lambda.sh`

This script automates the process of packaging the Python code and its dependencies and deploying it to AWS Lambda.

**Usage:**
```bash
./deploy_lambda.sh [staging|prod]
# Example (deploy to staging): ./deploy_lambda.sh staging
# Example (deploy to production): ./deploy_lambda.sh prod
# Defaults to 'staging' if no argument is provided.
```

**Functionality:**
1.  **Selects Environment**: Sets the correct Lambda function name (`ask-suno-staging` or `ask-suno`) based on the argument.
2.  **Checks Credentials**: Verifies that you have active AWS credentials and automatically runs `config_sso.sh` if you don't.
3.  **Packages Dependencies**:
    - It uses `pip download` to fetch all required packages from `requirements.in`.
    - Critically, it downloads wheels compiled for the specific AWS Lambda runtime environment (`manylinux_2_28_aarch64` for Python 3.13 on AL2023 ARM64), ensuring compatibility.
4.  **Assembles Package**: It creates a `lambda_package` directory, installs the downloaded wheels, and copies all necessary Python source files (`lambda_function.py`, `suno.py`, etc.) into it.
5.  **Creates Zip Archive**: The contents of the `lambda_package` are compressed into `lambda_deployment_package.zip`.
6.  **Deploys to Lambda**: The script uses `aws lambda update-function-code` to upload the zip archive to the target Lambda function in the specified region.

## Alexa Interface Taxonomy

The skill interacts with Alexa through a variety of interfaces (directives, events, and responses). This section provides a comprehensive list of these interactions as implemented in `lambda_function.py`.

### Incoming Directives & Events

This table lists all the requests the Lambda function is configured to handle from Alexa.

| Namespace | Name | Version | Handler Function | Description |
|---|---|---|---|---|
| `Alexa.Audio` | `SyncUserContent` | `1.0` | `lambda_handler` | Initiates catalog sync when a user links their account or enables the skill. |
| `AlexaSkillEvent` | `SkillAccountLinked` | N/A | `lambda_handler` | Event fired when OAuth account linking is complete. |
| `AlexaAudioPlayQueueEvent` | `ItemPlaybackStarted` | N/A | `handle_playback_event` | Fired when an item in the queue starts playing. Logs event to Suno backend. |
| `AlexaAudioPlayQueueEvent` | `ItemPlaybackFailed` | N/A | `handle_playback_event` | Fired when an item fails to play. Logs event to Suno backend. |
| `AlexaAudioPlayQueueEvent` | `ItemPlaybackFinished`| N/A | `handle_playback_event` | Fired when an item finishes playing. Logs event to Suno backend. |
| `AlexaAudioPlayQueueEvent` | `ItemPlaybackStopped`| N/A | `handle_playback_event` | Fired when playback is stopped. Logs event to Suno backend. |
| `Alexa.Audio.PlayQueue` | `GetNextItem` | `1.0` | `handle_alexa_audio_playqueue` | Requests the next item in the play queue. |
| `Alexa.Audio.PlayQueue` | `GetPreviousItem` | `1.0` | `handle_alexa_audio_playqueue` | Requests the previous item in the play queue. |
| `Alexa.Media.Search` | `GetPlayableContent` | `3.0` | `handle_alexa_media_search` | Requests a single playable item based on search criteria or actions (like `GENERATE_CONTENT`). |
| `Alexa.Media.Search` | `GetDisplayableContent`| `3.0` | `handle_alexa_media_search` | Requests a list of content to display on screen-based devices. |
| `Alexa.Media.Playback` | `Initiate` | `1.0` | `handle_alexa_media_playback` | Starts playback of a specific media item, creating a new queue. |
| `Alexa.Media.PlayQueue`| `SetLoop` | `1.0` | `handle_alexa_media_playqueue` | Sets the loop mode for the entire queue. **(See Note 1)** |
| `Alexa.Media.PlayQueue`| `SetRepeat` | `1.0` | `handle_alexa_media_playqueue` | Sets the repeat mode for a single item. |
| `Alexa.Media.PlayQueue`| `SetPlaybackContinuation`|`1.0`| `handle_alexa_media_playqueue`| Informs skill about user's continuous play preference. |

### Outgoing Responses

This table lists the successful responses the Lambda function can send back to Alexa.

| Response Name | Builder Function | Description |
|---|---|---|
| `SyncUserContent` | `lambda_handler` | Responds to a sync request with status: `ASYNC_UPDATE`, `NO_UPDATE`, or `NO_CONTENT`. |
| `GetPlayableContent.Response` | `build_media_search_playable_content_response` | Contains a single media item to be played immediately. |
| `GetDisplayableContent.Response`| `build_media_search_displayable_content_response` | Contains content groups and lists for visual display on screens. |
| `GetNextItem.Response` | `build_play_queue_item_response` | Contains the next item for the play queue, or indicates the queue is finished. |
| `GetPreviousItem.Response` | `build_play_queue_item_response` | Contains the previous item for the play queue, or indicates the queue is finished. |
| `Initiate.Response` | `process_initiate_playback` | Acknowledges playback initiation and provides the first queue item and queue-level controls. |
| `Response` | `handle_alexa_media_playqueue` | A generic success response for directives that don't return data, like `SetLoop`. |

### Error Responses and Mappings

The skill uses a custom exception hierarchy (`error_models.py`) to map internal and API errors to the appropriate Alexa error responses.

| Internal Exception (`SkillError` subclass) | Alexa Error Code | Builder Function | Description |
|---|---|---|---|
| `ContentNotFoundError` | `CONTENT_NOT_FOUND` | `build_media_error_response`| The requested content does not exist in the user's library. |
| `ContentFilteredError`| `CONTENT_FILTERED` | `build_media_error_response`| The content was blocked by a filter (e.g., explicit language, moderation). |
| `GeoRestrictionError`| `GEOGRAPHICAL_RESTRICTION_ERROR` | `build_media_error_response`| Content is not available in the user's region. |
| `AuthorizationError`| `INVALID_AUTHORIZATION_CREDENTIAL`| `build_alexa_error_response`| The user's OAuth token is invalid, expired, or insufficient. |
| `RateLimitError` | `RATE_LIMIT_EXCEEDED`| `build_alexa_error_response`| The skill has been rate-limited by Suno's API. |
| `SkillError` (and subclasses) | `INTERNAL_ERROR` | `build_alexa_error_response`| A general, unexpected error occurred within the skill. |
| `JSONDecodeError` / Unrecognized Event | `INVALID_DIRECTIVE` | `build_alexa_error_response`| The request from Alexa was malformed or unsupported. |

## Known Limitations & Workarounds

1.  **Note 1: Alexa sends `SetLoop` instead of `SetRepeat`**: Due to a quirk in how some Alexa devices interpret user requests for repeating a single song, the skill often receives a `SetLoop` directive. The handler at `handle_alexa_media_playqueue` correctly treats `SetLoop` as a request to repeat the current track and persists this state as `ON`/`OFF` in the Redis KV store. This ensures a reliable repeat experience despite the inconsistent directives from Alexa.

2.  **Image generation delays**: Falls back to CDN URLs if SSE timeout
3.  **Attribute allowlist**: Only GENRE, MEDIA_TYPE, TRACK supported

4.  **Partial Media Search v3.0 Support**: The skill handles v3.0 `GetPlayableContent` and `GetDisplayableContent` requests and supports key features like `rankedSelectionCriteria` and the `GENERATE_CONTENT` action. However, it does not implement support for complex predicate trees (e.g., `UNION`, `INTERSECTION`, `NOT`). The logic in `handle_attribute_query` contains a simplified approach to parsing these.

## Outstanding Questions for Investigation

1.  **Hardcoded Transcript Auth Token**: In `suno.py`, the `build_play_queue_item` function constructs a `transcript` object with a hardcoded `x-auth-token`.
    ```python
    "headers": [{"name": "x-auth-token", "value": "fbfd3378-a72d-45ef-9782-4edf140f5dd7"}]
    ```
    This should be investigated. Is this a required static key for a public endpoint, or should it be a user-specific or temporary token?

2.  **Redis KV Store ARN**: The ARN for the Redis KV store Lambda (`KV_STORE_LAMBDA_ARN`) is hardcoded in `lambda_function.py`. For better environment management, this should be moved to an environment variable or a configuration management system.

## Future Enhancements

- Support for additional Alexa attributes (LIBRARY, etc.)
- Improved search with complex predicate trees
- Play queue support

## Related Components

### Glockenspiel (Backend Monorepo)
The Suno backend (studio-api) that provides:
- OAuth endpoints for authentication
- Music generation APIs
- User library management  
- Playback event tracking
- Alexa catalog synchronization

Key implementation details:
- Uses Django OAuth Toolkit for OAuth 2.0 implementation
- Custom OAuth client creation via management command
- Rate limiting implemented per endpoint and user/IP
- Alexa catalog updates via S3 bucket and LWA tokens
- AlexaUserInfo model tracks user-Alexa associations
- Supports both full catalog sync and incremental updates

### Frontend OAuth 2.0 Consent Flow (`glockenspiel/ui/app-ui`)

While the Alexa Skill and `studio-api` backend handle the server-to-server aspects of the OAuth flow, the user-facing consent and authorization process is managed by the Suno Next.js frontend application. This flow is orchestrated by the React component located at `ui/app-ui/src/app/(root)/link-account/page.tsx`.

#### Flow Overview

The frontend's role is to securely identify the user, obtain their explicit consent for the permissions requested by the third-party application (e.g., Alexa), and bridge the gap between user authentication and the generation of an authorization code.

```mermaid
graph TD;
    A[Third-Party App e.g., Alexa] -->|"1\. Redirect User to<br>/api/v2/external/oauth/authorize"| B(Suno Backend);
    B -->|"2\. Redirect User to<br>/link-account"| C[Frontend: /link-account page];
    subgraph Frontend UI/UX Flow
        C -->|"3\. Store OAuth params in localStorage"| D{User Signed In?};
        D -->|"No<br>4\. Redirect"| E["/login page"];
        E -->|"5\. User Logs In"| F[Redirect back to /link-account];
        F --> D;
        D -->|"Yes<br>6\. Fetch Client Info"| G[Render Consent Screen];
        G -->|"7\. User clicks Authorize"| H[POST to /generate-code w/ Clerk token];
    end
    H -->|"8\. Backend generates code"| I(Suno Backend);
    I -->|"9\. Respond with redirect_url"| H;
    H -->|"10\. JS redirects browser"| J[Third-Party App Redirect URI];
    J -->|"11\. Exchange code for token"| I;
```

#### Technical Implementation Details

1. **Initiation & State Persistence**: The flow begins when the user lands on `/link-account` with `client_id`, `redirect_uri`, `state`, and `scope` in the URL. The component immediately validates these parameters and **persists them in the browser's `localStorage`** under the key `oauth_params`. This is a critical mechanism that allows the OAuth flow to survive the page reloads and redirects required for user login.

2. **Authentication Handling**:
   - The page uses the `@clerk/nextjs` hook `useAuth` to determine the user's authentication status (`isSignedIn`)
   - If the user is not logged in, they are redirected to `/login` with a `redirect_to` parameter pointing back to `/link-account`
   - After successful login, the user is returned to `/link-account`, which then retrieves the OAuth context from `localStorage` and seamlessly resumes the flow

3. **Dynamic Consent UI**:
   - Before rendering the consent screen, the component makes an authenticated GET request to `/api/v2/external/oauth/client-info` to fetch the client application's registered name, ensuring a user-friendly display
   - Requested scopes are parsed and mapped to human-readable descriptions (e.g., `read_music` becomes "Access your music library")
   - The `ClientLayout.tsx` file identifies this path to provide a focused layout, hiding standard site navigation

4. **Authorization Code Generation**:
   - When the user clicks "Authorize," the frontend sends a `POST` request to `/api/v2/external/oauth/generate-code`
   - This request is authenticated using a **Clerk JWT** in the `Authorization` header, which securely proves the user's identity to the backend
   - The body of the request contains the OAuth parameters that were originally stored in `localStorage`

5. **Final Redirect**: The backend responds with a JSON object containing a `redirect_url`. The frontend uses `window.location.href` to execute this final redirect, sending the user and their newly generated authorization code back to the third-party application to complete the flow. The `localStorage` key is cleared upon success.

This frontend component acts as the essential, user-facing intermediary in the OAuth 2.0 flow, handling user session state, consent, and interaction before handing control back to the server-to-server process.

### Audio Streaming Infrastructure (audiopipe.suno.ai)
The skill integrates with Suno's Modal-based audio streaming service:

#### Streaming Architecture
- **Queue-based System**: Uses Modal Queues for stream keys and audio chunks
- **Format Support**: MP3 and WebM with opus codec
- **Partition Strategy**: Content partitioned by clip ID for parallel streaming
- **Deployment Modes**: Separate dev/prod environments with dedicated queues

#### Advanced Streaming Features
1. **Filler Audio Support** (`/stream_with_filler/`)
   - Pre-loads shimmer.mp3 (192kbps, 63.5s duration) for seamless transitions
   - Initial 2-second buffer to prevent playback gaps
   - Automatic transition from filler to real audio when available
   - Three concurrent tasks:
     - Output flusher: Yields chunks to client
     - Preroll filler: Manages filler audio until real content
     - Real audio accumulator: Buffers and switches to actual content

2. **Server-Sent Events** 
   - `/clip_events/`: Stream generation events by clip ID
   - `/request_events/`: Stream events by request ID
   - Event types: `lyrics`, `error`, `image_generated`, `gen_streaming`
   - 60-second partition TTL for temporary event storage

### Modal Worker Architecture (Orchestrator)
The backend uses Modal workers for various AI tasks, including lyrics generation and moderation:

#### ChatGPT Worker Components
- **ChatGptStub**: Main orchestrator for lyrics generation and moderation
- **ConductorStub**: Distributes queue items to appropriate model workers

#### Alexa-Specific Features
1. **Early Callback for Faster Generation**
   - Enabled via `metadata.extra.early_callback` flag
   - Streams title and tags as soon as available via SSE
   - Triggers image generation early (before full lyrics completion)
   - Notifies Lambda with `early_title_tags` event type
   - Significantly improves perceived latency for Alexa users

2. **Real-time Event Streaming**
   - Events published to Modal Queue partitioned by request/clip ID
   - Event types include: `lyrics`, `error`, `generate_queued`, `early_title_tags`
   - Lambda consumes these via SSE endpoints:
     - `/request_events/?request_id=...` (request-level)
     - `/clip_events/?clip_id=...` (clip-level)

3. **Parallel Image Generation**
   - Image generation spawned immediately after moderation
   - Pro models (Flux) used for v4/auk/bluejay models when backlog < 25
   - Standard model (SDXL) used as fallback
   - Image progress notifications sent per clip

#### Error Handling Pipeline
1. **Moderation Failures**
   - Content filtering with specific error types
   - Artist name detection (can be disabled)
   - Explicit language filtering
   - Custom error messages for Alexa TTS

2. **Generation Failures**
   - GPT API failures with retry logic
   - Copyright detection via Elasticsearch
   - Rate limiting (10/min for generation)
   - Insufficient credits (402 response)

3. **Error Propagation**
   - Errors published to SSE event streams
   - Both request-level and clip-level notifications
   - Specific error types for Alexa error handling:
     - `moderation_failure`
     - `image_moderation_failure`
     - `content_generation_error`
     - `invalid_model_name`

#### Lyrics Generation Flow
1. **Input Processing**
   - Standard: Use GPT description prompt

2. **Moderation Pipeline**
   - Pre-generation moderation of prompts
   - Post-generation moderation of lyrics
   - Language detection for multilingual support
   - Instrumental detection and handling

3. **Generation & Streaming**
   - Title generated first (enables early callback)
   - Tags extracted for genre classification
   - Full lyrics generated with appropriate length
   - Results streamed via SSE in real-time

#### Integration with Lambda
- Lambda configures SSE timeout dynamically based on handler budget
- Early callbacks reduce user-perceived latency by 2-3 seconds
- Parallel processing of image + audio generation
- Request-level operations split to clip-level for processing

## Common Issues & Debugging

### Authentication Failures
- Check OAuth token validity
- Verify account linking status
- Review authorization headers

### Generation Timeouts
- Monitor SSE connection times
- Check dynamic timeout calculations
- Review CloudWatch logs for timeout patterns

### Content Not Found
- Verify clip IDs in user library
- Check search term formatting
- Review library sync status

### Playback Issues  
- Confirm audio URLs are accessible
- Check clip generation status
- Verify queue navigation logic

## Project Structure

```
alexa/
├── lambda_function.py          # Main AWS Lambda handler
├── suno.py                     # Suno API integration
├── error_models.py             # Error handling framework
├── constants.py                # Configuration constants
├── instrumental_determinator.py # Vocal/instrumental detection
├── anodyne.py                  # Title generation utilities
├── models.py                   # Data models
├── manifest.json               # Alexa skill manifest
├── docs/                       # Documentation
│   ├── OAuth Guide for Partner Integration.md
│   ├── Suno Error TTS.md
│   └── [PDF documentation files]

```

## Testing

### Local Testing Setup

#### Prerequisites
1. **AWS SSO Configuration**
   ```bash
   ./config_sso.sh us-east-1  # or us-west-2
   ```
   This configures AWS CLI with SSO authentication for Lambda invocations.

2. **Python Environment**
   ```bash
   uv sync  # Install dependencies using uv package manager
   ```

#### Running Tests

The primary testing tool is `test_lambda.py` which provides an interactive menu for testing different Alexa directives locally:

```bash
uv run test_lambda.py
```

**Test Menu Options:**
1. **Generate a song** - Tests song creation with custom prompts
2. **Play most recent song** - Tests playback of the latest track
3. **Initiate playback** - Tests starting playback with specific song ID
4. **Get next song** - Tests queue navigation forward
5. **Get previous song** - Tests queue navigation backward
6. **Browse library** - Tests GetDisplayableContent for browsing
7. **Search library** - Tests search functionality
8. **Full flow test** - Tests Create → Initiate → Navigation
9. **Repeat mode test** - Tests SetLoop/repeat functionality

#### OAuth Flow
When running tests, the script:
1. Starts a local server on port 3001
2. Opens browser for Suno OAuth authorization
3. Captures the auth code and exchanges for access token
4. Uses token for all subsequent API calls

#### Test Features

**Request Capture**: All test requests are saved to `aws_console_requests/` for:
- AWS Lambda console testing
- Debugging production issues
- Request replay and analysis

**Resource Validation**: Tests automatically verify:
- Audio stream connectivity and download
- Cover art image retrieval
- Lyrics (WebVTT) file access
- Saves samples to `resource_tests/` directory

**Timing Analysis**: Each test reports:
- Handler execution time
- Total processing time
- Time margin vs 5-second target
- Helps ensure responses meet Alexa's timeout requirements

#### Common Test Scenarios

**1. Song Generation Test**
```
Enter choice: 1
Enter song prompt: jazz song about coffee
```
Tests the complete generation flow including SSE title extraction.

**2. Full Flow Test (Recommended)**
```
Enter choice: 8
```
Automatically tests:
- Song creation
- Playback initiation
- GetNextItem (verifies Suno returns second version)
- GetPreviousItem
- Resource URL validation

**3. Repeat Mode Test**
```
Enter choice: 9
```
Verifies SetLoop directive handling:
- Creates a song
- Initiates playback
- Enables repeat (SetLoop enable=true)
- Verifies GetNextItem returns same song
- Disables repeat
- Verifies GetNextItem returns different song

### Unit Tests

Run specific test modules:
```bash
uv run python test_instrumental_determinator.py
```

Tests vocal/instrumental detection logic with various prompts.

### Debugging

**CloudWatch Logs**
```bash
./tail.sh  # Monitor Lambda logs in real-time
```

### Production Testing

**AWS Lambda Console**
2. Create test events in Lambda console
3. Monitor execution and CloudWatch logs

**Skill Testing**
1. Enable test mode in Alexa Developer Console
2. Use Alexa Simulator or physical device
3. Monitor Lambda logs during testing

### Troubleshooting

**Common Issues:**
- **OAuth Token Expired**: Re-run test script to get fresh token
- **SSO Session Expired**: Run `config_sso.sh` again
- **Resource Download Fails**: Check Suno API status and clip generation state

## Summary

This Alexa skill integrates Amazon's voice platform with Suno's music generation service. The system includes:

1. **Latency Management**: Early callbacks, parallel processing, and dynamic timeouts to improve response times
2. **Error Handling**: Multiple layers of error handling from API errors to user-facing messages
3. **Architecture**: Modal workers for generation tasks, queue-based streaming, and Lambda for request handling
4. **Features**: Music generation, library management, playback controls, and account sync
