Module livekit.plugins.ultravox.utils
Functions
def parse_tools(tools: list[llm.FunctionTool | llm.RawFunctionTool]) ‑> list[dict[str, typing.Any]]
-
Expand source code
def parse_tools(tools: list[llm.FunctionTool | llm.RawFunctionTool]) -> list[dict[str, Any]]: """Prepare tools for sending to Ultravox. https://docs.ultravox.ai/essentials/tools#creating-your-first-custom-tool""" results: list[dict[str, Any]] = [] for tool in tools: if is_raw_function_tool(tool): raw_fnc_info = get_raw_function_info(tool) name = raw_fnc_info.name description = raw_fnc_info.raw_schema.get("description", None) parameters = raw_fnc_info.raw_schema.get("parameters", {}) elif is_function_tool(tool): fnc_info = get_function_info(tool) model = function_arguments_to_pydantic_model(tool) name = fnc_info.name description = fnc_info.description parameters = model.model_json_schema() def _extract_type(prop: dict[str, Any]) -> str: """Best-effort guess of a parameter's primitive type.""" if "type" in prop: assert isinstance(prop["type"], str) return prop["type"] if "enum" in prop: return "string" if "items" in prop: return "array" for key in ("anyOf", "oneOf"): if key in prop: for variant in prop[key]: if isinstance(variant, dict) and "type" in variant: assert isinstance(variant["type"], str) return variant["type"] # Fallback to string return "string" results.append( { "temporaryTool": { "modelToolName": name, "description": description, "dynamicParameters": [ { "name": pn, "location": "PARAMETER_LOCATION_BODY", "schema": ( p if "type" in p else { # fallback minimal schema for enum/anyOf etc. "type": _extract_type(p), **( {"description": p.get("description")} if p.get("description") else {} ), } ), "required": pn in parameters.get("required", []), } for pn, p in parameters["properties"].items() ], "client": {}, } } ) return results
Prepare tools for sending to Ultravox. https://docs.ultravox.ai/essentials/tools#creating-your-first-custom-tool