feat: show client tools in debug preview
This commit is contained in:
@@ -71,6 +71,23 @@ export type SessionUpdateResult = {
|
||||
export type ClientToolHandler = (
|
||||
argumentsValue: Record<string, unknown>,
|
||||
) => unknown | Promise<unknown>;
|
||||
export type ClientToolDefinition = {
|
||||
name: string;
|
||||
label: string;
|
||||
description: string;
|
||||
parameters: readonly ClientToolParameter[];
|
||||
};
|
||||
export type ClientToolParameter = {
|
||||
name: string;
|
||||
type: string;
|
||||
required: boolean;
|
||||
description: string;
|
||||
};
|
||||
|
||||
type RegisteredClientTool = {
|
||||
definition: ClientToolDefinition;
|
||||
handler: ClientToolHandler;
|
||||
};
|
||||
|
||||
type PendingUserInput = {
|
||||
resolve: (result: UserInputResult) => void;
|
||||
@@ -276,6 +293,7 @@ export function useVoicePreview(
|
||||
const [audioOutputs, setAudioOutputs] = useState<MediaDeviceInfo[]>([]);
|
||||
const [selectedDeviceId, setSelectedDeviceId] = useState("");
|
||||
const [selectedOutputDeviceId, setSelectedOutputDeviceId] = useState("");
|
||||
const [clientTools, setClientTools] = useState<ClientToolDefinition[]>([]);
|
||||
|
||||
const transportRef = useRef<AppSmallWebRTCTransport | null>(null);
|
||||
const cleanupPromiseRef = useRef<Promise<void>>(Promise.resolve());
|
||||
@@ -290,7 +308,9 @@ export function useVoicePreview(
|
||||
const pendingSessionUpdatesRef = useRef(
|
||||
new Map<string, PendingSessionUpdate>(),
|
||||
);
|
||||
const clientToolHandlersRef = useRef(new Map<string, ClientToolHandler>());
|
||||
const clientToolHandlersRef = useRef(
|
||||
new Map<string, RegisteredClientTool>(),
|
||||
);
|
||||
const endedByServerRef = useRef(false);
|
||||
const selectedDeviceIdRef = useRef("");
|
||||
const selectedOutputDeviceIdRef = useRef("");
|
||||
@@ -396,10 +416,10 @@ export function useVoicePreview(
|
||||
const waitForResponse = msg.wait_for_response !== false;
|
||||
if (!toolCallId || !functionName) return;
|
||||
|
||||
const handler = clientToolHandlersRef.current.get(functionName);
|
||||
const registeredTool = clientToolHandlersRef.current.get(functionName);
|
||||
const transport = transportRef.current;
|
||||
if (!transport || transport.state !== "connected") return;
|
||||
if (!handler) {
|
||||
if (!registeredTool) {
|
||||
if (waitForResponse) {
|
||||
transport.sendAppMessage({
|
||||
type: "client-tool-result",
|
||||
@@ -418,7 +438,7 @@ export function useVoicePreview(
|
||||
!Array.isArray(msg.arguments)
|
||||
? (msg.arguments as Record<string, unknown>)
|
||||
: {};
|
||||
const data = await handler(argumentsValue);
|
||||
const data = await registeredTool.handler(argumentsValue);
|
||||
if (transportRef.current !== transport) return;
|
||||
if (!waitForResponse) return;
|
||||
transport.sendAppMessage({
|
||||
@@ -889,11 +909,27 @@ export function useVoicePreview(
|
||||
);
|
||||
|
||||
const registerClientTool = useCallback(
|
||||
(functionName: string, handler: ClientToolHandler): (() => void) => {
|
||||
clientToolHandlersRef.current.set(functionName, handler);
|
||||
(
|
||||
definition: ClientToolDefinition,
|
||||
handler: ClientToolHandler,
|
||||
): (() => void) => {
|
||||
const registeredTool = { definition, handler };
|
||||
clientToolHandlersRef.current.set(definition.name, registeredTool);
|
||||
setClientTools(
|
||||
[...clientToolHandlersRef.current.values()].map(
|
||||
(item) => item.definition,
|
||||
),
|
||||
);
|
||||
return () => {
|
||||
if (clientToolHandlersRef.current.get(functionName) === handler) {
|
||||
clientToolHandlersRef.current.delete(functionName);
|
||||
if (
|
||||
clientToolHandlersRef.current.get(definition.name) === registeredTool
|
||||
) {
|
||||
clientToolHandlersRef.current.delete(definition.name);
|
||||
setClientTools(
|
||||
[...clientToolHandlersRef.current.values()].map(
|
||||
(item) => item.definition,
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
},
|
||||
@@ -911,6 +947,7 @@ export function useVoicePreview(
|
||||
remoteStream,
|
||||
messages,
|
||||
sessionVariables,
|
||||
clientTools,
|
||||
callEnded,
|
||||
networkQuality,
|
||||
audioInputs,
|
||||
|
||||
Reference in New Issue
Block a user