Skip to content

Releases: Prism-Shadow/model-message-stream-protocol

v0.5.6

Choose a tag to compare

@hiyouga hiyouga released this 24 Oct 08:44
Immutable release. Only release title and notes can be modified.
afac919

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-pro and kimi-k3.1-pro-highspeed on Moonshot, moonshotai/kimi-k3.1-pro on OpenRouter and kimi-k3.1-pro on TokenDance, through moonshot-official in both packages. On the K3 series, kimi-k3 included, ThinkingLevel.NONE sends reasoning_effort: "none", which turns thinking off, and PromptCaching.ENHANCE sends prompt_cache_options with a 1h TTL (#294).
  • Claude thinking level none: anthropic-official turns thinking off for ThinkingLevel.NONE on 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, ProviderStreamError and ConcurrentCallError, each a subclass of the built-in it replaces, so existing except ValueError / catch code 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 UniConfig key (#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.6

Full details: English · 中文.

v0.5.5

Choose a tag to compare

@hiyouga hiyouga released this 23 Oct 07:12
Immutable release. Only release title and notes can be modified.
b094dcf

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-Flash on MiniMax and minimax/minimax-m3.1-flash:free on OpenRouter, in both packages; ThinkingLevel.NONE maps to reasoning.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 through anthropic-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 an mmsp-server.json. /status/ shows the daily probe (deepseek-flash on DeepSeek, gemini-3.8-flash on Vertex AI, deepseek-v4.1-flash on TokenDance): status, TTFT, TPS, 90 days of history and the month's probe cost, with Run a check now. /models.json serves 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 the stop event, 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_details replay 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 sends chat_template_kwargs from Python (#266); tts_config rejections raise UnsupportedParameterError (#269).
  • Dependencies: TypeScript requires openai ^6.42.0 and @anthropic-ai/sdk ^0.91.1, Python openai>=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.5

Full details: English · 中文.

v0.5.4

Choose a tag to compare

@hiyouga hiyouga released this 19 Oct 21:42
Immutable release. Only release title and notes can be modified.
e24fb7e

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_KEY only when given no base URL, or when given its own default endpoint, such as https://api.deepseek.com for deepseek-official. Any other base URL passed without a key raises ApiKeyRequiredError before any request. The message names both fixes: pass the key, or drop the base URL and set <P>_API_KEY, plus <P>_BASE_URL for an endpoint other than the default. The mmsp client still calls an open server keyless.
  • credentials module: CLIENT_CREDENTIALS, environmentCredential(clientType, baseUrl) and routedClientType(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 and AutoLLMClient resolve through the same table.
  • GPT-6 Luna: gpt-6-luna on OpenAI and openai/gpt-6-luna on OpenRouter, with ThinkingLevel.NONE kept as reasoning.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.4

Full details: English · 中文.

v0.5.3

Choose a tag to compare

@hiyouga hiyouga released this 14 Oct 08:15
Immutable release. Only release title and notes can be modified.
548dbb9

MMSP 0.5.3 adds Gemini 4 Argon support in Python and TypeScript (#253).

Highlights

  • Gemini 4 Argon: use gemini-4-argon with the default google-official client or explicitly select google-genai for generateContent.
  • Thinking levels: none maps to low; low, medium, and high keep their values; xhigh and max map to high. Omitting the level preserves Google's default medium.
  • 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.3

Full details: English · 中文.

v0.5.2

Choose a tag to compare

@hiyouga hiyouga released this 09 Oct 21:52
Immutable release. Only release title and notes can be modified.
790b270

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 FILE or npm 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 optional base_url and client_type.
    • Endpoints: GET /v1/models in OpenAI's list shape, and POST /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: $VAR cells are read from the environment (#247).
  • mmsp client. client_type="mmsp" calls an MMSP server and passes its stream through unchanged. An error the server reports comes back as the new UpstreamError (#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.
    • Test: checks a row straight against its upstream and reports first token, total time and TPS.
    • Open-server banner: shown while the server runs without keys.
    • Confirmation: Start and Apply ask first (#247, #250).
  • Claude Haiku 5.5. anthropic-official serves claude-haiku-5-5.
    • Parameters: thinking_level="none" runs at low effort. As on the rest of the 5.5 family, a forced tool_choice and fast_mode raise UnsupportedParameterError.
    • 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).
  • google-official. The official Gemini client now takes its vendor's name, like openai-official and anthropic-official. gemini-official still 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 / GoogleOfficialClient instead of gemini_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/clear ends it.

Install

pip install mmsp==0.5.2
npm install @prismshadow/mmsp@0.5.2

Full detail: changelog/0.5.2/README.md.

v0.5.1

Choose a tag to compare

@hiyouga hiyouga released this 01 Oct 13:02
Immutable release. Only release title and notes can be modified.
326dc9b

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-genai is 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-content still names it, as an alias (#244).
  • Vertex AI is no longer part of gemini-official. gemini-official speaks the Gemini API's Interactions endpoint only, and refuses a service-account key with an error that names google-genai, so a private key never travels as an API key (#244).
  • google-genai keeps its key with its endpoint. Like the other compatible clients, it reads GEMINI_API_KEY from the environment only together with GEMINI_BASE_URL or Google's own endpoint; a base_url passed in needs an api_key with it (#244).
  • Qwen3.8 27B. The registry lists qwen/qwen3.8-27b on OpenRouter and Qwen/Qwen3.8-27B on 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 a gemini- model id with no client type, now raise on one.
  • google-genai with a base_url needs an api_key passed in as well.
  • Code that imported the client by module path imports google_genai / GoogleGenaiClient in place of gemini_generate_content / GeminiGenerateContentClient.

Install

pip install mmsp==0.5.1
npm install @prismshadow/mmsp@0.5.1

Full detail: changelog/0.5.1/README.md.

v0.5.0

Choose a tag to compare

@hiyouga hiyouga released this 30 Sep 15:02
Immutable release. Only release title and notes can be modified.
7b5d6d5

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 mmsp on PyPI and @prismshadow/mmsp on npm, the module is mmsp, the error base class MMSPError, and the environment variables MMSP_DEBUG and MMSP_CACHE_DIR (#223).
  • Streaming protocol v2. A stream is delta events closed by exactly one stop event, and every content item streams as .delta fragments closed by its .done item, 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 .done types, 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 a client_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_KEY and ANTHROPIC_API_KEY go only to the endpoint the environment names, and a base_url without an api_key raises (#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/mmsp in place of agenthub-python / @prismshadow/agenthub, and import mmsp.
  • Read items by their .done types (text.done, thinking.done, tool_call.done …) and treat .delta fragments 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 as moonshotai/kimi-k3 now needs its client_type.

Install

pip install mmsp==0.5.0
npm install @prismshadow/mmsp@0.5.0

Full detail: changelog/0.5.0/README.md.

v0.4.15

Choose a tag to compare

@hiyouga hiyouga released this 14 Sep 13:17
Immutable release. Only release title and notes can be modified.
77748e4

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_v4 and minimax_m3 accumulated a response's function calls in a single slot, so a gateway that streams added(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 with 400 … No function call found for function_call_output, discarding the turn. Every harness turn that ran two tools in parallel hit it. partial_tool_call items now carry an optional item_id that 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.15

Full detail: changelog/0.4.15/README.md.

v0.4.14

Choose a tag to compare

@hiyouga hiyouga released this 12 Sep 11:51
Immutable release. Only release title and notes can be modified.
a1d7f73

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_v4 and gpt6 send 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 with 400 {"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 generic openai_responses / openai_chat clients 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_v4 keeps 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.14

Full detail: changelog/0.4.14/README.md.

v0.4.13

Choose a tag to compare

@hiyouga hiyouga released this 12 Sep 10:42
Immutable release. Only release title and notes can be modified.
617c88f

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-chat attached 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 with 400 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 for tool_call ids 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-adapter inherits 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