… in ChatHistory (microsoft#12753)
### Motivation and Context
The `add_tool_message` method of `ChatHistory` accepts string content
without requiring a `tool_call_id` parameter. This design is flawed from
an API design perspective. It created tool messages that:
1. Violated chat completion protocols: most LLM APIs (OpenAI, etc.)
require tool messages to have a `tool_call_id` that references a
previous function call
2. Broke conversation flow: tool messages should always be responses to
specific tool calls, maintaining the call-response relationship
3. Created malformed message sequences: messages without proper tool
call IDs would fail when sent to language models
<!-- Thank you for your contribution to the semantic-kernel repo!
Please help reviewers and future users, providing the following
information:
1. Why is this change required?
2. What problem does it solve?
3. What scenario does it contribute to?
4. If it fixes an open issue, please link to the issue here.
-->
### Description
This PR modifies the `add_tool_message` string overload to require a
`tool_call_id` parameter, which makes sure we have proper tool call
protocol compliance.
1. The string overload now validates that `tool_call_id` is provided and
raises a clear error if missing
2. Tool messages now create `FunctionResultContent` objects with both
`id` and `call_id` set to the provided `tool_call_id`
3. Added support for an optional `function_name` parameter for better
bookkeeping
4. Provides informative error messages explaining why `tool_call_id` is
required
- Closes microsoft#12744
Before:
```python
# This would create an invalid tool message without tool_call_id
# when the `.to_dict()` method is called on `ChatMessageContent`
chat_history.add_tool_message("Function result") # Creates broken message and losing pairing to the corresponding `FunctionCallContent`.
```
After:
```python
# Now requires tool_call_id for proper protocol compliance
chat_history.add_tool_message("Function result") # raises clear error due to missing `tool_call_id`
chat_history.add_tool_message("Function result", tool_call_id="call_123") # works correctly
# Optional function name for better bookkeeping
chat_history.add_tool_message("Function result", tool_call_id="call_123", function_name="get_weather") # works as well
```
<!-- Describe your changes, the overall approach, the underlying design.
These notes will help understanding how your code works. Thanks! -->
### Contribution Checklist
<!-- Before submitting this PR, please make sure: -->
- [X] The code builds clean without any errors or warnings
- [X] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [X] All unit tests pass, and I have added new tests where possible
- [X] I didn't break anyone 😄
Motivation and Context
The
add_tool_messagemethod ofChatHistoryaccepts string content without requiring atool_call_idparameter. This design is flawed from an API design perspective. It created tool messages that:tool_call_idthat references a previous function callDescription
This PR modifies the
add_tool_messagestring overload to require atool_call_idparameter, which makes sure we have proper tool call protocol compliance.tool_call_idis provided and raises a clear error if missingFunctionResultContentobjects with bothidandcall_idset to the providedtool_call_idfunction_nameparameter for better bookkeepingtool_call_idis requiredBefore:
After:
Contribution Checklist