@mastra/voice-google 0.12.0-beta.0 → 0.12.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +188 -2
- package/dist/docs/README.md +32 -0
- package/dist/docs/SKILL.md +33 -0
- package/dist/docs/SOURCE_MAP.json +6 -0
- package/dist/docs/agents/01-adding-voice.md +352 -0
- package/dist/docs/voice/01-overview.md +1019 -0
- package/dist/docs/voice/02-reference.md +184 -0
- package/dist/index.cjs +63 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +84 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +63 -20
- package/dist/index.js.map +1 -1
- package/package.json +8 -5
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Voice API Reference
|
|
2
|
+
|
|
3
|
+
> API reference for voice - 1 entries
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Reference: Google
|
|
9
|
+
|
|
10
|
+
> Documentation for the Google Voice implementation, providing text-to-speech and speech-to-text capabilities with support for both API key and Vertex AI authentication.
|
|
11
|
+
|
|
12
|
+
The Google Voice implementation in Mastra provides both text-to-speech (TTS) and speech-to-text (STT) capabilities using Google Cloud services. It supports multiple voices, languages, advanced audio configuration options, and both standard API key authentication and Vertex AI mode for enterprise deployments.
|
|
13
|
+
|
|
14
|
+
## Usage Example
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { GoogleVoice } from "@mastra/voice-google";
|
|
18
|
+
|
|
19
|
+
// Initialize with default configuration (uses GOOGLE_API_KEY environment variable)
|
|
20
|
+
const voice = new GoogleVoice();
|
|
21
|
+
|
|
22
|
+
// Text-to-Speech
|
|
23
|
+
const audioStream = await voice.speak("Hello, world!", {
|
|
24
|
+
languageCode: "en-US",
|
|
25
|
+
audioConfig: {
|
|
26
|
+
audioEncoding: "LINEAR16",
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Speech-to-Text
|
|
31
|
+
const transcript = await voice.listen(audioStream, {
|
|
32
|
+
config: {
|
|
33
|
+
encoding: "LINEAR16",
|
|
34
|
+
languageCode: "en-US",
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Get available voices for a specific language
|
|
39
|
+
const voices = await voice.getSpeakers({ languageCode: "en-US" });
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Constructor Parameters
|
|
43
|
+
|
|
44
|
+
### GoogleModelConfig
|
|
45
|
+
|
|
46
|
+
## Methods
|
|
47
|
+
|
|
48
|
+
### speak()
|
|
49
|
+
|
|
50
|
+
Converts text to speech using Google Cloud Text-to-Speech service.
|
|
51
|
+
|
|
52
|
+
Returns: `Promise<NodeJS.ReadableStream>`
|
|
53
|
+
|
|
54
|
+
### listen()
|
|
55
|
+
|
|
56
|
+
Converts speech to text using Google Cloud Speech-to-Text service.
|
|
57
|
+
|
|
58
|
+
Returns: `Promise<string>`
|
|
59
|
+
|
|
60
|
+
### getSpeakers()
|
|
61
|
+
|
|
62
|
+
Returns an array of available voice options, where each node contains:
|
|
63
|
+
|
|
64
|
+
### isUsingVertexAI()
|
|
65
|
+
|
|
66
|
+
Checks if Vertex AI mode is enabled.
|
|
67
|
+
|
|
68
|
+
Returns: `boolean` - `true` if using Vertex AI, `false` otherwise
|
|
69
|
+
|
|
70
|
+
### getProject()
|
|
71
|
+
|
|
72
|
+
Gets the configured Google Cloud project ID.
|
|
73
|
+
|
|
74
|
+
Returns: `string | undefined` - The project ID or `undefined` if not set
|
|
75
|
+
|
|
76
|
+
### getLocation()
|
|
77
|
+
|
|
78
|
+
Gets the configured Google Cloud location/region.
|
|
79
|
+
|
|
80
|
+
Returns: `string` - The location (default: `'us-central1'`)
|
|
81
|
+
|
|
82
|
+
## Authentication
|
|
83
|
+
|
|
84
|
+
The Google Voice provider supports two authentication methods:
|
|
85
|
+
|
|
86
|
+
### Standard Mode (API Key)
|
|
87
|
+
|
|
88
|
+
Uses a Google Cloud API key for authentication. Suitable for development and simple use cases.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// Using environment variable (GOOGLE_API_KEY)
|
|
92
|
+
const voice = new GoogleVoice();
|
|
93
|
+
|
|
94
|
+
// Using explicit API key
|
|
95
|
+
const voice = new GoogleVoice({
|
|
96
|
+
speechModel: { apiKey: "your-api-key" },
|
|
97
|
+
listeningModel: { apiKey: "your-api-key" },
|
|
98
|
+
speaker: "en-US-Casual-K",
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Vertex AI Mode (Service Account)
|
|
103
|
+
|
|
104
|
+
Uses Google Cloud project-based authentication with service accounts. Recommended for production and enterprise deployments.
|
|
105
|
+
|
|
106
|
+
**Benefits:**
|
|
107
|
+
- Better security (no API keys in code)
|
|
108
|
+
- IAM-based access control
|
|
109
|
+
- Project-level billing and quotas
|
|
110
|
+
- Audit logging
|
|
111
|
+
- Enterprise features
|
|
112
|
+
|
|
113
|
+
**Configuration Options:**
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// Using Application Default Credentials (ADC)
|
|
117
|
+
// Set GOOGLE_APPLICATION_CREDENTIALS and GOOGLE_CLOUD_PROJECT env vars
|
|
118
|
+
const voice = new GoogleVoice({
|
|
119
|
+
vertexAI: true,
|
|
120
|
+
project: "your-gcp-project",
|
|
121
|
+
location: "us-central1", // Optional, defaults to 'us-central1'
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Using service account key file
|
|
125
|
+
const voice = new GoogleVoice({
|
|
126
|
+
vertexAI: true,
|
|
127
|
+
project: "your-gcp-project",
|
|
128
|
+
speechModel: {
|
|
129
|
+
keyFilename: "/path/to/service-account.json",
|
|
130
|
+
},
|
|
131
|
+
listeningModel: {
|
|
132
|
+
keyFilename: "/path/to/service-account.json",
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Using in-memory credentials
|
|
137
|
+
const voice = new GoogleVoice({
|
|
138
|
+
vertexAI: true,
|
|
139
|
+
project: "your-gcp-project",
|
|
140
|
+
speechModel: {
|
|
141
|
+
credentials: {
|
|
142
|
+
client_email: "service-account@project.iam.gserviceaccount.com",
|
|
143
|
+
private_key: "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Required Permissions:**
|
|
150
|
+
|
|
151
|
+
**IAM Roles:**
|
|
152
|
+
|
|
153
|
+
For Text-to-Speech:
|
|
154
|
+
- `roles/texttospeech.admin` - Text-to-Speech Admin (full access)
|
|
155
|
+
- `roles/texttospeech.editor` - Text-to-Speech Editor (create and manage)
|
|
156
|
+
- `roles/texttospeech.viewer` - Text-to-Speech Viewer (read-only)
|
|
157
|
+
|
|
158
|
+
For Speech-to-Text:
|
|
159
|
+
- `roles/speech.client` - Speech-to-Text Client
|
|
160
|
+
|
|
161
|
+
**OAuth Scopes:**
|
|
162
|
+
|
|
163
|
+
For synchronous Text-to-Speech synthesis:
|
|
164
|
+
- `https://www.googleapis.com/auth/cloud-platform` - Full access to Google Cloud Platform services
|
|
165
|
+
|
|
166
|
+
For long-audio Text-to-Speech operations:
|
|
167
|
+
- `locations.longAudioSynthesize` - Create long-audio synthesis operations
|
|
168
|
+
- `operations.get` - Get operation status
|
|
169
|
+
- `operations.list` - List operations
|
|
170
|
+
|
|
171
|
+
## Important Notes
|
|
172
|
+
|
|
173
|
+
1. **Authentication**: Either a Google Cloud API key (standard mode) or service account credentials (Vertex AI mode) is required.
|
|
174
|
+
2. **Environment Variables**:
|
|
175
|
+
- `GOOGLE_API_KEY` - API key for standard mode
|
|
176
|
+
- `GOOGLE_CLOUD_PROJECT` - Project ID for Vertex AI mode
|
|
177
|
+
- `GOOGLE_CLOUD_LOCATION` - Location for Vertex AI mode (defaults to 'us-central1')
|
|
178
|
+
- `GOOGLE_APPLICATION_CREDENTIALS` - Path to service account key file
|
|
179
|
+
3. The default voice is set to `'en-US-Casual-K'`.
|
|
180
|
+
4. Both text-to-speech and speech-to-text services use LINEAR16 as the default audio encoding.
|
|
181
|
+
5. The `speak()` method supports advanced audio configuration through the Google Cloud Text-to-Speech API.
|
|
182
|
+
6. The `listen()` method supports various recognition configurations through the Google Cloud Speech-to-Text API.
|
|
183
|
+
7. Available voices can be filtered by language code using the `getSpeakers()` method.
|
|
184
|
+
8. Vertex AI mode provides enterprise features including IAM control, audit logs, and project-level billing.
|
package/dist/index.cjs
CHANGED
|
@@ -6,10 +6,16 @@ var textToSpeech = require('@google-cloud/text-to-speech');
|
|
|
6
6
|
var voice = require('@mastra/core/voice');
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
|
-
var resolveAuthConfig = (modelConfig, fallback) => {
|
|
9
|
+
var resolveAuthConfig = (modelConfig, fallback, vertexConfig) => {
|
|
10
10
|
const resolved = {};
|
|
11
|
+
if (vertexConfig?.vertexAI) {
|
|
12
|
+
const projectId = vertexConfig.project || process.env.GOOGLE_CLOUD_PROJECT;
|
|
13
|
+
if (projectId) {
|
|
14
|
+
resolved.projectId = projectId;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
11
17
|
const apiKey = modelConfig?.apiKey ?? fallback.apiKey;
|
|
12
|
-
if (apiKey) {
|
|
18
|
+
if (apiKey && !vertexConfig?.vertexAI) {
|
|
13
19
|
resolved.apiKey = apiKey;
|
|
14
20
|
}
|
|
15
21
|
const keyFilename = modelConfig?.keyFilename ?? fallback.keyFilename;
|
|
@@ -22,44 +28,57 @@ var resolveAuthConfig = (modelConfig, fallback) => {
|
|
|
22
28
|
}
|
|
23
29
|
return resolved;
|
|
24
30
|
};
|
|
25
|
-
var buildAuthOptions = (config) => {
|
|
31
|
+
var buildAuthOptions = (config, vertexConfig) => {
|
|
32
|
+
const options = {};
|
|
26
33
|
if (config.credentials) {
|
|
27
|
-
|
|
34
|
+
options.credentials = config.credentials;
|
|
28
35
|
}
|
|
29
36
|
if (config.keyFilename) {
|
|
30
|
-
|
|
37
|
+
options.keyFilename = config.keyFilename;
|
|
31
38
|
}
|
|
32
|
-
if (config.apiKey) {
|
|
33
|
-
|
|
39
|
+
if (config.apiKey && !vertexConfig?.vertexAI) {
|
|
40
|
+
options.apiKey = config.apiKey;
|
|
34
41
|
}
|
|
35
|
-
|
|
42
|
+
if (config.projectId) {
|
|
43
|
+
options.projectId = config.projectId;
|
|
44
|
+
}
|
|
45
|
+
return options;
|
|
36
46
|
};
|
|
37
47
|
var DEFAULT_VOICE = "en-US-Casual-K";
|
|
38
48
|
var GoogleVoice = class extends voice.MastraVoice {
|
|
39
49
|
ttsClient;
|
|
40
50
|
speechClient;
|
|
51
|
+
vertexAI;
|
|
52
|
+
project;
|
|
53
|
+
location;
|
|
41
54
|
/**
|
|
42
55
|
* Creates an instance of GoogleVoice
|
|
43
|
-
* @param {
|
|
56
|
+
* @param {GoogleVoiceConfig} config - Configuration options
|
|
44
57
|
* @param {GoogleModelConfig} [config.speechModel] - Configuration for speech synthesis
|
|
45
58
|
* @param {GoogleModelConfig} [config.listeningModel] - Configuration for speech recognition
|
|
46
59
|
* @param {string} [config.speaker] - Default voice ID to use for speech synthesis
|
|
60
|
+
* @param {boolean} [config.vertexAI] - Enable Vertex AI mode
|
|
61
|
+
* @param {string} [config.project] - Google Cloud project ID (required for Vertex AI)
|
|
62
|
+
* @param {string} [config.location] - Google Cloud region (default: 'us-central1')
|
|
47
63
|
*/
|
|
48
|
-
constructor({
|
|
49
|
-
listeningModel,
|
|
50
|
-
speechModel,
|
|
51
|
-
speaker
|
|
52
|
-
} = {}) {
|
|
64
|
+
constructor({ listeningModel, speechModel, speaker, vertexAI = false, project, location } = {}) {
|
|
53
65
|
const defaultApiKey = process.env.GOOGLE_API_KEY;
|
|
54
66
|
const defaultKeyFilename = process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
55
67
|
const defaultSpeaker = DEFAULT_VOICE;
|
|
68
|
+
const resolvedProject = project || process.env.GOOGLE_CLOUD_PROJECT;
|
|
69
|
+
const resolvedLocation = location || process.env.GOOGLE_CLOUD_LOCATION || "us-central1";
|
|
70
|
+
if (vertexAI && !resolvedProject) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
"Google Cloud project ID is required when using Vertex AI. Set GOOGLE_CLOUD_PROJECT environment variable or pass project to constructor."
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
const vertexConfig = { vertexAI, project: resolvedProject };
|
|
56
76
|
const sharedFallback = {
|
|
57
77
|
apiKey: defaultApiKey ?? speechModel?.apiKey ?? listeningModel?.apiKey,
|
|
58
78
|
keyFilename: defaultKeyFilename ?? speechModel?.keyFilename ?? listeningModel?.keyFilename,
|
|
59
|
-
credentials: speechModel?.credentials ?? listeningModel?.credentials
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
const listeningAuthConfig = resolveAuthConfig(listeningModel, sharedFallback);
|
|
79
|
+
credentials: speechModel?.credentials ?? listeningModel?.credentials};
|
|
80
|
+
const speechAuthConfig = resolveAuthConfig(speechModel, sharedFallback, vertexConfig);
|
|
81
|
+
const listeningAuthConfig = resolveAuthConfig(listeningModel, sharedFallback, vertexConfig);
|
|
63
82
|
super({
|
|
64
83
|
speechModel: {
|
|
65
84
|
name: "",
|
|
@@ -71,11 +90,35 @@ var GoogleVoice = class extends voice.MastraVoice {
|
|
|
71
90
|
},
|
|
72
91
|
speaker: speaker ?? defaultSpeaker
|
|
73
92
|
});
|
|
74
|
-
|
|
75
|
-
|
|
93
|
+
this.vertexAI = vertexAI;
|
|
94
|
+
this.project = resolvedProject;
|
|
95
|
+
this.location = resolvedLocation;
|
|
96
|
+
const ttsOptions = buildAuthOptions(speechAuthConfig, { vertexAI});
|
|
97
|
+
const speechOptions = buildAuthOptions(listeningAuthConfig, { vertexAI});
|
|
76
98
|
this.ttsClient = new textToSpeech.TextToSpeechClient(ttsOptions);
|
|
77
99
|
this.speechClient = new speech.SpeechClient(speechOptions);
|
|
78
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Check if Vertex AI mode is enabled
|
|
103
|
+
* @returns {boolean} True if using Vertex AI
|
|
104
|
+
*/
|
|
105
|
+
isUsingVertexAI() {
|
|
106
|
+
return this.vertexAI;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the configured Google Cloud project ID
|
|
110
|
+
* @returns {string | undefined} The project ID or undefined if not set
|
|
111
|
+
*/
|
|
112
|
+
getProject() {
|
|
113
|
+
return this.project;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get the configured Google Cloud location/region
|
|
117
|
+
* @returns {string} The location (default: 'us-central1')
|
|
118
|
+
*/
|
|
119
|
+
getLocation() {
|
|
120
|
+
return this.location;
|
|
121
|
+
}
|
|
79
122
|
/**
|
|
80
123
|
* Gets a list of available voices
|
|
81
124
|
* @returns {Promise<Array<{voiceId: string, languageCodes: string[]}>>} List of available voices and their supported languages. Default language is en-US.
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["MastraVoice","TextToSpeechClient","SpeechClient","stream","PassThrough"],"mappings":"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","file":"index.cjs","sourcesContent":["import { PassThrough } from 'stream';\n\nimport { SpeechClient } from '@google-cloud/speech';\nimport type { google as SpeechTypes } from '@google-cloud/speech/build/protos/protos';\nimport { TextToSpeechClient } from '@google-cloud/text-to-speech';\nimport type { google as TextToSpeechTypes } from '@google-cloud/text-to-speech/build/protos/protos';\nimport { MastraVoice } from '@mastra/core/voice';\n\n/**\n * Configuration for Google Cloud Voice models\n * @interface GoogleModelConfig\n * @property {string} [apiKey] - Optional Google Cloud API key. If not provided, will use GOOGLE_API_KEY environment variable\n * @property {string} [keyFilename] - Optional path to a service account key file. If not provided, will use GOOGLE_APPLICATION_CREDENTIALS environment variable\n * @property {{ client_email?: string; private_key?: string }} [credentials] - Optional in-memory service account credentials\n */\nexport interface GoogleModelConfig {\n apiKey?: string;\n keyFilename?: string;\n credentials?: {\n client_email?: string;\n private_key?: string;\n [key: string]: unknown;\n };\n}\n\ntype AuthConfig = Pick<GoogleModelConfig, 'apiKey' | 'keyFilename' | 'credentials'>;\n\ntype GoogleClientOptions = AuthConfig;\n\nconst resolveAuthConfig = (modelConfig: GoogleModelConfig | undefined, fallback: AuthConfig): AuthConfig => {\n const resolved: AuthConfig = {};\n\n const apiKey = modelConfig?.apiKey ?? fallback.apiKey;\n if (apiKey) {\n resolved.apiKey = apiKey;\n }\n\n const keyFilename = modelConfig?.keyFilename ?? fallback.keyFilename;\n if (keyFilename) {\n resolved.keyFilename = keyFilename;\n }\n\n const credentials = modelConfig?.credentials ?? fallback.credentials;\n if (credentials) {\n resolved.credentials = credentials;\n }\n\n return resolved;\n};\n\nconst buildAuthOptions = (config: AuthConfig): GoogleClientOptions => {\n if (config.credentials) {\n return { credentials: config.credentials };\n }\n\n if (config.keyFilename) {\n return { keyFilename: config.keyFilename };\n }\n\n if (config.apiKey) {\n return { apiKey: config.apiKey };\n }\n\n return {};\n};\n\nconst DEFAULT_VOICE = 'en-US-Casual-K';\n\n/**\n * GoogleVoice class provides Text-to-Speech and Speech-to-Text capabilities using Google Cloud services\n * @class GoogleVoice\n * @extends MastraVoice\n */\nexport class GoogleVoice extends MastraVoice {\n private ttsClient: TextToSpeechClient;\n private speechClient: SpeechClient;\n\n /**\n * Creates an instance of GoogleVoice\n * @param {Object} config - Configuration options\n * @param {GoogleModelConfig} [config.speechModel] - Configuration for speech synthesis\n * @param {GoogleModelConfig} [config.listeningModel] - Configuration for speech recognition\n * @param {string} [config.speaker] - Default voice ID to use for speech synthesis\n */\n constructor({\n listeningModel,\n speechModel,\n speaker,\n }: {\n listeningModel?: GoogleModelConfig;\n speechModel?: GoogleModelConfig;\n speaker?: string;\n } = {}) {\n const defaultApiKey = process.env.GOOGLE_API_KEY;\n const defaultKeyFilename = process.env.GOOGLE_APPLICATION_CREDENTIALS;\n const defaultSpeaker = DEFAULT_VOICE;\n\n const sharedFallback: AuthConfig = {\n apiKey: defaultApiKey ?? speechModel?.apiKey ?? listeningModel?.apiKey,\n keyFilename: defaultKeyFilename ?? speechModel?.keyFilename ?? listeningModel?.keyFilename,\n credentials: speechModel?.credentials ?? listeningModel?.credentials,\n };\n\n const speechAuthConfig = resolveAuthConfig(speechModel, sharedFallback);\n const listeningAuthConfig = resolveAuthConfig(listeningModel, sharedFallback);\n\n super({\n speechModel: {\n name: '',\n apiKey: speechAuthConfig.apiKey ?? defaultApiKey,\n },\n listeningModel: {\n name: '',\n apiKey: listeningAuthConfig.apiKey ?? defaultApiKey,\n },\n speaker: speaker ?? defaultSpeaker,\n });\n\n const ttsOptions = buildAuthOptions(speechAuthConfig);\n const speechOptions = buildAuthOptions(listeningAuthConfig);\n\n this.ttsClient = new TextToSpeechClient(ttsOptions);\n\n this.speechClient = new SpeechClient(speechOptions);\n }\n\n /**\n * Gets a list of available voices\n * @returns {Promise<Array<{voiceId: string, languageCodes: string[]}>>} List of available voices and their supported languages. Default language is en-US.\n */\n async getSpeakers({ languageCode = 'en-US' }: { languageCode?: string } = {}) {\n const [response] = await this.ttsClient.listVoices({ languageCode: languageCode });\n return (response?.voices || [])\n .filter(voice => voice.name && voice.languageCodes)\n .map(voice => ({\n voiceId: voice.name!,\n languageCodes: voice.languageCodes!,\n }));\n }\n\n private async streamToString(stream: NodeJS.ReadableStream): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n if (typeof chunk === 'string') {\n chunks.push(Buffer.from(chunk));\n } else {\n chunks.push(chunk);\n }\n }\n return Buffer.concat(chunks).toString('utf-8');\n }\n\n /**\n * Converts text to speech\n * @param {string | NodeJS.ReadableStream} input - Text or stream to convert to speech\n * @param {Object} [options] - Speech synthesis options\n * @param {string} [options.speaker] - Voice ID to use\n * @param {string} [options.languageCode] - Language code for the voice\n * @param {TextToSpeechTypes.cloud.texttospeech.v1.ISynthesizeSpeechRequest['audioConfig']} [options.audioConfig] - Audio configuration options\n * @returns {Promise<NodeJS.ReadableStream>} Stream of synthesized audio. Default encoding is LINEAR16.\n */\n async speak(\n input: string | NodeJS.ReadableStream,\n options?: {\n speaker?: string;\n languageCode?: string;\n audioConfig?: TextToSpeechTypes.cloud.texttospeech.v1.ISynthesizeSpeechRequest['audioConfig'];\n },\n ): Promise<NodeJS.ReadableStream> {\n const text = typeof input === 'string' ? input : await this.streamToString(input);\n\n const request: TextToSpeechTypes.cloud.texttospeech.v1.ISynthesizeSpeechRequest = {\n input: { text },\n voice: {\n name: options?.speaker || this.speaker,\n languageCode: options?.languageCode || options?.speaker?.split('-').slice(0, 2).join('-') || 'en-US',\n },\n audioConfig: options?.audioConfig || { audioEncoding: 'LINEAR16' },\n };\n\n const [response] = await this.ttsClient.synthesizeSpeech(request);\n\n if (!response.audioContent) {\n throw new Error('No audio content returned.');\n }\n\n if (typeof response.audioContent === 'string') {\n throw new Error('Audio content is a string.');\n }\n\n const stream = new PassThrough();\n stream.end(Buffer.from(response.audioContent));\n return stream;\n }\n\n /**\n * Checks if listening capabilities are enabled.\n *\n * @returns {Promise<{ enabled: boolean }>}\n */\n async getListener() {\n return { enabled: true };\n }\n\n /**\n * Converts speech to text\n * @param {NodeJS.ReadableStream} audioStream - Audio stream to transcribe. Default encoding is LINEAR16.\n * @param {Object} [options] - Recognition options\n * @param {SpeechTypes.cloud.speech.v1.IRecognitionConfig} [options.config] - Recognition configuration\n * @returns {Promise<string>} Transcribed text\n */\n async listen(\n audioStream: NodeJS.ReadableStream,\n options?: { stream?: boolean; config?: SpeechTypes.cloud.speech.v1.IRecognitionConfig },\n ): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of audioStream) {\n if (typeof chunk === 'string') {\n chunks.push(Buffer.from(chunk));\n } else {\n chunks.push(chunk);\n }\n }\n const buffer = Buffer.concat(chunks);\n\n let request = {\n config: {\n encoding: 'LINEAR16',\n languageCode: 'en-US',\n ...options?.config,\n },\n audio: {\n content: buffer.toString('base64'),\n },\n };\n const [response] = await this.speechClient.recognize(request as SpeechTypes.cloud.speech.v1.IRecognizeRequest);\n\n if (!response.results || response.results.length === 0) {\n throw new Error('No transcription results returned');\n }\n\n const transcription = response.results\n .map((result: any) => {\n if (!result.alternatives || result.alternatives.length === 0) {\n return '';\n }\n return result.alternatives[0].transcript || '';\n })\n .filter((text: string) => text.length > 0)\n .join(' ');\n\n if (!transcription) {\n throw new Error('No valid transcription found in results');\n }\n\n return transcription;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["MastraVoice","TextToSpeechClient","SpeechClient","stream","PassThrough"],"mappings":"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","file":"index.cjs","sourcesContent":["import { PassThrough } from 'node:stream';\n\nimport { SpeechClient } from '@google-cloud/speech';\nimport type { google as SpeechTypes } from '@google-cloud/speech/build/protos/protos';\nimport { TextToSpeechClient } from '@google-cloud/text-to-speech';\nimport type { google as TextToSpeechTypes } from '@google-cloud/text-to-speech/build/protos/protos';\nimport { MastraVoice } from '@mastra/core/voice';\n\n/**\n * Configuration for Google Cloud Voice models\n * @interface GoogleModelConfig\n * @property {string} [apiKey] - Optional Google Cloud API key. If not provided, will use GOOGLE_API_KEY environment variable\n * @property {string} [keyFilename] - Optional path to a service account key file. If not provided, will use GOOGLE_APPLICATION_CREDENTIALS environment variable\n * @property {{ client_email?: string; private_key?: string }} [credentials] - Optional in-memory service account credentials\n */\nexport interface GoogleModelConfig {\n apiKey?: string;\n keyFilename?: string;\n credentials?: {\n client_email?: string;\n private_key?: string;\n [key: string]: unknown;\n };\n}\n\n/**\n * Configuration options for GoogleVoice\n * @interface GoogleVoiceConfig\n */\nexport interface GoogleVoiceConfig {\n /** Configuration for speech synthesis (TTS) */\n speechModel?: GoogleModelConfig;\n /** Configuration for speech recognition (STT) */\n listeningModel?: GoogleModelConfig;\n /** Default voice ID to use for speech synthesis */\n speaker?: string;\n /**\n * Enable Vertex AI mode for enterprise deployments.\n * When true, uses Google Cloud project-based authentication instead of API keys.\n * Requires `project` to be set or GOOGLE_CLOUD_PROJECT environment variable.\n */\n vertexAI?: boolean;\n /**\n * Google Cloud project ID (required when vertexAI is true).\n * Falls back to GOOGLE_CLOUD_PROJECT environment variable.\n */\n project?: string;\n /**\n * Google Cloud region for Vertex AI endpoints.\n * Falls back to GOOGLE_CLOUD_LOCATION environment variable.\n * @default 'us-central1'\n */\n location?: string;\n}\n\ntype AuthConfig = Pick<GoogleModelConfig, 'apiKey' | 'keyFilename' | 'credentials'> & {\n projectId?: string;\n};\n\ntype GoogleClientOptions = AuthConfig;\n\nconst resolveAuthConfig = (\n modelConfig: GoogleModelConfig | undefined,\n fallback: AuthConfig,\n vertexConfig?: { vertexAI?: boolean; project?: string },\n): AuthConfig => {\n const resolved: AuthConfig = {};\n\n // For Vertex AI, prioritize project-based auth over API keys\n if (vertexConfig?.vertexAI) {\n const projectId = vertexConfig.project || process.env.GOOGLE_CLOUD_PROJECT;\n if (projectId) {\n resolved.projectId = projectId;\n }\n }\n\n const apiKey = modelConfig?.apiKey ?? fallback.apiKey;\n // Only use API key if not in Vertex AI mode\n if (apiKey && !vertexConfig?.vertexAI) {\n resolved.apiKey = apiKey;\n }\n\n const keyFilename = modelConfig?.keyFilename ?? fallback.keyFilename;\n if (keyFilename) {\n resolved.keyFilename = keyFilename;\n }\n\n const credentials = modelConfig?.credentials ?? fallback.credentials;\n if (credentials) {\n resolved.credentials = credentials;\n }\n\n return resolved;\n};\n\nconst buildAuthOptions = (\n config: AuthConfig,\n vertexConfig?: { vertexAI?: boolean; location?: string },\n): GoogleClientOptions => {\n const options: GoogleClientOptions = {};\n\n if (config.credentials) {\n options.credentials = config.credentials;\n }\n\n if (config.keyFilename) {\n options.keyFilename = config.keyFilename;\n }\n\n // Only use API key if not using Vertex AI\n if (config.apiKey && !vertexConfig?.vertexAI) {\n options.apiKey = config.apiKey;\n }\n\n // For Vertex AI, set the project ID\n if (config.projectId) {\n options.projectId = config.projectId;\n }\n\n return options;\n};\n\nconst DEFAULT_VOICE = 'en-US-Casual-K';\n\n/**\n * GoogleVoice class provides Text-to-Speech and Speech-to-Text capabilities using Google Cloud services.\n * Supports both standard Google Cloud API authentication and Vertex AI mode for enterprise deployments.\n *\n * @class GoogleVoice\n * @extends MastraVoice\n *\n * @example Standard usage with API key\n * ```typescript\n * const voice = new GoogleVoice({\n * speechModel: { apiKey: 'your-api-key' },\n * speaker: 'en-US-Studio-O',\n * });\n * ```\n *\n * @example Vertex AI mode (recommended for production)\n * ```typescript\n * const voice = new GoogleVoice({\n * vertexAI: true,\n * project: 'your-gcp-project',\n * location: 'us-central1',\n * speaker: 'en-US-Studio-O',\n * });\n * ```\n *\n * @example Vertex AI with service account\n * ```typescript\n * const voice = new GoogleVoice({\n * vertexAI: true,\n * project: 'your-gcp-project',\n * speechModel: {\n * keyFilename: '/path/to/service-account.json',\n * },\n * });\n * ```\n */\nexport class GoogleVoice extends MastraVoice {\n private ttsClient: TextToSpeechClient;\n private speechClient: SpeechClient;\n private readonly vertexAI: boolean;\n private readonly project?: string;\n private readonly location: string;\n\n /**\n * Creates an instance of GoogleVoice\n * @param {GoogleVoiceConfig} config - Configuration options\n * @param {GoogleModelConfig} [config.speechModel] - Configuration for speech synthesis\n * @param {GoogleModelConfig} [config.listeningModel] - Configuration for speech recognition\n * @param {string} [config.speaker] - Default voice ID to use for speech synthesis\n * @param {boolean} [config.vertexAI] - Enable Vertex AI mode\n * @param {string} [config.project] - Google Cloud project ID (required for Vertex AI)\n * @param {string} [config.location] - Google Cloud region (default: 'us-central1')\n */\n constructor({ listeningModel, speechModel, speaker, vertexAI = false, project, location }: GoogleVoiceConfig = {}) {\n const defaultApiKey = process.env.GOOGLE_API_KEY;\n const defaultKeyFilename = process.env.GOOGLE_APPLICATION_CREDENTIALS;\n const defaultSpeaker = DEFAULT_VOICE;\n\n // Resolve Vertex AI configuration\n const resolvedProject = project || process.env.GOOGLE_CLOUD_PROJECT;\n const resolvedLocation = location || process.env.GOOGLE_CLOUD_LOCATION || 'us-central1';\n\n // Validate Vertex AI configuration\n if (vertexAI && !resolvedProject) {\n throw new Error(\n 'Google Cloud project ID is required when using Vertex AI. ' +\n 'Set GOOGLE_CLOUD_PROJECT environment variable or pass project to constructor.',\n );\n }\n\n const vertexConfig = { vertexAI, project: resolvedProject };\n\n const sharedFallback: AuthConfig = {\n apiKey: defaultApiKey ?? speechModel?.apiKey ?? listeningModel?.apiKey,\n keyFilename: defaultKeyFilename ?? speechModel?.keyFilename ?? listeningModel?.keyFilename,\n credentials: speechModel?.credentials ?? listeningModel?.credentials,\n projectId: resolvedProject,\n };\n\n const speechAuthConfig = resolveAuthConfig(speechModel, sharedFallback, vertexConfig);\n const listeningAuthConfig = resolveAuthConfig(listeningModel, sharedFallback, vertexConfig);\n\n super({\n speechModel: {\n name: '',\n apiKey: speechAuthConfig.apiKey ?? defaultApiKey,\n },\n listeningModel: {\n name: '',\n apiKey: listeningAuthConfig.apiKey ?? defaultApiKey,\n },\n speaker: speaker ?? defaultSpeaker,\n });\n\n this.vertexAI = vertexAI;\n this.project = resolvedProject;\n this.location = resolvedLocation;\n\n const ttsOptions = buildAuthOptions(speechAuthConfig, { vertexAI, location: resolvedLocation });\n const speechOptions = buildAuthOptions(listeningAuthConfig, { vertexAI, location: resolvedLocation });\n\n this.ttsClient = new TextToSpeechClient(ttsOptions);\n this.speechClient = new SpeechClient(speechOptions);\n }\n\n /**\n * Check if Vertex AI mode is enabled\n * @returns {boolean} True if using Vertex AI\n */\n isUsingVertexAI(): boolean {\n return this.vertexAI;\n }\n\n /**\n * Get the configured Google Cloud project ID\n * @returns {string | undefined} The project ID or undefined if not set\n */\n getProject(): string | undefined {\n return this.project;\n }\n\n /**\n * Get the configured Google Cloud location/region\n * @returns {string} The location (default: 'us-central1')\n */\n getLocation(): string {\n return this.location;\n }\n\n /**\n * Gets a list of available voices\n * @returns {Promise<Array<{voiceId: string, languageCodes: string[]}>>} List of available voices and their supported languages. Default language is en-US.\n */\n async getSpeakers({ languageCode = 'en-US' }: { languageCode?: string } = {}) {\n const [response] = await this.ttsClient.listVoices({ languageCode: languageCode });\n return (response?.voices || [])\n .filter(voice => voice.name && voice.languageCodes)\n .map(voice => ({\n voiceId: voice.name!,\n languageCodes: voice.languageCodes!,\n }));\n }\n\n private async streamToString(stream: NodeJS.ReadableStream): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n if (typeof chunk === 'string') {\n chunks.push(Buffer.from(chunk));\n } else {\n chunks.push(chunk);\n }\n }\n return Buffer.concat(chunks).toString('utf-8');\n }\n\n /**\n * Converts text to speech\n * @param {string | NodeJS.ReadableStream} input - Text or stream to convert to speech\n * @param {Object} [options] - Speech synthesis options\n * @param {string} [options.speaker] - Voice ID to use\n * @param {string} [options.languageCode] - Language code for the voice\n * @param {TextToSpeechTypes.cloud.texttospeech.v1.ISynthesizeSpeechRequest['audioConfig']} [options.audioConfig] - Audio configuration options\n * @returns {Promise<NodeJS.ReadableStream>} Stream of synthesized audio. Default encoding is LINEAR16.\n */\n async speak(\n input: string | NodeJS.ReadableStream,\n options?: {\n speaker?: string;\n languageCode?: string;\n audioConfig?: TextToSpeechTypes.cloud.texttospeech.v1.ISynthesizeSpeechRequest['audioConfig'];\n },\n ): Promise<NodeJS.ReadableStream> {\n const text = typeof input === 'string' ? input : await this.streamToString(input);\n\n const request: TextToSpeechTypes.cloud.texttospeech.v1.ISynthesizeSpeechRequest = {\n input: { text },\n voice: {\n name: options?.speaker || this.speaker,\n languageCode: options?.languageCode || options?.speaker?.split('-').slice(0, 2).join('-') || 'en-US',\n },\n audioConfig: options?.audioConfig || { audioEncoding: 'LINEAR16' },\n };\n\n const [response] = await this.ttsClient.synthesizeSpeech(request);\n\n if (!response.audioContent) {\n throw new Error('No audio content returned.');\n }\n\n if (typeof response.audioContent === 'string') {\n throw new Error('Audio content is a string.');\n }\n\n const stream = new PassThrough();\n stream.end(Buffer.from(response.audioContent));\n return stream;\n }\n\n /**\n * Checks if listening capabilities are enabled.\n *\n * @returns {Promise<{ enabled: boolean }>}\n */\n async getListener() {\n return { enabled: true };\n }\n\n /**\n * Converts speech to text\n * @param {NodeJS.ReadableStream} audioStream - Audio stream to transcribe. Default encoding is LINEAR16.\n * @param {Object} [options] - Recognition options\n * @param {SpeechTypes.cloud.speech.v1.IRecognitionConfig} [options.config] - Recognition configuration\n * @returns {Promise<string>} Transcribed text\n */\n async listen(\n audioStream: NodeJS.ReadableStream,\n options?: { stream?: boolean; config?: SpeechTypes.cloud.speech.v1.IRecognitionConfig },\n ): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of audioStream) {\n if (typeof chunk === 'string') {\n chunks.push(Buffer.from(chunk));\n } else {\n chunks.push(chunk);\n }\n }\n const buffer = Buffer.concat(chunks);\n\n let request = {\n config: {\n encoding: 'LINEAR16',\n languageCode: 'en-US',\n ...options?.config,\n },\n audio: {\n content: buffer.toString('base64'),\n },\n };\n const [response] = await this.speechClient.recognize(request as SpeechTypes.cloud.speech.v1.IRecognizeRequest);\n\n if (!response.results || response.results.length === 0) {\n throw new Error('No transcription results returned');\n }\n\n const transcription = response.results\n .map((result: any) => {\n if (!result.alternatives || result.alternatives.length === 0) {\n return '';\n }\n return result.alternatives[0].transcript || '';\n })\n .filter((text: string) => text.length > 0)\n .join(' ');\n\n if (!transcription) {\n throw new Error('No valid transcription found in results');\n }\n\n return transcription;\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,25 +18,102 @@ export interface GoogleModelConfig {
|
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* Configuration options for GoogleVoice
|
|
22
|
+
* @interface GoogleVoiceConfig
|
|
23
|
+
*/
|
|
24
|
+
export interface GoogleVoiceConfig {
|
|
25
|
+
/** Configuration for speech synthesis (TTS) */
|
|
26
|
+
speechModel?: GoogleModelConfig;
|
|
27
|
+
/** Configuration for speech recognition (STT) */
|
|
28
|
+
listeningModel?: GoogleModelConfig;
|
|
29
|
+
/** Default voice ID to use for speech synthesis */
|
|
30
|
+
speaker?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Enable Vertex AI mode for enterprise deployments.
|
|
33
|
+
* When true, uses Google Cloud project-based authentication instead of API keys.
|
|
34
|
+
* Requires `project` to be set or GOOGLE_CLOUD_PROJECT environment variable.
|
|
35
|
+
*/
|
|
36
|
+
vertexAI?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Google Cloud project ID (required when vertexAI is true).
|
|
39
|
+
* Falls back to GOOGLE_CLOUD_PROJECT environment variable.
|
|
40
|
+
*/
|
|
41
|
+
project?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Google Cloud region for Vertex AI endpoints.
|
|
44
|
+
* Falls back to GOOGLE_CLOUD_LOCATION environment variable.
|
|
45
|
+
* @default 'us-central1'
|
|
46
|
+
*/
|
|
47
|
+
location?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* GoogleVoice class provides Text-to-Speech and Speech-to-Text capabilities using Google Cloud services.
|
|
51
|
+
* Supports both standard Google Cloud API authentication and Vertex AI mode for enterprise deployments.
|
|
52
|
+
*
|
|
22
53
|
* @class GoogleVoice
|
|
23
54
|
* @extends MastraVoice
|
|
55
|
+
*
|
|
56
|
+
* @example Standard usage with API key
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const voice = new GoogleVoice({
|
|
59
|
+
* speechModel: { apiKey: 'your-api-key' },
|
|
60
|
+
* speaker: 'en-US-Studio-O',
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @example Vertex AI mode (recommended for production)
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const voice = new GoogleVoice({
|
|
67
|
+
* vertexAI: true,
|
|
68
|
+
* project: 'your-gcp-project',
|
|
69
|
+
* location: 'us-central1',
|
|
70
|
+
* speaker: 'en-US-Studio-O',
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @example Vertex AI with service account
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const voice = new GoogleVoice({
|
|
77
|
+
* vertexAI: true,
|
|
78
|
+
* project: 'your-gcp-project',
|
|
79
|
+
* speechModel: {
|
|
80
|
+
* keyFilename: '/path/to/service-account.json',
|
|
81
|
+
* },
|
|
82
|
+
* });
|
|
83
|
+
* ```
|
|
24
84
|
*/
|
|
25
85
|
export declare class GoogleVoice extends MastraVoice {
|
|
26
86
|
private ttsClient;
|
|
27
87
|
private speechClient;
|
|
88
|
+
private readonly vertexAI;
|
|
89
|
+
private readonly project?;
|
|
90
|
+
private readonly location;
|
|
28
91
|
/**
|
|
29
92
|
* Creates an instance of GoogleVoice
|
|
30
|
-
* @param {
|
|
93
|
+
* @param {GoogleVoiceConfig} config - Configuration options
|
|
31
94
|
* @param {GoogleModelConfig} [config.speechModel] - Configuration for speech synthesis
|
|
32
95
|
* @param {GoogleModelConfig} [config.listeningModel] - Configuration for speech recognition
|
|
33
96
|
* @param {string} [config.speaker] - Default voice ID to use for speech synthesis
|
|
97
|
+
* @param {boolean} [config.vertexAI] - Enable Vertex AI mode
|
|
98
|
+
* @param {string} [config.project] - Google Cloud project ID (required for Vertex AI)
|
|
99
|
+
* @param {string} [config.location] - Google Cloud region (default: 'us-central1')
|
|
34
100
|
*/
|
|
35
|
-
constructor({ listeningModel, speechModel, speaker, }?:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
101
|
+
constructor({ listeningModel, speechModel, speaker, vertexAI, project, location }?: GoogleVoiceConfig);
|
|
102
|
+
/**
|
|
103
|
+
* Check if Vertex AI mode is enabled
|
|
104
|
+
* @returns {boolean} True if using Vertex AI
|
|
105
|
+
*/
|
|
106
|
+
isUsingVertexAI(): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Get the configured Google Cloud project ID
|
|
109
|
+
* @returns {string | undefined} The project ID or undefined if not set
|
|
110
|
+
*/
|
|
111
|
+
getProject(): string | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* Get the configured Google Cloud location/region
|
|
114
|
+
* @returns {string} The location (default: 'us-central1')
|
|
115
|
+
*/
|
|
116
|
+
getLocation(): string;
|
|
40
117
|
/**
|
|
41
118
|
* Gets a list of available voices
|
|
42
119
|
* @returns {Promise<Array<{voiceId: string, languageCodes: string[]}>>} List of available voices and their supported languages. Default language is en-US.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAEtF,OAAO,KAAK,EAAE,MAAM,IAAI,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AACpG,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE;QACZ,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAEtF,OAAO,KAAK,EAAE,MAAM,IAAI,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AACpG,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE;QACZ,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,iDAAiD;IACjD,cAAc,CAAC,EAAE,iBAAiB,CAAC;IACnC,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAuED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,WAAY,SAAQ,WAAW;IAC1C,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAElC;;;;;;;;;OASG;gBACS,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE,QAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAE,iBAAsB;IAoDjH;;;OAGG;IACH,eAAe,IAAI,OAAO;IAI1B;;;OAGG;IACH,UAAU,IAAI,MAAM,GAAG,SAAS;IAIhC;;;OAGG;IACH,WAAW,IAAI,MAAM;IAIrB;;;OAGG;IACG,WAAW,CAAC,EAAE,YAAsB,EAAE,GAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAO;;;;YAU9D,cAAc;IAY5B;;;;;;;;OAQG;IACG,KAAK,CACT,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,cAAc,EACrC,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,wBAAwB,CAAC,aAAa,CAAC,CAAC;KAC/F,GACA,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC;IA2BjC;;;;OAIG;IACG,WAAW;;;IAIjB;;;;;;OAMG;IACG,MAAM,CACV,WAAW,EAAE,MAAM,CAAC,cAAc,EAClC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,kBAAkB,CAAA;KAAE,GACtF,OAAO,CAAC,MAAM,CAAC;CA2CnB"}
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,16 @@ import { TextToSpeechClient } from '@google-cloud/text-to-speech';
|
|
|
4
4
|
import { MastraVoice } from '@mastra/core/voice';
|
|
5
5
|
|
|
6
6
|
// src/index.ts
|
|
7
|
-
var resolveAuthConfig = (modelConfig, fallback) => {
|
|
7
|
+
var resolveAuthConfig = (modelConfig, fallback, vertexConfig) => {
|
|
8
8
|
const resolved = {};
|
|
9
|
+
if (vertexConfig?.vertexAI) {
|
|
10
|
+
const projectId = vertexConfig.project || process.env.GOOGLE_CLOUD_PROJECT;
|
|
11
|
+
if (projectId) {
|
|
12
|
+
resolved.projectId = projectId;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
9
15
|
const apiKey = modelConfig?.apiKey ?? fallback.apiKey;
|
|
10
|
-
if (apiKey) {
|
|
16
|
+
if (apiKey && !vertexConfig?.vertexAI) {
|
|
11
17
|
resolved.apiKey = apiKey;
|
|
12
18
|
}
|
|
13
19
|
const keyFilename = modelConfig?.keyFilename ?? fallback.keyFilename;
|
|
@@ -20,44 +26,57 @@ var resolveAuthConfig = (modelConfig, fallback) => {
|
|
|
20
26
|
}
|
|
21
27
|
return resolved;
|
|
22
28
|
};
|
|
23
|
-
var buildAuthOptions = (config) => {
|
|
29
|
+
var buildAuthOptions = (config, vertexConfig) => {
|
|
30
|
+
const options = {};
|
|
24
31
|
if (config.credentials) {
|
|
25
|
-
|
|
32
|
+
options.credentials = config.credentials;
|
|
26
33
|
}
|
|
27
34
|
if (config.keyFilename) {
|
|
28
|
-
|
|
35
|
+
options.keyFilename = config.keyFilename;
|
|
29
36
|
}
|
|
30
|
-
if (config.apiKey) {
|
|
31
|
-
|
|
37
|
+
if (config.apiKey && !vertexConfig?.vertexAI) {
|
|
38
|
+
options.apiKey = config.apiKey;
|
|
32
39
|
}
|
|
33
|
-
|
|
40
|
+
if (config.projectId) {
|
|
41
|
+
options.projectId = config.projectId;
|
|
42
|
+
}
|
|
43
|
+
return options;
|
|
34
44
|
};
|
|
35
45
|
var DEFAULT_VOICE = "en-US-Casual-K";
|
|
36
46
|
var GoogleVoice = class extends MastraVoice {
|
|
37
47
|
ttsClient;
|
|
38
48
|
speechClient;
|
|
49
|
+
vertexAI;
|
|
50
|
+
project;
|
|
51
|
+
location;
|
|
39
52
|
/**
|
|
40
53
|
* Creates an instance of GoogleVoice
|
|
41
|
-
* @param {
|
|
54
|
+
* @param {GoogleVoiceConfig} config - Configuration options
|
|
42
55
|
* @param {GoogleModelConfig} [config.speechModel] - Configuration for speech synthesis
|
|
43
56
|
* @param {GoogleModelConfig} [config.listeningModel] - Configuration for speech recognition
|
|
44
57
|
* @param {string} [config.speaker] - Default voice ID to use for speech synthesis
|
|
58
|
+
* @param {boolean} [config.vertexAI] - Enable Vertex AI mode
|
|
59
|
+
* @param {string} [config.project] - Google Cloud project ID (required for Vertex AI)
|
|
60
|
+
* @param {string} [config.location] - Google Cloud region (default: 'us-central1')
|
|
45
61
|
*/
|
|
46
|
-
constructor({
|
|
47
|
-
listeningModel,
|
|
48
|
-
speechModel,
|
|
49
|
-
speaker
|
|
50
|
-
} = {}) {
|
|
62
|
+
constructor({ listeningModel, speechModel, speaker, vertexAI = false, project, location } = {}) {
|
|
51
63
|
const defaultApiKey = process.env.GOOGLE_API_KEY;
|
|
52
64
|
const defaultKeyFilename = process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
53
65
|
const defaultSpeaker = DEFAULT_VOICE;
|
|
66
|
+
const resolvedProject = project || process.env.GOOGLE_CLOUD_PROJECT;
|
|
67
|
+
const resolvedLocation = location || process.env.GOOGLE_CLOUD_LOCATION || "us-central1";
|
|
68
|
+
if (vertexAI && !resolvedProject) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
"Google Cloud project ID is required when using Vertex AI. Set GOOGLE_CLOUD_PROJECT environment variable or pass project to constructor."
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
const vertexConfig = { vertexAI, project: resolvedProject };
|
|
54
74
|
const sharedFallback = {
|
|
55
75
|
apiKey: defaultApiKey ?? speechModel?.apiKey ?? listeningModel?.apiKey,
|
|
56
76
|
keyFilename: defaultKeyFilename ?? speechModel?.keyFilename ?? listeningModel?.keyFilename,
|
|
57
|
-
credentials: speechModel?.credentials ?? listeningModel?.credentials
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
const listeningAuthConfig = resolveAuthConfig(listeningModel, sharedFallback);
|
|
77
|
+
credentials: speechModel?.credentials ?? listeningModel?.credentials};
|
|
78
|
+
const speechAuthConfig = resolveAuthConfig(speechModel, sharedFallback, vertexConfig);
|
|
79
|
+
const listeningAuthConfig = resolveAuthConfig(listeningModel, sharedFallback, vertexConfig);
|
|
61
80
|
super({
|
|
62
81
|
speechModel: {
|
|
63
82
|
name: "",
|
|
@@ -69,11 +88,35 @@ var GoogleVoice = class extends MastraVoice {
|
|
|
69
88
|
},
|
|
70
89
|
speaker: speaker ?? defaultSpeaker
|
|
71
90
|
});
|
|
72
|
-
|
|
73
|
-
|
|
91
|
+
this.vertexAI = vertexAI;
|
|
92
|
+
this.project = resolvedProject;
|
|
93
|
+
this.location = resolvedLocation;
|
|
94
|
+
const ttsOptions = buildAuthOptions(speechAuthConfig, { vertexAI});
|
|
95
|
+
const speechOptions = buildAuthOptions(listeningAuthConfig, { vertexAI});
|
|
74
96
|
this.ttsClient = new TextToSpeechClient(ttsOptions);
|
|
75
97
|
this.speechClient = new SpeechClient(speechOptions);
|
|
76
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if Vertex AI mode is enabled
|
|
101
|
+
* @returns {boolean} True if using Vertex AI
|
|
102
|
+
*/
|
|
103
|
+
isUsingVertexAI() {
|
|
104
|
+
return this.vertexAI;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get the configured Google Cloud project ID
|
|
108
|
+
* @returns {string | undefined} The project ID or undefined if not set
|
|
109
|
+
*/
|
|
110
|
+
getProject() {
|
|
111
|
+
return this.project;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get the configured Google Cloud location/region
|
|
115
|
+
* @returns {string} The location (default: 'us-central1')
|
|
116
|
+
*/
|
|
117
|
+
getLocation() {
|
|
118
|
+
return this.location;
|
|
119
|
+
}
|
|
77
120
|
/**
|
|
78
121
|
* Gets a list of available voices
|
|
79
122
|
* @returns {Promise<Array<{voiceId: string, languageCodes: string[]}>>} List of available voices and their supported languages. Default language is en-US.
|