Skip to content

Add tool/function call support to webhook conversation responses - #35

Merged
EuleMitKeule merged 6 commits into
masterfrom
copilot/add-tool-function-support
May 2, 2026
Merged

Add tool/function call support to webhook conversation responses#35
EuleMitKeule merged 6 commits into
masterfrom
copilot/add-tool-function-support

Conversation

Copilot AI commented Mar 2, 2026

Copy link
Copy Markdown
Contributor
  • Fix falsey tool results being dropped — use is not None check (entity.py:198)
  • Allow _send_payload to accept responses with only tool_calls and no text field (entity.py:123-124)
  • Raise explicit HomeAssistantError when MAX_TOOL_ITERATIONS exceeded (conversation.py:141-161)
  • Restore device_info and exposed_entities on follow-up tool iteration payloads (conversation.py:164-169)
  • Fix mypy: annotate reply as Any in ai_task.py
Original prompt

This section details on the original issue you should resolve

<issue_title>Add tool / function call support to webhook-conversation responses</issue_title>
<issue_description>Hello,

I would like to request support for tool / function execution results in the webhook-conversation integration.

At the moment, when using the webhook integration (for example with n8n), the webhook response contains only the natural language text reply from the assistant. If the assistant decides to execute a Home Assistant command (e.g. turning on a light), the tool execution itself is not returned in the webhook payload.

For reference, some conversation integrations (eg. Ollama integration) support returning both:

the assistant’s text response, and

a structured representation of the executed tool/function (tool name, arguments, target entity).

Having access to the executed tool information in the webhook response would allow external systems to:

know which device or entity was acted upon,

display the executed command in a UI (for example on an Android tablet with View Assist integration),

implement logic based on the actual action taken, not only the text response,

avoid the need for intermediary mechanisms (such as an MCP server) solely to expose tool execution data.

Thank you for your work on this project. I’m happy to provide example payloads or clarify the use case further if needed.</issue_description>

<agent_instructions>I don't think this needs any changes to the config flow. When the response is handled by the integration, it can probably use the function/tool calls if present to set either a custom field in the conversation context/data or there might already be a field for this purpose. You should do some research on how the ollama core integration the user mentioned handles this.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

- Parse tool_calls from webhook responses (both streaming and non-streaming)
- Add tool execution loop (up to MAX_TOOL_ITERATIONS) in conversation handler
- Include tool call info (tool_calls, tool_call_id, tool_name) in messages sent to webhook
- Update models with WebhookConversationToolCall type and optional fields
- Update AI task entity to handle new _send_payload return type

Co-authored-by: EuleMitKeule <47421406+EuleMitKeule@users.noreply.github.com>
Copilot AI changed the title [WIP] Add tool and function call support to webhook responses Add tool/function call support to webhook conversation responses Mar 2, 2026
@EuleMitKeule
EuleMitKeule marked this pull request as ready for review May 2, 2026 20:55
@EuleMitKeule
EuleMitKeule requested a review from Copilot May 2, 2026 20:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds webhook tool/function-call round-trip support to the conversation integration so external webhook backends can return structured tool calls, receive tool results back in subsequent requests, and more closely match Home Assistant’s native LLM tool-calling flow.

Changes:

  • Added tool-call models and extended webhook message serialization to include assistant tool calls plus tool result metadata.
  • Updated conversation handling to parse webhook tool_calls, loop over tool execution rounds, and support streamed tool_calls chunks.
  • Adjusted shared webhook send helpers and AI task handling for the new non-streaming/streaming response shapes.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
custom_components/webhook_conversation/models.py Adds TypedDicts/fields for tool calls and tool-result metadata in webhook messages.
custom_components/webhook_conversation/entity.py Changes webhook send helpers to return full response objects and serializes tool calls/tool results into outbound payloads.
custom_components/webhook_conversation/conversation.py Implements multi-iteration tool execution flow and streamed/non-streamed tool-call parsing for conversations.
custom_components/webhook_conversation/ai_task.py Adapts AI task response handling to the updated webhook helper return types.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread custom_components/webhook_conversation/entity.py Outdated
Comment thread custom_components/webhook_conversation/conversation.py
Comment thread custom_components/webhook_conversation/conversation.py Outdated
Comment thread custom_components/webhook_conversation/entity.py Outdated
@EuleMitKeule

Copy link
Copy Markdown
Owner

@copilot fix all the review comments and the mypy issues

…eration error, follow-up payload fields, mypy type annotation

Agent-Logs-Url: https://github.com/EuleMitKeule/webhook-conversation/sessions/7f6402e2-836c-4e52-841f-9e7505940d4d

Co-authored-by: EuleMitKeule <47421406+EuleMitKeule@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread custom_components/webhook_conversation/conversation.py Outdated
Comment thread custom_components/webhook_conversation/entity.py Outdated
@EuleMitKeule

Copy link
Copy Markdown
Owner

@copilot resolve the merge conflicts and review comments

… acceptance to conversation entity

Agent-Logs-Url: https://github.com/EuleMitKeule/webhook-conversation/sessions/a501f3d3-f7a4-41b9-83e4-456de77d65fe

Co-authored-by: EuleMitKeule <47421406+EuleMitKeule@users.noreply.github.com>

Copilot AI commented May 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts and review comments

Resolved in ba9d225:

  • _build_payload content slice — Added an include_last: bool = False parameter. Follow-up iterations now call _build_payload(chat_log, include_last=True) so ToolResultContent is included in the messages array sent to the webhook.
  • _send_payload tool-only scope — Added allow_tool_only: bool = False. The conversation entity passes allow_tool_only=True, so it accepts tool-call-only responses. The AI task entity keeps the default False, maintaining strict output-field validation.

@EuleMitKeule

Copy link
Copy Markdown
Owner

@copilot resolve the merge conflicts in this pull request, check ruff and mypy

…nflict and mypy

Co-authored-by: EuleMitKeule <47421406+EuleMitKeule@users.noreply.github.com>
…r_name in follow-up payloads

Agent-Logs-Url: https://github.com/EuleMitKeule/webhook-conversation/sessions/d03bf29a-ee84-448b-99fa-795654baed41

Co-authored-by: EuleMitKeule <47421406+EuleMitKeule@users.noreply.github.com>

Copilot AI commented May 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request, check ruff and mypy

Resolved in fa83ba3:

  • Merge conflicts — Merged master (commits 78982aa, dafc382, aa955a8) into the branch. The only conflict was in entity.py's streaming handler; resolved by keeping raw chunk yielding for tool call support while also incorporating master's n8n fix: handle "error" type chunks and don't break on "end" to support multi-step n8n workflows.
  • user_name restored — Added to follow-up iteration payloads to match the initial request.
  • for-else structure fixed — The raise HomeAssistantError(...) is correctly in the else clause of the for loop, not inside the loop body.
  • ruff — All checks passed.
  • mypy — Fixed no-redef error in ai_task.py by hoisting reply: Any annotation before the if/else block. No issues found.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • releases.astral.sh
    • Triggering command: /home/REDACTED/.local/bin/uv uv sync --dev (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@EuleMitKeule
EuleMitKeule merged commit 67e870f into master May 2, 2026
5 checks passed
@EuleMitKeule

Copy link
Copy Markdown
Owner

🎉 This PR is included in version 1.12.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add tool / function call support to webhook-conversation responses

3 participants