Bridgic LLMs
bitsky-tech/bridgic
LLM provider initialization for bridgic projects. An agent skill from bitsky-tech/bridgic.
Fixed workflow for developing MMSP itself — adding or updating model support, and changing its pages.
$ npx skills add Prism-Shadow/model-message-stream-protocol --skill mmsp-dev -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install Prism-Shadow/model-message-stream-protocol mmsp-dev --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/Prism-Shadow/model-message-stream-protocol.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/mmsp-dev .claude/skills/mmsp-dev && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "mmsp-dev" agent skill from https://github.com/Prism-Shadow/model-message-stream-protocol/tree/main/.agents/skills/mmsp-dev into .claude/skills/mmsp-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mmsp-dev", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/Prism-Shadow/model-message-stream-protocol/tree/main/.agents/skills/mmsp-devType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add Prism-Shadow/model-message-stream-protocol --skill mmsp-dev -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install Prism-Shadow/model-message-stream-protocol mmsp-dev --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Prism-Shadow/model-message-stream-protocol.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/mmsp-dev .agents/skills/mmsp-dev && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "mmsp-dev" agent skill from https://github.com/Prism-Shadow/model-message-stream-protocol/tree/main/.agents/skills/mmsp-dev into .agents/skills/mmsp-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mmsp-dev", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Prism-Shadow/model-message-stream-protocol --skill mmsp-dev -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install Prism-Shadow/model-message-stream-protocol mmsp-dev --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Prism-Shadow/model-message-stream-protocol.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/mmsp-dev .cursor/skills/mmsp-dev && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "mmsp-dev" agent skill from https://github.com/Prism-Shadow/model-message-stream-protocol/tree/main/.agents/skills/mmsp-dev into .cursor/skills/mmsp-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mmsp-dev", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/Prism-Shadow/model-message-stream-protocol.git --path .agents/skills/mmsp-dev--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add Prism-Shadow/model-message-stream-protocol --skill mmsp-dev -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install Prism-Shadow/model-message-stream-protocol mmsp-dev --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Prism-Shadow/model-message-stream-protocol.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/mmsp-dev .gemini/skills/mmsp-dev && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "mmsp-dev" agent skill from https://github.com/Prism-Shadow/model-message-stream-protocol/tree/main/.agents/skills/mmsp-dev into .gemini/skills/mmsp-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mmsp-dev", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install Prism-Shadow/model-message-stream-protocol mmsp-devInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add Prism-Shadow/model-message-stream-protocol --skill mmsp-dev -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/Prism-Shadow/model-message-stream-protocol.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/mmsp-dev .github/skills/mmsp-dev && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "mmsp-dev" agent skill from https://github.com/Prism-Shadow/model-message-stream-protocol/tree/main/.agents/skills/mmsp-dev into .github/skills/mmsp-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mmsp-dev", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Prism-Shadow/model-message-stream-protocol --skill mmsp-dev -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install Prism-Shadow/model-message-stream-protocol mmsp-dev --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Prism-Shadow/model-message-stream-protocol.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/mmsp-dev .opencode/skills/mmsp-dev && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "mmsp-dev" agent skill from https://github.com/Prism-Shadow/model-message-stream-protocol/tree/main/.agents/skills/mmsp-dev into .opencode/skills/mmsp-dev/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mmsp-dev", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
mmsp-devFixed workflow for developing MMSP itself — adding or updating model support, and changing its pages.
Mmsp Dev is an agent skill from Prism-Shadow/model-message-stream-protocol. Fixed workflow for developing MMSP itself — adding or updating model support, and changing its pages. Use when asked to support a new model or protocol version in this repository, sync llmsdkdocs, implement a provider client, or change the playground, the tracer or the site. Covers doc syncing, live API capture, paired Python/TypeScript implementation, model-scoped e2e testing, and the UI rules for the three pages.
Its SKILL.md is about 7.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 10 other files (for example `kill-ai-slop/GUIDE.md`, `kill-ai-slop/README.md` and `kill-ai-slop/references/detection.md`).
It sits in Testing & QA, covering End-to-end testing. It works with Python, TypeScript, OpenAI and DeepSeek. The repository describes itself as: One interface for 1,000+ LLMs, with zero-code switching and built-in observability. (GPT-6 / Claude 5 / Gemini 3.8). The licence is Apache-2.0.
4 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 326dc9b. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships script files (JavaScript), which the agent can run.
Shell commands in SKILL.md call:
npmgitmakeuvghnodeFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
openrouter.aiAlso links to:
beautifului.devpenguin.oooFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
GEMINI_API_KEYOPENAI_API_KEYANTHROPIC_API_KEYDEEPSEEK_API_KEYZAI_API_KEYMOONSHOT_API_KEYMINIMAX_API_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Mmsp Dev loads about 7.2k tokens when it runs. Until then it costs about 107 tokens; SKILL.md has 3,924 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from Prism-Shadow/model-message-stream-protocol at commit 326dc9b, republished under its Apache-2.0 licence (© Prism-Shadow). 3,924 words, ~7,195 tokens.
.claude/skills/mmsp-dev/SKILL.md (or your agent's skills folder). This skill also uses 7 other files; get the full folder from GitHub.Adding or updating model support follows the stages below, in order. Where a stage says stop and ask, pause and ask the user; do not continue until the issue is resolved, and never fill the gap yourself.
llmsdk_docs/<model_version>/ Official docs snapshot, one folder per model generation (README.md + docs/)
api_captures/<protocol>/ Git-ignored raw API captures: request payloads + stream events
src_py/mmsp/<client_type>/ Python client, one folder per client type: <vendor>_official/ or <protocol>/
src_py/mmsp/auto_client.py Creates the client a client_type names; a model id's family names its official client
src_ts/src/<client_type>/ TypeScript client, mirrors the Python folder
src_ts/src/autoClient.ts TypeScript routing, mirrors auto_client.py
src_py/tests/test_client.py Parameterized e2e tests (env-gated AVAILABLE_MODELS)
src_ts/tests/client.test.ts Same for TypeScript
changelog/unreleased/ Where unshipped changes go; renamed to the version at release
changelog/<version>/ Release summary (README.md) plus one detail file per entry
changelog/README.md The entry format: metadata block, body rules, bilingual pairing
CHANGELOG.md One brief line per release linking into changelog/
src_py/mmsp/integration/ The playground and the tracer pages, mirrored in src_ts/src/integration/
site/ The Astro site at mmsp.penguin.ooo
.agents/skills/mmsp-dev/kill-ai-slop/ Vendored AI-slop guide and scanner for the UI work below
<name>.zh.md Chinese counterpart, required for every file in changelog/llmsdk_docs/llmsdk_docs/<model_version>/ following the existing folder conventions, and list the folder in llmsdk_docs/README.md. Running this workflow is the explicit request that the repository rule against editing llmsdk_docs/ asks for.api_captures/src_py/tests/test_client.py (AVAILABLE_MODELS gating and _create_client). Stop and ask the user to supply the key if it is missing; the workflow must not continue without it.api_captures/<protocol>/ (git-ignored), e.g. round1.request.json plus round1.stream.jsonl with every raw stream event in order. Never save credentials.str() form and analyze from that. Keep the container parseable: wrap the text in a JSON object so the .jsonl stays one JSON value per line ({"unserializable_str": "<str(event)>"}, keeping the event in stream order), or put the whole exchange in a sibling .txt when nothing about it serializes. A str() capture is still the authoritative record of what the API returned. Never drop the event, hand-edit it into valid JSON, or fall back to the docs because serialization failed.openai_official/, anthropic_official/, gemini_official/, zai_official/, moonshot_official/, deepseek_official/, minimax_official/) speaks the vendor's own API, knows every generation of the vendor's models, and reads the vendor's key from the environment; a compatible client per wire protocol (openai_responses/, openai_chat/, openai_chat_vllm_adapter/, openai_embedding/, ant_messages/, google_genai/) speaks that protocol for any endpoint. The class is named after the folder (OpenAIOfficialClient, OpenaiChatClient), and the client type is the folder name with hyphens (openai-official, openai-chat)."4-6" in self._model, "gpt-6" in self._model), never by a bare substring like "claude" in model, and keep the older generations working. Never drop a generation unless the user explicitly instructs it.<vendor>-official client type in auto_client.py / autoClient.ts, and a new row in the model family table there: the family is the prefix every id of the vendor's models begins with (glm-, kimi-), matched case-insensitively.auto_client.py / autoClient.ts create the client a client_type names, from the one table of client types. Without a client_type, the family a model id begins with names its official client; an id of no known family raises and asks for one. The routing has no other rule: no substring matching on model ids, no version matching outside the official clients.api_key is used as it is. A client that reads the environment's generic key (OPENAI_API_KEY for openai_official and the OpenAI-protocol compatible clients, ANTHROPIC_API_KEY for anthropic_official and ant_messages, GEMINI_API_KEY for google_genai) reads it only when the endpoint comes from the environment too (OPENAI_BASE_URL / ANTHROPIC_BASE_URL / GEMINI_BASE_URL, or the provider's own default): given a base_url and no api_key, it raises at construction instead of sending that key to another endpoint. That is resolve_credentials / resolveCredentials in utils; call it, do not reimplement it. Any other official client (deepseek_official, zai_official, moonshot_official, minimax_official, gemini_official) reads its own variable (DEEPSEEK_API_KEY, ZAI_API_KEY, MOONSHOT_API_KEY, MINIMAX_API_KEY, GEMINI_API_KEY) whatever base URL it is given, and never the generic one; without either it raises <VAR> is required for <Client>.. Hand every credential to the vendor SDK explicitly, including "none" (authToken: null in TypeScript, a cleared auth_token in Python), because the SDKs fill whatever they are not handed from their own environment variables. The offline tests in tests/env-credentials.test.ts / tests/test_env_credentials.py build every client under a controlled environment and read the credential the SDK instance holds; add a new client to them.fidelity is an exception channel, not a mirror of the payload: a field earns a place there only when the Stage 2 probe shows the request fails or the model degrades without it. Provider-generated ids the API regenerates or ignores — a reasoning item id, an output-item id — stay out. Fields the API demands go in: GPT-5.5's phase, Claude's thinking signature, the exact reasoning field name a strict upstream requires.fidelity what a universal field already carries — the thinking text, a tool call's name or parsed arguments. Rebuild the wire item from the universal fields instead.tool_call_id is not optional: always capture the provider's call id and replay it. Where the wire format carries both an item id and a call id, the call id is the one that correlates a result to its call.openai_official/ is the shape for Responses-style protocols, openai_chat/ for Chat Completions: same method order, same control flow, same names. A new client should read as a diff against its reference, because that is how it will be reviewed.model_output.delta, model_output.item.call_id) and keep field access, usage arithmetic, and error text where they are used. Extract a helper only for a genuinely large, self-contained block — the kind that would bury the main flow if inlined, such as fetching and decoding an image — never for a few lines. Mirror the reference client's own private methods (_convert_thinking_level_*, _convert_tool_choice) instead of inventing a layer beside them; a shim that accepts both dicts and SDK objects is never one of them, because the events are typed with the SDK's own types.transform_model_output_to_uni_event / transformModelOutputToUniEvent turns one wire event into one UniEvent whose content_items are the .delta items that event carries, in wire order, and never a .done item. _streaming_response_internal / _streamingResponseInternal builds the request, opens the stream, and yields one event per wire event: a plain loop, with no item bookkeeping, no accumulator, no argument parsing, no usage merging, and no synthesized stop. usage_metadata / finish_reason ride on stop events wherever the wire reports them — Anthropic message_start and message_delta, the Chat Completions finish and usage chunks, response.completed — merged field by field by the base; a client's stop event never ends the public stream. A wire event with nothing universal is the empty delta event: no items, null usage and finish reason. The base class hands every delta to StreamItems (stream_items.py / streamItems.ts), which sends it out as it arrives and closes each item with its .done item when the next item begins or the client's stream ends; the base then emits the one stop event or raises EmptyResponseError. Events that break the protocol raise StreamProtocolError in every mode, and the shared e2e tests check every client's stream with assert_stream_grammar / assertStreamGrammar.fidelity.item_id. Model output is serial, so one item streams at a time and the provider's end-of-item events (content_block_stop, response.output_item.done, step.stop) are listed as no-ops: a gateway that closes its items late or out of order changes nothing. Pass the provider's own id, stringified, as fidelity.item_id: the Anthropic block index, the Responses event item_id or item.id or item.call_id (None / undefined where a gateway sends none), the Interactions step index, the Chat Completions wire field (reasoning_content, reasoning, content, tool_calls), the generateContent part kind (function_call, thought, inline_thinking, inline_data, text); embedding vectors carry none. StreamItems strips it, so it never reaches consumers, traces or histories.StreamItems decides where an item ends; clients never do. A delta belongs to the next item when it carries another item_id, is of another kind (an Interactions thought step going text, image, text is three items under one index), or begins an item by itself: a tool_call.delta carrying a name (every provider sends it once, on the call's first delta, so Chat Completions calls need no ids of their own), an image (inline_thinking, or inline_data with an image/* MIME type, while audio streams in chunks of one item), an embedding vector. Otherwise it continues the item streaming now: a delta without an id does, and so do a call's arguments whatever id a gateway puts on them. Fidelity sent alone under the item's id is that item's, whatever kind carries it (an Interactions thought_signature after an image thought). The per-kind table in that file — the growing field, the header fields of the first delta, how the chunks join — is the only per-kind code in the stream: the done item is the item's first delta with the growing field replaced by the join of every delta's (tool call arguments parsed) plus the item's fidelity.signature_delta, as a thinking.delta with empty thinking; the Responses reasoning channel / encrypted_content on an empty thinking.delta yielded at response.output_item.done, the last delta of that item; GPT's phase on an empty text.delta at response.output_item.added. StreamItems copies it onto the .done item. An identical fidelity repeated on later deltas of the same item goes out once (Chat Completions tags every reasoning delta with reasoning_field); a different one is a StreamProtocolError.tool_call.delta carrying the name and call id on the item-added event and continues with argument fragments; the completion event yields nothing but the fidelity unknown until then. Never read content back from a completed item or cross-check it against what the deltas produced; response.function_call_arguments.done returns the empty delta event. Leave provider error events (response.failed, response.error, error) to the unknown-event guard rather than translating them into MMSP errors, except on Gemini Interactions: neither of its SDKs raises on the SSE error event that arrives inside an open stream, so the guard would drop the provider's failure and the stream would end as one without usage, and gemini_official raises on an error event carrying an error object instead, with the provider's code and message. minimax_official is the deliberate exception: it ignores the argument deltas and reads each call from response.output_item.done, yielding one tool_call.delta with the name, call id, and whole arguments. A client streams a call on deltas or delivers the completed item, never both, so the fragments and the complete call can never disagree..done types. transform_uni_message_to_model_input matches text.done, thinking.done, tool_call.done, tool_result.done, and the rest; a message never carries a .delta item, and legacy item types are converted before a client sees the messages.reasoning / function_call, say) and the message text is collected separately, flush the collected text before appending the entry; a message appended after the items it preceded is what DeepSeek answers with "No tool output found for tool call". Anthropic Messages and Gemini keep one ordered block list per message, so appending in item order is enough; Chat Completions splits content and tool_calls into fields of one message and carries no interleaving at all.UniConfig keys rarely map one-to-one onto provider config keys. Stop and ask: list every non-obvious mapping and confirm it with the user before coding. Never decide silently.ThinkingLevel must stay usable on every client — never raise for a thinking level. Map each level to the closest level the model supports and degrade silently when a level has no exact equivalent (e.g. gemini_official maps NONE to MINIMAL, or to low on the models that reject minimal; moonshot_official maps NONE to low because K3 cannot disable reasoning).temperature and tool_choice (and other unsupported parameter values, e.g. prompt_caching) may reject with an exception, but must raise the MMSP-specific UnsupportedParameterError from errors.py / errors.ts, never a bare ValueError/Error. Keep the message wording consistent with existing clients (containing "not support").AVAILABLE_MODELS lists of both test files with correct capability flags. Do not add model-specific test functions or files.AVAILABLE_MODELS entry is the only test change a new model is entitled to. src_py/tests/test_client.py and src_ts/tests/client.test.ts are shared contracts every client must already satisfy: never rewrite their bodies, assertions, prompts, or helpers to accommodate one model, and never branch inside them on a model name. A failing shared test means the client is wrong until proven otherwise. Stop and ask for explicit approval before any broader test edit, and get it per change — approval for one edit is not approval for the next.AVAILABLE_MODELS keeps only the newest version of each model family per provider block (e.g. gemini-3.6-flash, not gemini-3.5-flash or 3.5-flash-lite as well). When a newer generation lands, replace the older entry — the old client folder stays supported and routed (see Stage 3) but is no longer e2e-tested.make lint in src_py/; npm run lint and npm run build in src_ts/.cd src_py && uv run pytest -vvv tests/test_client.py -k "<model-name>"cd src_ts && npm run test -- -t "<model-name>"src_py/mmsp/registry.py / src_ts/src/registry.ts list the supported models as entries of (model, base_url, client) plus input/output modalities, context window, and USD-stored pricing keyed by MMSP's usage buckets. Keep both languages identical; the registry unit test constructs every entry through AutoLLMClient.GET https://openrouter.ai/api/v1/models (docs: https://openrouter.ai/docs/api/api-reference/models/list-all-models-and-their-properties): pricing.prompt/completion are USD per token (multiply by 1e6), plus context_length and architecture.input_modalities/output_modalities. The API lists chat models only — embedding models are absent and must be checked via their model pages.cny() initializer (converted to USD storage at 7 CNY/USD).changelog/unreleased/, named for its state rather than a number because the version is not decided until release. Never create a numbered folder for unshipped work and never invent the next version number; release preparation renames unreleased/ to the decided version.changelog/unreleased/YYYY-MM-DD-<slug>.md in the format changelog/README.md specifies: the metadata block (Date, Type, Scope, PR, Issue, Breaking) directly under the title, then ## What changed recording what the change did, plus the factual detail it introduced (config mappings, registry metadata, protocol differences) and ## Compatibility when it breaks something.## Why, ## Problem, ## Decision, ## Alternatives considered, ## Verification, ## Risks do not belong on disk, and neither do claims like "X is not exported from Y": they read as fact, go stale as the code moves, and every later reader pays to re-check them.git log, or git blame.https://github.com/Prism-Shadow/model-message-stream-protocol/pull/N), in the metadata block and in the release-README line. A bare #N is not a link in a Markdown file. The PR number only exists once the PR is open, so open it first, then add both links in a follow-up commit on the same branch.changelog/<version>/YYYY-MM-DD-<slug>.zh.md in the same PR, mirroring the English file section for section. The metadata block stays English verbatim (only the Breaking reason is prose to translate), as do code identifiers, model ids, and links; changelog/README.md lists the standard heading renderings. An entry without its counterpart is unfinished.changelog/<version>/README.md and the matching line in README.zh.md, whose [详情] link points at the .zh.md entry; the root CHANGELOG.md and CHANGELOG.zh.md keep one line per release, added at release preparation.gh pr create --base dev; direct pushes to dev are rejected.The three pages share one look, and every change to them goes through two references before it ships:
kill-ai-slop/GUIDE.md, the field guide to the machine-default tics of generated interfaces, with its scanner: node .agents/skills/mmsp-dev/kill-ai-slop/scripts/scan.mjs <dir>. Follow its order — scan, triage each hit as slop or intended, report, then fix — and read references/taxonomy.md and references/fixes.md for what each tell is and what replaces it. The playground and tracer pages live inside Python and TypeScript strings, so scan an extracted copy of the HTML.The system they share:
--bg, --surface, --raised, --text, --muted, --subtle, --ring) with one accent; color carries meaning only (a stop reason, an item's kind). Light and dark follow the system through prefers-color-scheme and a data-theme override; the playground and the tracer share the mmsp.playground.theme key, the site uses mmsp-site.theme.cubic-bezier(0.23, 1, 0.32, 1), only where something changes, and off under prefers-reduced-motion.site/src/components/Logo.astro (two #477dfb tiles and two dark ones, white letters), also the favicon of all three pages. The site's brand scale in site/src/styles/global.css is built around #477dfb, a pure blue at the hue of fennel flower #7aa2f7, as brand-500: images and the mark use #477dfb, text on white uses brand-600 or darker, and text in the dark theme uses brand-400, which is #7aa2f7 itself. The language and theme controls of the top bar are buttons that cycle on click (the other language; system, light, dark), not menus. The home page fits one desktop window, footer included: the player zooms to at most 85%, then its two stream panes are capped and follow their newest line. The README and social images are rendered from site/artwork/ with render.sh. Before committing an image, shrink it: PNGs to at most 1760 px wide (twice the README column) and a 256-colour palette (imagequant, then pyoxipng), GIFs with gifsicle -O3 --lossy=15, dropping every other motion frame first. The README images together stay under 1 MB. Each tile of the mark is its own shape (the dark ones reach half a unit under the blue ones at the seams): one dark square under the blue tiles shows as a grey rim on white. The logo files for others to use are .github/images/mmsp-logo.svg and mmsp-logo-dark.svg (outlined letters) with 512 px PNGs of each, built by site/artwork/logo.py <NotoSans-Bold.ttf> .github/images with the PNGs rendered from the SVGs in Chrome. Every image has one copy in the repository: the site serves .github/images/social-preview.png through site/src/pages/social-preview.png.ts rather than a second file in site/public/.What the owner has asked for, and keeps asking for:
How the pages are built and checked:
CHAT_TEMPLATE in both servers. Python serves it through Jinja, so it may hold no {{, {% or {#, and every backslash is doubled; TypeScript holds it in a template literal, so backticks and ${ are escaped too. Edit it once and regenerate both embeddings; keep the element ids and function names the page tests assert._TRACER_HEAD, _TRACER_SCRIPT and _ICONS (TRACER_HEAD, TRACER_SCRIPT, ICONS) and a _page shell between tracer.py (Jinja page bodies) and tracer.ts (the same markup built in code). A tracer test asserts a trace page never contains 0.6, its sign of a leaked sixth embedding value, so no CSS number or SVG path there may contain it.jest.yml, pytest.yml) only for changes outside site/; a site-only change runs the site build alone.npm run build plus astro preview for the site): light and dark, desktop and a 390 px phone, no console errors, no horizontal scroll. A passing scan is not a better page; look at the screenshots.© Prism-Shadow, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 7 other files in .agents/skills/mmsp-dev of Prism-Shadow/model-message-stream-protocol.
Open the folder on GitHubat commit 326dc9b
Mmsp Dev next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Mmsp Dev this skillPrism-Shadow/model-message-stream-protocol | 113 | — | ~7.2k | Automated safety check: Pass | Apache-2.0 | |
| Bridgic LLMsbitsky-tech/bridgic | 155 | — | ~839 | Automated safety check: Notes | MIT | |
| Gemini Interactions APIAyuilos/Miffan | 182 | — | ~4.6k | Automated safety check: Pass | AGPL-3.0 | |
| RStudio Selenium to Playwright Migrationrstudio/rstudio | 5.1k | — | ~3.6k | Automated safety check: Pass | Custom licence | |
| Codex E2E Trace Validationliaohch3/claude-tap | 3.3k | — | ~3k | Automated safety check: Pass | MIT | |
| Blockless Extension E2EFreakStudioCN/mpy-hardware-extension | 118 | — | ~1.2k | Automated safety check: Notes | Custom licence |
bitsky-tech/bridgic
LLM provider initialization for bridgic projects. An agent skill from bitsky-tech/bridgic.
Ayuilos/Miffan
A skill your agent uses when writing code that calls the Gemini API for text generation, multi-turn chat, multimodal understanding, image generation, video generation, streaming responses…
rstudio/rstudio
Converts RStudio Python Selenium electron tests into TypeScript Playwright tests, checking each against a live RStudio before counting it as migrated.
liaohch3/claude-tap
Runs a real Codex CLI session through claude-tap and produces trace evidence and viewer screenshots for pull requests that touch capture, proxying or the viewer.
FreakStudioCN/mpy-hardware-extension
Run and debug the Blockless VS Code extension release gate: CI-equivalent API and extension tests, V0 protocol smoke, live DeepSeek full-stack e2e, VSIX packaging, local reinstall, direct…
omnigent-ai/omnigent
Spins up a local Omnigent server and exercises the Antigravity (Gemini) SDK harness end to end: building agents, running real turns, smoke tests and bug-bashing.
Prism-Shadow/model-message-stream-protocol
Guidance for using the MMSP Python SDK (mmsp). An agent skill from Prism-Shadow/model-message-stream-protocol.
Prism-Shadow/model-message-stream-protocol
Guidance for using the MMSP TypeScript SDK (@prismshadow/mmsp).
Categories
Fixed workflow for developing MMSP itself — adding or updating model support, and changing its pages. Mmsp Dev is an agent skill from Prism-Shadow/model-message-stream-protocol. Fixed workflow for developing MMSP itself — adding or updating model support, and changing its pages.
Mmsp Dev fits situations like: asked to support a new model; protocol version in this repository; sync llmsdkdocs; implement a provider client.
Run `npx skills add Prism-Shadow/model-message-stream-protocol --skill mmsp-dev -a claude-code`. Or copy the skill folder (.agents/skills/mmsp-dev in Prism-Shadow/model-message-stream-protocol) into .claude/skills/mmsp-dev in your project. Claude Code loads it when a task matches its description.
Run `npx skills add Prism-Shadow/model-message-stream-protocol --skill mmsp-dev -a codex`. Or copy the skill folder (.agents/skills/mmsp-dev in Prism-Shadow/model-message-stream-protocol) into .agents/skills/mmsp-dev in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Prism-Shadow/model-message-stream-protocol --skill mmsp-dev -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/mmsp-dev, .gemini/skills/mmsp-dev, .github/skills/mmsp-dev and .opencode/skills/mmsp-dev in your project.
Going by SKILL.md and its folder, Mmsp Dev needs JavaScript for the scripts in its folder, the command-line tools its instructions call (npm, git, make, uv, gh and node) and credentials named GEMINI_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY and DEEPSEEK_API_KEY. Our summary lists: Python 3; Node.js; A credential in OPENAI_API_KEY; A credential in ANTHROPIC_API_KEY.
SKILL.md names 3 domains. In commands or code: openrouter.ai; the agent is likely to contact it when it follows the instructions. As links in the text: beautifului.dev and penguin.ooo. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Mmsp Dev is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.2k tokens (SKILL.md is roughly 29k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Mmsp Dev: Bridgic LLMs (bitsky-tech/bridgic, 155 stars), Gemini Interactions API (Ayuilos/Miffan, 182 stars), RStudio Selenium to Playwright Migration (rstudio/rstudio, 5.1k stars) and Codex E2E Trace Validation (liaohch3/claude-tap, 3.3k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Prism-Shadow (a GitHub organization) maintains it in Prism-Shadow/model-message-stream-protocol, which has 113 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 4, 2026.
Source: Prism-Shadow/model-message-stream-protocol on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.