Repository navigation
Commit aeb4737
authored
Python: keep empty tool results through the prompt round trip (#14686)
### Motivation and Context
Fixes #14685.
Since #14472, `ChatHistory.add_tool_message("")` keeps an empty tool
result. But that result doesn't survive the XML prompt round trip that
`KernelFunctionFromPrompt` performs on every chat completion call.
`to_element()` renders it as a self-closing `<function_result
id="call_1" />`. When `from_element()` parses that back, it reads
`element.text`, which is `None` for an empty element.
`ChatMessageContent` then stringifies the value, so the model receives
the literal tool result `"None"` instead of an empty one.
### Description
- `FunctionResultContent.from_element` now maps a missing element text
to `""`. Non-empty results are unchanged.
- Added `test_element_round_trip_keeps_result` (empty and non-empty),
which serialises the element to XML and parses it back.
- Added `test_chat_history_prompt_round_trip_keeps_empty_tool_result`,
which reproduces the issue end to end through `to_prompt()` /
`from_rendered_prompt()`.
Before (main `4bb64ee`, macOS arm64, Python 3.12):
```
{'role': 'tool', 'content': 'None', 'tool_call_id': 'call_1'}
```
After:
```
{'role': 'tool', 'content': '', 'tool_call_id': 'call_1'}
```
Tests, run from `python/`:
- `pytest tests/unit/contents`: 421 passed on `main`, 424 passed with
this change.
- With the source change reverted, the two empty-result tests fail: `2
failed, 25 passed` in `test_function_result_content.py`.
- `ruff check` / `ruff format --check` on both files are clean.
This doesn't overlap the open #14375 (the
`from_function_call_content_and_result` factory) or #14480 (the
`add_tool_message` path), and it doesn't touch the JSON `serialize()` /
`restore_chat_history()` path, which already keeps `""`.
### Contribution Checklist
- [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 😄
AI-assisted: yes ([Cana](https://cana.build))1 parent 2a2e9af commit aeb4737
2 files changed
Lines changed: 20 additions & 1 deletion
File tree
- python
- semantic_kernel/contents
- tests/unit/contents
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
119 | | - | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
120 | 122 | | |
121 | 123 | | |
122 | 124 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| 10 | + | |
9 | 11 | | |
10 | 12 | | |
11 | 13 | | |
| |||
123 | 125 | | |
124 | 126 | | |
125 | 127 | | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
126 | 143 | | |
127 | 144 | | |
128 | 145 | | |
| |||
0 commit comments