Repository navigation
Releases: Prism-Shadow/model-message-stream-protocol
Release list
v0.5.6
MMSP 0.5.6 adds Kimi K3.1 Pro (#294), turns thinking off for ThinkingLevel.NONE on more Claude models (#293), types every error MMSP raises (#288, #290), and makes the history, concurrent calls and interruption behave the same in every client (#291, #292).
Highlights
- Kimi K3.1 Pro:
kimi-k3.1-proandkimi-k3.1-pro-highspeedon Moonshot,moonshotai/kimi-k3.1-proon OpenRouter andkimi-k3.1-proon TokenDance, throughmoonshot-officialin both packages. On the K3 series,kimi-k3included,ThinkingLevel.NONEsendsreasoning_effort: "none", which turns thinking off, andPromptCaching.ENHANCEsendsprompt_cache_optionswith a 1h TTL (#294). - Claude thinking level none:
anthropic-officialturns thinking off forThinkingLevel.NONEon Claude Sonnet 4.6, Opus 4.8, Sonnet 5 and Opus 5, and runs Fable 5 at its lowest effort (#293). - Typed errors:
RoutingError,InvalidMessageError,UnsupportedContentError,UnknownEventError,ProviderStreamErrorandConcurrentCallError, each a subclass of the built-in it replaces, so existingexcept ValueError/catchcode keeps working. Every bare raise in both packages uses them, and the MMSP server relays every MMSP error with its fields (#288, #290). - Interruption: an abort, a closed generator or a left loop closes the provider's request at once in every client of both packages, and an interrupted turn is neither recorded nor traced. An aborted TypeScript stream throws the signal's reason (#292).
- Usage: a token count of 0 stays 0, and a count the provider leaves out is null (#279).
- Gateways: the Chat Completions client records a gateway's encrypted reasoning under the shared fidelity keys and still reads the blocks 0.5.5 recorded (#287); TokenDance's DeepSeek V4.1 Flash moves to
openai-chat(#286). - Docs, site and playground: the configuration page states what each client sends, ignores or raises on for each
UniConfigkey (#289). The site's top bar becomes Overview, Docs, RFC, Model Index, Model Status and Changelog; the Model Index shows latency and throughput, the Model Status page pages through a year of history, and the RFC pages move to/rfcs/with search (#282, #283, #284, #285). The playground's reply head names the model and the time (#281).
Breaking
get_history() and set_history() copy the history deeply, so editing a message they return or receive no longer changes the recorded history; change it through set_history() / setHistory(). A second streaming_response_stateful while one is in flight on the same client raises ConcurrentCallError: read the first stream to its stop event, abort it or close it first, or give each conversation its own client. A message with nothing a client can send, empty or thinking alone, raises InvalidMessageError naming its message_index / messageIndex, where it was dropped or sent empty (#291).
Install
pip install mmsp==0.5.6
npm install @prismshadow/mmsp@0.5.6v0.5.5
MMSP 0.5.5 adds MiniMax-M3.1-Flash (#260) and Vertex AI, Bedrock and TokenDance rows in the registry (#261), puts a live model catalog and a status page on the site (#259, #263), writes the rules MMSP keeps down as RFCs (#265), and makes the Anthropic clients work on anthropic SDK 2.x (#270).
Highlights
- MiniMax-M3.1-Flash:
MiniMax-M3.1-Flashon MiniMax andminimax/minimax-m3.1-flash:freeon OpenRouter, in both packages;ThinkingLevel.NONEmaps toreasoning.effort: "low", the lowest the model takes. - Registry: Google Vertex AI (Gemini 4 Argon, 3.8 Flash, 3.7 Flash, image, TTS and embedding through
google-genai), Amazon Bedrock (the Global inference profiles of Claude throughanthropic-official) and TokenDance (DeepSeek, MiniMax, Kimi, GLM and Qwen); OpenRouter and SiliconFlow rows refreshed with prices. - Model catalog and status page:
/models/lists every registry entry with modalities, context and USD/CNY prices; each row opens a dialog with complete TypeScript and Python programs and anmmsp-server.json./status/shows the daily probe (deepseek-flashon DeepSeek,gemini-3.8-flashon Vertex AI,deepseek-v4.1-flashon TokenDance): status, TTFT, TPS, 90 days of history and the month's probe cost, with Run a check now./models.jsonserves the catalog to agents. - RFCs: MMSP-RFC-0001 defines the process; MMSP-RFC-0002 to MMSP-RFC-0012 state the rules, among them that every thinking level is usable, the final metadata always exists, and thinking survives the round trip. The site renders them under Design.
IncompleteStreamError: a provider stream that ends without its usage or finish reason raises it in place of thestopevent, in both packages and through the MMSP server (#272).- Fixes: the Anthropic clients send only their own key on SDK 0.87, 1.x and 2.x (#270); OpenRouter's encrypted
reasoning_detailsreplay as received (#273); a Claude replay omits a thinking item without a signature (#268); GLM and Kimi K2 extension keys reach the API from TypeScript (#267); the vLLM adapter sendschat_template_kwargsfrom Python (#266);tts_configrejections raiseUnsupportedParameterError(#269). - Dependencies: TypeScript requires
openai^6.42.0and@anthropic-ai/sdk^0.91.1, Pythonopenai>=2.34.0; the Dependabot alerts of both lockfiles are cleared (#274, #275).
Breaking
openai-chat-vllm-adapter reads VLLM_API_KEY and VLLM_BASE_URL and defaults to http://127.0.0.1:8000/v1; it no longer reads OPENAI_API_KEY or OPENAI_BASE_URL, and without a key it calls its server keyless. Set VLLM_BASE_URL or pass the base URL for a server elsewhere. A client on the OpenAI SDK handed another endpoint no longer sends OPENAI_ORG_ID, OPENAI_PROJECT_ID, OPENAI_ADMIN_KEY, OPENAI_WEBHOOK_SECRET or the headers of OPENAI_CUSTOM_HEADERS; pass such a header through default_headers / defaultHeaders (#276).
Install
pip install mmsp==0.5.5
npm install @prismshadow/mmsp@0.5.5v0.5.4
MMSP 0.5.4 gives every client one environment-key rule and exports it for hosts as @prismshadow/mmsp/credentials and mmsp.credentials (#258). It also adds GPT-6 Luna (#257).
Highlights
- One environment-key rule: a key passed in is always used. Without one, a client reads its
<P>_API_KEYonly when given no base URL, or when given its own default endpoint, such ashttps://api.deepseek.comfordeepseek-official. Any other base URL passed without a key raisesApiKeyRequiredErrorbefore any request. The message names both fixes: pass the key, or drop the base URL and set<P>_API_KEY, plus<P>_BASE_URLfor an endpoint other than the default. Themmspclient still calls an open server keyless. credentialsmodule:CLIENT_CREDENTIALS,environmentCredential(clientType, baseUrl)androutedClientType(model, clientType)tell a host what a client will do without building one. The TypeScript subpath imports nothing and fits a browser bundle. The clients andAutoLLMClientresolve through the same table.- GPT-6 Luna:
gpt-6-lunaon OpenAI andopenai/gpt-6-lunaon OpenRouter, withThinkingLevel.NONEkept asreasoning.effort: "none". - CI: model tests run for the clients a change affects, and publication waits for the full Python and TypeScript suites (#255). The README lists Vertex AI support for Gemini 4 Argon (#256).
Breaking
deepseek-official, zai-official, moonshot-official, minimax-official and google-official no longer send their environment key to a base_url other than their default endpoint. Pass api_key with such a URL, or drop base_url and set <P>_BASE_URL beside <P>_API_KEY. Code that matched the old refusal text should catch ApiKeyRequiredError.
Install
pip install mmsp==0.5.4
npm install @prismshadow/mmsp@0.5.4v0.5.3
MMSP 0.5.3 adds Gemini 4 Argon support in Python and TypeScript (#253).
Highlights
- Gemini 4 Argon: use
gemini-4-argonwith the defaultgoogle-officialclient or explicitly selectgoogle-genaifor generateContent. - Thinking levels:
nonemaps tolow;low,medium, andhighkeep their values;xhighandmaxmap tohigh. Omitting the level preserves Google's defaultmedium. - Model registry: includes the shared 1,048,576-token context window, text/image/video/audio input, text output, and standard list prices of $4 input, $20 output/thinking, and $0.20 cached input per million tokens. Introductory discounts are not included in registry prices.
- Documentation: official API snapshots and English/Chinese model and release documentation are included.
Synchronous streaming supports up to 65,536 output tokens, including thinking. Longer outputs require Google's stored background execution, which is outside MMSP's stateless streaming interface. Argon supports implicit caching only.
Install
pip install mmsp==0.5.3
npm install @prismshadow/mmsp@0.5.3v0.5.2
MMSP 0.5.2 adds an MMSP server that serves a table of models over HTTP, the mmsp client that calls it, and a server page in the playground. It also supports Claude Haiku 5.5 and gives the official Gemini client its vendor's name, google-official.
Highlights
- MMSP server.
- Start:
python -m mmsp.integration.server --config FILEornpm run server -- --config FILE. - What it serves: the models of one JSON table. Each row is
model_id,api_key,server_model_id, plus an optionalbase_urlandclient_type. - Endpoints:
GET /v1/modelsin OpenAI's list shape, andPOST /v1/stream, which answers with MMSP streams over server-sent events. - Keys: clients authenticate with the bearer keys in
api_keys. An empty list makes an open server. - Environment variables:
$VARcells are read from the environment (#247).
- Start:
mmspclient.client_type="mmsp"calls an MMSP server and passes its stream through unchanged. An error the server reports comes back as the newUpstreamError(#247).- Server page in the playground.
/server/saves the table to a config file, starts and stops the server, and charts requests, success rate, p50 / p90 latency, tokens out and TPS over 15 minutes to 30 days. - Claude Haiku 5.5.
anthropic-officialservesclaude-haiku-5-5.- Parameters:
thinking_level="none"runs at low effort. As on the rest of the 5.5 family, a forcedtool_choiceandfast_moderaiseUnsupportedParameterError. - Registry: lists it at $0.10 / $0.50 per million tokens (the price for prompts up to 100K tokens), plus OpenRouter's
anthropic/claude-haiku-5.5. Sonnet 5.5 cache reads drop to $0.10 (#249).
- Parameters:
google-official. The official Gemini client now takes its vendor's name, likeopenai-officialandanthropic-official.gemini-officialstill works as an alias (#248).- Playground chat. A message sent to another model, client type or endpoint starts a new conversation under a divider, so the page shows what the model actually sees (#250).
Compatibility
- Code that imported the Gemini client by module path now imports
google_official/GoogleOfficialClientinstead ofgemini_official/GeminiOfficialClient.client_type="gemini-official"keeps working. - In the playground's
/api/chat, a session keeps its history when the client options change (a new key, for example)./api/clearends it.
Install
pip install mmsp==0.5.2
npm install @prismshadow/mmsp@0.5.2Full detail: changelog/0.5.2/README.md.
v0.5.1
MMSP 0.5.1 makes google-genai the compatible client for Google's generateContent, with Vertex AI naming it, and moves the Qwen entries to Qwen3.8 27B. Vertex AI users change one argument; the compatibility notes below say which.
Highlights
google-genaiis the compatible client for generateContent, as the Google GenAI SDK speaks it, named after its wire protocol like the other compatible clients. It serves Vertex AI (the service-account JSON key as the API key), the Gemini API, and gateways that proxy generateContent.gemini-generate-contentstill names it, as an alias (#244).- Vertex AI is no longer part of
gemini-official.gemini-officialspeaks the Gemini API's Interactions endpoint only, and refuses a service-account key with an error that namesgoogle-genai, so a private key never travels as an API key (#244). google-genaikeeps its key with its endpoint. Like the other compatible clients, it readsGEMINI_API_KEYfrom the environment only together withGEMINI_BASE_URLor Google's own endpoint; abase_urlpassed in needs anapi_keywith it (#244).- Qwen3.8 27B. The registry lists
qwen/qwen3.8-27bon OpenRouter andQwen/Qwen3.8-27Bon SiliconFlow in place of Qwen3.6 35B A3B (#245). - Site and project. A pure blue brand color across the site, the mark and the images; a Design philosophy page; logo files in
.github/images/; the publish workflow skips a version that is already published (#234, #237, #238, #240, #242).
Compatibility
- With a Vertex AI service-account key, pass
client_type="google-genai"(clientType: "google-genai").gemini-official, and agemini-model id with no client type, now raise on one. google-genaiwith abase_urlneeds anapi_keypassed in as well.- Code that imported the client by module path imports
google_genai/GoogleGenaiClientin place ofgemini_generate_content/GeminiGenerateContentClient.
Install
pip install mmsp==0.5.1
npm install @prismshadow/mmsp@0.5.1Full detail: changelog/0.5.1/README.md.
v0.5.0
MMSP 0.5.0 is AgentHub under its new name, the Model Message Stream Protocol, and the first release on streaming protocol v2. It is a breaking release: the packages, the module, the client types and the stream shape all change, and the compatibility notes below say what to update.
Highlights
- AgentHub is now MMSP. The packages are
mmspon PyPI and@prismshadow/mmspon npm, the module ismmsp, the error base classMMSPError, and the environment variablesMMSP_DEBUGandMMSP_CACHE_DIR(#223). - Streaming protocol v2. A stream is
deltaevents closed by exactly onestopevent, and every content item streams as.deltafragments closed by its.doneitem, so a consumer never guesses whether a response or an item has finished. Content items recorded before 0.5.0 are still accepted, converted to the.donetypes, until 0.6.0 (#223). - Clients are named by type. An official client per vendor (
openai-official,anthropic-official,gemini-official,zai-official,moonshot-official,deepseek-official,minimax-official) and a compatible client per protocol (openai-responses,openai-chat,openai-chat-vllm-adapter,openai-embedding,ant-messages,gemini-generate-content). Without aclient_type, the family a model id begins with names its official client; any other id asks for one (#228). - Gemini on the Interactions API. Gemini text, image and TTS models move to the Interactions API on google-genai / @google/genai 2.x, and a Vertex AI service-account key goes through generateContent (#223).
- New models. Claude Opus 5.5, Sonnet 5.5 and Fable 5.1, GPT-6.1 Sol, DeepSeek Flash and Gemini 3.8 TTS, with two-speaker scripts sent to 3.8 TTS as per-turn speech metadata (#229).
- Credentials stay with their endpoint.
OPENAI_API_KEYandANTHROPIC_API_KEYgo only to the endpoint the environment names, and abase_urlwithout anapi_keyraises (#224). - A new playground, tracer and site. The playground sets the client type and base URL with the model and shows every stream item as it arrives; the tracer reads traces as aligned lists with a round rail; the documentation lives at https://mmsp.penguin.ooo (#226, #227, #229, #231).
Compatibility
- Install
mmsp/@prismshadow/mmspin place ofagenthub-python/@prismshadow/agenthub, and importmmsp. - Read items by their
.donetypes (text.done,thinking.done,tool_call.done…) and treat.deltafragments as live progress. - Replace the model-named client types with the new ones (for example
gpt-6→openai-official,claude-5→anthropic-official); a gateway model id such asmoonshotai/kimi-k3now needs itsclient_type.
Install
pip install mmsp==0.5.0
npm install @prismshadow/mmsp@0.5.0Full detail: changelog/0.5.0/README.md.
v0.4.15
AgentHub 0.4.15 keeps every function call of a parallel tool-call turn on the Responses clients, so a gateway that opens every call before closing any of them no longer costs the whole turn.
Highlights
- The Responses clients keep every call of an interleaved parallel tool-call turn.
openai_responses,gpt6,deepseek_v4andminimax_m3accumulated a response's function calls in a single slot, so a gateway that streamsadded(A),added(B),done(A),done(B)— Console Go does — lost every call but the last. The loss surfaced one request later: the assistant message replayed only the surviving call while both tool results were replayed, and the provider rejected the orphan with400 … No function call found for function_call_output, discarding the turn. Every harness turn that ran two tools in parallel hit it.partial_tool_callitems now carry an optionalitem_idthat the stateless Responses transforms fill from the output item id, the streaming loop keys its open calls by it, and a server that sends no ids keeps the previous single-call behaviour (#218, by @paskaa).
Both the Python and TypeScript implementations changed the same way; the tool-call-arguments suites cover the interleaved order on every Responses client.
Install
pip install agenthub-python==0.4.15
npm install @prismshadow/agenthub@0.4.15Full detail: changelog/0.4.15/README.md.
v0.4.14
AgentHub 0.4.14 sends a text-only tool result as a plain string on every Responses client the SDK ships, so a strictly validating DeepSeek Responses endpoint no longer rejects every request after a tool call.
Highlights
deepseek_v4andgpt6send a text-only tool result as a plain string. The two first-party Responses clients still wrapped every tool result in a content-part list, the multimodal form. A strictly validating DeepSeek Responses endpoint answers that list with400 {"code":"invalid_json"}on every request that replays a tool call, so a session died on the request after its first tool call (penguin-harness #404). Both clients now keep the list only for a result that carries images — the rule the genericopenai_responses/openai_chatclients took in 0.4.11 — so every Responses and Chat Completions client in the SDK behaves alike:gpt6,deepseek_v4,minimax_m3,openai_responses;openai_chat,openai_chat_vllm_adapter,kimi_k3,glm5_3.deepseek_v4keeps refusing images on the ids whose model reads none.
Both the Python and TypeScript implementations changed the same way. The message-order suites now assert the plain string on every Responses and Chat Completions client.
Install
pip install agenthub-python==0.4.14
npm install @prismshadow/agenthub@0.4.14Full detail: changelog/0.4.14/README.md.
v0.4.13
AgentHub 0.4.13 keeps a tool-calling turn replayable when the model produced no chain of thought, so a DeepSeek tool chain does not die part-way through behind an endpoint that reissues tool_call ids.
Highlights
- A tool-calling turn with no chain of thought still carries its reasoning field.
openai-chatattached the reasoning field only when the assistant turn had thinking text, so a turn that made tool calls and thought nothing went back with the field absent. DeepSeek refuses such a request with400 The `reasoning_content` in the thinking mode must be passed back to the API.whenever that turn is part of the tool-call chain still being continued — and it produces exactly those turns itself, answering with a bare tool call once a chain runs past its first few steps. The rejection is waived only fortool_callids DeepSeek issued, so an endpoint that reissues ids removes the waiver, and a run died mid-task on a provider 4xx that no retry could fix. The client now records the reasoning field the upstream has produced in the conversation and sends that field as an empty string on such a message, following the same fidelity rule as a non-empty replay (reasoning_content,reasoning, or both when the origin is ambiguous). A conversation that never produced a reasoning field never receives one, so a server that does not speak one is untouched.openai-chat-vllm-adapterinherits the transform.
Both the Python and TypeScript implementations changed the same way.
claude5, ant_messages, gpt6, openai_responses, glm5_3, kimi_k3, minimax_m3 and gemini3_8 were probed live against their own endpoints and need no equivalent change: none of them omits the reasoning carrier for a thinking-free tool turn, and none of those providers rejects one.
Install
pip install agenthub-python==0.4.13
npm install @prismshadow/agenthub@0.4.13