Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2.0.2: Client updates and bugfixes #12

Merged
merged 1 commit into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
{
"extends": "standard"
}
"root": true,
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": { "project": ["./tsconfig.json"] },
"plugins": [
"@typescript-eslint"
],
"rules": {
},
"ignorePatterns": ["test/**/*", "dist/**/*", "node_modules/**/*"]
}
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
[![Discord](https://img.shields.io/discord/875120158014853141?logo=discord&label=Discord&link=https%3A%2F%2Fdiscord.com%2Fchannels%2F875120158014853141&style=social)
](https://discord.gg/5aQNZyq3)


# AssemblyAI Node.js SDK

The AssemblyAI Node.js SDK provides an easy-to-use interface for interacting with the AssemblyAI API,
Expand Down Expand Up @@ -165,13 +164,13 @@ const { response } = await client.lemur.task({
Create the real-time service.

```typescript
const service = client.realtime.createService();
const rt = client.realtime.createService();
```

You can also pass in the following options.

```typescript
const service = client.realtime.createService({
const rt = client.realtime.createService({
realtimeUrl: 'wss://localhost/override',
apiKey: process.env.ASSEMBLYAI_API_KEY // The API key passed to `AssemblyAI` will be used by default,
sampleRate: 16_000,
Expand Down Expand Up @@ -209,14 +208,19 @@ After configuring your events, connect to the server.
await rt.connect();
```

Send audio data.
Send audio data via chunks.

```typescript
// Pseudo code for getting audio
getAudio((chunk) => {
rt.sendAudio(chunk);
});
```
Or send audio data via a stream by piping to the realtime stream.

```typescript
audioStream.pipe(rt.stream());
```

Close the connection when you're finished.

Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "assemblyai",
"version": "2.0.1",
"version": "2.0.2",
"description": "The AssemblyAI Node.js SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async and real-time transcription, as well as the latest LeMUR models.",
"main": "dist/index.js",
"module": "dist/index.esm.js",
Expand All @@ -18,7 +18,7 @@
"scripts": {
"build": "pnpm clean && pnpm rollup -c",
"clean": "rimraf dist",
"lint": "tslint -p tsconfig.json",
"lint": "eslint -c .eslintrc.json 'src/**/*'",
"test": "pnpm lint && pnpm test:unit",
"test:unit": "jest --config jest.config.rollup.ts",
"format": "prettier --write 'src/**/*.ts'",
Expand All @@ -45,8 +45,9 @@
"@types/jest": "^29.5.5",
"@types/node": "^20.5.7",
"@types/ws": "^8.5.5",
"@typescript-eslint/eslint-plugin": "^6.7.5",
"dotenv": "^16.3.1",
"eslint": "^8.43.0",
"eslint": "^8.48.0",
"i": "^0.3.7",
"jest": "^29.5.0",
"jest-cli": "^29.5.0",
Expand All @@ -63,7 +64,6 @@
"ts-jest": "^29.1.0",
"ts-node": "^10.9.1",
"tslib": "^2.5.3",
"tslint": "^6.1.3",
"typescript": "^5.2.2"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ module.exports = [
{ file: pkg.module, format: 'es' }
],
plugins,
external: ['axios', 'fs/promises', 'ws']
external: ['axios', 'fs/promises', 'stream', 'ws']
},
]
28 changes: 17 additions & 11 deletions scripts/kitchensink.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createReadStream } from 'fs'
import 'dotenv/config'
import AssemblyAI, { Transcript, CreateTranscriptParameters } from '../src/index';
import { FinalTranscript, PartialTranscript, RealtimeTranscript } from '../src/types'
import { FinalTranscript, LemurBaseResponse, PartialTranscript, RealtimeTranscript } from '../src/types'

const client = new AssemblyAI({
apiKey: process.env.ASSEMBLYAI_API_KEY || '',
Expand Down Expand Up @@ -52,7 +52,7 @@ const client = new AssemblyAI({
})();

const audioUrl = 'https://storage.googleapis.com/aai-docs-samples/espn.m4a';
const createTranscriptParams: CreateTranscriptParameters = {
const createTranscriptParams: CreateTranscriptParameters = {
audio_url: audioUrl,
boost_param: 'high',
word_boost: ['Chicago', 'draft'],
Expand All @@ -79,10 +79,10 @@ const createTranscriptParams: CreateTranscriptParameters = {

(async function runLemurModels() {
const transcript = await client.transcripts.create(createTranscriptParams);
await lemurSummary(transcript);
await lemurQuestionAnswer(transcript);
await lemurActionPoints(transcript);
await lemurCustomTask(transcript);
await lemurSummary(transcript).then(purgeLemurRequestData);
await lemurQuestionAnswer(transcript).then(purgeLemurRequestData);
await lemurActionPoints(transcript).then(purgeLemurRequestData);
await lemurCustomTask(transcript).then(purgeLemurRequestData);
await deleteTranscript(transcript);
})();

Expand Down Expand Up @@ -255,11 +255,8 @@ const createTranscriptParams: CreateTranscriptParameters = {
})();

async function searchTranscript(transcript: Transcript) {
console.error('Search is not yet implemented');
// const result = await client.transcripts.search(transcript.id, {
// words: ['draft', 'football']
// });
// console.log(result);
const result = await client.transcripts.wordSearch(transcript.id, ['draft', 'football']);
console.log(result);
}

async function exportAsSubtitles(transcript: Transcript) {
Expand Down Expand Up @@ -294,6 +291,7 @@ async function lemurSummary(transcript: Transcript) {
answer_format: 'bullet points'
})
console.log(response.response);
return response;
}

async function lemurQuestionAnswer(transcript: Transcript) {
Expand All @@ -316,6 +314,7 @@ async function lemurQuestionAnswer(transcript: Transcript) {
max_output_size: 3000
})
console.log(response.response);
return response;
}

async function lemurActionPoints(transcript: Transcript) {
Expand All @@ -326,6 +325,7 @@ async function lemurActionPoints(transcript: Transcript) {
max_output_size: 3000
})
console.log(response.response);
return response;
}

async function lemurCustomTask(transcript: Transcript) {
Expand All @@ -337,4 +337,10 @@ async function lemurCustomTask(transcript: Transcript) {
max_output_size: 3000
})
console.log(response.response);
return response;
}

async function purgeLemurRequestData(lemurResponse: LemurBaseResponse) {
const { response } = await client.lemur.purgeRequestData(lemurResponse.request_id);
console.log(response);
};
6 changes: 4 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import AssemblyAI from "./services";

import * as services from "./services";
import { AssemblyAI } from "./services";
export * from "./services";
export type * from "./types";
export default AssemblyAI;
class AssemblyAIExports extends AssemblyAI {}
module.exports = Object.assign(AssemblyAIExports, services);
4 changes: 1 addition & 3 deletions src/services/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ import { AxiosInstance } from "axios";
/**
* Base class for services that communicate with the API.
*/
abstract class BaseService {
export abstract class BaseService {
/**
* Create a new service.
* @param params The AxiosInstance to send HTTP requests to the API.
*/
constructor(protected client: AxiosInstance) {}
}

export default BaseService;
4 changes: 2 additions & 2 deletions src/services/files/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { readFile } from "fs/promises";
import BaseService from "@/services/base";
import { BaseService } from "@/services/base";
import { UploadedFile } from "@/types";

export default class FileService extends BaseService {
export class FileService extends BaseService {
/**
* Upload a local file to AssemblyAI.
* @param path The local file to upload.
Expand Down
9 changes: 5 additions & 4 deletions src/services/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { createAxiosClient } from "@/utils/axios";
import { BaseServiceParams } from "@/types";
import LemurService from "./lemur";
import { LemurService } from "./lemur";
import { RealtimeService, RealtimeServiceFactory } from "./realtime";
import TranscriptService from "./transcripts";
import FileService from "./files";
import { TranscriptService } from "./transcripts";
import { FileService } from "./files";

export default class AssemblyAI {
class AssemblyAI {
/**
* The files service.
*/
Expand Down Expand Up @@ -41,6 +41,7 @@ export default class AssemblyAI {
}

export {
AssemblyAI,
LemurService,
RealtimeServiceFactory,
RealtimeService,
Expand Down
16 changes: 14 additions & 2 deletions src/services/lemur/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import {
LemurQuestionAnswerResponse,
LemurActionItemsResponse,
LemurTaskResponse,
PurgeLemurRequestDataResponse,
} from "@/types";
import BaseService from "@/services/base";
import { BaseService } from "@/services/base";

export default class LemurService extends BaseService {
export class LemurService extends BaseService {
async summary(params: LemurSummaryParameters): Promise<LemurSummaryResponse> {
const { data } = await this.client.post<LemurSummaryResponse>(
"/lemur/v3/generate/summary",
Expand Down Expand Up @@ -46,4 +47,15 @@ export default class LemurService extends BaseService {
);
return data;
}

/**
* Delete the data for a previously submitted LeMUR request.
* @param id ID of the LeMUR request
*/
async purgeRequestData(id: string): Promise<PurgeLemurRequestDataResponse> {
const { data } = await this.client.delete<PurgeLemurRequestDataResponse>(
`/lemur/v3/${id}`
);
return data;
}
}
16 changes: 14 additions & 2 deletions src/services/realtime/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
RealtimeErrorMessages,
RealtimeErrorType,
} from "@/utils/errors";
import { Writable } from "stream";

const defaultRealtimeUrl = "wss://api.assemblyai.com/v2/realtime/ws";

Expand Down Expand Up @@ -75,12 +76,13 @@ export class RealtimeService {
): void;
on(event: "error", listener: (error: Error) => void): void;
on(event: "close", listener: (code: number, reason: string) => void): void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
on(event: RealtimeEvents, listener: (...args: any[]) => void) {
this.listeners[event] = listener;
}

connect() {
return new Promise<SessionBeginsEventData>((resolve, _) => {
return new Promise<SessionBeginsEventData>((resolve) => {
if (this.socket) {
throw new Error("Already connected");
}
Expand Down Expand Up @@ -160,12 +162,22 @@ export class RealtimeService {
this.socket.send(JSON.stringify(payload));
}

stream(): Writable {
const stream = new Writable({
write: (chunk: Buffer, encoding, next) => {
this.sendAudio(chunk);
next();
},
});
return stream;
}

async close(waitForSessionTermination = true) {
if (this.socket) {
if (this.socket.readyState === WebSocket.OPEN) {
const terminateSessionMessage = `{"terminate_session": true}`;
if (waitForSessionTermination) {
const sessionTerminatedPromise = new Promise<void>((resolve, _) => {
const sessionTerminatedPromise = new Promise<void>((resolve) => {
this.sessionTerminatedResolve = resolve;
});
this.socket.send(terminateSessionMessage);
Expand Down
27 changes: 24 additions & 3 deletions src/services/transcripts/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import BaseService from "@/services/base";
import { BaseService } from "@/services/base";
import {
ParagraphsResponse,
SentencesResponse,
Expand All @@ -12,11 +12,12 @@ import {
Retrieveable,
SubtitleFormat,
RedactedAudioResponse,
WordSearchResponse,
} from "@/types";
import { AxiosInstance } from "axios";
import FileService from "../files";
import { FileService } from "../files";

export default class TranscriptService
export class TranscriptService
extends BaseService
implements
Createable<Transcript, CreateTranscriptParameters, CreateTranscriptOptions>,
Expand Down Expand Up @@ -58,6 +59,7 @@ export default class TranscriptService
options?: CreateTranscriptOptions
): Promise<Transcript> {
const startTime = Date.now();
// eslint-disable-next-line no-constant-condition
while (true) {
const transcript = await this.get(transcriptId);
if (transcript.status === "completed" || transcript.status === "error") {
Expand Down Expand Up @@ -115,6 +117,25 @@ export default class TranscriptService
return res.data;
}

/**
* Search through the transcript for a specific set of keywords.
* You can search for individual words, numbers, or phrases containing up to five words or numbers.
* @param id The identifier of the transcript.
* @param id Keywords to search for.
* @return A promise that resolves to the sentences.
*/
async wordSearch(id: string, words: string[]): Promise<WordSearchResponse> {
const { data } = await this.client.get<WordSearchResponse>(
`/v2/transcript/${id}/word-search`,
{
params: {
words: JSON.stringify(words),
},
}
);
return data;
}

/**
* Retrieve all sentences of a transcript.
* @param id The identifier of the transcript.
Expand Down
2 changes: 1 addition & 1 deletion src/types/services/abstractions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @template T The type of the resource.
* @template Parameters The type of the parameters required to create the resource.
*/
interface Createable<T, Parameters, Options = Record<string, any>> {
interface Createable<T, Parameters, Options = Record<string, unknown>> {
/**
* Create a new resource.
* @param params The parameters of the new resource.
Expand Down
2 changes: 1 addition & 1 deletion src/utils/errors/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export {
default as RealtimeError,
RealtimeError,
RealtimeErrorType,
RealtimeErrorMessages,
} from "./realtime";
Loading