@alexkroman1/aai-ui 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client-config.d.ts +16 -0
- package/dist/components/sync-chat-view.d.ts +17 -0
- package/dist/default-client/assets/{audio-COt0_Zvp.js → audio-NYmRKbVI.js} +1 -1
- package/dist/default-client/assets/index-Dx70XGBr.js +121 -0
- package/dist/default-client/assets/index-NMhTOGW2.css +2 -0
- package/dist/default-client/index.html +2 -2
- package/dist/define-client-Cl1bl24M.js +711 -0
- package/dist/define-client.d.ts +9 -0
- package/dist/define-client.js +4 -93
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -3
- package/dist/{session-core-Cfz7PPhN.js → session-core-B64kau_v.js} +4 -4
- package/dist/session-core.js +1 -1
- package/dist/sync-mic.d.ts +49 -0
- package/dist/sync-session.d.ts +49 -0
- package/dist/sync-vad.d.ts +54 -0
- package/dist/types.d.ts +1 -11
- package/dist/types.js +1 -13
- package/package.json +2 -2
- package/dist/default-client/assets/index-B2bISVbm.css +0 -2
- package/dist/default-client/assets/index-DtsWxxc_.js +0 -94
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-connection client-config lookup.
|
|
3
|
+
*
|
|
4
|
+
* `GET client-config` (relative to the agent's base URL — see
|
|
5
|
+
* `sdk/client-config.ts` in `@alexkroman1/aai`) tells the default client how
|
|
6
|
+
* to talk to the agent before any connection exists, most importantly which
|
|
7
|
+
* transport `agent({ transport })` declared. Every failure path — network
|
|
8
|
+
* error, 404 from an older server, malformed body — degrades to the
|
|
9
|
+
* WebSocket default, so this lookup can never break an existing agent.
|
|
10
|
+
*/
|
|
11
|
+
import { type ClientConfigResponse } from "@alexkroman1/aai/protocol";
|
|
12
|
+
export type { ClientConfigResponse } from "@alexkroman1/aai/protocol";
|
|
13
|
+
/** Resolve a relative endpoint path against the agent's base URL. */
|
|
14
|
+
export declare function buildAgentUrl(platformUrl: string, endpointPath: string): URL;
|
|
15
|
+
/** Fetch the agent's client config; any failure yields the WebSocket default. */
|
|
16
|
+
export declare function fetchClientConfig(platformUrl: string, fetchFn?: typeof globalThis.fetch): Promise<ClientConfigResponse>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync-transport chat view: mic toggle (client-side VAD), text composer,
|
|
3
|
+
* message list, and spoken-reply playback — one HTTP request per turn.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare function SyncChatView({ syncUrl, title, greeting, }: {
|
|
8
|
+
/** The agent server's sync endpoint, e.g. `https://host/slug/sync`. */
|
|
9
|
+
syncUrl: string;
|
|
10
|
+
/** Agent name shown in the header. */
|
|
11
|
+
title?: string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Greeting shown as the opening assistant message. Sync turns have no
|
|
14
|
+
* session start for the server to speak it on, so it is display-only.
|
|
15
|
+
*/
|
|
16
|
+
greeting?: string | undefined;
|
|
17
|
+
}): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./index-
|
|
1
|
+
import{t as e}from"./index-Dx70XGBr.js";var t=1e3,n=65e3,r=250;async function i(e,t){let n=await new OfflineAudioContext(1,1,t).decodeAudioData(e),r=Math.ceil(n.duration*t),i=new OfflineAudioContext(1,r,t),a=i.createBufferSource();a.buffer=n,a.connect(i.destination),a.start();let o=(await i.startRendering()).getChannelData(0),s=new Int16Array(o.length),c=0;for(let e of o){let t=Math.max(-1,Math.min(1,e));s[c++]=t<0?t*32768:t*32767}return s}async function a(i){let{sttSampleRate:a,ttsSampleRate:o,captureWorkletSrc:s,playbackWorkletSrc:c,onMicData:l,onError:u}=i,d=o,f=new AudioContext({sampleRate:d,latencyHint:`playback`}),p=navigator.mediaDevices.getUserMedia({audio:{deviceId:{ideal:`default`},echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,voiceIsolation:!0}}),m;try{[m]=await Promise.all([p,f.resume(),f.audioWorklet.addModule(s),f.audioWorklet.addModule(c)])}catch(e){throw p.then(e=>{for(let t of e.getTracks())t.stop()}).catch(()=>{}),await f.close().catch(e=>{console.warn(`AudioContext close failed:`,e)}),e}let h=f.createMediaStreamSource(m),g=new AudioWorkletNode(f,`capture-processor`,{channelCount:1,channelCountMode:`explicit`,processorOptions:{contextRate:d,sttSampleRate:a,bufferSeconds:e}});h.connect(g),g.onprocessorerror=()=>{let e=Error(`Audio capture worklet crashed`);console.error(`[aai-ui]`,e.message),u?.(e)},g.port.postMessage({event:`start`});let _=null;g.port.onmessage=e=>{e.data.event===`chunk`?l(e.data.buffer):e.data.event===`stopped`&&(_?.(),_=null)};let v=null,y=null,b=new AbortController;function x(){if(v)return v;let e=new AudioWorkletNode(f,`playback-processor`,{processorOptions:{sampleRate:d}});return e.connect(f.destination),e.port.onmessage=e=>{if(e.data.event===`stop`){if(e.data.reason===`interrupt`)return;y?.(),y=null}},e.onprocessorerror=()=>{let e=Error(`Audio playback worklet crashed`);console.error(`[aai-ui]`,e.message),y?.(),y=null,u?.(e)},v=e,e}let S={enqueue(e){b.signal.aborted||e.byteLength!==0&&x().port.postMessage({event:`write`,buffer:new Uint8Array(e)},[e])},done(){return!v||f.state!==`running`?Promise.resolve():new Promise(e=>{y?.();let r=()=>{clearInterval(i),clearTimeout(a),y===r&&(y=null),e()},i=setInterval(()=>{f.state!==`running`&&r()},t),a=setTimeout(r,n);y=r,v?.port.postMessage({event:`done`})})},flush(){v&&(y?.(),y=null,v.port.postMessage({event:`interrupt`}))},async close(){if(!b.signal.aborted){b.abort(),await new Promise(e=>{let t=setTimeout(e,r);_=()=>{clearTimeout(t),e()},g.port.postMessage({event:`stop`})}),h.disconnect(),g.disconnect(),v&&v.disconnect();for(let e of m.getTracks())e.stop();await f.close().catch(()=>{})}},async[Symbol.asyncDispose](){await S.close()}};return S}export{a as createVoiceIO,i as decodeAudioToPcm16};
|