Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions livekit-agents/livekit/agents/voice/generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,14 @@ def _tool_completed(out: ToolExecutionOutput) -> None:
"speech_id": speech_handle.id,
},
)
_tool_completed(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently xai is calling these tools even though they are supposed to be executed on the server side, I'll raise with them.. but just to note that this will likely break the xai tools

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which tool did you test? XSearch or WebSearch?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for example, web + x search request:

 14:32:53.218 WARNI… livekit.agents     unknown AI function `web_search_with_snippets` {"function": "web_search_with_snippets", "speech_id": "speech_c7ce525a9080", "room": "mock_room"}
   14:32:53.221 WARNI… livekit.agents     unknown AI function `x_keyword_search` {"function": "x_keyword_search", "speech_id": "speech_c7ce525a9080", "room": "mock_room"}
   14:32:53.223 WARNI… livekit.agents     unknown AI function `x_semantic_search` {"function": "x_semantic_search", "speech_id": "speech_c7ce525a9080", "room": "mock_room"}

Copy link
Contributor

@Hormold Hormold Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • x_semantic_search
  • x_keyword_search
  • x_user_search
  • x_thread_fetch
  • web_search_with_snippets
  • browse_page

here is full list

make_tool_output(
fnc_call=fnc_call,
output=None,
exception=RuntimeError(f"unknown AI function `{fnc_call.name}`"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should expose the list of available functions back to the LLM to help with the next step (optionally)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should already have it in context?

include_error_details_in_llm_output=True,
)
)
continue

if not is_function_tool(function_tool) and not is_raw_function_tool(function_tool):
Expand Down Expand Up @@ -690,7 +698,12 @@ class ToolExecutionOutput:


def make_tool_output(
*, fnc_call: llm.FunctionCall, output: Any, exception: BaseException | None
*,
fnc_call: llm.FunctionCall,
output: Any,
exception: BaseException | None,
show_error: bool = False,
include_error_details_in_llm_output: bool = False,
) -> ToolExecutionOutput:
from .agent import Agent

Expand Down Expand Up @@ -723,12 +736,20 @@ def make_tool_output(
)

if exception is not None:
error_str = "An internal error occurred"

# Only send the actual error message, when it's explictly
# allowed as it may contain sensitive information
if include_error_details_in_llm_output:
message = str(exception).strip()
error_str = f"An internal error occurred: {message}"

return ToolExecutionOutput(
fnc_call=fnc_call.model_copy(),
fnc_call_out=llm.FunctionCallOutput(
name=fnc_call.name,
call_id=fnc_call.call_id,
output="An internal error occurred", # Don't send the actual error message, as it may contain sensitive information # noqa: E501
output=error_str,
is_error=True,
),
agent_task=None,
Expand Down
Loading