omp-discord-presence0.4.0
Discord Rich Presence for omp (oh-my-pi): live status, model logos, GitHub button, subagent party and privacy controls. Works on Windows, macOS, Linux and WSL.
Built for omp
The author tagged this package omp-package.
Reports 0
No reports yet.
Readme
omp-discord-presence
Discord Rich Presence extension for omp (oh-my-pi) coding agent. See CHANGELOG.md for what changed in each release.
Discord shows the installed omp version, the project name, any active omp mode (plan, goal, loop, vibe), the current state (idle / thinking / using tool), the active tool, the model and its effort (thinking level), with the model maker's logo as a small badge:
OH MY PI
omp v18.15.0 · my-project · plan mode
using tool · bash · anthropic/claude-opus-4 · effort: high
[ View on GitHub ]
Features
- Live status: idle, thinking, using a tool, waiting for you (approval,
ask, plan review), compacting context, retrying, and away after a quiet period. - Session details: omp version, project name, active omp modes (plan, goal, loop, vibe), and the model with its effort. A model or effort switch shows within seconds, even without a prompt.
- Elapsed timer since the latest prompt or since the session started (your choice), and a hover on the omp icon showing how many omp sessions are open.
- Model logo: the model maker's logo as a small badge, from lobe-icons (156 logos, matched on the model id first, then the provider).
- GitHub button: View on GitHub for public repos.
- Subagents as a party: running task/eval subagents show as
(3 of 4). - Optional extras: git branch (
project @ main) and context-window usage (context 42%), both off by default. - Privacy:
- hide any project's name with
/discord-presence hide; - private GitHub repos are hidden automatically and fail closed;
- the model, button and branch can each be turned off;
- goal objectives, plan paths, approval reasons and retry errors are never sent.
- hide any project's name with
- Settings menu in the omp TUI (
/discord-presence settings), with per-project overrides. Every change applies live to all running sessions. - Tab completion for every
/discord-presencesubcommand. - Status report (
/discord-presence status): exactly what Discord receives, and why a logo or button is missing. - Works everywhere: Windows, macOS, Linux and WSL. On WSL, a bundled bridge means no
socatrelay is needed.
What Discord shows
Status changes reach Discord within about 4 seconds. Updates are spaced out because Discord accepts only 5 activity updates per 20 seconds, and the latest state is always sent last. While tools run in parallel, the status stays on "using tool" until the last one finishes. Automatic context compaction and provider retries get their own status (compacting context, retrying · attempt 2/5). The retry's error message is never shown. The model and effort follow the selection in the omp session: a switch (/model, the model picker, ⇧⇥ for effort) shows within a few seconds, even without a prompt.
The elapsed time on Discord counts from the latest prompt by default. Set Timer to since session start in /discord-presence settings to count from when the omp session opened instead.
Hovering the large omp icon shows the omp version and how many omp sessions are open on this machine, e.g. oh-my-pi v18.15.0 · 2 sessions open. Every omp process counts. Each main session leaves a marker file in discord-presence-sessions/ in omp's agent directory and removes it on exit. Markers left by a crashed process are dropped the next time the sessions are counted.
Active modes are joined with +, and paused modes get (paused), e.g. plan mode + goal mode (paused). Only the mode name is shown: the goal objective and the plan file path stay private.
The current git branch can be added after the project name (my-project @ main; a detached HEAD shows the short commit). It is off by default, because branch names often reveal what you're working on. Turn it on in /discord-presence settings. A branch switch, by the agent or by you in another terminal, shows up after the next turn or within 15 seconds. Hidden projects never show their branch.
After 15 minutes without a prompt (configurable in /discord-presence settings, or never), idle turns into away. The next prompt switches it back to thinking.
Context-window usage can be shown at the end of the status (… · effort: high · context 42%). It is off by default. Turn it on in /discord-presence settings or with /discord-presence context on. The value updates after every turn.
While subagents (task tool, eval agents) are working, Discord shows them as a party after the status line, e.g. using tool · wait · … (3 of 4). The party counts agents, the main one included:
- First number: agents still working. Second number: all agents in the current batch.
- Example: a task with 3 subagents starts at
(4 of 4), then drops to(3 of 4)and(2 of 4)as they finish, and disappears when the last one is done. - Nested subagents are included.
- The next batch starts a new count.
When omp is blocked on you, the status says so instead of thinking:
waiting for approval · bash: a tool call needs your approval. This only happens whentools.approvalModeprompts, e.g.always-askorwrite. The approval reason is not shown, because it can quote the command.waiting for your answer: theasktool is open.waiting for plan review: the plan-mode review is open.
Waiting never turns into away.
GitHub button
When the project is a git repository whose origin remote points to a public GitHub repo, the status gets a View on GitHub button linking to it.
- When there's no button: non-GitHub remotes, private repos and folders without git get none. Visibility is checked once per session with an anonymous GitHub API request, so a private repo's owner/name is never published.
- Hidden projects:
/discord-presence hideremoves the button too. - Your own view: Discord never shows your own activity buttons to you. Other people see them on your profile.
Private repos are hidden automatically
When origin points to a private GitHub repo, the project name is replaced with private project on its own; no /discord-presence hide needed. The button is left out too. It works from the same anonymous GitHub check:
- Fails closed: if the visibility can't be checked (offline, GitHub rate limit), the project is hidden too.
- No early leak: nothing is sent to Discord until the check finishes, at most 5 seconds.
- Not covered: origins that aren't recognizably GitHub, such as SSH host aliases like
git@github-work:owner/repoor GitHub Enterprise hosts. Hide those with/discord-presence hide. - To show a private repo's name anyway: turn off Auto-hide private repos in
/discord-presence settings./discord-presence showsays so when a project is auto-hidden.
Works out of the box on Windows, macOS, Linux and WSL. No Discord setup, relay, or socat needed on the user's side.
Requirements
- The Discord desktop app running on the same machine (the browser version has no Rich Presence).
- Discord → Settings → Activity Privacy → Share your detected activities with others turned on.
Install
omp install omp-discord-presence
Restart omp and the status appears; on WSL the bundled bridge starts by itself. Run /discord-presence status inside omp to check that it is connected.
Other ways to load it:
omp -e /path/to/omp-discord-presence # this session only, nothing installed
omp install /path/to/omp-discord-presence # link a local checkout (run `pnpm install` in it first)
Only the main session talks to Discord. Subagent sessions (task tool, eval agents) never connect; they only report how many of them are running, which is shown as the Discord party.
Update
omp plugin upgrade omp-discord-presence
Then restart omp. omp doesn't check plugins for updates on its own, so run this whenever you want the latest release. To move to a specific version instead:
omp install omp-discord-presence@0.2.0
- What's kept: settings, hidden projects and per-project overrides live in
~/.omp/agent/discord-presence-state.json, outside the plugin, so updates keep them. The plugin also stays enabled. - Linked checkouts (
omp install /path) can't be upgraded. Rungit pull && pnpm installin the folder, then restart omp.
Uninstall
omp plugin uninstall omp-discord-presence
Restart omp. When the plugin's last session ends, it clears its activity from Discord. This also removes a linked checkout from omp; the folder itself stays.
- Pause without uninstalling:
/discord-presence offstops the presence in every session, and/discord-presence onresumes it;omp plugin disable omp-discord-presence(andenable) stops omp from loading the plugin at all.
- Remove the saved settings too:
rm ~/.omp/agent/discord-presence-state.json.
Platform support
| Where omp runs | How it reaches Discord |
|---|---|
| Windows | Directly, via Discord's named pipe |
| macOS / Linux | Directly, via Discord's Unix socket |
| WSL (Discord on Windows) | Built-in bridge, nothing to install |
WSL
Under WSL, Discord runs on Windows and only exposes the named pipe \\.\pipe\discord-ipc-0. Linux programs can't use that pipe, so the plugin bridges it itself:
- On connect, it checks whether
$XDG_RUNTIME_DIR/discord-ipc-0already answers. That happens when Linux Discord is running, you run your ownsocatrelay, or another omp session already started the bridge. If it answers, the plugin uses it. - Otherwise it serves that socket itself and relays each connection through the bundled
bin/npiperelay.exe(npiperelay v0.1.0, MIT, seebin/npiperelay.LICENSE). - When the session that owns the bridge exits, other running sessions reconnect within 15 seconds and one of them takes over.
Requirements: WSL interop must be enabled (the default), and Discord must be the stable client. PTB and Canary use a different pipe and aren't bridged.
How it works
Overview
flowchart TD
subgraph omp["omp session"]
E1["session_start"]
E2["agent_start / turn_end / agent_end"]
E3["tool_execution_start / end"]
E8["tool_approval / plan_review<br/>requested / resolved"]
E6["auto_compaction / auto_retry<br/>start / end"]
E7["mode_changed<br/>(plan / goal / loop / vibe)"]
E4["/discord-presence commands<br/>+ settings menu"]
E5["session_shutdown"]
end
subgraph subs["subagent sessions (same process)"]
SA["agent_start / agent_end"]
end
subgraph plugin["discord-presence plugin (main session only)"]
P["presence state<br/>status · detail · model · context"]
SC["shared subagent counter<br/>running · batch"]
S[("discord-presence-state.json<br/>global settings · hiddenProjects<br/>per-project overrides")]
EF["settings for this project<br/>(global + overrides)"]
T["throttle<br/>0.75 s debounce, 4 s spacing"]
RC{"GitHub check<br/>finished? (≤ 5 s)"}
B["build activity"]
end
subgraph inputs["read when building"]
V["omp version"]
M["live model + effort<br/>(polled every 3 s)"]
L["lobe-icons logo key"]
G["GitHub visibility<br/>public → button<br/>private → auto-hide"]
BR["git branch<br/>(polled every 15 s while shown)"]
A["app name + icon<br/>(Discord API)"]
OS["open omp sessions<br/>(marker files, all processes)"]
end
E1 & E2 & E3 & E6 & E7 & E8 --> P
SA --> SC --> P
E4 -- "on / off / hide / show / settings" --> S
S -- "file watcher<br/>(all sessions)" --> EF --> P
P --> T --> RC -- "yes" --> B
V & M & L & G & BR & A & OS --> B
B -- "SET_ACTIVITY<br/>details · state · logo · button · party" --> RPC["discord-rpc client"]
RPC --> D["Discord desktop app"]
E5 -- "clear activity, close bridge" --> RPC
Subagent sessions (task tool, eval agents) also load the plugin, but they never connect, so they can't overwrite or clear the main session's status. They run in the same process and share the plugin module. Each one bumps a shared counter while its agent loop runs, and the main session shows that count as the Discord party size.
Project name and privacy
What goes in the first line (omp v… · <project> · <modes>) is decided like this; the button follows the same decision:
flowchart TD
S["session cwd"] --> H{"in hiddenProjects?<br/>(/discord-presence hide)"}
H -- "yes" --> PP["private project<br/>no button · no branch"]
H -- "no" --> O{"git origin<br/>on GitHub?"}
O -- "no" --> N["folder name<br/>no button"]
O -- "yes" --> API{"anonymous GitHub API"}
API -- "public (200)" --> NB["folder name<br/>+ View on GitHub"]
API -- "private (404)<br/>or unknown (offline, rate limit)" --> AH{"Auto-hide private repos<br/>on? (default)"}
AH -- "yes" --> PP
AH -- "no" --> N
N & NB --> BRQ{"Git branch shown<br/>for this project?"}
BRQ -- "yes" --> NBR["name @ branch"]
BRQ -- "no" --> NN["name"]
Connecting to Discord
flowchart TD
C["connect()"] --> Q{"does $XDG_RUNTIME_DIR/discord-ipc-0<br/>answer?"}
Q -- "yes: Linux Discord, socat,<br/>or another omp session" --> R["discord-rpc login"]
Q -- "no" --> W{"running in WSL?"}
W -- "no: Windows / macOS / Linux" --> R
W -- "yes" --> BR["remove stale socket,<br/>serve discord-ipc-0"]
BR --> R
BR -. "each connection" .-> NP["bin/npiperelay.exe"]
NP -. "\\.\pipe\discord-ipc-0" .-> DW["Discord on Windows"]
R -- "READY" --> OK["connected: send activity"]
R -- "error / timeout" --> RT["close client,<br/>retry in 15 s"]
OK -- "disconnected" --> RT
RT --> C
If the session that owns the WSL bridge exits, the other sessions lose their connection, retry, and one of them starts a new bridge.
Status states
stateDiagram-v2
[*] --> offline: plugin loaded
offline --> idle: session_start
idle --> working: agent_start
working --> tool: tool_execution_start
tool --> tool: another tool starts / ends<br/>while one is still running
tool --> working: last running tool ends
working --> idle: agent_end
tool --> idle: agent_end
working --> retrying: auto_retry_start
retrying --> working: auto_retry_end
idle --> away: no prompt for the away time<br/>(15 min by default)
away --> working: agent_start
tool --> waiting: approval requested,<br/>or the ask tool runs
waiting --> tool: approval resolved
waiting --> working: ask answered
working --> waiting: plan review opened
waiting --> idle: plan review closed
idle --> compacting: auto_compaction_start
working --> compacting: auto_compaction_start
tool --> compacting: auto_compaction_start
compacting --> idle: auto_compaction_end<br/>(agent not running)
compacting --> working: auto_compaction_end<br/>(agent running)
compacting --> tool: auto_compaction_end<br/>(a tool is still running)
| Status | Text on Discord |
|---|---|
offline |
starting |
idle |
idle |
away |
away (idle for the away time, 15 minutes by default) |
working |
thinking |
tool |
using tool · <tool name> |
waiting |
waiting for approval · <tool> / your answer / plan review |
compacting |
compacting context |
retrying |
retrying · attempt <n>/<max> |
Commands
Inside omp:
/discord-presence settings # interactive settings menu
/discord-presence # toggle on/off globally
/discord-presence status
/discord-presence off
/discord-presence on
/discord-presence refresh
/discord-presence hide # hide this project's name (alias: private)
/discord-presence show # show this project's name again (alias: public)
/discord-presence context on|off # show context-window usage (off by default)
Press Tab after /discord-presence to pick a subcommand from a list with short descriptions. Partial input narrows it, e.g. context o offers context on and context off.
Settings menu
/discord-presence settings opens a menu in the omp TUI. Press Enter on a row to change it; the menu stays open, so several settings can be changed in a row. Esc or Done closes it.
╭─ Discord presence settings ─────────────────────────╮
│ ❯ Editing: all projects │
│ Enter switches between global defaults and… │
│ This project: visible │
│ Presence: on │
│ Auto-hide private repos: on │
│ Model, effort & logo: shown │
│ GitHub button: shown │
│ Git branch: hidden │
│ Context usage: hidden │
│ Timer: since latest prompt │
│ Away after: 15 min │
│ Done │
╰─────────────────────────────────────────────────────╯
| Setting | Default | Effect |
|---|---|---|
| Presence | on | Show omp activity on Discord, for every session. |
| This project | visible | Show the folder name, or private project (same as hide / show). Shows hidden (private repo) when auto-hidden. |
| Auto-hide private repos | on | private project when origin is a private GitHub repo, or its visibility can't be checked. |
| Model, effort & logo | shown | When hidden, the model, its effort and the model logo are left out; the logo would reveal the model's maker. |
| GitHub button | shown | The View on GitHub button for public repos. |
| Git branch | hidden | Append @ <branch> to the project name. git is only polled while this is on. |
| Context usage | hidden | Append context N%. |
| Timer | since latest prompt | What the elapsed time counts from: the latest prompt, or the session start. |
| Away after | 15 min | Idle time before away: 5, 10, 15, 30 or 60 minutes, or never. |
Every change is saved and applied live to all running sessions. Outside the TUI (print, RPC), settings points to the settings file instead.
Per-project settings
Press Enter on Editing to switch from the global defaults to this project. There, the display settings can be overridden for the current project and its subdirectories, e.g. no GitHub button and no model in a work repo, while other projects keep the global values:
╭─ Discord presence settings ─────────────────────────╮
│ ❯ Editing: this project (work-repo) │
│ This project: visible │
│ Model, effort & logo: hidden · this project │
│ GitHub button: hidden · this project │
│ Git branch: shown · this project │
│ Context usage: hidden · global │
│ Reset this project to the global settings │
│ Done │
╰─────────────────────────────────────────────────────╯
- Which settings: Model, effort & logo; GitHub button; Git branch; Context usage. Presence, auto-hide and the away time stay global.
· global/· this project: whether the row follows the global value or is overridden here. Enter flips an overridden row back to the global value.- Subdirectories: a session in a subdirectory uses the overrides of the closest project above it.
- Reset: Reset this project to the global settings removes all of the project's overrides.
- Status report:
/discord-presence statuslists the overrides in force.
Status report
status shows exactly what Discord receives, and why parts may be missing:
Discord presence: enabled · connected (WSL bridge started by this session)
App: OH MY PI (1566329796068384808)
Sent to Discord:
omp v18.15.0 · omp-discord-presence
idle · anthropic/claude-opus-5-5 · effort: high
logo: claude ✓ uploaded
button: View on GitHub → https://github.com/hiiruki/omp-discord-presence
last update 9s ago
Project: omp-discord-presence · visible · branch hidden
Context: hidden (now 2%) · idle 10s, away in 14m 50s
Timer: since the latest prompt · 2 omp sessions open
Project overrides: none
Settings: /home/me/.omp/agent/discord-presence-state.json
- Connection: direct IPC, the WSL bridge, or a socket another omp session or relay already serves.
- Logo: checked against the application's public Art Asset list.
✗ not uploadedmeans the key is missing in the Developer Portal. - Button: the GitHub URL, or why there is none (project hidden, no git origin, not on GitHub, private repo, GitHub API unreachable).
- Away timer: how long the session has been idle and when it turns
away. - Private data: goal objectives, plan paths, retry errors and the hidden-project list are never shown.
Hidden projects and storage
hide replaces the project name with private project on Discord. It applies to the current directory and everything below it, so a session started in a subdirectory of a hidden project stays hidden. show removes every hidden entry that covers the current directory.
All settings, per-project overrides and the hidden project list are shared by every omp session, and changes apply live to every running session. They are stored in omp's agent directory:
~/.omp/agent/discord-presence-state.json
With omp --profile <name>, that is the profile's agent directory (~/.omp/profiles/<name>/agent/ by default), so each profile keeps its own settings. PI_CODING_AGENT_DIR moves it too.
{
"enabled": true,
"hiddenProjects": ["/home/me/work/secret-client"],
"showContext": false,
"showModel": true,
"showButton": true,
"awayMinutes": 15,
"timer": "prompt",
"autoHidePrivate": true,
"showBranch": false,
"projects": {
"/home/me/work/client-app": { "showModel": false, "showButton": false }
}
}
Troubleshooting
/discord-presence statussays "not connected": check that the Discord desktop app is running and that activity sharing is on. The plugin retries every 15 seconds.- Status stays "not connected" right after restarting omp many times in a row: Discord briefly stops answering when clients reconnect rapidly. Wait a minute.
- Logo badge is blank: run
/discord-presence status.logo: … ✗ not uploadedmeans that Art Asset is missing from the Discord application (see below).logo: nonemeans no lobe-icons rule matches the model.
Development
The development and release conventions are in AGENTS.md: tooling, code rules, tests, commit format, changelog, versioning and the release steps. omp and other coding agents load it automatically.
pnpm install
pnpm typecheck # tsc (TypeScript 7)
pnpm lint # oxlint
pnpm test # bun test, about 30 s
omp -e . # try the checkout in a real omp session
The tests drive the extension the way omp does, against a fake Discord IPC server and a stubbed network:
- Unit tests: GitHub remote parsing (credentials are never captured), model-logo matching, per-project setting precedence.
- Logo assets: every logo key has a PNG, every PNG is reachable, Discord's 300-asset and 512 px limits are respected.
- Behaviour: the status flow with parallel tools, approval waiting that never sends the reason, a private repo's name never being sent, the GitHub button and
hide, per-project overrides reaching subdirectory sessions live, the subagent party, presence off, and Tab completion.
They run with a throwaway omp agent directory (PI_CODING_AGENT_DIR) and Discord socket (XDG_RUNTIME_DIR). test/preload.ts refuses to run if the override doesn't take, so your real settings and Discord are never touched.
CI (.github/workflows/ci.yml) runs typecheck, lint, the tests and an npm pack dry run on every push to main and every pull request.
Publishing a release (maintainer)
Releases are published by GitHub Actions (.github/workflows/release.yml) when a version tag is pushed:
Add the changes under
## [Unreleased]inCHANGELOG.md, then rename that heading to the new version and date and update the compare links at the bottom.Bump
versioninpackage.json: patch for fixes, minor for features (while below 1.0).Commit as
chore(release): x.y.z, tagvx.y.z, and push both:git tag -s vx.y.z -m vx.y.z git push origin main vx.y.zThe workflow then:
- reruns CI;
- checks that the tag matches
package.jsonand thatCHANGELOG.mdhas the version; - runs
npm publishwith provenance; - creates the GitHub release from that changelog section.
Users pick it up with
omp plugin upgrade omp-discord-presence.
One-time setup: npm trusted publishing. The workflow publishes without a token, through OIDC. On npmjs.com, open the package → Settings → Trusted Publisher, choose GitHub Actions, and enter:
| Field | Value |
|---|---|
| Organization or user | hiiruki |
| Repository | omp-discord-presence |
| Workflow filename | release.yml |
| Environment name | npm |
The npm environment is created in the GitHub repo on the first run. Add required reviewers to it under Settings → Environments if releases should wait for approval. Publishing by hand still works with npm publish.
The package ships only extensions/, bin/, assets/ and CHANGELOG.md (plus README.md, LICENSE and package.json, which npm always includes), about 1.9 MB. @oh-my-pi/pi-coding-agent and @oh-my-pi/pi-utils are optional peers resolved from the running omp, so installing the plugin doesn't pull a second copy of omp.
Changes to the Discord application (name, icon, Art Assets) reach every user immediately, with no release. New logo rules in extensions/model-icons.generated.ts still need a release.
Discord application (maintainer setup)
Users don't need any of this. Everything below lives in the Discord application whose ID the plugin uses (default 1566329796068384808), so it applies to every user at once.
Name
The activity title ("OH MY PI") is the application name in the Discord Developer Portal. RPC can't change it. After renaming, restart the Discord client so it drops the cached name.
Images
- Large image: the application's own icon, fetched from Discord at startup.
- Small image: the logo for the model selected in the omp session, from lobe-icons. The plugin uses lobe's own model rules (
modelMappings) in lobe's order, matched against the model id, so Claude through OpenRouter, Copilot or a gateway still shows the Claude logo. If no model rule matches, lobe's provider rules (providerMappings) are tried. Hover the logo to see the model and effort. Models without a logo show no small image.
The logos live in assets/models/ (PNGs from @lobehub/icons-static-png, MIT; the colored variant when lobe has one). Discord can't read local files, so upload them as Art Assets:
- Open the Developer Portal, select the app, then go to Rich Presence → Art Assets.
- Click Add Image(s) and select the files listed by the sync script below (the first time: every file in
assets/models/). - Keep each asset name equal to its file name without
.png(for exampleclaude,deepseek), then Save Changes. New assets can take a few minutes to appear.
Supported logos
156 logos from @lobehub/icons@6.13.0. They cover 5309 of the 5949 models in omp's bundled catalog.
Matched against the model id (first matching rule in lobe's order wins; keywords are case-insensitive regexes):
| Logo | Key | Model id contains | omp catalog models |
|---|---|---|---|
openai |
gpt-3, gpt-4, gpt-5, gpt-oss, o1-, ^o1, /o1, o3-, ^o3, /o3, o4-, ^o4, /o4, text-embedding-, tts-, whisper-, codex, davinci, babbage, omni-moderation, text-moderation, text-adb, text-ada, computer-use, ^gpt-, /gpt-, openai |
879 | |
sora |
sora |
1 | |
dalle |
dalle, dall-e |
0 | |
glmv |
^glm-(.*)v, /glm-(.*)v, -glm-(.*)v |
41 | |
zai |
^glm-5, /glm-5, /glm5, -glm-4, ^glm-4, /glm-4, /glm4, -glm-5 |
316 | |
chatglm |
^glm-, /glm-, chatglm, -glm- |
12 | |
codegeex |
^codegeex, /codegeex |
0 | |
claude |
claude |
550 | |
anthropic |
anthropic |
0 | |
aws |
titan |
0 | |
fireworks |
accounts/fireworks/models/fire |
0 | |
internlm |
internlm, internvl |
1 | |
nousresearch |
deephermes, hermes, genstruct, minos |
19 | |
nvidia |
nemotron, openreasoning, nemoretriever, neva-, nv- |
170 | |
meta |
llama, /l3 |
193 | |
llava |
llava |
0 | |
nanobanana |
gemini-3.1-flash-image-preview, gemini-3-pro-image-preview, gemini-\d+(?:\.\d+)?-(?:flash(?:-lite)?|pro)-image(?:-preview)?(?::|$), nanobanana, nano-banana |
27 | |
gemini |
gemini |
277 | |
deepmind |
^imagen-, /imagen-, ^imagen\d/, /imagen\d |
0 | |
gemma |
gemma |
197 | |
moonshot |
kimi, moonshot |
189 | |
qiniu |
qiniu |
0 | |
qwen |
qwen, qwq, qvq, wanx, wan\d/, wan\d\.\d-, tongyi, gte-rerank |
657 | |
minimax |
minimax, abab, ^image- |
186 | |
mistral |
mistral, mixtral, codestral, mathstral, /mn-, pixtral, ministral, magistral, devstral, voxtral |
213 | |
perplexity |
pplx, sonar |
21 | |
yi |
^yi-, /yi-, -yi- |
4 | |
openrouter |
^openrouter |
19 | |
relace |
^relace-, /relace- |
3 | |
arcee |
^trinity-, /trinity-, afm-4.5b, caller-large, spotlight, maestro-reasoning, virtuoso-medium-v2, virtuoso-large, coder-large, arcee-blitz |
23 | |
essentialai |
^rnj-, /rnj- |
5 | |
deepcogito |
^deepcogito-, /deepcogito-, ^cogito-, /cogito- |
3 | |
morph |
^morph-, /morph- |
3 | |
ai2 |
^olmo-, /olmo- |
10 | |
inception |
^mercury, /mercury |
28 | |
openchat |
^openchat |
0 | |
aya |
aya |
0 | |
cohere |
command |
16 | |
dbrx |
dbrx |
1 | |
stepfun |
step |
47 | |
aimass |
taichu |
0 | |
ai360 |
360gpt, 360zhinao |
0 | |
baichuan |
baichuan |
4 | |
rwkv |
rwkv, /eagle- |
0 | |
wenxin |
ernie, irag |
35 | |
jina |
^jina, /jina |
1 | |
jimeng |
^jimeng-, /jimeng-, seedream, seededit, seedance- |
21 | |
doubao |
^ep-, doubao- |
32 | |
kling |
^kling, kling-, klingai |
19 | |
hunyuan |
hunyuan, hy3, hy4 |
37 | |
fishaudio |
^d_, ^g_, ^wd_ |
0 | |
bytedance |
skylark, seed-, bytedance |
34 | |
burncloud |
burncloud |
0 | |
stability |
stable-diffusion, stable-video, stable-cascade, sdxl, stablelm, ^stable-, ^sd3, ^sd2, ^sd1 |
2 | |
flux |
flux |
12 | |
suno |
suno |
0 | |
microsoft |
wizardlm, /phi-, ^phi-, -phi-, mai-, microsoft |
31 | |
adobe |
firefly |
0 | |
ai21 |
jamba, ^j2-, ai21 |
9 | |
upstage |
^solar-, /solar |
17 | |
palm |
palm |
11 | |
sensenova |
SenseChat, SenseNova |
0 | |
grok |
^grok-, /grok- |
212 | |
ideogram |
ideogram, ^v_1, ^v_2, ^v3$, ^upscale$, ^describe$ |
0 | |
muse |
(^|/)muse-(spark|wonder|image|video)($|-) |
75 | |
spark |
spark, general$, generalv3$, generalv3.5$, 4.0ultra$, pro-128k$, ^max-32k$, ^lite$, ^x1$ |
2 | |
udio |
udio |
5 | |
unionalpha |
union-alpha, unionalpha, pareto |
15 | |
deepseek |
deepseek |
281 | |
voyage |
voyage |
16 | |
assemblyai |
assemblyai |
0 | |
liquid |
liquid, lfm |
19 | |
inflection |
inflection- |
4 | |
aionlabs |
aion- |
26 | |
aihubmix |
aihubmix |
0 | |
v0 |
^v0- |
3 | |
vertexai |
^veo-, /veo-, ^veo3 |
3 | |
google |
google, learnlm, nano-banana |
5 | |
cogview |
cogview |
0 | |
kolors |
kolors |
0 | |
baiducloud |
baidu, qianfan |
5 | |
phind |
phind |
0 | |
dolphin |
dolphin |
0 | |
ibm |
ibm, granite |
15 | |
skywork |
skywork |
0 | |
bilibiliindex |
bilibili-index, index-tts |
0 | |
bilibili |
bilibili |
0 | |
lg |
kmmlu, exaone, lgai |
0 | |
tii |
falcon |
1 | |
menlo |
menlo, lucy, jan-nano |
0 | |
longcat |
longcat |
20 | |
kwaipilot |
kat- |
24 | |
nova |
^nova-, /nova- |
28 | |
xiaomimimo |
^mimo-, /mimo- |
112 | |
baai |
^baai, ^bge-, /bge-, touchd, robobrain |
4 | |
ace |
ace-step |
0 | |
cursor |
^composer, /composer, -composer |
4 | |
typesafeai |
(^|/)jev($|-), typesafe |
14 |
Fallback matched against the provider id (only when no model rule matches):
| Logo | Key | Provider id contains | omp catalog models |
|---|---|---|---|
alibaba |
alibaba |
0 | |
alephalpha |
alephalpha |
0 | |
antgroup |
antgroup |
0 | |
anyscale |
anyscale |
0 | |
apple |
apple |
0 | |
baidu |
baidu |
0 | |
bailian |
bailian, bailiancodingplan |
0 | |
baseten |
baseten |
0 | |
bilibili |
bilibili |
0 | |
bytedance |
bytedance |
34 | |
centml |
centml |
0 | |
civitai |
civitai |
0 | |
crusoe |
crusoe |
0 | |
deepinfra |
deepinfra |
6 | |
deepmind |
deepmind |
0 | |
empiriolabs |
empiriolabs |
0 | |
exa |
exa |
0 | |
featherless |
featherless |
0 | |
friendli |
friendli |
0 | |
googlecloud |
googlecloud |
0 | |
huawei |
huawei |
0 | |
huaweicloud |
huaweicloud |
0 | |
hyperbolic |
hyperbolic |
0 | |
ibm |
ibm |
15 | |
iflytekcloud |
iflytekcloud |
0 | |
inference |
inference |
0 | |
infermatic |
infermatic |
0 | |
kluster |
kluster |
0 | |
lambda |
lambda |
0 | |
leptonai |
leptonai |
0 | |
llmapi |
llmapi |
0 | |
llmgateway |
llmgateway |
0 | |
lg |
lg |
0 | |
menlo |
menlo |
0 | |
metaai |
meta |
0 | |
microsoft |
microsoft |
31 | |
nplcloud |
nplcloud |
0 | |
nousresearch |
nousresearch |
19 | |
parasail |
parasail |
0 | |
searchapi |
searchapi |
0 | |
snowflake |
snowflake |
0 | |
stability |
stability |
2 | |
statecloud |
statecloud |
0 | |
streamlake |
streamlake |
0 | |
sub2api |
sub2api |
0 | |
submodel |
submodel |
0 | |
targon |
targon |
0 | |
tencent |
tencent |
0 | |
tii |
tii |
1 | |
typesafeai |
typesafe, typesafe-ai, typesafeai |
14 | |
unsloth |
unsloth |
0 | |
yandex |
yandex |
0 | |
aimass |
aimass |
0 | |
aistudio |
aistudio |
0 | |
novita |
novita |
12 | |
openai |
chatgpt, openai |
879 | |
opencode |
opencode, opencodecodingplan, opencodego, opencodezen |
20 | |
perplexity |
perplexity |
21 | |
mistral |
mistral |
213 | |
groq |
groq |
2 | |
together |
togetherai |
0 | |
doubao |
doubao |
32 | |
hunyuan |
hunyuan |
37 | |
nvidia |
nvidia |
170 | |
tencentcloud |
tencentcloud |
0 | |
wenxin |
wenxin |
35 | |
lmstudio |
lmstudio |
0 | |
magpie |
magpie, magpie |
0 | |
grok |
supergrok |
212 | |
higress |
higress |
0 | |
vertexai |
vertexai |
3 | |
jina |
jina |
1 | |
azureai |
azureai |
0 | |
volcengine |
volcengine, volcenginecodingplan |
0 | |
cohere |
cohere |
16 | |
comfyui |
comfyui |
0 | |
cometapi |
cometapi |
0 | |
vercel |
v0 |
0 | |
bfl |
bfl |
0 | |
flexai |
flexai |
0 | |
ollama |
ollamacloud |
0 |
Updating the logos
extensions/model-icons.generated.ts, assets/models/ and the tables above are generated. Don't edit them by hand. Regenerate them after bumping LOBE_ICONS_VERSION / STATIC_PNG_VERSION in scripts/sync-model-icons.ts, or after updating @oh-my-pi/pi-catalog to refresh the omp catalog counts:
pnpm sync-icons
The script:
- Reads lobe's
modelMappings/providerMappingsfrom@lobehub/icons(pinned version). - Downloads a PNG for every icon those rules can select into
assets/models/, not only the ones omp's catalog uses today, so custom gateway models and future models already have a logo. Lobe's other icons (apps and tools no rule points to) are left out; Discord allows 300 Art Assets per application. - Writes the rules in lobe's order. A rule whose icon has no PNG maps to
null: no badge rather than a wrong one. - Regenerates the tables above. It resolves every model in omp's bundled catalog (
@oh-my-pi/pi-catalog) the same way the extension does, to count coverage. - Compares the result with the application's public Art Asset list and prints which keys to upload and which to delete in the portal.
Environment overrides
# Use your own Discord application (it needs its own Art Assets)
export OMP_DISCORD_CLIENT_ID=1566329796068384808
# Large image: an Art Asset key (at least 512×512) or any image URL
export OMP_DISCORD_LARGE_IMAGE_KEY=omp-logo