Skip to content
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
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

- Add streaming parameters to match the Python SDK:
- `voiceFocus` and `voiceFocusThreshold` (replaces the unreleased `noiseSuppressionModel` / `noiseSuppressionThreshold`)
- `continuousPartials`
- `customerSupportAudioCapture` (logs a warning when enabled — records session audio for AssemblyAI support)
- `continuousPartials` (U3Pro speech models only)
- `customerSupportAudioCapture` — internal/unstable; sent on the wire as `_customer_support_audio_capture` to mirror the server's stability marker. Records session audio for AssemblyAI support; only enable when coordinating with support
- `includePartialTurns` — explicitly include or exclude partial (non-final) turns
- `redactPii`, `redactPiiPolicies`, `redactPiiSub` — server-side PII redaction on final turns
- `webhookUrl`, `webhookAuthHeaderName`, `webhookAuthHeaderValue`
- Add `StreamingPiiPolicy` and `StreamingPiiSubstitution` exported types. `StreamingPiiPolicy` covers the full server-side `AAIEntities` enum (65 entities)
- Add `speaker` field to `StreamingWord`

## [4.20.0]
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.33.0",
"version": "4.33.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
14 changes: 13 additions & 1 deletion src/services/streaming/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,24 @@ export class StreamingTranscriber {
);
}

if (this.params.interruptionDelay !== undefined) {
searchParams.set(
"interruption_delay",
this.params.interruptionDelay.toString(),
);
}

if (this.params.customerSupportAudioCapture) {
console.warn(
"`customerSupportAudioCapture=true` will record session audio. Only enable this when explicitly coordinating with AssemblyAI support.",
);
// The server's canonical wire name is `_customer_support_audio_capture`
// (leading underscore = "not officially supported / unstable"). The
// server also accepts `customer_support_audio_capture` via
// `populate_by_name=True`, but we send the underscore form to honor
// the server's stability marker.
searchParams.set(
"customer_support_audio_capture",
"_customer_support_audio_capture",
this.params.customerSupportAudioCapture.toString(),
);
}
Expand Down
34 changes: 28 additions & 6 deletions src/types/streaming/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export type StreamingTranscriberParams = {
voiceFocus?: VoiceFocusModel;
voiceFocusThreshold?: number;
continuousPartials?: boolean;
interruptionDelay?: number;
customerSupportAudioCapture?: boolean;
includePartialTurns?: boolean;
redactPii?: boolean;
Expand Down Expand Up @@ -82,53 +83,73 @@ export type VoiceFocusModel = "near-field" | "far-field";

export type StreamingPiiSubstitution = "hash" | "entity_name";

// Source of truth: assemblyai/engineering/projects/pii/enums.py (`AAIEntities`).
// Keep this union in sync when entities are added or removed server-side.
export type StreamingPiiPolicy =
| "account_number"
| "banking_information"
| "blood_type"
| "credit_card_number"
| "credit_card_expiration"
| "corporate_action"
| "credit_card_cvv"
| "credit_card_expiration"
| "credit_card_number"
| "date"
| "date_interval"
| "date_of_birth"
| "day"
| "drivers_license"
| "drug"
| "duration"
| "effect"
| "email_address"
| "event"
| "filename"
| "gender_sexuality"
| "financial_metric"
| "gender"
| "gender_sexuality"
| "healthcare_number"
| "injury"
| "ip_address"
| "language"
| "location"
| "location_address"
| "location_address_street"
| "location_city"
| "location_coordinate"
| "location_country"
| "location_state"
| "location_zip"
| "marital_status"
| "medical_code"
| "medical_condition"
| "medical_process"
| "money_amount"
| "month"
| "nationality"
| "number_sequence"
| "occupation"
| "organization"
| "organization_id"
| "organization_medical_facility"
| "passport_number"
| "password"
| "person_age"
| "person_name"
| "phone_number"
| "physical_attribute"
| "political_affiliation"
| "occupation"
| "organization"
| "organization_medical_facility"
| "product"
| "project"
| "religion"
| "sexuality"
| "statistics"
| "time"
| "trend"
| "url"
| "us_social_security_number"
| "username"
| "vehicle_id"
| "year"
| "zodiac_sign";

export type StreamingTokenParams = {
Expand Down Expand Up @@ -199,6 +220,7 @@ export type StreamingUpdateConfiguration = {
keyterms_prompt?: string[];
prompt?: string;
filter_profanity?: boolean;
interruption_delay?: number;
};

export type StreamingForceEndpoint = {
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/streaming.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,37 @@ describe("streaming", () => {
await connect(rt, server);
});

it("should include interruption_delay in connection URL", async () => {
await cleanup();
WS.clean();

const wsUrl =
`${websocketBaseUrl}?token=123&sample_rate=16000` +
`&speech_model=u3-rt-pro` +
`&interruption_delay=500`;
server = new WS(wsUrl);
rt = new StreamingTranscriber({
websocketBaseUrl,
token: "123",
sampleRate: 16_000,
speechModel: "u3-rt-pro",
interruptionDelay: 500,
});
onOpen = jest.fn();
rt.on("open", onOpen);
await connect(rt, server);
});

it("should include interruption_delay in updateConfiguration message", async () => {
rt.updateConfiguration({ interruption_delay: 250 });
await expect(server).toReceiveMessage(
JSON.stringify({
type: "UpdateConfiguration",
interruption_delay: 250,
}),
);
});

it("should include voice_focus and voice_focus_threshold in connection URL", async () => {
await cleanup();
WS.clean();
Expand Down
Loading