### Initialize and Start Project Source: https://github.com/deepgram-starters/csharp-flux/blob/main/AGENTS.md Commands to initialize submodules, install dependencies, and start the backend and frontend servers. ```bash # Initialize (clone submodules + install deps) make init # Set up environment test -f .env || cp sample.env .env # then set DEEPGRAM_API_KEY # Start both servers make start # Backend: http://localhost:8081 # Frontend: http://localhost:8080 ``` -------------------------------- ### Dependency Installation Source: https://github.com/deepgram-starters/csharp-flux/blob/main/AGENTS.md Commands to install backend and frontend dependencies. ```bash dotnet restore cd frontend && corepack pnpm install ``` -------------------------------- ### Local Development Quick Start Commands Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Provides essential Make commands for initializing, running, testing, and maintaining the project locally. Includes commands for checking prerequisites, initializing the project, starting servers, running tests, and updating submodules. ```bash # Check prerequisites (git, dotnet) make check-prereqs # Initialize project: clone submodules and install dependencies make init # Set up environment cp sample.env .env # Edit .env and add your DEEPGRAM_API_KEY # Start both servers (backend on 8081, frontend on 8080) make start # Or start servers separately: make start-backend # Terminal 1 make start-frontend # Terminal 2 # Run contract conformance tests make test # Update submodules to latest make update # Clean build artifacts make clean # Show git and submodule status make status # Eject frontend from submodule (for standalone modifications) make eject-frontend ``` -------------------------------- ### Initialize and Start Local Development Source: https://github.com/deepgram-starters/csharp-flux/blob/main/README.md Use these make commands to initialize the project, set your API key, and start the local development server. Ensure you have a Deepgram API key. ```bash make init cp sample.env .env # Add your DEEPGRAM_API_KEY make start ``` -------------------------------- ### Start and Stop Commands Source: https://github.com/deepgram-starters/csharp-flux/blob/main/AGENTS.md Utility commands for managing the application lifecycle. ```bash make start ``` ```bash # Terminal 1 — Backend dotnet run # Terminal 2 — Frontend cd frontend && corepack pnpm run dev -- --port 8080 --no-open ``` ```bash lsof -ti:8080,8081 | xargs kill -9 2>/dev/null ``` ```bash rm -rf bin obj frontend/node_modules frontend/.vite make init ``` -------------------------------- ### GET /api/metadata Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Retrieves configuration metadata about the starter application. ```APIDOC ## GET /api/metadata ### Description Returns metadata about this starter application from the deepgram.toml configuration file. ### Method GET ### Endpoint /api/metadata ### Response #### Success Response (200) - **title** (string) - Application title - **description** (string) - Application description - **author** (string) - Author information - **repository** (string) - GitHub repository URL - **useCase** (string) - Primary use case - **language** (string) - Programming language - **framework** (string) - Backend framework - **sdk** (string) - SDK version - **tags** (array) - List of relevant tags #### Response Example { "title": "C# Flux", "description": "Get started using Deepgram's Flux real-time transcription with this C# demo app", "author": "Deepgram DX Team (https://developers.deepgram.com)", "repository": "https://github.com/deepgram-starters/csharp-flux", "useCase": "flux", "language": "csharp", "framework": "dotnet", "sdk": "6.6.1", "tags": ["flux", "streaming", "speech-to-text", "real-time", "turn-detection", "csharp", "dotnet"] } ``` -------------------------------- ### Conventional Commits Examples Source: https://github.com/deepgram-starters/csharp-flux/blob/main/AGENTS.md Examples of valid commit messages following the conventional commits format. ```git feat(csharp-flux): add diarization support ``` ```git fix(csharp-flux): resolve WebSocket close handling ``` ```git refactor(csharp-flux): simplify session endpoint ``` ```git chore(deps): update frontend submodule ``` -------------------------------- ### Add Keyterms Query Parameters Source: https://github.com/deepgram-starters/csharp-flux/blob/main/AGENTS.md Example of how to pass keyterms as repeated query parameters in the WebSocket URL. ```text ?keyterm=Deepgram&keyterm=Nova&keyterm=Aura ``` -------------------------------- ### Configure Flux WebSocket Query Parameters Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Example URL format for configuring Flux behavior via query parameters. ```bash # WebSocket URL format with all available parameters: ws://localhost:8081/api/flux?encoding=linear16&sample_rate=16000&eot_threshold=0.7&eager_eot_threshold=0.5&eot_timeout_ms=5000&keyterm=Deepgram&keyterm=Nova # Parameter reference: # | Parameter | Default | Range | Description | # |----------------------|------------------|--------------|------------------------------------------------| # | encoding | linear16 | linear16,opus| Audio encoding format | # | sample_rate | 16000 | 8000-48000 | Audio sample rate in Hz | # | eot_threshold | 0.7 | 0.0-1.0 | End-of-turn confidence threshold | # | eager_eot_threshold | (disabled) | 0.0-1.0 | Tentative end-of-turn threshold | # | eot_timeout_ms | 5000 | 0-30000 | Silence duration (ms) before automatic EOT | # | keyterm | (none) | (repeatable) | Custom vocabulary hints | # Tuning tips: # - Lower eot_threshold (0.3): Faster endings, may cut off mid-sentence # - Higher eot_threshold (0.9): More patience, better for longer utterances # - Enable eager_eot_threshold: Shows tentative completions, can resume # - Lower eot_timeout_ms: Quick timeout on silence # - Higher eot_timeout_ms: More patience for thinking pauses ``` -------------------------------- ### GET /health Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Checks the health status of the backend server. ```APIDOC ## GET /health ### Description Returns the health status of the backend server. Used by container orchestration platforms to monitor application health. ### Method GET ### Endpoint /health ### Response #### Success Response (200) - **status** (string) - Current health status - **service** (string) - Service name #### Response Example { "status": "ok", "service": "flux" } ``` -------------------------------- ### Get Application Metadata Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Retrieve metadata about the C# Flux starter application, including its use case, language, and framework. This information is useful for understanding the project's configuration. ```bash # Get application metadata curl -s http://localhost:8081/api/metadata | jq # Response: { "title": "C# Flux", "description": "Get started using Deepgram's Flux real-time transcription with this C# demo app", "author": "Deepgram DX Team (https://developers.deepgram.com)", "repository": "https://github.com/deepgram-starters/csharp-flux", "useCase": "flux", "language": "csharp", "framework": "dotnet", "sdk": "6.6.1", "tags": ["flux", "streaming", "speech-to-text", "real-time", "turn-detection", "csharp", "dotnet"] } ``` -------------------------------- ### Flux Turn Event Examples Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Illustrates the different types of structured events emitted by Deepgram Flux, including StartOfTurn, Update, EagerEndOfTurn, TurnResumed, and EndOfTurn. These events help in understanding the flow of user speech and transcription. ```javascript // Example Flux event responses // 1. StartOfTurn - User began speaking { "type": "StartOfTurn", "start": 0.0, "channel_index": [0, 1] } ``` ```javascript // 2. Update - Interim transcript within the turn { "type": "Update", "start": 0.0, "duration": 1.5, "is_final": false, "channel": { "alternatives": [{ "transcript": "Hello how are", "confidence": 0.95, "words": [...] }] } } ``` ```javascript // 3. EagerEndOfTurn - Tentative end detected (user might continue) { "type": "EagerEndOfTurn", "channel": { "alternatives": [{ "transcript": "Hello how are you", "confidence": 0.97 }] } } ``` ```javascript // 4. TurnResumed - User spoke again after eager EOT { "type": "TurnResumed" } ``` ```javascript // 5. EndOfTurn - Confirmed end of turn (final transcript) { "type": "EndOfTurn", "start": 0.0, "duration": 2.1, "is_final": true, "channel": { "alternatives": [{ "transcript": "Hello how are you doing today", "confidence": 0.98, "words": [ {"word": "Hello", "start": 0.0, "end": 0.3, "confidence": 0.99}, {"word": "how", "start": 0.35, "end": 0.5, "confidence": 0.98}, ... ] }] } } ``` -------------------------------- ### GET /api/session Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Issues a JWT session token required for authenticating WebSocket connections to the Flux API. ```APIDOC ## GET /api/session ### Description Issues a JWT session token for WebSocket authentication. The token is valid for 1 hour and must be passed as a WebSocket subprotocol when connecting to the /api/flux endpoint. ### Method GET ### Endpoint /api/session ### Response #### Success Response (200) - **token** (string) - The JWT session token for WebSocket authentication. #### Response Example { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDk4MzY0MDB9.abc123..." } ``` -------------------------------- ### Docker Deployment Commands Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Instructions for building a Docker image and running the application as a container, including setting environment variables and deploying to Fly.io. This section covers both local Docker usage and cloud deployment steps. ```bash # Build Docker image docker build -f deploy/Dockerfile -t csharp-flux . # Run container with environment variables docker run -d \ -p 8080:8080 \ -e DEEPGRAM_API_KEY=your_api_key \ -e SESSION_SECRET=your_secure_secret \ csharp-flux # Deploy to Fly.io fly launch # First time fly deploy # Subsequent deploys # Set secrets on Fly.io fly secrets set DEEPGRAM_API_KEY=your_api_key fly secrets set SESSION_SECRET=your_secure_secret ``` -------------------------------- ### Run Tests and Check Endpoints Source: https://github.com/deepgram-starters/csharp-flux/blob/main/AGENTS.md Commands to run conformance tests and manually check API endpoints. ```bash # Run conformance tests (requires app to be running) make test ``` ```bash # Manual endpoint check curl -sf http://localhost:8081/api/metadata | python3 -m json.tool ``` ```bash curl -sf http://localhost:8081/api/session | python3 -m json.tool ``` -------------------------------- ### Commit Frontend Changes Source: https://github.com/deepgram-starters/csharp-flux/blob/main/AGENTS.md Steps to commit and push changes made to the frontend submodule. ```bash cd frontend && git add . && git commit -m "feat: description" ``` ```bash cd frontend && git push origin main ``` ```bash cd .. && git add frontend && git commit -m "chore(deps): update frontend submodule" ``` -------------------------------- ### Environment Configuration Variables Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Defines the environment variables required for configuring the application, including the Deepgram API key, server port, host, and JWT signing secret. Ensure these are set in your .env file. ```bash # Required: Your Deepgram API key DEEPGRAM_API_KEY=your_deepgram_api_key_here # Optional: Backend server port (default: 8081) PORT=8081 # Optional: Server bind address (default: 0.0.0.0) HOST=0.0.0.0 # Optional: JWT signing secret for production (auto-generated if not set) SESSION_SECRET=your_secure_random_secret_here # Get your API key at: https://console.deepgram.com ``` -------------------------------- ### Connect and Stream Audio via Flux WebSocket Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Establishes a WebSocket connection with JWT authentication and streams microphone audio using the Web Audio API. ```javascript // Browser JavaScript: Connect to Flux WebSocket with authentication async function connectFlux() { // Step 1: Get session token const sessionRes = await fetch('http://localhost:8081/api/session'); const { token } = await sessionRes.json(); // Step 2: Build WebSocket URL with Flux parameters const params = new URLSearchParams({ encoding: 'linear16', sample_rate: '16000', eot_threshold: '0.7', // End-of-turn confidence (0.0-1.0) eager_eot_threshold: '0.5', // Tentative EOT threshold eot_timeout_ms: '5000' // Silence timeout in ms }); // Add keyterms for vocabulary hints params.append('keyterm', 'Deepgram'); params.append('keyterm', 'Nova'); // Step 3: Connect with JWT in subprotocol const ws = new WebSocket( `ws://localhost:8081/api/flux?${params}`, [`access_token.${token}`] ); ws.onopen = () => console.log('Connected to Flux'); ws.onmessage = (event) => { const msg = JSON.parse(event.data); // Handle different turn event types switch (msg.type) { case 'StartOfTurn': console.log('User started speaking'); break; case 'Update': console.log('Interim:', msg.channel.alternatives[0].transcript); break; case 'EagerEndOfTurn': console.log('Tentative end of turn'); break; case 'TurnResumed': console.log('User continued speaking'); break; case 'EndOfTurn': console.log('Final:', msg.channel.alternatives[0].transcript); break; } }; ws.onerror = (err) => console.error('WebSocket error:', err); ws.onclose = () => console.log('Connection closed'); return ws; } // Step 4: Stream audio from microphone async function streamAudio(ws) { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const audioContext = new AudioContext({ sampleRate: 16000 }); const source = audioContext.createMediaStreamSource(stream); const processor = audioContext.createScriptProcessor(4096, 1, 1); processor.onaudioprocess = (e) => { if (ws.readyState === WebSocket.OPEN) { const inputData = e.inputBuffer.getChannelData(0); const pcm16 = new Int16Array(inputData.length); for (let i = 0; i < inputData.length; i++) { pcm16[i] = Math.max(-32768, Math.min(32767, inputData[i] * 32768)); } ws.send(pcm16.buffer); } }; source.connect(processor); processor.connect(audioContext.destination); } ``` -------------------------------- ### API Endpoints Source: https://github.com/deepgram-starters/csharp-flux/blob/main/AGENTS.md Overview of the available API endpoints for the csharp-flux application. ```APIDOC ## API Endpoints | Endpoint | Method | Auth | Purpose | |----------|--------|------|---------| | `/api/session` | GET | None | Issue JWT session token | | `/api/metadata` | GET | None | Return app metadata (useCase, framework, language) | | `/api/flux` | WS | JWT | Advanced real-time transcription with turn-based detection. | ``` -------------------------------- ### Flux-Specific Parameters Source: https://github.com/deepgram-starters/csharp-flux/blob/main/AGENTS.md Customization parameters for Flux's real-time transcription, including end-of-turn (EOT) detection. ```APIDOC ## Flux-Specific Parameters Flux extends live transcription with end-of-turn (EOT) detection. These are passed as WebSocket URL query parameters: | Parameter | Default | Range | Effect | |-----------|---------|-------|--------| | `model` | `flux-general-en` | See below | Flux STT model | | `encoding` | `linear16` | `linear16`, `opus` | Audio encoding | | `sample_rate` | `16000` | `8000`-`48000` | Audio sample rate | | `eot_threshold` | `0.7` | `0.0`-`1.0` | Confidence for end-of-turn detection (higher = more conservative) | | `eager_eot_threshold` | (disabled) | `0.0`-`1.0` | Threshold for tentative (eager) end-of-turn | | `eot_timeout_ms` | `5000` | `0`-`30000` | Silence duration (ms) before automatic EOT | | `keyterm` | (none) | Repeated param | Custom vocabulary hints (can specify multiple) | ### Understanding Turn Events Flux provides structured turn-based events instead of simple interim/final: 1. **StartOfTurn** — User started speaking (new turn) 2. **Update** — Interim transcript update within the turn 3. **EagerEndOfTurn** — Tentative end detected (user might continue) 4. **TurnResumed** — User spoke again after eager EOT 5. **EndOfTurn** — Confirmed end of turn (final transcript) ### Tuning EOT Behavior - **Lower `eot_threshold`** (e.g., 0.3): Faster turn endings, but may cut off mid-sentence - **Higher `eot_threshold`** (e.g., 0.9): Waits longer, better for longer utterances - **Enable `eager_eot_threshold`**: Shows tentative completions, can resume if user keeps talking - **Lower `eot_timeout_ms`**: Faster timeout on silence - **Higher `eot_timeout_ms`**: More patience for thinking pauses ### Adding Keyterms Keyterms boost recognition of specific words. In the backend, add them as repeated query params: ``` ?keyterm=Deepgram&keyterm=Nova&keyterm=Aura ``` The frontend has a comma-separated input field for keyterms. ### Frontend UI Controls The frontend provides: - EOT threshold slider (0.0-1.0) - Eager EOT toggle + threshold slider - EOT timeout input (ms) - Keyterm input (comma-separated) - Theme toggle (light/dark/system) To add new controls, edit `frontend/main.js` and include values in the `URLSearchParams` when connecting. ``` -------------------------------- ### Request JWT Session Token Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Use this cURL command to request a JWT session token from the backend. This token is required for authenticating WebSocket connections to the Deepgram Flux API. ```bash # Request a session token curl -s http://localhost:8081/api/session | jq # Response: { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDk4MzY0MDB9.abc123..." } # Store token for WebSocket connection TOKEN=$(curl -s http://localhost:8081/api/session | jq -r '.token') echo "Session token: $TOKEN" ``` -------------------------------- ### Health Check Endpoint Source: https://context7.com/deepgram-starters/csharp-flux/llms.txt Check the health status of the backend server using this cURL command. This endpoint is typically used by orchestration platforms to monitor application availability. ```bash # Check server health curl -s http://localhost:8081/health | jq # Response: { "status": "ok", "service": "flux" } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.