Skip to content

Python: serialize empty lists in Agent Framework tools - #14544

Open
fhgffy wants to merge 3 commits into
microsoft:mainfrom
fhgffy:fix/empty-agent-framework-tool-results
Open

fhgffy wants to merge 3 commits into
microsoft:mainfrom
fhgffy:fix/empty-agent-framework-tool-results

Conversation

@fhgffy

@fhgffy fhgffy commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Motivation and Context

A kernel function returning an empty list raises IndexError when called through as_agent_framework_tool(). This is a normal result for tools such as searches with no matches: the wrapper attempts to read results[0] after serializing zero items.

Description

Serialize empty and multi-item lists as JSON arrays, while keeping the existing single-item unwrapping and no-result behavior. Add four regression cases for empty, single-item and multi-item lists, plus None.

Validation on Windows / Python 3.12:

  • The empty-list case fails on the original code; the other three cases pass.
  • tests/unit/functions: 189 passed after the change.
  • Ruff check and format checks pass for both changed files; wheel and sdist builds pass.
  • The test runs the real SK invocation path and substitutes only the optional AIFunction constructor. It does not exercise a live Agent Framework integration.

The full test run stops during collection because the optional Bedrock dependency boto3 is absent. The native mypy check reports 27 diagnostics; all 27 match the unmodified baseline. Neither check is reported as passing.

Contribution Checklist

Copilot AI balanced review requested due to automatic review settings October 5, 2026 07:31
@fhgffy
fhgffy requested a review from a team as a code owner October 5, 2026 07:31
@fhgffy
fhgffy temporarily deployed to github-app-auth October 5, 2026 07:32 — with GitHub Actions Inactive
@fhgffy
fhgffy temporarily deployed to github-app-auth October 5, 2026 07:32 — with GitHub Actions Inactive
@semantic-kernel-automation semantic-kernel-automation Bot added the python Pull requests for the Python Semantic Kernel label Oct 5, 2026

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.

Copilot review overview

🟢 Approval recommended

The focused fix resolves the reported exception while preserving documented behavior with adequate regression coverage.

Review effort: Balanced
Findings: None

What changed in this PR

Fixes Agent Framework tool serialization for kernel functions returning empty lists.

Changes:

  • Serializes empty and multi-item lists as JSON arrays.
  • Preserves single-item unwrapping and None behavior.
  • Adds regression coverage for all relevant list cardinalities.
File Description
python/​semantic_kernel/​functions/​kernel_function.py Handles empty lists without indexing into them.
python/​tests/​unit/​functions/​test_kernel_function_from_method.py Tests empty, single-item, multi-item, and None results.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

Community review. This does not clear the merge gate. I ran the real KernelFunction.as_agent_framework_tool wrapper on upstream main and on this PR head (python 3.13, semantic-kernel python/ from the checkout), with a stub agent_framework module providing AIFunction, and called the returned tool.func(). I did not run the PR's pytest file.

The fix is correct and minimal. On main, a function returning [] makes the wrapper raise IndexError: list index out of range (results is empty and len(results) > 1 is false, so it takes json.dumps(results[0])). With != 1 the empty list is serialized as "[]".

Results per return value (main, then PR head):

function returns main PR head
[] IndexError '[]'
["one"] '"one"' '"one"'
["one", "two"] '["one", "two"]' same
[{"a": 1}] '{"a": 1}' same
[[1, 2]] '[1, 2]' same
[[]] '[]' '[]'
None "The function did not return a result." same

So nothing regresses and the crash is gone.

Not caused by this PR, but the new test pins it and the table shows it: a one-element list is unwrapped while any other length is not. So the agent cannot tell ["one"] from "one", [[1, 2]] from [1, 2], or [[]] from []; with this PR [] and [[]] now produce the same text. If the wrapper's contract is "return the JSON of what the function returned", the unwrap branch is the odd part. I would not expect this PR to change it, but the added (["one"], '"one"') test case makes the current behavior look intentional, so it is worth a sentence from the maintainers on whether it is.

Preserve upstream logging imports and the empty-list tool result regressions.
@fhgffy
fhgffy temporarily deployed to github-app-auth October 21, 2026 16:32 — with GitHub Actions Inactive

This branch was successfully deployed

1 active deployment
github-app-auth — f4902065 Deployed Oct 26, 2026 by eavanvalkenburg via add_label #29450
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Pull requests for the Python Semantic Kernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants