Bug: server-side compaction is not emitted on Responses tool-call-only turns
メンテナーはふだん 1 日以内に返信
@nightcityblade がすでに取り組んでいます。
2026年5月2日 から。
評価
調査の方向性
まず、提供されたツール呼び出しループと context_management 設定を使用し、responses.create と responses.parse で報告されたシーケンスを再現します。SDK が返す出力項目を、基盤となる Responses API の動作と比較します。Python ライブラリがツール呼び出しのみのターンで compaction items を破棄するかどうかを判定し、破棄する場合は修正後の動作に対する回帰テストを定義すれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Confirm this is an issue with the Python library and not an underlying OpenAI API
- This is an issue with the Python library
Describe the bug
Describe the bug
I am using the Responses API through openai-python with:
context_management=[{"type": "compaction", "compact_threshold": 1000}]store=Falsegpt-5.4
I see different behavior depending on the output type of the turn:
-
For a long plain request,
response.outputcontains:messagecompaction
-
For a long request that returns only
function_call,response.outputcontains only:function_call
-
If I continue the tool loop and the next turn is again only
function_call, there is still nocompaction. -
Only when the model finally returns an assistant
messagedoesresponse.outputinclude:messagecompaction
This means that in tool-heavy agent loops with several consecutive tool-call turns, context can continue growing without any emitted compaction item, and the loop can eventually hit
context_length_exceeded before compaction appears.
I reproduced this through openai-python using both client.responses.create(...) and client.responses.parse(...).
If this is expected backend/API behavior rather than a Python SDK issue, please let me know and I can move the report.
To Reproduce
- Create a long input that is clearly above the compaction threshold.
- Enable server-side compaction with a very low threshold, for example:
context_management=[{"type": "compaction", "compact_threshold": 1000}] - Force the first turn to produce a
function_call. - Send the corresponding
function_call_output. - If the model produces another
function_call, observe that there is still nocompactionitem inresponse.output. - Observe that
compactiononly appears once the model finally emits an assistantmessage.
Observed output from my repro:
R1 input_tokens 5084
R1 output_types ['function_call']
R2 input_tokens 5119
R2 output_types ['function_call']
R3 input_tokens 5154
R3 output_types ['message', 'compaction']
For comparison, a plain long request with the same threshold produces compaction immediately:
CREATE input_tokens 5007
CREATE output_types ['message', 'compaction']
To Reproduce
import asyncio
from openai import AsyncOpenAI
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
AZURE_ENDPOINT = "https://<your-resource>.openai.azure.com/openai/v1/"
MODEL = "gpt-5.4"
async def main():
cred = DefaultAzureCredential()
token_provider = get_bearer_token_provider(
cred,
"https://cognitiveservices.azure.com/.default"
)
client = AsyncOpenAI(
base_url=AZURE_ENDPOINT,
api_key=token_provider,
)
long_text = "context " * 5000
tools = [{
"type": "function",
"name": "echo_tool",
"description": "Echo a short string",
"parameters": {
"type": "object",
"properties": {
"text": {"type": "string"}
},
"required": ["text"],
"additionalProperties": False
}
}]
cm = [{"type": "compaction", "compact_threshold": 1000}]
conversation = [{
"role": "user",
"content": (
long_text +
"\n\nCall echo_tool twice in sequence. "
"First with text=first. After I return the tool result, "
"call echo_tool again with text=second. "
"Only after the second tool result, answer DONE."
)
}]
for step in range(1, 5):
response = await client.responses.create(
model=MODEL,
input=conversation,
tools=tools,
store=False,
context_management=cm,
)
print(f"R{step} input_tokens:", response.usage.input_tokens)
print(f"R{step} output_types:", [getattr(i, 'type', None) for i in response.output])
conversation.extend(response.output)
function_calls = [i for i in response.output if getattr(i, "type", None) == "function_call"]
if function_calls:
for idx, fc in enumerate(function_calls, start=1):
conversation.append({
"type": "function_call_output",
"call_id": fc.call_id,
"output": f"tool-result-{step}-{idx}",
})
else:
break
await client.close()
await cred.close()
asyncio.run(main())
Code snippets
OS
Windows
Python version
3.11.5
Library version
openai 2.21.0
- 主要言語
- Python
- スター
- 31.8k
- フォーク
- 7.3k
- 平均マージ
- 1日 3時間
- マージ済み PR(30日)
- 131
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
openai/openai-python のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
openai/openai-python#4022 · コメント 19 件 ·
メンテナーはふだん 1 日以内に返信
-
fix(auth): SubjectTokenProviderError drops response and duplicates error message in workload identity providers対応中かも @mohmedmm が 9 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
openai/openai-python#4017 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
Querystring drops explicit empty-string scalar values対応中かも @sylvesterkaczmarek が 31 日前に担当しました。 オープンsdk-breaking-change v4
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
openai/openai-python#3837 ·
メンテナーはふだん 1 日以内に返信
-
Define + export `ServiceTiers` string literal対応中かも @SparshGarg999 が 58 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
openai/openai-python#3556 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
Empty OPENAI_BASE_URL prevents fallback to default API endpoint対応中かも @Sehastrajit-S が 24 日前に担当しました。 オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
openai/openai-python#2927 · コメント 6 件 ·
メンテナーはふだん 1 日以内に返信
openai/openai-python の issue をすべて見る
似ている issue
-
needs triage
難易度 2/5 1〜3時間 初心者へのやさしさ 83/100
darnitdevorg/darnit#587 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
メンテナーはふだん 1 日以内に返信
-
accessibility good first issue
難易度 1/5 1〜3時間 初心者へのやさしさ 92/100
メンテナーはふだん 1 日以内に返信
-
llm translation
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
bug bug-hunt
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
メンテナーはふだん 1 日以内に返信