Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Python: [Python] structured_outputs_transform reuses ChatHistory across calls (prompt pollution)

Open Beginner friendly
#14,483 2 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 2 days

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
ai

Research direction

Read semantic_kernel/agents/orchestration/tools.py, focusing on structured_outputs_transform and its output_transform closure. Use the provided mocked repro to check the chat-history length across repeated calls; done means each invocation has only the system message and current message, producing lengths [2, 2, 2].

Written by the indexing model from the issue text.

Description

python triage

Description

structured_outputs_transform creates a single ChatHistory in the factory and closes over it. Each output_transform call add_messages into that same history, so prior orchestration outputs leak into later structured-output prompts and the history grows without bound (lengths 2→3→4…).

Environment

  • semantic-kernel==1.44.1 (Python)
  • Python 3.13
  • Repro uses a mocked chat service (no API keys)

Minimal repro

import asyncio
from typing import Any
from pydantic import BaseModel, PrivateAttr
from semantic_kernel.agents.orchestration.tools import structured_outputs_transform
from semantic_kernel.connectors.ai.chat_completion_client_base import ChatCompletionClientBase
from semantic_kernel.connectors.ai.prompt_execution_settings import PromptExecutionSettings
from semantic_kernel.contents import ChatMessageContent
from semantic_kernel.contents.utils.author_role import AuthorRole

class Out(BaseModel):
    answer: str

class FakeSettings(PromptExecutionSettings):
    response_format: Any = None

class FakeService(ChatCompletionClientBase):
    _calls: list = PrivateAttr(default_factory=list)
    def __init__(self) -> None:
        super().__init__(service_id="fake", ai_model_id="fake")
    def get_prompt_execution_settings_class(self):
        return FakeSettings
    async def get_chat_message_contents(self, chat_history, settings, **kwargs):
        self._calls.append(len(chat_history.messages))
        return [ChatMessageContent(role=AuthorRole.ASSISTANT, content='{"answer":"x"}')]
    async def get_chat_message_content(self, chat_history, settings, **kwargs):
        self._calls.append(len(chat_history.messages))
        return ChatMessageContent(role=AuthorRole.ASSISTANT, content='{"answer":"x"}')

async def main():
    svc = FakeService()
    transform = structured_outputs_transform(Out, svc)
    await transform(ChatMessageContent(role=AuthorRole.USER, content="first"))
    await transform(ChatMessageContent(role=AuthorRole.USER, content="second"))
    await transform(ChatMessageContent(role=AuthorRole.USER, content="third"))
    print(svc._calls)  # ACTUAL: [2, 3, 4]  EXPECTED: [2, 2, 2]

asyncio.run(main())

Expected

Each transform invocation uses a fresh history (system + current message only), so independent orchestration steps do not pollute each other.

Actual

Shared history grows across calls; prior outputs leak into later structured-output prompts.

Root cause (pointer)

semantic_kernel/agents/orchestration/tools.py — structured_outputs_transform: chat_history = ChatHistory(...) created once in the factory and mutated inside output_transform.

Suggested fix direction

Construct a fresh ChatHistory (with the system message) inside output_transform on every call.

Dominant language
C#
Stars
28.6k
Forks
4.8k
Avg merge
13h 24m
Merged PRs (30d)
11

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from microsoft/semantic-kernel

All issues in microsoft/semantic-kernel

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.