import {
isTranscriptionProviderId,
type TranscriptResult,
type TranscriptionProviderId,
} from './types';
import {
transcribePathResumable as assemblyaiTranscribePathResumable,
type AssemblyAiProviderStatus,
type AssemblyAiResumeCheckpoint,
type AssemblyAiCheckpointWriter,
type TranscribeOptions,
} from './assemblyai';
import { localTranscribePathResumable } from './local-asr';
import { genericCloudTranscribePath } from './generic-cloud-asr';
export const TRANSCRIPTION_PROVIDER_KEY = 'cc.transcriptionProvider';
export const TRANSCRIPTION_LANGUAGE_KEY = 'cc.transcriptionLanguage';
export const TRANSCRIPTION_DIARIZATION_KEY = 'cc.transcriptionDiarization';
export const TRANSCRIPTION_PROVIDER_CHANGE_EVENT = 'openchatcut:transcription-provider-change';
* on-device engine; `all` also fires on paid cloud providers; `off` never.
* Default `local` protects cloud budgets while keeping the free engine automatic. */
export const AUTO_TRANSCRIBE_INGEST_KEY = 'cc.autoTranscribeIngest';
export type AutoTranscribeIngestSetting = 'off' | 'local' | 'all';
export function autoTranscribeIngestSetting(): AutoTranscribeIngestSetting {
try {
const value = localStorage.getItem(AUTO_TRANSCRIBE_INGEST_KEY);
if (value === 'off' || value === 'all') return value;
} catch {
}
return 'local';
}
export function shouldAutoTranscribeIngest(
provider: TranscriptionProviderId = preferredTranscriptionProvider(),
): boolean {
const setting = autoTranscribeIngestSetting();
return setting === 'all' || (setting === 'local' && provider === 'local');
}
export function setAutoTranscribeIngest(setting: AutoTranscribeIngestSetting): void {
try {
localStorage.setItem(AUTO_TRANSCRIBE_INGEST_KEY, setting);
} catch {
}
}
export function preferredTranscriptionProvider(): TranscriptionProviderId {
try {
const value = localStorage.getItem(TRANSCRIPTION_PROVIDER_KEY);
if (isTranscriptionProviderId(value)) return value;
} catch {
}
return 'assemblyai';
}
export function preferredTranscriptionLanguage(): string {
try {
const value = localStorage.getItem(TRANSCRIPTION_LANGUAGE_KEY)?.trim();
if (value) return value;
} catch {
}
return 'zh';
}
export function preferredTranscriptionDiarization(): boolean {
try {
const value = localStorage.getItem(TRANSCRIPTION_DIARIZATION_KEY);
if (value === '0') return false;
if (value === '1') return true;
} catch {
}
return true;
}
export function setPreferredTranscriptionProvider(provider: TranscriptionProviderId): void {
try {
localStorage.setItem(TRANSCRIPTION_PROVIDER_KEY, provider);
window.dispatchEvent(new Event(TRANSCRIPTION_PROVIDER_CHANGE_EVENT));
} catch {
}
}
export type { AssemblyAiProviderStatus, AssemblyAiResumeCheckpoint, AssemblyAiCheckpointWriter, TranscribeOptions };
export { TranscriptionError, extractAudioForAsr, transcriptionSourceForPath } from './assemblyai';
export type TranscriptionCheckpointWriter = AssemblyAiCheckpointWriter;
* Route one immutable provider attempt. Callers that persist work pass the
* provider captured at job start so a settings change cannot switch it midway.
*/
export async function transcribePathResumable(
path: string,
resume: AssemblyAiResumeCheckpoint,
onCheckpoint: AssemblyAiCheckpointWriter,
onWait?: (note?: string) => void,
opts: TranscribeOptions = {},
provider: TranscriptionProviderId = preferredTranscriptionProvider(),
): Promise<TranscriptResult> {
const capturedOptions: TranscribeOptions = {
...opts,
languageCode: opts.languageCode ?? preferredTranscriptionLanguage(),
diarize: opts.diarize ?? preferredTranscriptionDiarization(),
};
if (provider === 'local') {
return localTranscribePathResumable(path, resume, onCheckpoint, onWait, capturedOptions);
}
if (provider === 'assemblyai') {
return assemblyaiTranscribePathResumable(path, resume, onCheckpoint, onWait, capturedOptions);
}
return genericCloudTranscribePath(provider, path, onCheckpoint, onWait, capturedOptions);
}
export async function transcribePath(
path: string,
onWait?: (note?: string) => void,
opts: TranscribeOptions = {},
provider: TranscriptionProviderId = preferredTranscriptionProvider(),
): Promise<TranscriptResult> {
return transcribePathResumable(path, {}, () => {}, onWait, opts, provider);
}