assemblyai 3.0.0 → 3.0.1

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.
@@ -1,8 +1,8 @@
1
1
  // import the fs module instead if specific named exports
2
2
  // to keep the assemblyai module more compatible. Some fs polyfills don't include `createReadStream`.
3
3
  import fs from "fs";
4
- import { BaseService } from "@/services/base";
5
- import { UploadedFile, FileUploadParameters, FileUploadData } from "@/types";
4
+ import { BaseService } from "../base";
5
+ import { UploadedFile, FileUploadParameters, FileUploadData } from "../..";
6
6
 
7
7
  export class FileService extends BaseService {
8
8
  /**
@@ -15,16 +15,14 @@ export class FileService extends BaseService {
15
15
  if (typeof input === "string") fileData = fs.createReadStream(input);
16
16
  else fileData = input;
17
17
 
18
- const { data } = await this.client.post<UploadedFile>(
19
- "/v2/upload",
20
- fileData,
21
- {
22
- headers: {
23
- "Content-Type": "application/octet-stream",
24
- },
25
- }
26
- );
27
-
18
+ const data = await this.fetchJson<UploadedFile>("/v2/upload", {
19
+ method: "POST",
20
+ body: fileData as BodyInit,
21
+ headers: {
22
+ "Content-Type": "application/octet-stream",
23
+ },
24
+ duplex: "half",
25
+ } as RequestInit);
28
26
  return data.upload_url;
29
27
  }
30
28
  }
@@ -1,10 +1,11 @@
1
- import { createAxiosClient } from "@/utils/axios";
2
- import { BaseServiceParams } from "@/types";
1
+ import { BaseServiceParams } from "..";
3
2
  import { LemurService } from "./lemur";
4
3
  import { RealtimeService, RealtimeServiceFactory } from "./realtime";
5
4
  import { TranscriptService } from "./transcripts";
6
5
  import { FileService } from "./files";
7
6
 
7
+ const defaultBaseUrl = "https://api.assemblyai.com";
8
+
8
9
  class AssemblyAI {
9
10
  /**
10
11
  * The files service.
@@ -31,12 +32,13 @@ class AssemblyAI {
31
32
  * @param params The parameters for the service, including the API key and base URL, if any.
32
33
  */
33
34
  constructor(params: BaseServiceParams) {
34
- params.baseUrl = params.baseUrl || "https://api.assemblyai.com";
35
- const client = createAxiosClient(params);
36
- this.files = new FileService(client);
37
- this.transcripts = new TranscriptService(client, this.files);
38
- this.lemur = new LemurService(client);
39
- this.realtime = new RealtimeServiceFactory(client, params);
35
+ params.baseUrl = params.baseUrl || defaultBaseUrl;
36
+ if (params.baseUrl && params.baseUrl.endsWith("/"))
37
+ params.baseUrl = params.baseUrl.slice(0, -1);
38
+ this.files = new FileService(params);
39
+ this.transcripts = new TranscriptService(params, this.files);
40
+ this.lemur = new LemurService(params);
41
+ this.realtime = new RealtimeServiceFactory(params);
40
42
  }
41
43
  }
42
44
 
@@ -8,54 +8,55 @@ import {
8
8
  LemurActionItemsResponse,
9
9
  LemurTaskResponse,
10
10
  PurgeLemurRequestDataResponse,
11
- } from "@/types";
12
- import { BaseService } from "@/services/base";
11
+ } from "../..";
12
+ import { BaseService } from "../base";
13
13
 
14
14
  export class LemurService extends BaseService {
15
- async summary(params: LemurSummaryParameters): Promise<LemurSummaryResponse> {
16
- const { data } = await this.client.post<LemurSummaryResponse>(
17
- "/lemur/v3/generate/summary",
18
- params
19
- );
20
- return data;
15
+ summary(params: LemurSummaryParameters): Promise<LemurSummaryResponse> {
16
+ return this.fetchJson<LemurSummaryResponse>("/lemur/v3/generate/summary", {
17
+ method: "POST",
18
+ body: JSON.stringify(params),
19
+ });
21
20
  }
22
21
 
23
- async questionAnswer(
22
+ questionAnswer(
24
23
  params: LemurQuestionAnswerParameters
25
24
  ): Promise<LemurQuestionAnswerResponse> {
26
- const { data } = await this.client.post<LemurQuestionAnswerResponse>(
25
+ return this.fetchJson<LemurQuestionAnswerResponse>(
27
26
  "/lemur/v3/generate/question-answer",
28
- params
27
+ {
28
+ method: "POST",
29
+ body: JSON.stringify(params),
30
+ }
29
31
  );
30
- return data;
31
32
  }
32
33
 
33
- async actionItems(
34
+ actionItems(
34
35
  params: LemurActionItemsParameters
35
36
  ): Promise<LemurActionItemsResponse> {
36
- const { data } = await this.client.post<LemurActionItemsResponse>(
37
+ return this.fetchJson<LemurActionItemsResponse>(
37
38
  "/lemur/v3/generate/action-items",
38
- params
39
+ {
40
+ method: "POST",
41
+ body: JSON.stringify(params),
42
+ }
39
43
  );
40
- return data;
41
44
  }
42
45
 
43
- async task(params: LemurTaskParameters): Promise<LemurTaskResponse> {
44
- const { data } = await this.client.post<LemurTaskResponse>(
45
- "/lemur/v3/generate/task",
46
- params
47
- );
48
- return data;
46
+ task(params: LemurTaskParameters): Promise<LemurTaskResponse> {
47
+ return this.fetchJson<LemurTaskResponse>("/lemur/v3/generate/task", {
48
+ method: "POST",
49
+ body: JSON.stringify(params),
50
+ });
49
51
  }
50
52
 
51
53
  /**
52
54
  * Delete the data for a previously submitted LeMUR request.
53
55
  * @param id ID of the LeMUR request
54
56
  */
55
- async purgeRequestData(id: string): Promise<PurgeLemurRequestDataResponse> {
56
- const { data } = await this.client.delete<PurgeLemurRequestDataResponse>(
57
- `/lemur/v3/${id}`
58
- );
59
- return data;
57
+ purgeRequestData(id: string): Promise<PurgeLemurRequestDataResponse> {
58
+ return this.fetchJson<PurgeLemurRequestDataResponse>(`/lemur/v3/${id}`, {
59
+ method: "DELETE",
60
+ });
60
61
  }
61
62
  }
@@ -3,30 +3,35 @@ import {
3
3
  RealtimeTokenParams,
4
4
  CreateRealtimeServiceParams,
5
5
  RealtimeServiceParams,
6
- } from "@/types";
7
- import { AxiosInstance } from "axios";
6
+ RealtimeTemporaryTokenResponse,
7
+ } from "../..";
8
8
  import { RealtimeService } from "./service";
9
+ import { BaseService } from "../base";
9
10
 
10
- export class RealtimeServiceFactory {
11
- constructor(
12
- private client: AxiosInstance,
13
- private params: BaseServiceParams
14
- ) {}
11
+ export class RealtimeServiceFactory extends BaseService {
12
+ private rtFactoryParams: BaseServiceParams;
13
+ constructor(params: BaseServiceParams) {
14
+ super(params);
15
+ this.rtFactoryParams = params;
16
+ }
15
17
 
16
18
  createService(params?: CreateRealtimeServiceParams): RealtimeService {
17
- if (!params) params = { apiKey: this.params.apiKey };
19
+ if (!params) params = { apiKey: this.rtFactoryParams.apiKey };
18
20
  else if (!("token" in params) && !params.apiKey) {
19
- params.apiKey = this.params.apiKey;
21
+ params.apiKey = this.rtFactoryParams.apiKey;
20
22
  }
21
23
 
22
24
  return new RealtimeService(params as RealtimeServiceParams);
23
25
  }
24
26
 
25
27
  async createTemporaryToken(params: RealtimeTokenParams) {
26
- const response = await this.client.post<{ token: string }>(
28
+ const data = await this.fetchJson<RealtimeTemporaryTokenResponse>(
27
29
  "/v2/realtime/token",
28
- params
30
+ {
31
+ method: "POST",
32
+ body: JSON.stringify(params),
33
+ }
29
34
  );
30
- return response.data.token;
35
+ return data.token;
31
36
  }
32
37
  }
@@ -1,2 +1,2 @@
1
- export * from "@/services/realtime/factory";
2
- export * from "@/services/realtime/service";
1
+ export * from "./factory";
2
+ export * from "./service";
@@ -8,13 +8,13 @@ import {
8
8
  PartialTranscript,
9
9
  FinalTranscript,
10
10
  SessionBeginsEventData,
11
- } from "@/types";
11
+ } from "../..";
12
12
  import {
13
13
  RealtimeError,
14
14
  RealtimeErrorMessages,
15
15
  RealtimeErrorType,
16
- } from "@/utils/errors";
17
- import { Writable } from "stream";
16
+ } from "../../utils/errors";
17
+ import Stream from "stream";
18
18
 
19
19
  const defaultRealtimeUrl = "wss://api.assemblyai.com/v2/realtime/ws";
20
20
 
@@ -32,7 +32,6 @@ export class RealtimeService {
32
32
  this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
33
33
  this.sampleRate = params.sampleRate ?? 16_000;
34
34
  this.wordBoost = params.wordBoost;
35
- this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
36
35
  if ("apiKey" in params) this.apiKey = params.apiKey;
37
36
  if ("token" in params) this.token = params.token;
38
37
 
@@ -162,8 +161,8 @@ export class RealtimeService {
162
161
  this.socket.send(JSON.stringify(payload));
163
162
  }
164
163
 
165
- stream(): Writable {
166
- const stream = new Writable({
164
+ stream(): NodeJS.WritableStream {
165
+ const stream = new Stream.Writable({
167
166
  write: (chunk: Buffer, encoding, next) => {
168
167
  this.sendAudio(chunk);
169
168
  next();
@@ -1,4 +1,4 @@
1
- import { BaseService } from "@/services/base";
1
+ import { BaseService } from "../base";
2
2
  import {
3
3
  ParagraphsResponse,
4
4
  SentencesResponse,
@@ -14,8 +14,8 @@ import {
14
14
  RedactedAudioResponse,
15
15
  TranscriptListParameters,
16
16
  WordSearchResponse,
17
- } from "@/types";
18
- import { AxiosInstance } from "axios";
17
+ BaseServiceParams,
18
+ } from "../..";
19
19
  import { FileService } from "../files";
20
20
 
21
21
  export class TranscriptService
@@ -26,8 +26,8 @@ export class TranscriptService
26
26
  Deletable<Transcript>,
27
27
  Listable<TranscriptList>
28
28
  {
29
- constructor(client: AxiosInstance, private files: FileService) {
30
- super(client);
29
+ constructor(params: BaseServiceParams, private files: FileService) {
30
+ super(params);
31
31
  }
32
32
 
33
33
  /**
@@ -46,13 +46,16 @@ export class TranscriptService
46
46
  params.audio_url = uploadUrl;
47
47
  }
48
48
 
49
- const res = await this.client.post<Transcript>("/v2/transcript", params);
49
+ const data = await this.fetchJson<Transcript>("/v2/transcript", {
50
+ method: "POST",
51
+ body: JSON.stringify(params),
52
+ });
50
53
 
51
54
  if (options?.poll ?? true) {
52
- return await this.poll(res.data.id, options);
55
+ return await this.poll(data.id, options);
53
56
  }
54
57
 
55
- return res.data;
58
+ return data;
56
59
  }
57
60
 
58
61
  private async poll(
@@ -83,9 +86,8 @@ export class TranscriptService
83
86
  * @param id The identifier of the transcript.
84
87
  * @returns A promise that resolves to the transcript.
85
88
  */
86
- async get(id: string): Promise<Transcript> {
87
- const res = await this.client.get<Transcript>(`/v2/transcript/${id}`);
88
- return res.data;
89
+ get(id: string): Promise<Transcript> {
90
+ return this.fetchJson<Transcript>(`/v2/transcript/${id}`);
89
91
  }
90
92
 
91
93
  /**
@@ -96,15 +98,17 @@ export class TranscriptService
96
98
  parameters?: TranscriptListParameters | string
97
99
  ): Promise<TranscriptList> {
98
100
  let url = "/v2/transcript";
99
- let query: TranscriptListParameters | undefined;
100
101
  if (typeof parameters === "string") {
101
102
  url = parameters;
102
103
  } else if (parameters) {
103
- query = parameters;
104
+ url = `${url}?${new URLSearchParams(
105
+ Object.keys(parameters).map((key) => [
106
+ key,
107
+ parameters[key as keyof TranscriptListParameters]?.toString() || "",
108
+ ])
109
+ )}`;
104
110
  }
105
- const { data } = await this.client.get<TranscriptList>(url, {
106
- params: query,
107
- });
111
+ const data = await this.fetchJson<TranscriptList>(url);
108
112
  for (const transcriptListItem of data.transcripts) {
109
113
  transcriptListItem.created = new Date(transcriptListItem.created);
110
114
  if (transcriptListItem.completed) {
@@ -112,7 +116,7 @@ export class TranscriptService
112
116
  }
113
117
  }
114
118
 
115
- return data as unknown as TranscriptList;
119
+ return data;
116
120
  }
117
121
 
118
122
  /**
@@ -120,28 +124,21 @@ export class TranscriptService
120
124
  * @param id The identifier of the transcript.
121
125
  * @returns A promise that resolves to the transcript.
122
126
  */
123
- async delete(id: string): Promise<Transcript> {
124
- const res = await this.client.delete<Transcript>(`/v2/transcript/${id}`);
125
- return res.data;
127
+ delete(id: string): Promise<Transcript> {
128
+ return this.fetchJson(`/v2/transcript/${id}`, { method: "DELETE" });
126
129
  }
127
130
 
128
131
  /**
129
132
  * Search through the transcript for a specific set of keywords.
130
133
  * You can search for individual words, numbers, or phrases containing up to five words or numbers.
131
134
  * @param id The identifier of the transcript.
132
- * @param id Keywords to search for.
135
+ * @param words Keywords to search for.
133
136
  * @return A promise that resolves to the sentences.
134
137
  */
135
- async wordSearch(id: string, words: string[]): Promise<WordSearchResponse> {
136
- const { data } = await this.client.get<WordSearchResponse>(
137
- `/v2/transcript/${id}/word-search`,
138
- {
139
- params: {
140
- words: JSON.stringify(words),
141
- },
142
- }
138
+ wordSearch(id: string, words: string[]): Promise<WordSearchResponse> {
139
+ return this.fetchJson<WordSearchResponse>(
140
+ `/v2/transcript/${id}/word-search?words=${JSON.stringify(words)}`
143
141
  );
144
- return data;
145
142
  }
146
143
 
147
144
  /**
@@ -149,11 +146,8 @@ export class TranscriptService
149
146
  * @param id The identifier of the transcript.
150
147
  * @return A promise that resolves to the sentences.
151
148
  */
152
- async sentences(id: string): Promise<SentencesResponse> {
153
- const { data } = await this.client.get<SentencesResponse>(
154
- `/v2/transcript/${id}/sentences`
155
- );
156
- return data;
149
+ sentences(id: string): Promise<SentencesResponse> {
150
+ return this.fetchJson<SentencesResponse>(`/v2/transcript/${id}/sentences`);
157
151
  }
158
152
 
159
153
  /**
@@ -161,11 +155,10 @@ export class TranscriptService
161
155
  * @param id The identifier of the transcript.
162
156
  * @return A promise that resolves to the paragraphs.
163
157
  */
164
- async paragraphs(id: string): Promise<ParagraphsResponse> {
165
- const { data } = await this.client.get<ParagraphsResponse>(
158
+ paragraphs(id: string): Promise<ParagraphsResponse> {
159
+ return this.fetchJson<ParagraphsResponse>(
166
160
  `/v2/transcript/${id}/paragraphs`
167
161
  );
168
- return data;
169
162
  }
170
163
 
171
164
  /**
@@ -175,11 +168,8 @@ export class TranscriptService
175
168
  * @return A promise that resolves to the subtitles text.
176
169
  */
177
170
  async subtitles(id: string, format: SubtitleFormat = "srt"): Promise<string> {
178
- const { data } = await this.client.get<string>(
179
- `/v2/transcript/${id}/${format}`
180
- );
181
-
182
- return data;
171
+ const response = await this.fetch(`/v2/transcript/${id}/${format}`);
172
+ return await response.text();
183
173
  }
184
174
 
185
175
  /**
@@ -187,11 +177,10 @@ export class TranscriptService
187
177
  * @param id The identifier of the transcript.
188
178
  * @return A promise that resolves to the subtitles text.
189
179
  */
190
- async redactions(id: string): Promise<RedactedAudioResponse> {
191
- const { data } = await this.client.get<RedactedAudioResponse>(
180
+ redactions(id: string): Promise<RedactedAudioResponse> {
181
+ return this.fetchJson<RedactedAudioResponse>(
192
182
  `/v2/transcript/${id}/redacted-audio`
193
183
  );
194
- return data;
195
184
  }
196
185
  }
197
186
 
@@ -2,7 +2,8 @@ type FileUploadParameters = string | FileUploadData;
2
2
  type FileUploadData =
3
3
  | NodeJS.ReadableStream
4
4
  | ReadableStream
5
- | Buffer
5
+ | Blob
6
+ | BufferSource
6
7
  | ArrayBufferView
7
8
  | ArrayBufferLike
8
9
  | Uint8Array;
@@ -78,19 +78,25 @@ export type ContentSafetyLabelResult = {
78
78
  sentences_idx_end: number;
79
79
  /** @description The sentence index at which the section begins */
80
80
  sentences_idx_start: number;
81
+ /** @description The transcript of the section flagged by the Content Moderation model */
82
+ text: string;
83
+ /** @description Timestamp information for the section */
84
+ timestamp: Timestamp;
85
+ };
86
+
87
+ export type ContentSafetyLabelsResult = {
88
+ results: ContentSafetyLabelResult[];
81
89
  /** @description A summary of the Content Moderation severity results for the entire audio file */
82
90
  severity_score_summary: {
83
91
  [key: string]: SeverityScoreSummary;
84
92
  };
93
+ /** @description Will be either success, or unavailable in the rare case that the Content Moderation model failed. */
94
+ status: AudioIntelligenceModelStatus;
85
95
  /** @description A summary of the Content Moderation confidence results for the entire audio file */
86
96
  summary: {
87
97
  [key: string]: number;
88
98
  };
89
- /** @description The transcript of the section flagged by the Content Moderation model */
90
- text: string;
91
- /** @description Timestamp information for the section */
92
- timestamp: Timestamp;
93
- };
99
+ } | null;
94
100
 
95
101
  export type CreateRealtimeTemporaryTokenParameters = {
96
102
  /** @description The amount of time until the token expires in seconds. */
@@ -450,7 +456,7 @@ export type SentimentAnalysisResult = {
450
456
  end: number;
451
457
  /** @description The detected sentiment for the sentence, one of POSITIVE, NEUTRAL, NEGATIVE */
452
458
  sentiment: Sentiment;
453
- /** @description The speaker of the sentence if Speaker Diarization is enabled, else null */
459
+ /** @description The speaker of the sentence if [Speaker Diarization](https://www.assemblyai.com/docs/models/speaker-diarization) is enabled, else null */
454
460
  speaker?: string | null;
455
461
  /** @description The starting time, in milliseconds, of the sentence */
456
462
  start: number;
@@ -506,7 +512,7 @@ export type Timestamp = {
506
512
  start: number;
507
513
  };
508
514
 
509
- /** @description THe result of the topic detection model. */
515
+ /** @description The result of the topic detection model. */
510
516
  export type TopicDetectionResult = {
511
517
  labels?: {
512
518
  /** @description The IAB taxonomical label for the label of the detected topic, where > denotes supertopic/subtopic relationship */
@@ -564,11 +570,7 @@ export type Transcript = {
564
570
  * @description An array of results for the Content Moderation model, if it was enabled during the transcription request.
565
571
  * See [Content moderation](https://www.assemblyai.com/docs/Models/content_moderation) for more information.
566
572
  */
567
- content_safety_labels?: {
568
- results: ContentSafetyLabelResult[];
569
- /** @description Will be either success, or unavailable in the rare case that the Content Safety Labels model failed. */
570
- status: AudioIntelligenceModelStatus;
571
- } | null;
573
+ content_safety_labels?: ContentSafetyLabelsResult;
572
574
  /** @description Customize how words are spelled and formatted using to and from values */
573
575
  custom_spelling?: TranscriptCustomSpelling[] | null;
574
576
  /** @description Whether custom topics was enabled in the transcription request, either true or false */
@@ -593,7 +595,7 @@ export type Transcript = {
593
595
  /** @description Enable [Topic Detection](https://www.assemblyai.com/docs/Models/iab_classification), can be true or false */
594
596
  iab_categories?: boolean | null;
595
597
  /**
596
- * @description An array of results for the Topic Detection model, if it was enabled during the transcription request.
598
+ * @description The result of the Topic Detection model, if it was enabled during the transcription request.
597
599
  * See [Topic Detection](https://www.assemblyai.com/docs/Models/iab_classification) for more information.
598
600
  */
599
601
  iab_categories_result?: {
@@ -809,12 +811,20 @@ export type TranscriptSentence = {
809
811
  export type TranscriptStatus = "queued" | "processing" | "completed" | "error";
810
812
 
811
813
  export type TranscriptUtterance = {
812
- channel: string;
813
- /** Format: double */
814
+ /**
815
+ * Format: double
816
+ * @description The confidence score for the transcript of this utterance
817
+ */
814
818
  confidence: number;
819
+ /** @description The ending time, in milliseconds, of the utterance in the audio file */
815
820
  end: number;
821
+ /** @description The speaker of this utterance, where each speaker is assigned a sequential capital letter - e.g. "A" for Speaker A, "B" for Speaker B, etc. */
822
+ speaker: string;
823
+ /** @description The starting time, in milliseconds, of the utterance in the audio file */
816
824
  start: number;
825
+ /** @description The text for this utterance */
817
826
  text: string;
827
+ /** @description The words in the utterance. */
818
828
  words: TranscriptWord[];
819
829
  };
820
830
 
@@ -1,3 +0,0 @@
1
- import { BaseServiceParams } from "@/types";
2
- export declare function createAxiosClient(params: BaseServiceParams): import("axios").AxiosInstance;
3
- export declare function throwApiError(error: unknown): Promise<never>;
@@ -1,19 +0,0 @@
1
- import axios, { isAxiosError } from "axios";
2
- import { BaseServiceParams } from "@/types";
3
-
4
- export function createAxiosClient(params: BaseServiceParams) {
5
- const client = axios.create({
6
- baseURL: params.baseUrl,
7
- headers: { Authorization: params.apiKey },
8
- });
9
-
10
- client.interceptors.response.use(undefined, throwApiError);
11
- return client;
12
- }
13
-
14
- export function throwApiError(error: unknown) {
15
- if (isAxiosError(error) && error.response?.data?.error) {
16
- return Promise.reject(new Error(error.response.data.error));
17
- }
18
- return Promise.reject(error);
19
- }