feat: add OpenAI-compatible API mock with SDK verification harness - #13
Merged
Conversation
Add a `rest/openai` example: a drop-in mock of the common OpenAI API
endpoints for any "OpenAI compatible" AI harness to run against.
It's a plain rest plugin mock with externalised response files. The one
`POST /v1/chat/completions` endpoint routes to three response files by
matching the request body: streaming (Server-Sent Events) when
`stream: true`, a `get_weather` tool call when the body mentions the
weather, and a plain assistant message otherwise. The requested model is
captured and templated back into each response. Also covers
`GET /v1/models`, `GET /v1/models/{model}`, legacy `POST /v1/completions`
and `POST /v1/embeddings`.
A `harness/` subdir drives the mock with the real `openai` Python SDK and
asserts every endpoint round-trips, so users can verify the mock (and use
it in CI). Verified against openai-python 2.48.0.
Claude-Session: https://claude.ai/code/session_01NGFQaVnKN4wv322agMownn
The three POST /v1/chat/completions resources shared a path but their body
conditions overlapped, so a single request could match more than one. Clients
that stream by default hit this: a "weather" message is both `stream: true`
and contains "weather", matching the streaming and tool-call resources
equally. Imposter then warns ("more than one resource matched") and picks one
arbitrarily — returning the stream instead of the tool call.
Make the conditions disjoint: streaming matches `$.stream == "true"`; the tool
and plain resources additionally require `$.stream != "true"`, and plain
requires the body not contain "weather". Verified on both the native and JVM
engines: all six stream/weather combinations route to exactly one resource with
no match warnings, and the SDK harness still passes.
Also quote `value: "true"` — unquoted it is a YAML boolean, which the string
body matcher never equals (a cross-engine footgun).
Claude-Session: https://claude.ai/code/session_01NGFQaVnKN4wv322agMownn
outofcoffee
marked this pull request as ready for review
July 25, 2026 23:37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
rest/openaiexample: a drop-in mock of the common OpenAI API endpoints, so any "OpenAI compatible" AI harness (chat, tool calling, streaming) can be pointed at Imposter instead of the real API.OpenAI's API is REST + Server-Sent Events (no websockets), so this is a plain
restplugin mock with externalised response files.What it covers
GET /v1/modelsGET /v1/models/{model}POST /v1/chat/completionsstream: true, aget_weathertool call when the body mentions the weather, otherwise a plain assistant messagePOST /v1/completionsPOST /v1/embeddingsThe requested
modelis captured and templated back into every response.Verification harness
rest/openai/harness/drives the mock with the realopenaiPython SDK and asserts every endpoint round-trips (models, chat, tool calls, streaming reassembly, embeddings). Handy as a smoke test or in CI, and it doubles as proof the mock is genuinely OpenAI-compatible. Verified locally againstopenai-python2.48.0 — all checks pass.Notes
Authorizationheader, so any API key works.https://claude.ai/code/session_01NGFQaVnKN4wv322agMownn