Skip to content

Commit f385a57

Browse files
committed
Support Gemini via Cloud TTS API with style and language params, add Google gcloud auth support for same, and improve setup flow
1 parent 9960924 commit f385a57

21 files changed

Lines changed: 1106 additions & 176 deletions

CLAUDE.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ go vet ./... # Static analysis
1818
- `internal/config/` — Runtime state (debug, dry-run flags)
1919
- `internal/output/` — JSON/table/CSV/raw output formatting
2020
- `internal/keyring/` — API key storage in OS keyring
21-
- `internal/provider/` — TTSProvider and STTProvider interfaces, registry
21+
- `internal/provider/` — TTSProvider and STTProvider interfaces, registry, AuthConfig
22+
- `internal/gcpauth/` — GCP Application Default Credentials resolution and token exchange (no SDK)
2223
- `internal/tts/` — TTS provider implementations (Google, ElevenLabs, OpenAI)
2324
- `internal/stt/` — STT provider implementations (Google, AssemblyAI, OpenAI)
2425
- `internal/audio/` — WAV header generation, PCM/mulaw/alaw conversion
@@ -27,14 +28,15 @@ go vet ./... # Static analysis
2728
## Key Conventions
2829

2930
- REST over SDK: Use net/http directly, no Google Cloud SDK
30-
- API key resolution: flag → env var → OS keyring
31+
- Auth resolution (Google): ADC/OAuth2 → env var → OS keyring; (others): env var → OS keyring
3132
- Default audio: 8kHz mu-law WAV (IVR standard)
3233
- Provider registration: init() functions in tts/ and stt/ packages register with provider.Registry
3334
- Output formatting: Use output.PrintObject() for structured data, fmt.Fprintf(os.Stderr, ...) for status messages
3435
- Config: Non-secret config in ~/.prompt-tools/config.json, secrets in OS keyring under "prompt-tools-cli" service name
3536

3637
## Environment Variables
3738

39+
- `GOOGLE_APPLICATION_CREDENTIALS` — Path to GCP service account JSON key file (ADC)
3840
- `GOOGLE_API_KEY` — Google Cloud API key
3941
- `ELEVENLABS_API_KEY` — ElevenLabs API key
4042
- `ASSEMBLYAI_API_KEY` — AssemblyAI API key

cmd/batch_transcribe.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ var batchTranscribeCmd = &cobra.Command{
8484
return nil
8585
}
8686

87-
// Resolve API key
88-
apiKey, err := resolveAPIKey(providerName)
87+
// Resolve auth
88+
auth, err := resolveAuth(providerName)
8989
if err != nil {
9090
return err
9191
}
9292

93-
sttProvider, err := provider.NewSTT(providerName, apiKey)
93+
sttProvider, err := provider.NewSTT(providerName, auth)
9494
if err != nil {
9595
return err
9696
}

cmd/bulk.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ var bulkGenerateCmd = &cobra.Command{
2424
2525
Input format (row 1 = headers, skipped automatically):
2626
27-
Filename | Voice | Text | SSML | Sample Rate | Encoding | Notes
28-
welcome.wav | en-US-Chirp3-HD-Achernar | Welcome to support. | no | | | Main greeting
29-
#holiday.wav | en-US-Chirp3-HD-Achernar | Closed for holiday. | no | | | Skipped
30-
es/welcome.wav | es-MX-Chirp3-HD-A | Bienvenido. | no | | | Subdirectory
27+
Filename | Voice | Text | SSML | Sample Rate | Encoding | Notes | Style | Language
28+
welcome.wav | en-US-Chirp3-HD-…| Welcome to support. | no | | | Main greeting | |
29+
#holiday.wav | en-US-Chirp3-HD-…| Closed for holiday. | no | | | Skipped | |
30+
es/welcome.wav | es-MX-Chirp3-HD-A| Bienvenido. | no | | | Subdirectory | |
31+
gemini.wav | Achernar | Welcome to support. | no | | | Gemini+style | speak warmly | en-US
3132
3233
- Rows starting with # are skipped.
33-
- Voice, Sample Rate, and Encoding are optional (defaults from config).
34+
- Voice, Sample Rate, Encoding, Style, and Language are optional (defaults from config).
3435
- SSML column: yes/no — whether Text contains SSML markup.
36+
- Style column: voice steering prompt (Gemini voices with GCP OAuth2 auth only).
37+
- Language column: language code for Gemini voices (default: en-US).
3538
- Filename supports subdirectories (e.g., en-US/welcome.wav) — folders are created automatically.
3639
3740
Examples:
@@ -124,13 +127,13 @@ Examples:
124127
return nil
125128
}
126129

127-
// Resolve API key and create provider
128-
apiKey, err := resolveAPIKey(providerName)
130+
// Resolve auth and create provider
131+
auth, err := resolveAuth(providerName)
129132
if err != nil {
130133
return err
131134
}
132135

133-
tts, err := provider.NewTTS(providerName, apiKey)
136+
tts, err := provider.NewTTS(providerName, auth)
134137
if err != nil {
135138
return err
136139
}

cmd/config_cmd.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"strings"
77

88
"github.com/Cloverhound/prompt-tools-cli/internal/appconfig"
9+
"github.com/Cloverhound/prompt-tools-cli/internal/gcpauth"
910
"github.com/Cloverhound/prompt-tools-cli/internal/keyring"
1011
"github.com/Cloverhound/prompt-tools-cli/internal/output"
1112
"github.com/spf13/cobra"
@@ -57,6 +58,13 @@ var configShowCmd = &cobra.Command{
5758
}
5859
}
5960

61+
// Show GCP ADC status
62+
if gcpauth.HasCredentials() {
63+
display.APIKeys["google_adc"] = "configured"
64+
} else {
65+
display.APIKeys["google_adc"] = "not set"
66+
}
67+
6068
return output.PrintObject(display)
6169
},
6270
}
@@ -230,6 +238,26 @@ var configSetAPIKeyCmd = &cobra.Command{
230238
},
231239
}
232240

241+
var configSetGCPProjectCmd = &cobra.Command{
242+
Use: "set-gcp-project <project-id>",
243+
Short: "Set GCP project for Google API quota/billing",
244+
Args: cobra.ExactArgs(1),
245+
RunE: func(cmd *cobra.Command, args []string) error {
246+
cfg, err := appconfig.Load()
247+
if err != nil {
248+
return err
249+
}
250+
gc := cfg.Providers["google"]
251+
gc.ProjectID = args[0]
252+
cfg.Providers["google"] = gc
253+
if err := cfg.Save(); err != nil {
254+
return err
255+
}
256+
fmt.Printf("GCP project set to %s\n", args[0])
257+
return nil
258+
},
259+
}
260+
233261
var configClearAPIKeyCmd = &cobra.Command{
234262
Use: "clear-api-key <google|elevenlabs|assemblyai|openai>",
235263
Short: "Remove API key from keyring",
@@ -266,5 +294,6 @@ func init() {
266294
configCmd.AddCommand(configSetEncodingCmd)
267295
configCmd.AddCommand(configSetAPIKeyCmd)
268296
configCmd.AddCommand(configClearAPIKeyCmd)
297+
configCmd.AddCommand(configSetGCPProjectCmd)
269298
rootCmd.AddCommand(configCmd)
270299
}

0 commit comments

Comments
 (0)