Class OpenAiResponsesStore

java.lang.Object
org.mockserver.llm.OpenAiResponsesStore

public final class OpenAiResponsesStore extends Object
Process-wide server-side state for the OpenAI Responses API (POST /v1/responses). The Responses API is stateful in a way the Chat Completions and Anthropic Messages APIs are not: a client may send only the new turn's input plus a previous_response_id, and the server reconstructs the full conversation from the stored prior turn. This registry models that so agents that chain turns via previous_response_id can run against the mock.

Three behaviours, all opt-in-by-data and back-compatible (a request with no previous_response_id and the default store:true behaves exactly as before, only additionally recording the issued response for later chaining/retrieval):

  • ChainingOpenAiResponsesCodec.decode prepends the stored prior conversation when the inbound request carries a previous_response_id, so conversation matchers and usage inference see the full dialogue.
  • Store flag — honours the store field (default true); a store:false response is neither retrievable nor chainable.
  • RetrievalGET /v1/responses/{id} returns the stored response body verbatim.

Bounded (LRU) so a long-running proxy cannot grow it without limit, thread-safe, and cleared on HttpState.reset() for test isolation. Mirrors the singleton shape of LlmQuotaRegistry.

  • Method Details

    • getInstance

      public static OpenAiResponsesStore getInstance()
    • put

      public void put(OpenAiResponsesStore.StoredResponse record)
    • get

    • reset

      public void reset()
      Clear all stored responses. Called on server reset and for test isolation.
    • priorMessagesFor

      public List<ParsedMessage> priorMessagesFor(String requestBody)
      If requestBody carries a previous_response_id whose response is stored, return the prior conversation's messages so the codec can prepend them to the current turn's messages; otherwise an empty list. Fail-soft: an unparseable body or unknown id yields an empty list (no chaining), never an error.
    • recordIfStored

      public void recordIfStored(String requestBody, ParsedConversation chainedConversation, Completion completion, String encodedBody)
      Record the response just issued for a POST /v1/responses turn so it can be chained (via previous_response_id) or retrieved (via GET /v1/responses/{id}). No-op unless the request opts in to storage (store defaults to true; store:false skips it).

      The stored conversation is the fully-chained decode of this request (which, when the request carried a previous_response_id, already includes the prior turns) plus this turn's assistant output — so a subsequent turn referencing this id reconstructs the entire dialogue. Fail-soft: any parsing error simply skips registration and never affects the served response.

      Parameters:
      chainedConversation - the codec's decode of this request (already chained)
      completion - the assistant completion that was encoded
      encodedBody - the response body that was returned to the client
    • retrievalResponseOrNull

      public HttpResponse retrievalResponseOrNull(HttpRequest request)
      If request is a GET /v1/responses/{id} whose id is stored, return the stored response body as a 200 application/json response; otherwise null so the caller falls through to normal handling. Returning null for an unknown id keeps the mock non-intrusive — a user-configured expectation or the standard 404 path still applies.