Skip to content

Conversation

@seratch
Copy link
Member

@seratch seratch commented Dec 12, 2025

This pull request adds seamless support of the newly added compaction typed items in agent convo history: https://platform.openai.com/docs/api-reference/responses/compact

Key changes

The key changes are:

  1. Support compaction type items in history
  2. Add OpenAIResponsesCompactionSession, which is a decorator of any Session implementation (except OpenAIConversationsSession) and runs the compaction API call when the compaction should be done for the context efficiency

How it works

When the compaction is done, all the items except user messages in history data will be compacted into a single encrypted content as below:

[
  {
    "id": "msg_0857699edcad0c8600693bbe84218481a0abc41dd37854ea76",
    "type": "message",
    "status": "completed",
    "content": [
      {
        "type": "input_text",
        "text": "Call fetch_image_data with label \"alpha\". Then explain compaction in 1 sentence."
      }
    ],
    "role": "user"
  },
  {
    "id": "msg_0857699edcad0c8600693bbe8f1a9481a083584278da0af74f",
    "type": "message",
    "status": "completed",
    "content": [
      {
        "type": "input_text",
        "text": "Call fetch_image_data with label \"beta\". Then add a fun fact about space in 1 sentence."
      }
    ],
    "role": "user"
  },
  {
    "id": "msg_0857699edcad0c8600693bbe9c271881a0aaa3a993a337f9bf",
    "type": "message",
    "status": "completed",
    "content": [
      {
        "type": "input_text",
        "text": "Call fetch_image_data with label \"gamma\". Then add a fun fact about oceans in 1 sentence."
      }
    ],
    "role": "user"
  },
  {
    "id": "msg_0857699edcad0c8600693bbec5a47c81a092b11723771d5139",
    "type": "message",
    "status": "completed",
    "content": [
      {
        "type": "input_text",
        "text": "Call fetch_image_data with label \"delta\". Then add a fun fact about volcanoes in 1 sentence."
      }
    ],
    "role": "user"
  },
  {
    "id": "msg_0857699edcad0c8600693bbed5b19481a0961473e7127873b9",
    "type": "message",
    "status": "completed",
    "content": [
      {
        "type": "input_text",
        "text": "Call fetch_image_data with label \"epsilon\". Then add a fun fact about deserts in 1 sentence."
      }
    ],
    "role": "user"
  },
  {
    "id": "cmp_0857699edcad0c8601693bbee5e0f081a0a020c6a7f4305161",
    "type": "compaction",
    "encrypted_content": "gAAAAABpO77lnRqRPYqAvgFZT7x9m8uhUfyDC4C4Xb9__..."
  }
]

At least, "type": "compaction" must be supported in agent loops.

@changeset-bot
Copy link

changeset-bot bot commented Dec 12, 2025

🦋 Changeset detected

Latest commit: c728136

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@openai/agents-openai Patch
@openai/agents-core Patch
@openai/agents Patch
@openai/agents-extensions Patch
@openai/agents-realtime Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@rka-oai
Copy link

rka-oai commented Dec 12, 2025

Thank you for doing this! LGTM. LMK if I can help support responses.compact support in the SDK any further. (Let's still wait for someone who's more familiar than me with Agents SDK to stamp, but looks good from a responses POV.

@seratch seratch force-pushed the oai-responses-compact branch from 62e6c76 to c728136 Compare December 15, 2025 06:07
Comment on lines +56 to +64
/**
* Returns the number of items that should contribute to the compaction threshold.
*
* This function is used to decide when to call `responses.compact`, and it is also used to keep
* an incremental count as new items are appended to the underlying session.
*
* Defaults to counting every stored item except `compaction` items and user messages.
*/
countCompactionItems?: (items: AgentInputItem[]) => number;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the most common way people would want to compact is based on the token size of messages not necessarily the amount of messages. That is how I think Codex does it for example. Right now my understanding is the way that you can do that is by changing the countCompactionItems to count tokens instead and then set the compactionThreshold as a token number. Right?

Is there a way we can make that more seamless?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dkundel-openai This is a good point.

A challenge is that our APIs do not provide a simple way to get the accumulated token consumption for an agent turn. Therefore, I believe compactionThreshold + countCompactionItems should be one reasonable way to decide to run compaction.
I still think we can use this simple method as the default built-in one, but I agree we should redesign this hook to be a more generic one like shouldCompact(items): boolean. With that, developers can do anything in the method. What do yo think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify, I am fine with any names for the hook apart from "shouldCompact"

responseId: string | undefined;
};

export interface OpenAIResponsesCompactionAwareSession extends Session {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this type of Session extends the regular session can't we just call compaction inside the addItem part of Session rather than introducing a new subtype? My understanding was that the point of Session was that it would decide what to store and how to store it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you use responses.compact API with an external session store, your code has to clear all items (at least all non-user-message items) associated with the session ID first, then re-insert everything (N user messages + 1 compaction item). Because of that, it doesn’t fit well with addItems / getItems method customization.

That said, it's still feasible to do above in addItems method. Another benefit of the current design is that you can use this new subclass as a decorator-design-pattern style wrapper around your existing session store. This enables developers to reuse this single logic without having similar logic within their code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants