client sdk
This commit is contained in:
Vendored
+336
@@ -0,0 +1,336 @@
|
||||
/**
|
||||
* Type declarations for `audio-agent-client.js`.
|
||||
*
|
||||
* The SDK is plain ESM with no build step; this file exists so TypeScript
|
||||
* consumers get autocompletion and type checking. Keep it in sync with the JS.
|
||||
*/
|
||||
|
||||
export interface AudioFormat {
|
||||
readonly sampleRate: 44100;
|
||||
readonly frameSamples: 882;
|
||||
readonly frameBytes: 1764;
|
||||
readonly sttSampleRate: 16000;
|
||||
}
|
||||
|
||||
export const AUDIO: AudioFormat;
|
||||
|
||||
export const CLIENT_EVENTS: readonly string[];
|
||||
|
||||
/** Union accepted by every audio-sending helper. */
|
||||
export type AudioChunk =
|
||||
| Int16Array
|
||||
| Float32Array
|
||||
| ArrayBuffer
|
||||
| ArrayBufferView
|
||||
| number[];
|
||||
|
||||
export function int16ArrayFromBytes(buffer: ArrayBuffer | ArrayBufferView): Int16Array;
|
||||
export function float32ToInt16(floats: Float32Array | number[]): Int16Array;
|
||||
export function int16ToFloat32(ints: Int16Array): Float32Array;
|
||||
export function toInt16(chunk: AudioChunk): Int16Array;
|
||||
|
||||
/** Any object with a `type` discriminator, as emitted by the engine. */
|
||||
export interface ServerEvent {
|
||||
type: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
/** Server-assigned session id, sent once at connect time. */
|
||||
export interface SessionEvent extends ServerEvent {
|
||||
type: 'session';
|
||||
id: string;
|
||||
}
|
||||
export interface CuesEvent extends ServerEvent {
|
||||
type: 'cues';
|
||||
lang: string;
|
||||
config: Record<string, unknown>;
|
||||
}
|
||||
export interface UserEvent extends ServerEvent {
|
||||
type: 'user';
|
||||
text: string;
|
||||
}
|
||||
export interface AssistantDeltaEvent extends ServerEvent {
|
||||
type: 'assistant_delta';
|
||||
text: string;
|
||||
}
|
||||
export interface AssistantMarkdownEvent extends ServerEvent {
|
||||
type: 'assistant_markdown';
|
||||
text: string;
|
||||
}
|
||||
export interface AssistantEndEvent extends ServerEvent {
|
||||
type: 'assistant_end';
|
||||
}
|
||||
export interface CueEvent extends ServerEvent {
|
||||
type: 'cue';
|
||||
kind: 'filler' | 'start_filler' | 'backchannel';
|
||||
name: string;
|
||||
category?: string;
|
||||
pause_ms?: number;
|
||||
}
|
||||
export interface BargeInEvent extends ServerEvent {
|
||||
type: 'barge_in';
|
||||
source: string;
|
||||
prob?: number;
|
||||
}
|
||||
export interface ToolCallEvent extends ServerEvent {
|
||||
type: 'tool_call';
|
||||
name: string;
|
||||
arguments: unknown;
|
||||
}
|
||||
export interface AudioSourceEvent extends ServerEvent {
|
||||
type: 'audio_source';
|
||||
state: 'loading' | 'playing' | 'stopped' | 'error';
|
||||
url: string;
|
||||
text?: string;
|
||||
}
|
||||
export interface ErrorEvent extends ServerEvent {
|
||||
type: 'error';
|
||||
text: string;
|
||||
}
|
||||
|
||||
/** Payload of the local `audio` event: one decoded PCM frame. */
|
||||
export interface AudioFrame {
|
||||
samples: Int16Array;
|
||||
buffer: ArrayBuffer;
|
||||
sampleRate: number;
|
||||
}
|
||||
|
||||
/** Payload of the local `close` event. */
|
||||
export interface CloseEvent {
|
||||
code: number;
|
||||
reason: string;
|
||||
wasClean: boolean;
|
||||
}
|
||||
|
||||
/** Payload for connection-level failures (as opposed to a server `error` event). */
|
||||
export interface TransportError {
|
||||
error: Error;
|
||||
event?: unknown;
|
||||
fatal: boolean;
|
||||
}
|
||||
|
||||
export interface AudioAgentClientOptions {
|
||||
/** Full `ws://`/`wss://` URL; wins over `baseUrl`. */
|
||||
url?: string;
|
||||
/** Engine origin, e.g. `http://localhost:8787`; `/ws` is appended. */
|
||||
baseUrl?: string;
|
||||
/** Path appended to `baseUrl` (default `/ws`). */
|
||||
path?: string;
|
||||
/** Reconnect automatically after an unexpected close (default `false`). */
|
||||
autoReconnect?: boolean;
|
||||
reconnectMinDelayMs?: number;
|
||||
reconnectMaxDelayMs?: number;
|
||||
/** WebSocket implementation to use (required on Node < 22, e.g. the `ws` package). */
|
||||
WebSocket?: typeof WebSocket;
|
||||
}
|
||||
|
||||
export type ConnectionState = 'idle' | 'connecting' | 'open' | 'closed';
|
||||
|
||||
export class AudioAgentClient {
|
||||
constructor(options?: AudioAgentClientOptions);
|
||||
readonly url: string;
|
||||
autoReconnect: boolean;
|
||||
reconnectMinDelayMs: number;
|
||||
reconnectMaxDelayMs: number;
|
||||
readonly state: ConnectionState;
|
||||
readonly connected: boolean;
|
||||
|
||||
connect(): Promise<this>;
|
||||
close(code?: number, reason?: string): void;
|
||||
|
||||
sendAudio(chunk: AudioChunk): boolean;
|
||||
sendText(text: string): boolean;
|
||||
sendControl(message: Record<string, unknown>): boolean;
|
||||
sendUserText(text: string): boolean;
|
||||
interrupt(): boolean;
|
||||
playAudioSource(url: string): boolean;
|
||||
stopAudioSource(): boolean;
|
||||
setAudioSourceVolume(gain: number): boolean;
|
||||
setReference(path: string, text?: string): boolean;
|
||||
clearReference(): boolean;
|
||||
speak(text: string): boolean;
|
||||
|
||||
on(type: 'audio', handler: (frame: AudioFrame) => void): () => void;
|
||||
on(type: 'open', handler: (info: { url: string }) => void): () => void;
|
||||
on(type: 'close', handler: (info: CloseEvent) => void): () => void;
|
||||
on(type: 'state', handler: (state: ConnectionState) => void): () => void;
|
||||
on(
|
||||
type: 'reconnecting',
|
||||
handler: (info: { attempt: number; delay: number }) => void,
|
||||
): () => void;
|
||||
on(type: 'error', handler: (payload: TransportError | ErrorEvent) => void): () => void;
|
||||
on(type: 'event' | 'unknown', handler: (event: ServerEvent) => void): () => void;
|
||||
on(type: string, handler: (payload: any) => void): () => void;
|
||||
|
||||
once(type: string, handler: (payload: any) => void): () => void;
|
||||
off(type: string, handler: (payload: any) => void): void;
|
||||
emit(type: string, payload?: unknown): void;
|
||||
}
|
||||
|
||||
export interface AudioAgentRestOptions {
|
||||
fetch?: typeof fetch;
|
||||
headers?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface ToolsResponse {
|
||||
ok: boolean;
|
||||
count: number;
|
||||
source: 'file' | 'request' | 'none';
|
||||
tools: object[];
|
||||
}
|
||||
|
||||
export interface PhrasesResponse {
|
||||
default: string;
|
||||
languages: Array<{ code: string; label: string; phrase: string }>;
|
||||
}
|
||||
|
||||
export interface SetVoiceResponse {
|
||||
ok: boolean;
|
||||
lang: string;
|
||||
audio: string;
|
||||
phrase: string;
|
||||
}
|
||||
|
||||
export interface TranscribeResponse {
|
||||
ok: boolean;
|
||||
text: string;
|
||||
duration_ms: number;
|
||||
tokens: number;
|
||||
}
|
||||
|
||||
/** Where the effective system prompt comes from (decreasing precedence). */
|
||||
export type PromptSource = 'session' | 'global' | 'env' | 'default' | 'none';
|
||||
|
||||
/** Response of `GET`/`POST /api/prompt`. */
|
||||
export interface PromptResponse {
|
||||
ok: boolean;
|
||||
session_id: string | null;
|
||||
source: PromptSource;
|
||||
prompt: string;
|
||||
has_override: boolean;
|
||||
direct_answers_applied: boolean;
|
||||
}
|
||||
|
||||
/** Response of `POST /api/auth/phone-login` (upstream AquaChile payload). */
|
||||
export interface PhoneLoginResponse {
|
||||
sessionToken?: string;
|
||||
user?: Record<string, any>;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
/** Error thrown by {@link AudioAgentRest}, carrying the HTTP status and body. */
|
||||
export interface RestError extends Error {
|
||||
status: number;
|
||||
body: unknown;
|
||||
}
|
||||
|
||||
export class AudioAgentRest {
|
||||
constructor(baseUrl: string, options?: AudioAgentRestOptions);
|
||||
readonly baseUrl: string;
|
||||
|
||||
health(): Promise<string>;
|
||||
getTools(): Promise<ToolsResponse>;
|
||||
setTools(tools: object[]): Promise<ToolsResponse>;
|
||||
getPrompt(sessionId?: string): Promise<PromptResponse>;
|
||||
setPrompt(prompt: string | null, sessionId?: string | null): Promise<PromptResponse>;
|
||||
phoneLogin(phoneNumber: string, sessionId?: string | null): Promise<PhoneLoginResponse>;
|
||||
getCustomVoicePhrases(): Promise<PhrasesResponse>;
|
||||
setCustomVoice(
|
||||
lang: string,
|
||||
audio: Blob | ArrayBuffer | ArrayBufferView,
|
||||
text?: string,
|
||||
): Promise<SetVoiceResponse>;
|
||||
clearCustomVoice(): Promise<{ ok: boolean }>;
|
||||
transcribe(audio: Blob | ArrayBuffer | ArrayBufferView): Promise<TranscribeResponse>;
|
||||
openapi(): Promise<object>;
|
||||
}
|
||||
|
||||
export interface MicCaptureOptions {
|
||||
sampleRate?: number;
|
||||
frameSamples?: number;
|
||||
constraints?: MediaStreamConstraints;
|
||||
}
|
||||
|
||||
export class MicCapture {
|
||||
constructor(options?: MicCaptureOptions);
|
||||
readonly sampleRate: number;
|
||||
readonly frameSamples: number;
|
||||
readonly contextSampleRate: number | null;
|
||||
start(): Promise<void>;
|
||||
stop(): void;
|
||||
on(type: 'frame', handler: (samples: Int16Array) => void): () => void;
|
||||
on(type: 'start', handler: (info: { sampleRate: number }) => void): () => void;
|
||||
on(type: 'stop', handler: () => void): () => void;
|
||||
on(type: string, handler: (payload: any) => void): () => void;
|
||||
once(type: string, handler: (payload: any) => void): () => void;
|
||||
off(type: string, handler: (payload: any) => void): void;
|
||||
}
|
||||
|
||||
export interface PcmPlayerOptions {
|
||||
sampleRate?: number;
|
||||
bufferMs?: number;
|
||||
gain?: number;
|
||||
}
|
||||
|
||||
export class PcmPlayer {
|
||||
constructor(options?: PcmPlayerOptions);
|
||||
readonly sampleRate: number;
|
||||
bufferMs: number;
|
||||
gain: number;
|
||||
resume(): Promise<void>;
|
||||
push(chunk: AudioChunk): void;
|
||||
setGain(value: number): void;
|
||||
flush(): void;
|
||||
close(): void;
|
||||
isIdle(): boolean;
|
||||
on(type: 'chunk', handler: (info: { startAt: number; samples: number }) => void): () => void;
|
||||
on(type: 'flush', handler: () => void): () => void;
|
||||
on(type: 'idle', handler: () => void): () => void;
|
||||
on(type: string, handler: (payload: any) => void): () => void;
|
||||
once(type: string, handler: (payload: any) => void): () => void;
|
||||
off(type: string, handler: (payload: any) => void): void;
|
||||
}
|
||||
|
||||
export interface AudioSessionOptions extends AudioAgentClientOptions {
|
||||
client?: AudioAgentClient;
|
||||
player?: PcmPlayer;
|
||||
/** Playback jitter buffer in ms (default 150). */
|
||||
bufferMs?: number;
|
||||
/** Stream the microphone automatically (default `true`). */
|
||||
forwardMic?: boolean;
|
||||
}
|
||||
|
||||
export class AudioSession {
|
||||
constructor(options?: AudioSessionOptions);
|
||||
readonly client: AudioAgentClient;
|
||||
readonly player: PcmPlayer;
|
||||
readonly mic: MicCapture | null;
|
||||
forwardMic: boolean;
|
||||
|
||||
start(options?: { microphone?: boolean }): Promise<void>;
|
||||
stop(): Promise<void>;
|
||||
sendUserText(text: string): boolean;
|
||||
interrupt(): boolean;
|
||||
|
||||
on(type: 'audio' | 'session' | 'assistant_delta' | 'assistant_markdown' | 'cues' | 'user' | 'cue' | 'barge_in'
|
||||
| 'tool_call' | 'audio_source' | 'error' | 'assistant_end' | 'open' | 'close'
|
||||
| 'state' | 'reconnecting' | string, handler: (payload: any) => void): () => void;
|
||||
once(type: string, handler: (payload: any) => void): () => void;
|
||||
off(type: string, handler: (payload: any) => void): void;
|
||||
emit(type: string, payload?: unknown): void;
|
||||
}
|
||||
|
||||
declare const _default: {
|
||||
AUDIO: AudioFormat;
|
||||
CLIENT_EVENTS: readonly string[];
|
||||
int16ArrayFromBytes: typeof int16ArrayFromBytes;
|
||||
float32ToInt16: typeof float32ToInt16;
|
||||
int16ToFloat32: typeof int16ToFloat32;
|
||||
toInt16: typeof toInt16;
|
||||
AudioAgentClient: typeof AudioAgentClient;
|
||||
AudioAgentRest: typeof AudioAgentRest;
|
||||
MicCapture: typeof MicCapture;
|
||||
PcmPlayer: typeof PcmPlayer;
|
||||
AudioSession: typeof AudioSession;
|
||||
};
|
||||
export default _default;
|
||||
Reference in New Issue
Block a user