@hasna/connectors 0.4.2 → 0.5.0

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.
Files changed (205) hide show
  1. package/bin/index.js +113 -1
  2. package/bin/mcp.js +113 -1
  3. package/bin/serve.js +112 -0
  4. package/connectors/connect-assemblyai/.env.example +11 -0
  5. package/connectors/connect-assemblyai/CLAUDE.md +128 -0
  6. package/connectors/connect-assemblyai/README.md +193 -0
  7. package/connectors/connect-assemblyai/package.json +50 -0
  8. package/connectors/connect-assemblyai/src/api/client.ts +192 -0
  9. package/connectors/connect-assemblyai/src/api/index.ts +71 -0
  10. package/connectors/connect-assemblyai/src/cli/index.ts +384 -0
  11. package/connectors/connect-assemblyai/src/index.ts +19 -0
  12. package/connectors/connect-assemblyai/src/types/index.ts +277 -0
  13. package/connectors/connect-assemblyai/src/utils/config.ts +103 -0
  14. package/connectors/connect-assemblyai/src/utils/output.ts +119 -0
  15. package/connectors/connect-assemblyai/tsconfig.json +16 -0
  16. package/connectors/connect-baseten/.env.example +11 -0
  17. package/connectors/connect-baseten/CLAUDE.md +128 -0
  18. package/connectors/connect-baseten/README.md +193 -0
  19. package/connectors/connect-baseten/package.json +51 -0
  20. package/connectors/connect-baseten/src/api/client.ts +71 -0
  21. package/connectors/connect-baseten/src/api/index.ts +40 -0
  22. package/connectors/connect-baseten/src/cli/index.ts +244 -0
  23. package/connectors/connect-baseten/src/index.ts +19 -0
  24. package/connectors/connect-baseten/src/types/index.ts +55 -0
  25. package/connectors/connect-baseten/src/utils/config.ts +103 -0
  26. package/connectors/connect-baseten/src/utils/output.ts +119 -0
  27. package/connectors/connect-baseten/tsconfig.json +16 -0
  28. package/connectors/connect-cerebras/.env.example +11 -0
  29. package/connectors/connect-cerebras/CLAUDE.md +128 -0
  30. package/connectors/connect-cerebras/README.md +193 -0
  31. package/connectors/connect-cerebras/package.json +51 -0
  32. package/connectors/connect-cerebras/src/api/client.ts +64 -0
  33. package/connectors/connect-cerebras/src/api/index.ts +32 -0
  34. package/connectors/connect-cerebras/src/cli/index.ts +244 -0
  35. package/connectors/connect-cerebras/src/index.ts +19 -0
  36. package/connectors/connect-cerebras/src/types/index.ts +65 -0
  37. package/connectors/connect-cerebras/src/utils/config.ts +103 -0
  38. package/connectors/connect-cerebras/src/utils/output.ts +119 -0
  39. package/connectors/connect-cerebras/tsconfig.json +16 -0
  40. package/connectors/connect-cohere/.env.example +11 -0
  41. package/connectors/connect-cohere/CLAUDE.md +128 -0
  42. package/connectors/connect-cohere/README.md +193 -0
  43. package/connectors/connect-cohere/package.json +53 -0
  44. package/connectors/connect-cohere/src/api/client.ts +109 -0
  45. package/connectors/connect-cohere/src/api/index.ts +59 -0
  46. package/connectors/connect-cohere/src/cli/index.ts +255 -0
  47. package/connectors/connect-cohere/src/index.ts +19 -0
  48. package/connectors/connect-cohere/src/types/index.ts +132 -0
  49. package/connectors/connect-cohere/src/utils/config.ts +197 -0
  50. package/connectors/connect-cohere/src/utils/output.ts +119 -0
  51. package/connectors/connect-cohere/tsconfig.json +16 -0
  52. package/connectors/connect-deepgram/.env.example +11 -0
  53. package/connectors/connect-deepgram/CLAUDE.md +128 -0
  54. package/connectors/connect-deepgram/README.md +193 -0
  55. package/connectors/connect-deepgram/package.json +51 -0
  56. package/connectors/connect-deepgram/src/api/client.ts +235 -0
  57. package/connectors/connect-deepgram/src/api/index.ts +57 -0
  58. package/connectors/connect-deepgram/src/cli/index.ts +339 -0
  59. package/connectors/connect-deepgram/src/index.ts +19 -0
  60. package/connectors/connect-deepgram/src/types/index.ts +232 -0
  61. package/connectors/connect-deepgram/src/utils/config.ts +103 -0
  62. package/connectors/connect-deepgram/src/utils/output.ts +119 -0
  63. package/connectors/connect-deepgram/tsconfig.json +16 -0
  64. package/connectors/connect-deepseek/.env.example +11 -0
  65. package/connectors/connect-deepseek/CLAUDE.md +128 -0
  66. package/connectors/connect-deepseek/README.md +193 -0
  67. package/connectors/connect-deepseek/package.json +51 -0
  68. package/connectors/connect-deepseek/src/api/client.ts +108 -0
  69. package/connectors/connect-deepseek/src/api/index.ts +36 -0
  70. package/connectors/connect-deepseek/src/cli/index.ts +167 -0
  71. package/connectors/connect-deepseek/src/index.ts +19 -0
  72. package/connectors/connect-deepseek/src/types/index.ts +72 -0
  73. package/connectors/connect-deepseek/src/utils/config.ts +103 -0
  74. package/connectors/connect-deepseek/src/utils/output.ts +119 -0
  75. package/connectors/connect-deepseek/tsconfig.json +16 -0
  76. package/connectors/connect-fal/.env.example +11 -0
  77. package/connectors/connect-fal/CLAUDE.md +128 -0
  78. package/connectors/connect-fal/README.md +193 -0
  79. package/connectors/connect-fal/package.json +51 -0
  80. package/connectors/connect-fal/src/api/client.ts +172 -0
  81. package/connectors/connect-fal/src/api/index.ts +55 -0
  82. package/connectors/connect-fal/src/cli/index.ts +341 -0
  83. package/connectors/connect-fal/src/index.ts +19 -0
  84. package/connectors/connect-fal/src/types/index.ts +135 -0
  85. package/connectors/connect-fal/src/utils/config.ts +103 -0
  86. package/connectors/connect-fal/src/utils/output.ts +119 -0
  87. package/connectors/connect-fal/tsconfig.json +16 -0
  88. package/connectors/connect-fireworks/.env.example +11 -0
  89. package/connectors/connect-fireworks/CLAUDE.md +128 -0
  90. package/connectors/connect-fireworks/README.md +193 -0
  91. package/connectors/connect-fireworks/package.json +51 -0
  92. package/connectors/connect-fireworks/src/api/client.ts +63 -0
  93. package/connectors/connect-fireworks/src/api/index.ts +36 -0
  94. package/connectors/connect-fireworks/src/cli/index.ts +244 -0
  95. package/connectors/connect-fireworks/src/index.ts +19 -0
  96. package/connectors/connect-fireworks/src/types/index.ts +70 -0
  97. package/connectors/connect-fireworks/src/utils/config.ts +103 -0
  98. package/connectors/connect-fireworks/src/utils/output.ts +119 -0
  99. package/connectors/connect-fireworks/tsconfig.json +16 -0
  100. package/connectors/connect-groq/.env.example +11 -0
  101. package/connectors/connect-groq/CLAUDE.md +128 -0
  102. package/connectors/connect-groq/README.md +193 -0
  103. package/connectors/connect-groq/package.json +52 -0
  104. package/connectors/connect-groq/src/api/client.ts +108 -0
  105. package/connectors/connect-groq/src/api/index.ts +36 -0
  106. package/connectors/connect-groq/src/cli/index.ts +171 -0
  107. package/connectors/connect-groq/src/index.ts +19 -0
  108. package/connectors/connect-groq/src/types/index.ts +69 -0
  109. package/connectors/connect-groq/src/utils/config.ts +103 -0
  110. package/connectors/connect-groq/src/utils/output.ts +119 -0
  111. package/connectors/connect-groq/tsconfig.json +16 -0
  112. package/connectors/connect-luma/.env.example +11 -0
  113. package/connectors/connect-luma/CLAUDE.md +128 -0
  114. package/connectors/connect-luma/README.md +193 -0
  115. package/connectors/connect-luma/package.json +53 -0
  116. package/connectors/connect-luma/src/api/client.ts +85 -0
  117. package/connectors/connect-luma/src/api/index.ts +44 -0
  118. package/connectors/connect-luma/src/cli/index.ts +300 -0
  119. package/connectors/connect-luma/src/index.ts +19 -0
  120. package/connectors/connect-luma/src/types/index.ts +60 -0
  121. package/connectors/connect-luma/src/utils/config.ts +103 -0
  122. package/connectors/connect-luma/src/utils/output.ts +119 -0
  123. package/connectors/connect-luma/tsconfig.json +16 -0
  124. package/connectors/connect-modal/.env.example +11 -0
  125. package/connectors/connect-modal/CLAUDE.md +128 -0
  126. package/connectors/connect-modal/README.md +193 -0
  127. package/connectors/connect-modal/package.json +51 -0
  128. package/connectors/connect-modal/src/api/client.ts +119 -0
  129. package/connectors/connect-modal/src/api/index.ts +69 -0
  130. package/connectors/connect-modal/src/cli/index.ts +224 -0
  131. package/connectors/connect-modal/src/index.ts +21 -0
  132. package/connectors/connect-modal/src/types/index.ts +60 -0
  133. package/connectors/connect-modal/src/utils/config.ts +114 -0
  134. package/connectors/connect-modal/src/utils/output.ts +119 -0
  135. package/connectors/connect-modal/tsconfig.json +16 -0
  136. package/connectors/connect-perplexity/.env.example +4 -0
  137. package/connectors/connect-perplexity/CLAUDE.md +156 -0
  138. package/connectors/connect-perplexity/README.md +184 -0
  139. package/connectors/connect-perplexity/package.json +58 -0
  140. package/connectors/connect-perplexity/scripts/publish.ts +210 -0
  141. package/connectors/connect-perplexity/src/api/client.ts +119 -0
  142. package/connectors/connect-perplexity/src/api/example.ts +118 -0
  143. package/connectors/connect-perplexity/src/api/index.ts +48 -0
  144. package/connectors/connect-perplexity/src/cli/index.ts +421 -0
  145. package/connectors/connect-perplexity/src/index.ts +24 -0
  146. package/connectors/connect-perplexity/src/types/index.ts +140 -0
  147. package/connectors/connect-perplexity/src/utils/config.ts +208 -0
  148. package/connectors/connect-perplexity/src/utils/output.ts +119 -0
  149. package/connectors/connect-perplexity/tsconfig.json +16 -0
  150. package/connectors/connect-replicate/.env.example +11 -0
  151. package/connectors/connect-replicate/CLAUDE.md +128 -0
  152. package/connectors/connect-replicate/README.md +193 -0
  153. package/connectors/connect-replicate/package.json +51 -0
  154. package/connectors/connect-replicate/src/api/client.ts +109 -0
  155. package/connectors/connect-replicate/src/api/index.ts +71 -0
  156. package/connectors/connect-replicate/src/cli/index.ts +250 -0
  157. package/connectors/connect-replicate/src/index.ts +19 -0
  158. package/connectors/connect-replicate/src/types/index.ts +85 -0
  159. package/connectors/connect-replicate/src/utils/config.ts +103 -0
  160. package/connectors/connect-replicate/src/utils/output.ts +119 -0
  161. package/connectors/connect-replicate/tsconfig.json +16 -0
  162. package/connectors/connect-roboflow/.env.example +11 -0
  163. package/connectors/connect-roboflow/CLAUDE.md +272 -0
  164. package/connectors/connect-roboflow/README.md +193 -0
  165. package/connectors/connect-roboflow/package.json +51 -0
  166. package/connectors/connect-roboflow/scripts/release.ts +179 -0
  167. package/connectors/connect-roboflow/src/api/client.ts +213 -0
  168. package/connectors/connect-roboflow/src/api/example.ts +48 -0
  169. package/connectors/connect-roboflow/src/api/index.ts +51 -0
  170. package/connectors/connect-roboflow/src/cli/index.ts +254 -0
  171. package/connectors/connect-roboflow/src/index.ts +103 -0
  172. package/connectors/connect-roboflow/src/types/index.ts +237 -0
  173. package/connectors/connect-roboflow/src/utils/auth.ts +274 -0
  174. package/connectors/connect-roboflow/src/utils/bulk.ts +212 -0
  175. package/connectors/connect-roboflow/src/utils/config.ts +326 -0
  176. package/connectors/connect-roboflow/src/utils/output.ts +175 -0
  177. package/connectors/connect-roboflow/src/utils/settings.ts +114 -0
  178. package/connectors/connect-roboflow/src/utils/storage.ts +198 -0
  179. package/connectors/connect-roboflow/tsconfig.json +16 -0
  180. package/connectors/connect-runway/.env.example +11 -0
  181. package/connectors/connect-runway/CLAUDE.md +128 -0
  182. package/connectors/connect-runway/README.md +193 -0
  183. package/connectors/connect-runway/package.json +52 -0
  184. package/connectors/connect-runway/src/api/client.ts +78 -0
  185. package/connectors/connect-runway/src/api/index.ts +40 -0
  186. package/connectors/connect-runway/src/cli/index.ts +283 -0
  187. package/connectors/connect-runway/src/index.ts +19 -0
  188. package/connectors/connect-runway/src/types/index.ts +52 -0
  189. package/connectors/connect-runway/src/utils/config.ts +103 -0
  190. package/connectors/connect-runway/src/utils/output.ts +119 -0
  191. package/connectors/connect-runway/tsconfig.json +16 -0
  192. package/connectors/connect-together/.env.example +11 -0
  193. package/connectors/connect-together/CLAUDE.md +128 -0
  194. package/connectors/connect-together/README.md +193 -0
  195. package/connectors/connect-together/package.json +52 -0
  196. package/connectors/connect-together/src/api/client.ts +106 -0
  197. package/connectors/connect-together/src/api/index.ts +47 -0
  198. package/connectors/connect-together/src/cli/index.ts +228 -0
  199. package/connectors/connect-together/src/index.ts +19 -0
  200. package/connectors/connect-together/src/types/index.ts +91 -0
  201. package/connectors/connect-together/src/utils/config.ts +142 -0
  202. package/connectors/connect-together/src/utils/output.ts +119 -0
  203. package/connectors/connect-together/tsconfig.json +16 -0
  204. package/dist/index.js +112 -0
  205. package/package.json +1 -1
@@ -0,0 +1,235 @@
1
+ import type {
2
+ DeepgramConfig,
3
+ TranscriptionOptions,
4
+ TranscriptionResult,
5
+ SpeakOptions,
6
+ SpeakResponse,
7
+ ProjectsResponse,
8
+ BalanceResponse,
9
+ UsageSummary,
10
+ } from '../types';
11
+ import { DeepgramApiError } from '../types';
12
+
13
+ const DEFAULT_BASE_URL = 'https://api.deepgram.com/v1';
14
+
15
+ export interface RequestOptions {
16
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
17
+ params?: Record<string, string | number | boolean | undefined>;
18
+ body?: Record<string, unknown> | unknown[] | string | Buffer;
19
+ headers?: Record<string, string>;
20
+ }
21
+
22
+ export class DeepgramClient {
23
+ private readonly apiKey: string;
24
+ private readonly baseUrl: string;
25
+
26
+ constructor(config: DeepgramConfig) {
27
+ if (!config.apiKey) {
28
+ throw new Error('API key is required');
29
+ }
30
+ this.apiKey = config.apiKey;
31
+ this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
32
+ }
33
+
34
+ private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
35
+ const url = new URL(`${this.baseUrl}${path}`);
36
+
37
+ if (params) {
38
+ Object.entries(params).forEach(([key, value]) => {
39
+ if (value !== undefined && value !== null && value !== '') {
40
+ url.searchParams.append(key, String(value));
41
+ }
42
+ });
43
+ }
44
+
45
+ return url.toString();
46
+ }
47
+
48
+ async request<T>(path: string, options: RequestOptions = {}): Promise<T> {
49
+ const { method = 'GET', params, body, headers = {} } = options;
50
+
51
+ const url = this.buildUrl(path, params);
52
+
53
+ // Deepgram uses Token auth
54
+ const requestHeaders: Record<string, string> = {
55
+ 'Authorization': `Token ${this.apiKey}`,
56
+ 'Accept': 'application/json',
57
+ ...headers,
58
+ };
59
+
60
+ if (body && ['POST', 'PUT', 'PATCH'].includes(method) && !Buffer.isBuffer(body)) {
61
+ requestHeaders['Content-Type'] = 'application/json';
62
+ }
63
+
64
+ const fetchOptions: RequestInit = {
65
+ method,
66
+ headers: requestHeaders,
67
+ };
68
+
69
+ if (body && ['POST', 'PUT', 'PATCH'].includes(method)) {
70
+ fetchOptions.body = Buffer.isBuffer(body) ? body : (typeof body === 'string' ? body : JSON.stringify(body));
71
+ }
72
+
73
+ const response = await fetch(url, fetchOptions);
74
+
75
+ if (response.status === 204) {
76
+ return {} as T;
77
+ }
78
+
79
+ let data: unknown;
80
+ const contentType = response.headers.get('content-type') || '';
81
+
82
+ if (contentType.includes('application/json')) {
83
+ const text = await response.text();
84
+ if (text) {
85
+ try {
86
+ data = JSON.parse(text);
87
+ } catch {
88
+ data = text;
89
+ }
90
+ }
91
+ } else if (contentType.includes('audio/')) {
92
+ data = await response.arrayBuffer();
93
+ } else {
94
+ data = await response.text();
95
+ }
96
+
97
+ if (!response.ok) {
98
+ const errorMessage = typeof data === 'object' && data !== null
99
+ ? JSON.stringify(data)
100
+ : String(data || response.statusText);
101
+ throw new DeepgramApiError(errorMessage, response.status);
102
+ }
103
+
104
+ return data as T;
105
+ }
106
+
107
+ async get<T>(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<T> {
108
+ return this.request<T>(path, { method: 'GET', params });
109
+ }
110
+
111
+ async post<T>(path: string, body?: Record<string, unknown> | unknown[] | string | Buffer, params?: Record<string, string | number | boolean | undefined>, headers?: Record<string, string>): Promise<T> {
112
+ return this.request<T>(path, { method: 'POST', body: body as Record<string, unknown>, params, headers });
113
+ }
114
+
115
+ // ============================================
116
+ // Transcription Methods
117
+ // ============================================
118
+
119
+ async transcribeUrl(audioUrl: string, options: TranscriptionOptions = {}): Promise<TranscriptionResult> {
120
+ const params: Record<string, string | number | boolean | undefined> = {
121
+ model: options.model,
122
+ language: options.language,
123
+ punctuate: options.punctuate,
124
+ profanity_filter: options.profanity_filter,
125
+ diarize: options.diarize,
126
+ smart_format: options.smart_format,
127
+ filler_words: options.filler_words,
128
+ multichannel: options.multichannel,
129
+ alternatives: options.alternatives,
130
+ numerals: options.numerals,
131
+ utterances: options.utterances,
132
+ utt_split: options.utt_split,
133
+ paragraphs: options.paragraphs,
134
+ summarize: options.summarize === true ? 'true' : options.summarize === 'v2' ? 'v2' : undefined,
135
+ topics: options.topics === true ? 'true' : options.topics === 'v2' ? 'v2' : undefined,
136
+ intents: options.intents,
137
+ sentiment: options.sentiment,
138
+ detect_language: options.detect_language,
139
+ detect_entities: options.detect_entities,
140
+ detect_topics: options.detect_topics,
141
+ callback: options.callback,
142
+ callback_method: options.callback_method,
143
+ };
144
+
145
+ return this.post<TranscriptionResult>('/listen', { url: audioUrl }, params);
146
+ }
147
+
148
+ async transcribeBuffer(audioData: Buffer, options: TranscriptionOptions = {}, contentType = 'audio/wav'): Promise<TranscriptionResult> {
149
+ const params: Record<string, string | number | boolean | undefined> = {
150
+ model: options.model,
151
+ language: options.language,
152
+ punctuate: options.punctuate,
153
+ profanity_filter: options.profanity_filter,
154
+ diarize: options.diarize,
155
+ smart_format: options.smart_format,
156
+ filler_words: options.filler_words,
157
+ multichannel: options.multichannel,
158
+ alternatives: options.alternatives,
159
+ numerals: options.numerals,
160
+ utterances: options.utterances,
161
+ utt_split: options.utt_split,
162
+ paragraphs: options.paragraphs,
163
+ summarize: options.summarize === true ? 'true' : options.summarize === 'v2' ? 'v2' : undefined,
164
+ topics: options.topics === true ? 'true' : options.topics === 'v2' ? 'v2' : undefined,
165
+ intents: options.intents,
166
+ sentiment: options.sentiment,
167
+ detect_language: options.detect_language,
168
+ detect_entities: options.detect_entities,
169
+ detect_topics: options.detect_topics,
170
+ };
171
+
172
+ return this.post<TranscriptionResult>('/listen', audioData, params, { 'Content-Type': contentType });
173
+ }
174
+
175
+ // ============================================
176
+ // Text-to-Speech Methods
177
+ // ============================================
178
+
179
+ async speak(text: string, options: SpeakOptions = {}): Promise<SpeakResponse> {
180
+ const params: Record<string, string | number | boolean | undefined> = {
181
+ model: options.model || 'aura-asteria-en',
182
+ encoding: options.encoding,
183
+ container: options.container,
184
+ sample_rate: options.sample_rate,
185
+ bit_rate: options.bit_rate,
186
+ };
187
+
188
+ const response = await fetch(this.buildUrl('/speak', params), {
189
+ method: 'POST',
190
+ headers: {
191
+ 'Authorization': `Token ${this.apiKey}`,
192
+ 'Content-Type': 'application/json',
193
+ },
194
+ body: JSON.stringify({ text }),
195
+ });
196
+
197
+ if (!response.ok) {
198
+ const errorText = await response.text();
199
+ throw new DeepgramApiError(errorText, response.status);
200
+ }
201
+
202
+ const audio = Buffer.from(await response.arrayBuffer());
203
+ return {
204
+ audio,
205
+ contentType: response.headers.get('content-type') || 'audio/mpeg',
206
+ requestId: response.headers.get('dg-request-id') || '',
207
+ modelName: response.headers.get('dg-model-name') || '',
208
+ modelUuid: response.headers.get('dg-model-uuid') || '',
209
+ characters: parseInt(response.headers.get('dg-char-count') || '0'),
210
+ };
211
+ }
212
+
213
+ // ============================================
214
+ // Project Methods
215
+ // ============================================
216
+
217
+ async listProjects(): Promise<ProjectsResponse> {
218
+ return this.get<ProjectsResponse>('/projects');
219
+ }
220
+
221
+ async getBalance(projectId: string): Promise<BalanceResponse> {
222
+ return this.get<BalanceResponse>(`/projects/${projectId}/balances`);
223
+ }
224
+
225
+ async getUsage(projectId: string, start: string, end: string): Promise<UsageSummary> {
226
+ return this.get<UsageSummary>(`/projects/${projectId}/usage`, { start, end });
227
+ }
228
+
229
+ getApiKeyPreview(): string {
230
+ if (this.apiKey.length > 10) {
231
+ return `${this.apiKey.substring(0, 6)}...${this.apiKey.substring(this.apiKey.length - 4)}`;
232
+ }
233
+ return '***';
234
+ }
235
+ }
@@ -0,0 +1,57 @@
1
+ import type {
2
+ DeepgramConfig,
3
+ TranscriptionOptions,
4
+ TranscriptionResult,
5
+ SpeakOptions,
6
+ SpeakResponse,
7
+ ProjectsResponse,
8
+ BalanceResponse,
9
+ UsageSummary,
10
+ } from '../types';
11
+ import { DeepgramClient } from './client';
12
+
13
+ export class Deepgram {
14
+ private readonly client: DeepgramClient;
15
+
16
+ constructor(config: DeepgramConfig) {
17
+ this.client = new DeepgramClient(config);
18
+ }
19
+
20
+ async transcribeUrl(audioUrl: string, options?: TranscriptionOptions): Promise<TranscriptionResult> {
21
+ return this.client.transcribeUrl(audioUrl, options);
22
+ }
23
+
24
+ async transcribeBuffer(audioData: Buffer, options?: TranscriptionOptions, contentType?: string): Promise<TranscriptionResult> {
25
+ return this.client.transcribeBuffer(audioData, options, contentType);
26
+ }
27
+
28
+ async speak(text: string, options?: SpeakOptions): Promise<SpeakResponse> {
29
+ return this.client.speak(text, options);
30
+ }
31
+
32
+ async listProjects(): Promise<ProjectsResponse> {
33
+ return this.client.listProjects();
34
+ }
35
+
36
+ async getBalance(projectId: string): Promise<BalanceResponse> {
37
+ return this.client.getBalance(projectId);
38
+ }
39
+
40
+ async getUsage(projectId: string, start: string, end: string): Promise<UsageSummary> {
41
+ return this.client.getUsage(projectId, start, end);
42
+ }
43
+
44
+ static fromEnv(): Deepgram {
45
+ const apiKey = process.env.DEEPGRAM_API_KEY;
46
+ if (!apiKey) {
47
+ throw new Error('DEEPGRAM_API_KEY environment variable is required');
48
+ }
49
+ return new Deepgram({ apiKey });
50
+ }
51
+
52
+ getApiKeyPreview(): string {
53
+ return this.client.getApiKeyPreview();
54
+ }
55
+ }
56
+
57
+ export { DeepgramClient } from './client';
@@ -0,0 +1,339 @@
1
+ #!/usr/bin/env bun
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { Deepgram } from '../api';
5
+ import {
6
+ getApiKey,
7
+ setApiKey,
8
+ clearConfig,
9
+ getConfigDir,
10
+ setProfileOverride,
11
+ getCurrentProfile,
12
+ setCurrentProfile,
13
+ listProfiles,
14
+ createProfile,
15
+ deleteProfile,
16
+ profileExists,
17
+ loadProfile,
18
+ } from '../utils/config';
19
+ import type { OutputFormat } from '../utils/output';
20
+ import { success, error, info, print } from '../utils/output';
21
+
22
+ const CONNECTOR_NAME = 'connect-deepgram';
23
+ const VERSION = '0.0.1';
24
+
25
+ const program = new Command();
26
+
27
+ program
28
+ .name(CONNECTOR_NAME)
29
+ .description('Deepgram connector CLI - Speech-to-text and text-to-speech with multi-profile support')
30
+ .version(VERSION)
31
+ .option('-k, --api-key <key>', 'API key (overrides config)')
32
+ .option('-f, --format <format>', 'Output format (json, pretty)', 'pretty')
33
+ .option('-p, --profile <profile>', 'Use a specific profile')
34
+ .hook('preAction', (thisCommand) => {
35
+ const opts = thisCommand.opts();
36
+ if (opts.profile) {
37
+ if (!profileExists(opts.profile)) {
38
+ error(`Profile "${opts.profile}" does not exist. Create it with "${CONNECTOR_NAME} profile create ${opts.profile}"`);
39
+ process.exit(1);
40
+ }
41
+ setProfileOverride(opts.profile);
42
+ }
43
+ if (opts.apiKey) {
44
+ process.env.DEEPGRAM_API_KEY = opts.apiKey;
45
+ }
46
+ });
47
+
48
+ function getFormat(cmd: Command): OutputFormat {
49
+ const parent = cmd.parent;
50
+ return (parent?.opts().format || 'pretty') as OutputFormat;
51
+ }
52
+
53
+ function getClient(): Deepgram {
54
+ const apiKey = getApiKey();
55
+ if (!apiKey) {
56
+ error(`No API key configured. Run "${CONNECTOR_NAME} config set-key <key>" or set DEEPGRAM_API_KEY environment variable.`);
57
+ process.exit(1);
58
+ }
59
+ return new Deepgram({ apiKey });
60
+ }
61
+
62
+ // ============================================
63
+ // Profile Commands
64
+ // ============================================
65
+ const profileCmd = program
66
+ .command('profile')
67
+ .description('Manage configuration profiles');
68
+
69
+ profileCmd
70
+ .command('list')
71
+ .description('List all profiles')
72
+ .action(() => {
73
+ const profiles = listProfiles();
74
+ const current = getCurrentProfile();
75
+ if (profiles.length === 0) {
76
+ info('No profiles found. Use "profile create <name>" to create one.');
77
+ return;
78
+ }
79
+ success(`Profiles:`);
80
+ profiles.forEach(p => {
81
+ const isActive = p === current ? chalk.green(' (active)') : '';
82
+ console.log(` ${p}${isActive}`);
83
+ });
84
+ });
85
+
86
+ profileCmd
87
+ .command('use <name>')
88
+ .description('Switch to a profile')
89
+ .action((name: string) => {
90
+ if (!profileExists(name)) {
91
+ error(`Profile "${name}" does not exist. Create it with "profile create ${name}"`);
92
+ process.exit(1);
93
+ }
94
+ setCurrentProfile(name);
95
+ success(`Switched to profile: ${name}`);
96
+ });
97
+
98
+ profileCmd
99
+ .command('create <name>')
100
+ .description('Create a new profile')
101
+ .option('--api-key <key>', 'API key')
102
+ .option('--use', 'Switch to this profile after creation')
103
+ .action((name: string, opts) => {
104
+ if (profileExists(name)) {
105
+ error(`Profile "${name}" already exists`);
106
+ process.exit(1);
107
+ }
108
+ createProfile(name, { apiKey: opts.apiKey });
109
+ success(`Profile "${name}" created`);
110
+ if (opts.use) {
111
+ setCurrentProfile(name);
112
+ info(`Switched to profile: ${name}`);
113
+ }
114
+ });
115
+
116
+ profileCmd
117
+ .command('delete <name>')
118
+ .description('Delete a profile')
119
+ .action((name: string) => {
120
+ if (name === 'default') {
121
+ error('Cannot delete the default profile');
122
+ process.exit(1);
123
+ }
124
+ if (deleteProfile(name)) {
125
+ success(`Profile "${name}" deleted`);
126
+ } else {
127
+ error(`Profile "${name}" not found`);
128
+ process.exit(1);
129
+ }
130
+ });
131
+
132
+ profileCmd
133
+ .command('show [name]')
134
+ .description('Show profile configuration')
135
+ .action((name?: string) => {
136
+ const profileName = name || getCurrentProfile();
137
+ const config = loadProfile(profileName);
138
+ const active = getCurrentProfile();
139
+ console.log(chalk.bold(`Profile: ${profileName}${profileName === active ? chalk.green(' (active)') : ''}`));
140
+ info(`API Key: ${config.apiKey ? `${config.apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
141
+ });
142
+
143
+ // ============================================
144
+ // Config Commands
145
+ // ============================================
146
+ const configCmd = program
147
+ .command('config')
148
+ .description('Manage CLI configuration (for active profile)');
149
+
150
+ configCmd
151
+ .command('set-key <apiKey>')
152
+ .description('Set API key')
153
+ .action((apiKey: string) => {
154
+ setApiKey(apiKey);
155
+ success(`API key saved to profile: ${getCurrentProfile()}`);
156
+ });
157
+
158
+ configCmd
159
+ .command('show')
160
+ .description('Show current configuration')
161
+ .action(() => {
162
+ const profileName = getCurrentProfile();
163
+ const apiKey = getApiKey();
164
+ console.log(chalk.bold(`Active Profile: ${profileName}`));
165
+ info(`Config directory: ${getConfigDir()}`);
166
+ info(`API Key: ${apiKey ? `${apiKey.substring(0, 8)}...` : chalk.gray('not set')}`);
167
+ });
168
+
169
+ configCmd
170
+ .command('clear')
171
+ .description('Clear configuration for active profile')
172
+ .action(() => {
173
+ clearConfig();
174
+ success(`Configuration cleared for profile: ${getCurrentProfile()}`);
175
+ });
176
+
177
+ // ============================================
178
+ // Transcription Commands
179
+ // ============================================
180
+ const listenCmd = program
181
+ .command('listen')
182
+ .description('Speech-to-text commands');
183
+
184
+ listenCmd
185
+ .command('url <audioUrl>')
186
+ .description('Transcribe audio from URL')
187
+ .option('-m, --model <model>', 'Model (nova-2, nova, enhanced, base, whisper)', 'nova-2')
188
+ .option('-l, --language <code>', 'Language code')
189
+ .option('--punctuate', 'Enable punctuation')
190
+ .option('--diarize', 'Enable speaker diarization')
191
+ .option('--smart-format', 'Enable smart formatting')
192
+ .option('--paragraphs', 'Enable paragraph detection')
193
+ .option('--summarize', 'Enable summarization')
194
+ .option('--sentiment', 'Enable sentiment analysis')
195
+ .option('--topics', 'Enable topic detection')
196
+ .option('--utterances', 'Enable utterance detection')
197
+ .action(async (audioUrl: string, opts) => {
198
+ try {
199
+ const client = getClient();
200
+ const result = await client.transcribeUrl(audioUrl, {
201
+ model: opts.model as any,
202
+ language: opts.language,
203
+ punctuate: opts.punctuate || undefined,
204
+ diarize: opts.diarize || undefined,
205
+ smart_format: opts.smartFormat || undefined,
206
+ paragraphs: opts.paragraphs || undefined,
207
+ summarize: opts.summarize || undefined,
208
+ sentiment: opts.sentiment || undefined,
209
+ topics: opts.topics || undefined,
210
+ utterances: opts.utterances || undefined,
211
+ });
212
+
213
+ const format = getFormat(listenCmd);
214
+ if (format === 'json') {
215
+ print(result, format);
216
+ } else {
217
+ success('Transcription complete');
218
+ info(`Duration: ${result.metadata.duration}s`);
219
+ info(`Model: ${result.metadata.models.join(', ')}`);
220
+
221
+ const transcript = result.results.channels[0]?.alternatives[0]?.transcript;
222
+ if (transcript) {
223
+ console.log(chalk.bold('\nTranscript:'));
224
+ console.log(transcript);
225
+ }
226
+
227
+ if (result.results.summary?.short) {
228
+ console.log(chalk.bold('\nSummary:'));
229
+ console.log(result.results.summary.short);
230
+ }
231
+ }
232
+ } catch (err) {
233
+ error(String(err));
234
+ process.exit(1);
235
+ }
236
+ });
237
+
238
+ // ============================================
239
+ // Text-to-Speech Commands
240
+ // ============================================
241
+ const speakCmd = program
242
+ .command('speak')
243
+ .description('Text-to-speech commands');
244
+
245
+ speakCmd
246
+ .command('generate <text>')
247
+ .description('Generate speech from text')
248
+ .option('-m, --model <model>', 'Voice model (aura-asteria-en, aura-luna-en, aura-stella-en, etc.)', 'aura-asteria-en')
249
+ .option('-o, --output <file>', 'Output file path')
250
+ .option('-e, --encoding <encoding>', 'Audio encoding (mp3, linear16, mulaw, alaw, opus, flac, aac)', 'mp3')
251
+ .action(async (text: string, opts) => {
252
+ try {
253
+ const client = getClient();
254
+ const result = await client.speak(text, {
255
+ model: opts.model,
256
+ encoding: opts.encoding as any,
257
+ });
258
+
259
+ if (opts.output) {
260
+ const fs = await import('fs');
261
+ fs.writeFileSync(opts.output, result.audio);
262
+ success(`Audio saved to ${opts.output}`);
263
+ info(`Characters: ${result.characters}`);
264
+ info(`Model: ${result.modelName}`);
265
+ } else {
266
+ const format = getFormat(speakCmd);
267
+ if (format === 'json') {
268
+ print({
269
+ contentType: result.contentType,
270
+ characters: result.characters,
271
+ modelName: result.modelName,
272
+ audioSize: result.audio.length,
273
+ }, format);
274
+ } else {
275
+ success('Speech generated');
276
+ info(`Characters: ${result.characters}`);
277
+ info(`Model: ${result.modelName}`);
278
+ info(`Audio size: ${result.audio.length} bytes`);
279
+ info('Use --output <file> to save the audio');
280
+ }
281
+ }
282
+ } catch (err) {
283
+ error(String(err));
284
+ process.exit(1);
285
+ }
286
+ });
287
+
288
+ // ============================================
289
+ // Project Commands
290
+ // ============================================
291
+ const projectCmd = program
292
+ .command('project')
293
+ .description('Project management commands');
294
+
295
+ projectCmd
296
+ .command('list')
297
+ .description('List projects')
298
+ .action(async () => {
299
+ try {
300
+ const client = getClient();
301
+ const result = await client.listProjects();
302
+ const format = getFormat(projectCmd);
303
+ if (format === 'json') {
304
+ print(result, format);
305
+ } else {
306
+ success('Projects:');
307
+ result.projects.forEach(p => {
308
+ console.log(` ${p.name} (${p.project_id})`);
309
+ });
310
+ }
311
+ } catch (err) {
312
+ error(String(err));
313
+ process.exit(1);
314
+ }
315
+ });
316
+
317
+ projectCmd
318
+ .command('balance <projectId>')
319
+ .description('Get project balance')
320
+ .action(async (projectId: string) => {
321
+ try {
322
+ const client = getClient();
323
+ const result = await client.getBalance(projectId);
324
+ const format = getFormat(projectCmd);
325
+ if (format === 'json') {
326
+ print(result, format);
327
+ } else {
328
+ success('Balances:');
329
+ result.balances.forEach(b => {
330
+ console.log(` ${b.amount} ${b.units}`);
331
+ });
332
+ }
333
+ } catch (err) {
334
+ error(String(err));
335
+ process.exit(1);
336
+ }
337
+ });
338
+
339
+ program.parse();
@@ -0,0 +1,19 @@
1
+ // Deepgram Connector
2
+ // TypeScript wrapper for Deepgram speech-to-text and text-to-speech API
3
+
4
+ export { Deepgram } from './api';
5
+ export * from './types';
6
+ export { DeepgramClient } from './api';
7
+
8
+ export {
9
+ getApiKey,
10
+ setApiKey,
11
+ getCurrentProfile,
12
+ setCurrentProfile,
13
+ listProfiles,
14
+ createProfile,
15
+ deleteProfile,
16
+ loadProfile,
17
+ saveProfile,
18
+ clearConfig,
19
+ } from './utils/config';