diff --git a/internal/provider/openai.go b/internal/provider/openai.go index 227ae94..0d51e7c 100644 --- a/internal/provider/openai.go +++ b/internal/provider/openai.go @@ -63,6 +63,17 @@ func (p *OpenAIProvider) Models() []Model { SupportedLanguages: allLangs, Endpoint: &EndpointConfig{BaseURL: "https://api.openai.com", Path: "/v1/audio/transcriptions"}, }, + { + ID: "gpt-4o-realtime-preview", + Name: "GPT-4o Realtime", + Description: "Real-time streaming transcription with GPT-4o", + Type: Transcription, + Streaming: true, + Local: false, + AdapterType: "openai-realtime", + SupportedLanguages: allLangs, + Endpoint: &EndpointConfig{BaseURL: "wss://api.openai.com", Path: "/v1/realtime"}, + }, // LLM models { ID: "gpt-4o-mini", diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 6920049..6e8a454 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -176,9 +176,9 @@ func TestModelsOfType(t *testing.T) { trans := ModelsOfType(p, Transcription) llm := ModelsOfType(p, LLM) - // OpenAI has 3 transcription models: whisper-1, gpt-4o-transcribe, gpt-4o-mini-transcribe - if len(trans) != 3 { - t.Errorf("ModelsOfType(Transcription) = %d, want 3", len(trans)) + // OpenAI has 4 transcription models: whisper-1, gpt-4o-transcribe, gpt-4o-mini-transcribe, gpt-4o-realtime-preview + if len(trans) != 4 { + t.Errorf("ModelsOfType(Transcription) = %d, want 4", len(trans)) } // OpenAI has 2 LLM models: gpt-4o-mini, gpt-4o if len(llm) != 2 { @@ -263,6 +263,39 @@ func TestValidateModelLanguage(t *testing.T) { } } +func TestOpenAIRealtimeModel(t *testing.T) { + m, err := GetModel("openai", "gpt-4o-realtime-preview") + if err != nil { + t.Fatalf("GetModel('openai', 'gpt-4o-realtime-preview') error: %v", err) + } + + if !m.Streaming { + t.Error("gpt-4o-realtime-preview should have Streaming=true") + } + + if m.AdapterType != "openai-realtime" { + t.Errorf("gpt-4o-realtime-preview AdapterType=%q, want 'openai-realtime'", m.AdapterType) + } + + if m.Endpoint == nil { + t.Fatal("gpt-4o-realtime-preview should have Endpoint set") + } + + if m.Endpoint.BaseURL != "wss://api.openai.com" { + t.Errorf("gpt-4o-realtime-preview Endpoint.BaseURL=%q, want 'wss://api.openai.com'", m.Endpoint.BaseURL) + } + + if len(m.SupportedLanguages) != 57 { + t.Errorf("gpt-4o-realtime-preview has %d languages, want 57", len(m.SupportedLanguages)) + } + + // default model should still be whisper-1 + p := GetProvider("openai") + if p.DefaultModel(Transcription) != "whisper-1" { + t.Errorf("DefaultModel(Transcription) = %q, want 'whisper-1'", p.DefaultModel(Transcription)) + } +} + func TestElevenLabsProvider(t *testing.T) { p := GetProvider("elevenlabs") if p == nil { diff --git a/progress.txt b/progress.txt index 5f53d66..ed39f91 100644 --- a/progress.txt +++ b/progress.txt @@ -368,4 +368,14 @@ Started: Sun Feb 1 12:22:47 AM CET 2026 - readLoop calls reconnect() on read errors, readLoop calls reconnect() after failed reads - SendChunk() calls reconnect() on write errors and retries the chunk - Sends notification error to resultsCh on successful reconnect -- All tests passing with -race flag, typecheck passes \ No newline at end of file +- All tests passing with -race flag, typecheck passes + +### Task 36: Add OpenAI Realtime model to OpenAI provider +- Added `gpt-4o-realtime-preview` model to OpenAI provider's Models() +- Type=Transcription, Streaming=true, AdapterType='openai-realtime' +- Endpoint.BaseURL='wss://api.openai.com', Path='/v1/realtime' +- SupportedLanguages=language.AllLanguageCodes() (all 57 languages) +- DefaultModel(Transcription) unchanged (still returns 'whisper-1') +- Added TestOpenAIRealtimeModel test verifying all properties +- Updated TestModelsOfType to expect 4 transcription models for OpenAI +- All tests passing, typecheck passes \ No newline at end of file diff --git a/tasks/prd.jsonc b/tasks/prd.jsonc index 5c8e549..45aa5c4 100644 --- a/tasks/prd.jsonc +++ b/tasks/prd.jsonc @@ -847,7 +847,7 @@ "DefaultModel(Transcription) still returns 'whisper-1'", "Typecheck passes" ], - "passes": false + "passes": true }, { "title": "Create OpenAI Realtime StreamingAdapter",