feat(speech): add configurable TTS playback modes

This commit is contained in:
Shantur Rathore
2026-03-26 20:46:49 +00:00
parent 740f37db86
commit d13ecba322
15 changed files with 561 additions and 55 deletions

View File

@@ -123,6 +123,28 @@ async function request<T>(path: string, init?: RequestInit): Promise<T> {
}
}
async function requestRaw(path: string, init?: RequestInit): Promise<Response> {
const url = API_BASE ? new URL(path, API_BASE).toString() : path
const headers = normalizeHeaders(init?.headers)
if (init?.body !== undefined && !headers["Content-Type"]) {
headers["Content-Type"] = "application/json"
}
const method = (init?.method ?? "GET").toUpperCase()
const startedAt = Date.now()
logHttp(`${method} ${path}`)
const response = await fetch(url, { ...init, headers, credentials: init?.credentials ?? "include" })
if (!response.ok) {
const message = await response.text()
logHttp(`${method} ${path} -> ${response.status}`, { durationMs: Date.now() - startedAt, error: message })
throw new Error(message || `Request failed with ${response.status}`)
}
logHttp(`${method} ${path} -> ${response.status}`, { durationMs: Date.now() - startedAt })
return response
}
export const serverApi = {
fetchWorkspaces(): Promise<WorkspaceDescriptor[]> {
@@ -253,12 +275,22 @@ export const serverApi = {
body: JSON.stringify(payload),
})
},
synthesizeSpeech(payload: { text: string; format?: "mp3" | "wav" | "opus" }): Promise<SpeechSynthesisResponse> {
synthesizeSpeech(payload: { text: string; format?: "mp3" | "wav" | "opus" | "aac" }): Promise<SpeechSynthesisResponse> {
return request<SpeechSynthesisResponse>("/api/speech/synthesize", {
method: "POST",
body: JSON.stringify(payload),
})
},
synthesizeSpeechStream(
payload: { text: string; format?: "mp3" | "wav" | "opus" | "aac" },
signal?: AbortSignal,
): Promise<Response> {
return requestRaw("/api/speech/synthesize/stream", {
method: "POST",
body: JSON.stringify(payload),
signal,
})
},
listFileSystem(path?: string, options?: { includeFiles?: boolean }): Promise<FileSystemListResponse> {
const params = new URLSearchParams()
if (path && path !== ".") {