Skip to content

Commit

Permalink
Merge pull request #31 from AssemblyAI/E07417BDFEA3614F5967B1520F8B2F61
Browse files Browse the repository at this point in the history
Release 4.2.1
  • Loading branch information
Swimburger committed Jan 23, 2024
2 parents 7f5efee + bb6aa31 commit a88f2d4
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 63 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## [4.2.1] - 2024-01-23

### Added
- Add `answer_format` to `LemurActionItemsParams` type

### Changed
- Rename `RealtimeService` to `RealtimeTranscriber`, `RealtimeServiceFactory` to `RealtimeTranscriberFactory`, `RealtimeTranscriberFactory.createService()` to `RealtimeTranscriberFactory.transcriber()`. Deprecated aliases are provided for all old types and functions for backwards compatibility.
- Restrict the type for `redact_pii_audio_quality` from `string` to `RedactPiiAudioQuality` an enum string.

## [4.2.0] - 2024-01-11

### Added
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,18 +184,18 @@ const { response } = await client.lemur.task({
});
```

## Transcribe in real time
## Transcribe in real-time

Create the real-time service.
Create the real-time transcriber.

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

You can also pass in the following options.

```typescript
const rt = client.realtime.createService({
const rt = client.realtime.transcriber({
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 All @@ -207,7 +207,7 @@ You can also generate a temporary auth token for real-time.

```typescript
const token = await client.realtime.createTemporaryToken({ expires_in = 60 });
const rt = client.realtime.createService({
const rt = client.realtime.transcriber({
token: token,
});
```
Expand Down
10 changes: 5 additions & 5 deletions docs/compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ If you do use an older version of Node.js like version 16, you'll need to polyfi
To make the SDK compatible with the browser, the SDK aims to use web standards as much as possible.
However, there are still incompatibilities between Node.js and the browser.

- `RealtimeService` doesn't support the AssemblyAI API key in the browser.
- `RealtimeTranscriber` doesn't support the AssemblyAI API key in the browser.
Instead, you have to generate a temporary auth token using `client.realtime.createTemporaryToken`, and pass in the resulting token to the real-time transcriber.

Generate a temporary auth token on the server.
Expand All @@ -31,16 +31,16 @@ However, there are still incompatibilities between Node.js and the browser.
> If you embed the API key on the client, everyone can see it and use it for themselves.
Then pass the token via an API to the client.
On the client, create an instance of `RealtimeService` using the token.
On the client, create an instance of `RealtimeTranscriber` using the token.

```js
import { RealtimeService } from "assemblyai";
import { RealtimeTranscriber } from "assemblyai";
// or the following if you're using UMD
// const { RealtimeService } = assemblyai;
// const { RealtimeTranscriber } = assemblyai;

const token = getToken(); // getToken is a function for you to implement

const rt = new RealtimeService({
const rt = new RealtimeTranscriber({
token: token,
});
```
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "assemblyai",
"version": "4.2.0",
"version": "4.2.1",
"description": "The AssemblyAI JavaScript 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.",
"engines": {
"node": ">=18"
Expand Down
15 changes: 2 additions & 13 deletions scripts/generate-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,8 @@ async function generateTypes(apiSpecPath: string, outputPath: string) {
alphabetize: true,
exportType: true,
transform(schemaObject) {
if (
"x-fern-type" in schemaObject &&
schemaObject["x-fern-type"] === "datetime"
) {
// Use Date as type instead of String, even though it will be a string.
// The service code manually converts the string into a Date.
// Fe see `TranscriptService#list`.
return schemaObject.nullable ? "Date | null" : "Date";
}
},
postTransform(type) {
if (type === `components["schemas"]["LemurModel"] | string`) {
return `LiteralUnion<components["schemas"]["LemurModel"], string>`;
if ("x-ts-type" in schemaObject) {
return schemaObject["x-ts-type"];
}
},
});
Expand Down
6 changes: 3 additions & 3 deletions scripts/kitchensink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
LemurBaseResponse,
PartialTranscript,
RealtimeTranscript,
CreateRealtimeServiceParams,
CreateRealtimeTranscriberParams,
TranscribeParams,
} from "../src";

Expand All @@ -17,7 +17,7 @@ const client = new AssemblyAI({

(async function transcribeUsingRealtime() {
const useToken = false;
const serviceParams: CreateRealtimeServiceParams = {
const serviceParams: CreateRealtimeTranscriberParams = {
sampleRate: 16_000,
wordBoost: ["gore", "climate"],
token: useToken
Expand All @@ -27,7 +27,7 @@ const client = new AssemblyAI({
: undefined,
encoding: "pcm_s16le",
};
const rt = client.realtime.createService(serviceParams);
const rt = client.realtime.transcriber(serviceParams);

rt.on("open", ({ sessionId, expiresAt }) => {
console.log("Session ID:", sessionId, "Expires At:", expiresAt);
Expand Down
13 changes: 10 additions & 3 deletions src/services/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { BaseServiceParams } from "..";
import { LemurService } from "./lemur";
import { RealtimeService, RealtimeServiceFactory } from "./realtime";
import {
RealtimeTranscriber,
RealtimeTranscriberFactory,
RealtimeService,
RealtimeServiceFactory,
} from "./realtime";
import { TranscriptService } from "./transcripts";
import { FileService } from "./files";

Expand All @@ -25,7 +30,7 @@ class AssemblyAI {
/**
* The realtime service.
*/
public realtime: RealtimeServiceFactory;
public realtime: RealtimeTranscriberFactory;

/**
* Create a new AssemblyAI client.
Expand All @@ -38,13 +43,15 @@ class AssemblyAI {
this.files = new FileService(params);
this.transcripts = new TranscriptService(params, this.files);
this.lemur = new LemurService(params);
this.realtime = new RealtimeServiceFactory(params);
this.realtime = new RealtimeTranscriberFactory(params);
}
}

export {
AssemblyAI,
LemurService,
RealtimeTranscriberFactory,
RealtimeTranscriber,
RealtimeServiceFactory,
RealtimeService,
TranscriptService,
Expand Down
23 changes: 18 additions & 5 deletions src/services/realtime/factory.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
import {
BaseServiceParams,
RealtimeTokenParams,
CreateRealtimeServiceParams,
RealtimeServiceParams,
CreateRealtimeTranscriberParams,
RealtimeTranscriberParams,
RealtimeTemporaryTokenResponse,
CreateRealtimeServiceParams,
} from "../..";
import { RealtimeService } from "./service";
import { RealtimeService, RealtimeTranscriber } from "./service";
import { BaseService } from "../base";

export class RealtimeServiceFactory extends BaseService {
export class RealtimeTranscriberFactory extends BaseService {
private rtFactoryParams: BaseServiceParams;
constructor(params: BaseServiceParams) {
super(params);
this.rtFactoryParams = params;
}

/**
* @deprecated Use transcriber(...) instead
*/
createService(params?: CreateRealtimeServiceParams): RealtimeService {
return this.transcriber(params);
}

transcriber(params?: CreateRealtimeTranscriberParams): RealtimeTranscriber {
const serviceParams = { ...params } as Record<string, unknown>;
if (!serviceParams.token && !serviceParams.apiKey) {
serviceParams.apiKey = this.rtFactoryParams.apiKey;
}

return new RealtimeService(serviceParams as RealtimeServiceParams);
return new RealtimeTranscriber(serviceParams as RealtimeTranscriberParams);
}

async createTemporaryToken(params: RealtimeTokenParams) {
Expand All @@ -35,3 +43,8 @@ export class RealtimeServiceFactory extends BaseService {
return data.token;
}
}

/**
* @deprecated Use RealtimeTranscriberFactory instead
*/
export class RealtimeServiceFactory extends RealtimeTranscriberFactory {}
20 changes: 13 additions & 7 deletions src/services/realtime/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { ErrorEvent, MessageEvent, CloseEvent } from "ws";
import {
RealtimeEvents,
RealtimeListeners,
RealtimeServiceParams,
RealtimeTranscriberParams,
RealtimeMessage,
RealtimeTranscript,
PartialTranscript,
FinalTranscript,
SessionBeginsEventData,
AudioEncoding,
AudioData,
} from "../..";
import {
RealtimeError,
Expand All @@ -20,7 +21,7 @@ import {

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

export class RealtimeService {
export class RealtimeTranscriber {
private realtimeUrl: string;
private sampleRate: number;
private wordBoost?: string[];
Expand All @@ -31,7 +32,7 @@ export class RealtimeService {
private listeners: RealtimeListeners = {};
private sessionTerminatedResolve?: () => void;

constructor(params: RealtimeServiceParams) {
constructor(params: RealtimeTranscriberParams) {
this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
this.sampleRate = params.sampleRate ?? 16_000;
this.wordBoost = params.wordBoost;
Expand Down Expand Up @@ -157,16 +158,16 @@ export class RealtimeService {
});
}

sendAudio(audio: ArrayBufferLike) {
sendAudio(audio: AudioData) {
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
throw new Error("Socket is not open for communication");
}
this.socket.send(audio);
}

stream(): WritableStream<ArrayBufferLike> {
return new WritableStream<ArrayBufferLike>({
write: (chunk: ArrayBufferLike) => {
stream(): WritableStream<AudioData> {
return new WritableStream<AudioData>({
write: (chunk: AudioData) => {
this.sendAudio(chunk);
},
});
Expand Down Expand Up @@ -194,3 +195,8 @@ export class RealtimeService {
this.socket = undefined;
}
}

/**
* @deprecated Use RealtimeTranscriber instead
*/
export class RealtimeService extends RealtimeTranscriber {}
9 changes: 5 additions & 4 deletions src/types/asyncapi.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ type OneOf<T extends any[]> = T extends [infer Only]
? OneOf<[XOR<A, B>, ...Rest]>
: never;

export type AudioData = {
/** @description Base64 encoded raw audio data */
audio_data: string;
};
/**
* Format: binary
* @description Binary audio data
*/
export type AudioData = ArrayBufferLike;

/**
* @description The encoding of the audio data
Expand Down
25 changes: 21 additions & 4 deletions src/types/openapi.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,12 +475,21 @@ export type Error = {
* "64nygnr62k-405c-4ae8-8a6b-d90b40ff3cce"
* ],
* "context": "This is an interview about wildfires.",
* "answer_format": "Bullet Points",
* "final_model": "default",
* "temperature": 0,
* "max_output_size": 3000
* }
*/
export type LemurActionItemsParams = LemurBaseParams;
export type LemurActionItemsParams = LemurBaseParams & {
/**
* @description How you want the action items to be returned. This can be any text.
* Defaults to "Bullet Points".
*
* @default Bullet Points
*/
answer_format?: string;
};

/**
* @example {
Expand Down Expand Up @@ -931,6 +940,14 @@ export type RedactedAudioResponse = {
*/
export type RedactedAudioStatus = "redacted_audio_ready";

/**
* @description Controls the filetype of the audio created by redact_pii_audio. Currently supports mp3 (default) and wav. See [PII redaction](https://www.assemblyai.com/docs/models/pii-redaction) for more details.
* @default mp3
* @example mp3
* @enum {string}
*/
export type RedactPiiAudioQuality = "mp3" | "wav";

/**
* @example {
* "sentences": [
Expand Down Expand Up @@ -2076,7 +2093,7 @@ export type Transcript = {
* @description The audio quality of the PII-redacted audio file, if redact_pii_audio is enabled.
* See [PII redaction](https://www.assemblyai.com/docs/models/pii-redaction) for more information.
*/
redact_pii_audio_quality?: string | null;
redact_pii_audio_quality?: RedactPiiAudioQuality | null;
/**
* @description The list of PII Redaction policies that were enabled, if PII Redaction is enabled.
* See [PII redaction](https://www.assemblyai.com/docs/models/pii-redaction) for more information.
Expand Down Expand Up @@ -2244,7 +2261,7 @@ export type TranscriptList = {
*/
export type TranscriptListItem = {
audio_url: string;
completed?: Date;
completed: Date | null;
created: Date;
/** Format: uuid */
id: string;
Expand Down Expand Up @@ -2346,7 +2363,7 @@ export type TranscriptOptionalParams = {
* @description Controls the filetype of the audio created by redact_pii_audio. Currently supports mp3 (default) and wav. See [PII redaction](https://www.assemblyai.com/docs/models/pii-redaction) for more details.
* @default mp3
*/
redact_pii_audio_quality?: string;
redact_pii_audio_quality?: RedactPiiAudioQuality;
/** @description The list of PII Redaction policies to enable. See [PII redaction](https://www.assemblyai.com/docs/models/pii-redaction) for more details. */
redact_pii_policies?: PiiPolicy[];
/** @description The replacement logic for detected PII, can be "entity_type" or "hash". See [PII redaction](https://www.assemblyai.com/docs/models/pii-redaction) for more details. */
Expand Down
Loading

0 comments on commit a88f2d4

Please sign in to comment.