From 1fbbeacd1345bb028b735e58d5468ac52a750193 Mon Sep 17 00:00:00 2001 From: ochenstarik-ui <267932263+ochenstarik-ui@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:14:34 +0700 Subject: [PATCH] Restore local provider logos and add model-family brand marks --- docs/reports/model-provider-logos.md | 11 ++++++ docs/screenshots/a50/brand-catalog.png | Bin 0 -> 73853 bytes .../router/web/static/app.js | 33 ++++++++++++++---- .../web/static/brands/LICENSE-lobe-icons.txt | 21 +++++++++++ .../router/web/static/brands/README.md | 3 ++ .../router/web/static/brands/antigravity.png | Bin 0 -> 13126 bytes .../router/web/static/brands/catalog.html | 1 + .../router/web/static/brands/claude-color.svg | 1 + .../web/static/brands/deepseek-color.svg | 1 + .../router/web/static/brands/gemini-color.svg | 1 + .../router/web/static/brands/grok.svg | 1 + .../router/web/static/brands/lmstudio.svg | 1 + .../router/web/static/brands/meta-color.svg | 1 + .../web/static/brands/mistral-color.svg | 1 + .../router/web/static/brands/nvidia-color.svg | 1 + .../router/web/static/brands/ollama.svg | 1 + .../router/web/static/brands/openai.png | Bin 0 -> 6607 bytes .../router/web/static/brands/opencode.png | Bin 0 -> 1615 bytes .../router/web/static/brands/openrouter.svg | 1 + .../router/web/static/brands/qwen-color.svg | 1 + .../router/web/static/brands/unknown.svg | 1 + .../router/web/static/brands/vllm-color.svg | 1 + .../router/web/static/style.css | 9 +++++ .../router/web/static/workflow.js | 2 +- .../router/web/static/workspace.js | 2 +- tests/test_brand_icons.js | 13 +++++++ 26 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 docs/reports/model-provider-logos.md create mode 100644 docs/screenshots/a50/brand-catalog.png create mode 100644 src/antigravity_provider/router/web/static/brands/LICENSE-lobe-icons.txt create mode 100644 src/antigravity_provider/router/web/static/brands/README.md create mode 100644 src/antigravity_provider/router/web/static/brands/antigravity.png create mode 100644 src/antigravity_provider/router/web/static/brands/catalog.html create mode 100644 src/antigravity_provider/router/web/static/brands/claude-color.svg create mode 100644 src/antigravity_provider/router/web/static/brands/deepseek-color.svg create mode 100644 src/antigravity_provider/router/web/static/brands/gemini-color.svg create mode 100644 src/antigravity_provider/router/web/static/brands/grok.svg create mode 100644 src/antigravity_provider/router/web/static/brands/lmstudio.svg create mode 100644 src/antigravity_provider/router/web/static/brands/meta-color.svg create mode 100644 src/antigravity_provider/router/web/static/brands/mistral-color.svg create mode 100644 src/antigravity_provider/router/web/static/brands/nvidia-color.svg create mode 100644 src/antigravity_provider/router/web/static/brands/ollama.svg create mode 100644 src/antigravity_provider/router/web/static/brands/openai.png create mode 100644 src/antigravity_provider/router/web/static/brands/opencode.png create mode 100644 src/antigravity_provider/router/web/static/brands/openrouter.svg create mode 100644 src/antigravity_provider/router/web/static/brands/qwen-color.svg create mode 100644 src/antigravity_provider/router/web/static/brands/unknown.svg create mode 100644 src/antigravity_provider/router/web/static/brands/vllm-color.svg create mode 100644 tests/test_brand_icons.js diff --git a/docs/reports/model-provider-logos.md b/docs/reports/model-provider-logos.md new file mode 100644 index 0000000..013879b --- /dev/null +++ b/docs/reports/model-provider-logos.md @@ -0,0 +1,11 @@ +# Логотипы моделей и провайдеров + +2026-08-31, предварительная часть перед A50. База `17b368a`. + +Причина отсутствия изображений: getProviderIcon ссылался на codex.png, claude.png и другие файлы, отсутствовавшие в web/static; реальные provider ids antigravity/claude также не совпадали с алиасами в таблице. Неизвестным провайдерам ошибочно назначалась llama.png. + +Существующие OpenAI/Antigravity/OpenCode PNG скопированы без изменения из assets/providers. Набор дополнен локальными SVG Gemini, Claude, Grok, Ollama, NVIDIA, OpenRouter, DeepSeek, Qwen, Meta, Mistral, vLLM, LM Studio из [Lobe Icons](https://github.com/lobehub/lobe-icons). Лицензия MIT и точная ревизия сохранены рядом с файлами; загрузки с CDN при работе Hub нет. + +Провайдер определяется по provider id, логотип модели — по её семейству. Название модели не изменяется; неизвестная модель получает нейтральный символ. Нет выдачи Ollama за бренд любой размещённой на нём модели. Добавлены значки назначенных моделей в карточки аккаунтов, рядом с выбором модели в маршрутизации и вместо общего символа на узлах графа. Единственное изменение workflow.js — отображение изображения; топология и настройки не затронуты. + +Проверки: test_brand_icons.js проверяет алиасы, семейства, fallback и существование файлов; прежние два JS-набора проходят. Браузер подтвердил complete/naturalWidth для 16/16 изображений. Снимок: docs/screenshots/a50/brand-catalog.png. Это каталог, не доказательство сквозной работы A50 или авторизованных аккаунтов. Новый клиент находится в отдельном worktree A50; установленный Hub и preview A48 не заменены. diff --git a/docs/screenshots/a50/brand-catalog.png b/docs/screenshots/a50/brand-catalog.png new file mode 100644 index 0000000000000000000000000000000000000000..7397cb05ba91fc76b530454248540903bbdbd027 GIT binary patch literal 73853 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 literal 0 HcmV?d00001 diff --git a/src/antigravity_provider/router/web/static/app.js b/src/antigravity_provider/router/web/static/app.js index ae65cdf..12f1f8b 100644 --- a/src/antigravity_provider/router/web/static/app.js +++ b/src/antigravity_provider/router/web/static/app.js @@ -787,6 +787,7 @@ function renderAccountCard(profile) { + ${quotaGridHtml} `; @@ -991,14 +992,32 @@ function renderOverviewView() { function getProviderIcon(provider) { const map = { - 'openai-codex': 'codex.png', - 'google-antigravity': 'антигравити.png', - 'opencode-go': 'opencode.png', - 'anthropic-claude': 'claude.png', - 'deepseek': 'deepseek.png', - 'grok': 'grok.jfif' + 'openai-codex':'openai.png', openai:'openai.png', codex:'openai.png', + antigravity:'antigravity.png', 'google-antigravity':'antigravity.png', + 'opencode-go':'opencode.png', opencode:'opencode.png', + claude:'claude-color.svg', 'anthropic-claude':'claude-color.svg', anthropic:'claude-color.svg', + grok:'grok.svg', xai:'grok.svg', ollama:'ollama.svg', + nvidia:'nvidia-color.svg', openrouter:'openrouter.svg', + deepseek:'deepseek-color.svg', vllm:'vllm-color.svg', lmstudio:'lmstudio.svg', + local:'unknown.svg', 'llama.cpp':'unknown.svg', }; - return map[provider] || 'llama.png'; + return 'brands/'+(map[String(provider || '').toLowerCase()] || 'unknown.svg'); +} + +function getModelIcon(model) { + const name=String(model || '').toLowerCase().split('/').at(-1); + const family=[ + [/^gemini(?:[-.:]|$)/,'gemini-color.svg'], + [/^claude(?:[-.:]|$)/,'claude-color.svg'],[/^(?:gpt|chatgpt|codex|o[134])(?:[-.:0-9]|$)/,'openai.png'], + [/^grok(?:[-.:]|$)/,'grok.svg'],[/^deepseek(?:[-.:]|$)/,'deepseek-color.svg'], + [/^qwen(?:[-.:0-9]|$)/,'qwen-color.svg'],[/^(?:llama|meta-llama)(?:[-.:0-9]|$)/,'meta-color.svg'], + [/^(?:mistral|mixtral|codestral|devstral|magistral)(?:[-.:0-9]|$)/,'mistral-color.svg'], + ].find(([pattern])=>pattern.test(name)); + return 'brands/'+(family?.[1] || 'unknown.svg'); +} + +function modelBrandLabel(model) { + return `${escapeHtml(model || 'Модель: Н/Д')}`; } function renderRoutingView() { renderAccountRouting(); } diff --git a/src/antigravity_provider/router/web/static/brands/LICENSE-lobe-icons.txt b/src/antigravity_provider/router/web/static/brands/LICENSE-lobe-icons.txt new file mode 100644 index 0000000..1dd53d2 --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/LICENSE-lobe-icons.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 LobeHub + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/antigravity_provider/router/web/static/brands/README.md b/src/antigravity_provider/router/web/static/brands/README.md new file mode 100644 index 0000000..b1c0b3d --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/README.md @@ -0,0 +1,3 @@ +# Brand assets + +Existing PNGs copied unchanged from assets/providers. Other SVG marks: https://github.com/lobehub/lobe-icons (MIT), revision 4aaf4ee1fb2678a7f989ea570f0f6ce14a9abf75; license bundled. Served locally without CDN. SVG geometry unchanged. Trademarks belong to their owners. diff --git a/src/antigravity_provider/router/web/static/brands/antigravity.png b/src/antigravity_provider/router/web/static/brands/antigravity.png new file mode 100644 index 0000000000000000000000000000000000000000..d53a1b803e4e486863b34e4aabad30688c713fd7 GIT binary patch literal 13126 zcmV-MGr7!(P)6V8AiYEJ;Qz#vwd{A%xhLY}q7yWHj#u z5=`(CCx8fGz&rvo@V&>w1aCnz#&`*FSgo++L1OSG8EcuXyYH>4_nmX9>Q?uR!Ioz< zJ+eyQ)xCXtnVCN4{O3PQRUsUL!wrLi^?^lzg8*BYXj^lg3^t1SxLqi(J#`yCNrGapW4L1rp2!8U5 zC;lcD({Hx3=2g0cr_@Q-O$VlleAq$(6bPzB$gG0QXwX)HD-l{Pe8Aak9CdzWefy19 zgL5!CG^B^d#w-FjI7G%FqX5qF--3u>@BPAwPp<3Pzi`dgnX7WlW~Ll8X3$}Y7E44q zSonwq0vH4+l*0lYlzd=rm8vTZU=*|pyvW_~-;06aXoR}zKnU7_!0HdRzH*Es*?Q37!zt-OSv6XrGy27r{8+jYF+O6YF@)<{9+19gE}wC;@Rryto`AwpAU}+N(&OigDhW1 zL?9HfAZQ?nfIvJGLFtwQTUdj+DLyy#`j@|)kzi;@!!jIdIkNq2>xU3v7$^7KJ(l;v zGfDVP=}e$LW1$yLgl`-Pp9D+K$q|HJvMV5$Ag?LCf`oe{csVPu3c=CAE0LyGFI~TBH$6&T`<3#z*@sloHv%;RY=NAP9Zvy*tSP%atfMO^Q z?m!{{f_#Q`J_BG&$@{|N4(M0OA)k+OP42)r)320nS@px-)lYm59Q%oB7y-AO@&szR zkvlPH?12ZV-plcTp!CO3LV7x0JD-Y-B3OxJ^ z0tgbg=n?=>DLrLv*{ktslY8#`2#2DBgUbp9mJI?74-b>yhtp0wW397$zo)<)Su_lh zGey>@tdO)|!NICItP2*MSb2PG=(+H`oaLTtLjb;J>vs_W1Q8riwqRwJXH%%&uwv}m ze_T#!<7I;Y>(}qZkrA*n<^Id_KD~Cj39fXRDqRM26#i&|ri2Z&oD!>NG#~`X1P%CF zLxFM-D$w(RA8@$Xh6aKdfgDQc7!L5EBB+KbtuD&Hb#ES83u9xB>k-RfsO1yykD2Rl ze%WcYKKv}m z;~3sh3OFTmp164zP#qXyUB~AH;={FO=qEQo*WN8ydW{3+pmGOt&-7@mntA=CRij_N zbvd|#u1A3J@j*R;V1KgjU*1|@S$oD*LzxmYC7~X{yz*90EFgvuz70sz`0fad!skJ-Y-qIKb-#nZiD z`E(}h=d(uuLK|(JAOQak&aBEZJ(btaSoQfYU)}8}pt{}q$<5Bd)Z1$-YsbvC&=gK9 z@%I(+qsPJ0TV(aY@+0XB9Kl5R*jhBvEPzayF#9&DJ(Y zk;~XvSEB$f2kYNw_y0gCcx=&h&N)=hDzbe5fX&oP>UI?V{yt zy5@!u;sO4-va<3lpn$FJ(=|W#h#+X-ulaYfW;LMz=rdM*@yl257#z$tc4@6Zb-VTN zg~nMuD|(KZX@M;uQ*6cL`zd@&e7~Rp`Tokk3o2B6Al^$}*GiEhpaP$Lv=ESh(#aG7 z#2SJ}0*Vq6p1_d-g^LcLD9elJZ`m+0!MzIIIJz1E#_kx-r}usDdsz*SYt33`ol?#q zTYf+RO3Bf+SUd+{!U_E2z~}=n2nfJdUHWT_{;{|2k}TiyJvv7u@cv)(bDj_Q1FaQQ z@CO=e`!lVIyngbk&wugeZsh`9i2%bp1~W3G>8T%`UK^-Ab!OJF^^3)ezYhtVX#J40 z@0V+TcvPUMfTM#L0T3eOP@o*b1H|&fIUqraxulj=g$9PMRTc|Ml!g{gQ1Jq*l+CFL zsns|Kx_ES@0>Fk144H+qe^NN*O2`H7J?xilLiXWabOUnD$`AyfxPlNOwv@jnCE$B0 zVI)P6do9iwCJN%+LToJIkg(k)_~en^XRK2WU-`gULysrxXHwW@qwBg^hTX6l!4doM ze|z(~qHJ!QoV4Ja(#9g4!8!$wV4n{qE`aNAimUbXj~*k)W99vv;(zj(B18?2qeu(R z7kC_B)7kN1<2CrlbkH?1OQ+~(lP{w3Fx{h+u$;L#0n~|R%cHWacXGD)0|59-7$2t} z-&K5|>l7e-NsVUlhdnE5dbU|mStjEgJPV(cK!neNrw}YE00{-+HIi^dek^?LP_lPk z3N{?15a=LN4y+?V)4fXIB7DUuKT!@Mdi0#)G@)}Aw0|BHHzxyFx{qqgI%pdErtc38 zT?}Jmh1bWf2@ShT0UY26PMFb~H}~FccfYQju~3pT^_FifDS=K9fUbj$i!y|34hI05|A=P!PD7zBoL(_mM_Xdj}fwf2EK>TH>iVBPE8qO zS7rHcxqvL;;imlq7_|Pbo%j5b(-E*Mba+ zDi%s(Q50_ifa{^lMpr4o&fP~dG#1Xh5mfGs)ASXJ_4`H+b^%`atOV@yDG?Mn0a<>< z2k5cDzNiC1KJx%4g3rP=`+N}L^FOir0RK6C2)hTmAE2KEPrtGt0v(jR2nxZWjI(;O zq-WGCetyN3W=)>2o@trW0pK&^)HT#4nZd46fNkU37@haErcciX>Z@k=7L;yb_%~kYCJ3Dc zt|Kx8=x3KezTb+D1VS7i8!{e`Q(p}|FH%IEeMCt6`&j;VMMQ!v(FRI=kO7d zM|3YFiG0q0OUjv=w4^Gy;Xltj`xu&6C@pSFKe8@@fBT_tpMUi3$?3t?j6-8H%?+I1 z+D$|Nv3%wLwn6|23q8;0u#nI|5P)0)kw7|V_NXRzPWJ7H7zP3;F~8&mf~AY~2bd2Q zEgZlkRxa)0a!s%ENMJc1z|Dj$W6C3HJ^jf@UFAB9QC-5UUGjo zL<3njRQ(Xg%%$HNUcGDoo{e_aV(AF}y~PvETTy^O27}Or2oivc0+4b@8jq}A3n^pe z@F`(W24{%d2Qw7bmPU;>pDI-tYKoLd{isI7>p`_P3D2A#woh5zNRr*8bb;Y;D3()&yp~( zQiN~_^rHuO&jZ+1_ynC3;S)Mob`X^Qm4kyoHp$=u0xpQvi}j1;hY*nA-zz~BK3RX@ z2^5_eKhs#DGnl#3w$300*nKo3A3UlR;EwS-I8|3T`wE3M@{z6*y7&LiBY?{U_Spr9 zaxe$*M3EJMY@N+H^JFljghLoeA}6tmDop;5yS^! zlOYrTAcYW8%DBT^!7vw~C#Ec5>C}t=b$Gb%#F3GirFH{L9g5({#*uRSzi!W422O1> zEE>=%gnT4)3iAvdkn@=zJAcn#Q@BUhgbw^1)Y{)i;UJx%CcS_3JRO+Fv!QF>DMa^T zCsF7bz$9!8VWg@;!_tS7bnxeo237BGgexBVyst_Vv(D_>7PE38IQ`F{%eI3i&(C~k;UV7YV%cKlbWbc_UgPhxJMiy`ug$%+2UPG@ z&(<6eL7o$<_m;0}5%SB9Od&%*J)d01*C}o_BOXAX`OI&=W80HRJ(jXlXz38ZIUGT> ze|F1zAG2qwd7_zhBrp}oUr>Tz<#aC)KN2R9K_YrF5}?P-`XxWWp&2KIe8JyW2rKq4 z%_2npW9Ua@kdjHhRU{HZB7(62gg(>IA`xOgO!9n=z?K~-KoLVJkpR7h?;CWsEZ6kZ z^66%40|5MFd_4B3JbDyhczl~40VpSD%*m>+Z=f+*7|Y>bi1|gh!Q$mC*D?O*YkADD z?*$(lMSKR3AX^f8(oDjF_fdgM2sqdHSxI~+kS`EPxW_9(2-ElF;27?a;wf5RM3h5T zqVS0z-=Y?kg)^AQH3N&~O99{$yN_PKWKqD9DZsct7fzjuM8*t#-Ps)LXF+=uh|0hM z_rmufVMqsy;41~-aEz@wZ4@D)NS;sz37a)QAc2I+87i`C>lMQzKrA2=p$IAHQcx!F z01E6vR?_nU47mcSRH`XTL0k30n>T;3_oPcV%`R0qxMaR(V&jMz9Uaw$fx%{jzGx5s zLHOQpTW0p67}h^#A080GBZ0hD-WS~hlRvrVyx$M+VPym11WY=4+Lu)E0+*ocP}Sow zE@>5)NhJQBpHxCDKiqE%5j(Cq9CYYZt@qcb%It)t3+h1*G?gncPFY$J*$s|^r%Y^3jG?YgB22baVJ1ky88;3=x!uT7&UEroyHssjQr z?EA-3`0@Te5vA`B}(F0sdG3q&Mr zSt&w<9y*YG3YdL=h!SFITCOE$!I1&;00jM7v6ba#D<(NnCfdGoYLvLX67cLzV*!jS1QL$;{MmTHSMOtKporT9IE5)*qE2Ig8M%b0`D1hlSywLQn_~ zi2!=ez^);bko|pMM&`vNnH+{We!>IVR}&4(&{d012|*0}Kzx2h60_*@h5S)cNRmkY zo`tLznxH8k0BhH+J?K2(pd-L8pZ+aDy$EalU}qb~LYB1&J^K2J*hRtl>R*Ka7zPFb zS7~4g|B~(??*6GJi#XpLD%S2>3HVYT%j={gh^~zjkd|kBlR5DKMjDF!y$fMp;JcCo z9|&!0kX)m}Sz6-8A}hc+jN3zA0gjgLA86TZ15MI1F2fMU3G64ae~AA(U|%dZDgS!- zkJCKjoI#(9XFu%)$H|{yXvhjd)53@c&~+q%zTZD62f2Wl3vgE8KTJm9bUrDYsY<`} zv!ZhNGO_0gl|rDR^{y1wo_W=ufAN^JMt<)e-yi7?O$Bfc#}Lgsc8m_(y=U)p$)c>w zRC|`s`}zp|q3V`F3f2OWYOU`YNr zxPSlj2`;ZcrfgF4M}`#v42ha53=ICfO8q9e|EL7y&*eE`{vH*=bqc#xHV$NZna?0n zr%&>jXC$>9G=n(sgRoYRa0ST=$P%^82SQsouRj=)L{&++>JeZL;VhMh2@$D5=8l8Q z0}d(z>{=^-T+85#T%G*?tg%khHxPyIDAVW5y|M2vvj29g7fbi7KVkaSS(-CtcuNfM z@6o_frxv5V5CHBErhA+&j@^Mm+zpb%8?qI4lwo7OD0NRR=T>OZU&I zB(2P8;~b36amH9ei1i=;9}~xt<2aa;MzVul{vEo0bk+VntrKmN$Wo^0iwu@s6@J>u zUI^(zj4#QatfSx)iIsm%at_vB*>7AP2?N(--%Y=!5OHY|_2nbq9V~o+vWkJMODZW? zKJ76jKg%OZtSr(8OBPXn0Vz1~d}T+Bfq1|`y;00O9{_#^uz?oFJ}41^I@tcdHHE(g zwf-Z^7FzQE(&Q;FARvGwfT}2O34$0=iZ@cn`anjYuQs2*q<$p;+FksWORKWp$s z(9;Xf&RFL%Ri$=4oCj-9QR4|_{3{iwwyC4Je10M|-v33tUUb$rYIIUHn8ZK{<_T~RdBDLz0B*xUJ9N!8Yj!^{^K9ENBzV;>=%l&BL%&qiBxNgpzk>ZV;UiPR zJ%lI1o_o;nS-^+}&MzuewR%*EqEHhImf{zJAS9q^Wlm-lO5Vn24=HQt(IldQPZWhb zL3{py5>d$cfO_xB+H7OrNdWNEgT({X!Sw%o_q0xg+Q4d4QUQ<Ywqvc>eO28{XZt4oeyQ~bpWnvz zgYOTy`cUt$EI;u2YG5D%BJI3xo zCCwr9p{JyaMX42(s$n=+aPsJ=)0;LOoObbpf&dd6gw&Kq50)*0T#fAWeVEst`%go^ z#Ny-nUJovOSsN(y{3TYNDusu5$pL`x3QkF*40(;r9SBJ!xkn!t7OD~?fRHN)+sm|B zKP@CF5rgbin6<4wUifW|X%UI0HDIvkxF6s7!{c~MJ($$kRRkkI2QXxw*FU|givwtp*&d2hrhC*J21)*CYMF)B8 zr-m~8SBud}QAs}CcM@^LAG(TUi}Q#)Jl8O|E>qU)E3;;E@5uo0gR1*<@y4QS*wC2# zjG0#XJgl$iwdzB_cZC1Y z)(H^$vN_A&_BXH)xs5zdCiASouNumV818tJ^`F8n!ncz#A7D4;GlFSOL9j#3mM!{$ zCtZH|k9yACgiT*iaLX0}CN^#`RO2?FUSwKSP7Uzyt>3TE6B;_(g`d{?E1zF26PvL1 z5Ml)@kEvLOT1vB&wAqZvOe1POl+s%9wW6gXd2Ki1Y^9S9PM31Q(9$J5pxRG3?i~c3 zN5u^|V&F_6bf zc%KCywzQA?6&h7vg-xRe`R8q0Tp2B@3mAkAY63=VqY0;A&&ryeoH1;AA^b}$KlJOh z#rkPlH^%ts|4`V>I>eATB1cpZqQHK=IzAT@&fh7w*?Oja4;!40LM zugI?@BrT+gs!#!#A{N(C9P(Yrw8}U&%GmrR0C4Hfor}BY(4s29(d&21(yvyXDgw`4 zJLB)j>_rlnT6R0RYa@0Y89!<-MbIkm)7rM|FR~Io)03;ujBi%A&(~&kLv`5%fGGgj z4FLZR09Vt^Q!jImZ&-L$Y2hupSDir9{#;=UA}<*dl|Tq!a228i6|<+7ufPQoLhn&T zt|iW()--x~vuM$)pMTNz2UflRZEN<0NNO=;w3z;db^Ek``ccpBpWpujr~95r%YShK z$mjcs{Dn}kO8)rvt~B$PX8Jn9zHm)GUf1#rjcsNct{AAPOK4h%5@guLWc4J^d=PGcUbt%TYHBjXFKHNQt3ELx7>t zQ8l({lbN}9?=xN2`$XF!_D}hLPxO-2zS|B@@}!@yV*KqcAYu42!`I|}d4?@}b6u%- z-grKKD+ql9fE^h@J2ApjcB_%L-C(@cZe_Hl+cwZ68~MFgoq4(Y(wzqWr>?1Uc!G~5 z#NkyVs+@q&20&XxAPCO^Ov3tOh);kLrlj+qq%G*WYL$&s38>cHv3Q2MXbP~)_qNSC z^%CqE0N0#0V6&_p{zC;XN$&=T@66=QYx&$m>+*W8vl6a&*_7HcGJ+)ueqtM#3B+>Z zk^B*eZh|+X6J`2e=i+_kBr3ee!i^x^zD7%WLAM8uVT!~C( zBzvWB&Z?Fv=+Aoz@1a1IqebcyTQr6_;d|W65?^Ku;?V+#ReD#?-!ESQXgk^KtmqNR zM`g2Gu2fl^f6MuJ&d3Oup&_T)+85YoPS9r(B9L;OhhzO2Y*b+HRy|sAc$uV_<)~@} zA#4lLn?;inL(hEY6?>jYf6HQ}g%?Kwh_sB1*cX5HyN|I>J;yX@ zrxYpwwk37u5pwkZNj*PK;`HnLvGkQPx+l|FY2JR@1+`1q$2)+ru|+JRAUaZn-#**r z*PV;E_bc^cuy7aFl&00~YlJ~gXO!JbtEuA~GE#nc^^AJ+8kB5|U>xJ3& z-`?)>#jyGZ8@GQH3sSgiH{%cc9Gr#@_JF3&K_QKy&X86E$Q=a5sCGUH3gB}Fe2=(- z&k1lMBcs*C9FbR8E(&n;`VBJsr{zxfbMVMy=fwLGN>$b#vV9@X9b}=lGhn^1B`6deD-cu0EZN^yy?mvb!*&9EWtmokd!Xv5(HYY{y_Yy`F+(q z{#eSj&SX6#eDlw@ZOt~50B%29NZL}2333P9UA|*0el4?bURGDy0+;~#GLI12Q^#Sc z`gp%`6O~eMrVtC$ve?si^v~~`dO=!PTgb8CA2>8B-9JBQtv%7@1CO_~_5*GCn!tK{ zp{L64w-LQLtzFKlOe-kNeMj}_H_~^@vHC%rM>pRf^kHJS75@$z@HySf`%u${^CIB5 z!VHit=N(T##Q)7PnZLu>%^2ZfHH=mp0?xT*F(Dwzt~ux6P)b@^9ztosiM1 ztUf?~f(9MX@0#YWWAbb(SsGhhmyNMaXh<=4Y{BcWfKOz-6dKZslJb1jU=pr{4@g^@ z7rv{|ASwanka{v~7)MLY!}tPM2N(3iLaaL5bZ21CN-ZlTR=xR=;PJOmDMB@c+mBFO zWAURS=uhMhXH7cO*7xDRuh{!Q|%3O_8=1PSasE+O_Auri=3 z$PE~HCFMOATKN}L0m3g=mhfs@@LKvZ&o)?hSU4dFKKgtboxY!mlhM7ocFp3to3`d( zSj?ixf{YQgq@e%jPw^MIfC(-JUx3-dM|COw>RI+PmV#?kFiZ? zNKwDG1wLtJ?QN&=vM@Zp=z#ht|Z7d6ehz=Qe^2I^{yOdU$g zjP33qMhLtXf%pG>1YRI35tRkd9s|F(&~9MC6o7sy?)@w6kR_+(;lCnwRh(Zf-_{=X z1&AaHt+EVV!`|PwO8q6F%h(-DySvtbpulzK;>}pXn66VQ)Ee>cz8NIAf+RaQx6LdR zj8V6mw2!uW*6TmiI-aABp;1n^cZULa_d$h`S?aLY(f4<@bcH64j?SLg zUSYxMno=3MznXX(-p}aLB{Ba)9qU+O9rk7LZd*WuHi`(V4@Ti8u0XPY?e&8YHWC_8 zld7s|)hyHyeg3X>L)bM6FbL!PInC0%4r?p?c3B?wJIP%XeEZTZm3=!)f2eJmpFCdc z4|CYJ2nmqI9wS5uM?qb8KK_TcuwB==*+;klt43Pktaw4J6(o~Sq(B554HO24s6%O? zzLSMe0Gt@vXog0=Un>l5vdt#JJt;v|#0hR7$?Ho`gnS9{e`ZAJbf&PL!SLAmI4j(u zJHx(THP~%Aher*-`)m{Tpk^fy6!1zAu6e|~K)Vuno}kLYTFmv+c7C@wnZ7S_GqBVO zFf_{2h5vWo%8jbF;>oUPQsl0xt=bY4h_iEp@Y_?qv{sVt$&_oB-+A1z`X9ymJ6gGx z(-=WZEoJ}v9k@#aT%vm@EVQ;W1WesRTcOA|mOxYzT1^6=Ve}tV*wGav5M9f_n?dE& z-sO9plhwHs#@{woOB!OU)^5LaPEEtRnMhI6XPJ))Unh8c4gS_N;BKVAMxwqrqQ6g~ z0`dJmOX!Irm57U`qjKY`-|`Q8*Kkhc5tfJ_nF0(CEBYl)*}m%-=kzP=>TE8CSUH!3elVLIw|50r-a^x~uQF z=VhvA)ze*TmLe6^S=ybC4|E`a6WtpE~$m#LTcrCQxdP)&fp@^Pq6SBATFrq?KVIxv%S=CivvuV$!hX-09IzR-V zY$Up=rrmI<(!b;&Af-Lc)iy034oyJ!$)WPq8k4t(}>4NR!?>h+lP0 zqx1LT$Fv@Tb`5jSs#WS@{@kIZ**WWA4svf&F2;XT20oqj^43$r1p*4h_ObSLjM`j< zLuC!4z+?8$n744ac>p2d!&U$Z&(KXx+pXBMvPV|Zpvqr>_^REjTD}G5Mgdar!Cb+6 zZg?B+>*h|M#Yz#cUIFiMP1w&pgg!;g(oM=EDF=ugp}MDvCb*)+&2Rj)>pu__cz6on zt@MNI=lye3*`lORqrCm)7w9Vwy|C}0rHH@s$9R`U zcwa_^BEL&W33$|r(?68!MU^|QD?uvFMGYKtHQ8d6Bge|YReEQePO+VDUz(aabu+ryU zw(E4rSDkKWCk^}lIjvr41ORiQ00(HP(+cKb0t=%64#&m--gM

kX?fwT9Z<)75a2l2&vD zeudcdQzYL{6Fa|p>xJ2;AGOfmIXq-vy9Mv5DL9{d2098nsS?O{oKy_sBr4RcSuiHU zvtE9QJ0+kCJW>T190mt5=Bb?Xcbb<<>zubAe$)04P*(H6Oe2M${ zc6yWa%pD%-tfH@9fS+`;@Rh6%S!^HchzydYE87Z3^0c8f3ZPNK-=DqRT_{zypoBUc|Kt7ARP(FC!UtCX)|??AO`37}CqUJ5q8Yru zMbh7w_WHF8KQ7N+(!@?|l%KzKYxb$Go7mZ9u7H-d%K_d_vx>ML6fD0p{OiaM(2%p$ z#jG`@f_ITNlY_yVHOe)tvgSMXmv&&@xzHxr-R)+pVw9dbv1JMyd zzT#YL4rH(iEbPH7**GHQ+ex=jxEB-!5wl|2maeY;aKi`6cZB6^=KQ#}N0dAm0r$#} z-9K>W{+@3*)qA{cPV)lK?Y(^+1)ey`!T%!GmH9xPsYdzXf4L}sM?jQ?{iY7>G33MK z7hdd6Ybp4uDZsEH`gV%8qI%mq(|u8Svtz4s1-XNlk6(cQ+$oC+0lbf(xBPsvXVm2@ zNcbfS-%s1BJiYh&b9UokZ+8)|Pk_dNY5{!V)DJd~?<9p@0ccI!ag8HrPrPjMQ?9n+G&{4eM9|q>pAU0g zKomZdSv}9NwBKFj^w0=`lT`0vzyC;~w+P^0u{l(pvudVwiZ`_Rk zepvX6qy*alhqnP-`vLg8>w({AB|u!LMuH1Ez_d{MQ;mjT9<7fHavoGHN ze_egW8D?hEfTAs3{L9lGKY6oPs)X>7&$srcHB5G{2hnGy~P|piH6$%Z{3P#sRmq;_d!NPKXi&!em~90Rr3vq5SRii z*3_~0>@#o4ngyPNS&eu0oo~m@un~5=&lx^6d4HCxmbvDbOuwF&Zxb$YIM!e6!J8DZ znAI&8;W;n(fV(T}fxk8-0Pj32OR=(@%8o_;ZG1D<3(y+nN~hnToWoNrZBmrX>kG`E z^etV&l{ZFE8mYLWTlR|InbNNy;ZsO)xWIFemB7ylyk#rCzh+@bDcG-T+*c^IgSPrW zd&ZE~Z?YwAre=@BXT5($b~@uNOM<}V%KtR+_6~^Y(~eIwl-|8{YxeP2U^txLU$PN6 z*Qp^*s5-t$CM&;Rj1CT=#zI8+$&S5iu{>6>glvzG(3cKD}N)GTu?^&(! zJ33QeTxq92d+nBid+4?FgARA|bm{O3BWmFz;(p5CxYG**zgs$Z9soR!UV;k#GuQCt gU+afUs6_w&0j}Ubft5s{g8%>k07*qoM6N<$f{$)jvH$=8 literal 0 HcmV?d00001 diff --git a/src/antigravity_provider/router/web/static/brands/catalog.html b/src/antigravity_provider/router/web/static/brands/catalog.html new file mode 100644 index 0000000..b29d0f3 --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/catalog.html @@ -0,0 +1 @@ +Hermes Hub — логотипы моделей и провайдеров

Логотипы моделей и провайдеров

Локальные файлы. Первые три — существующий набор; остальные — масштабируемые SVG. Последний значок используется только для неизвестной модели.

openai.pngopenai.png
antigravity.pngantigravity.png
opencode.pngopencode.png
gemini-color.svggemini-color.svg
claude-color.svgclaude-color.svg
grok.svggrok.svg
ollama.svgollama.svg
nvidia-color.svgnvidia-color.svg
openrouter.svgopenrouter.svg
deepseek-color.svgdeepseek-color.svg
qwen-color.svgqwen-color.svg
meta-color.svgmeta-color.svg
mistral-color.svgmistral-color.svg
vllm-color.svgvllm-color.svg
lmstudio.svglmstudio.svg
unknown.svgunknown.svg
\ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/claude-color.svg b/src/antigravity_provider/router/web/static/brands/claude-color.svg new file mode 100644 index 0000000..62dc0db --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/claude-color.svg @@ -0,0 +1 @@ +Claude \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/deepseek-color.svg b/src/antigravity_provider/router/web/static/brands/deepseek-color.svg new file mode 100644 index 0000000..3fc2302 --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/deepseek-color.svg @@ -0,0 +1 @@ +DeepSeek \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/gemini-color.svg b/src/antigravity_provider/router/web/static/brands/gemini-color.svg new file mode 100644 index 0000000..62681df --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/gemini-color.svg @@ -0,0 +1 @@ +Gemini \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/grok.svg b/src/antigravity_provider/router/web/static/brands/grok.svg new file mode 100644 index 0000000..efb1a61 --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/grok.svg @@ -0,0 +1 @@ +Grok \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/lmstudio.svg b/src/antigravity_provider/router/web/static/brands/lmstudio.svg new file mode 100644 index 0000000..ea0816b --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/lmstudio.svg @@ -0,0 +1 @@ +LM Studio \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/meta-color.svg b/src/antigravity_provider/router/web/static/brands/meta-color.svg new file mode 100644 index 0000000..a8a8d94 --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/meta-color.svg @@ -0,0 +1 @@ +Meta \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/mistral-color.svg b/src/antigravity_provider/router/web/static/brands/mistral-color.svg new file mode 100644 index 0000000..8e03e24 --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/mistral-color.svg @@ -0,0 +1 @@ +Mistral \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/nvidia-color.svg b/src/antigravity_provider/router/web/static/brands/nvidia-color.svg new file mode 100644 index 0000000..a9683c2 --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/nvidia-color.svg @@ -0,0 +1 @@ +Nvidia \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/ollama.svg b/src/antigravity_provider/router/web/static/brands/ollama.svg new file mode 100644 index 0000000..cc887e3 --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/ollama.svg @@ -0,0 +1 @@ +Ollama \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/openai.png b/src/antigravity_provider/router/web/static/brands/openai.png new file mode 100644 index 0000000000000000000000000000000000000000..7bfb26c0f7887100f8400670ce9ad92f8433cc9f GIT binary patch literal 6607 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 N002ovPDHLkV1jX+S)Kp@ literal 0 HcmV?d00001 diff --git a/src/antigravity_provider/router/web/static/brands/opencode.png b/src/antigravity_provider/router/web/static/brands/opencode.png new file mode 100644 index 0000000000000000000000000000000000000000..145cae786c8ddacfa3873d688988cc9aea49fbde GIT binary patch literal 1615 zcma)7Yc!Mz82)C=@EL>Ax{Mkbgi#zeC+fJ(7(!cP2&G&mtcF}BX~u2&kR+6GjWG!m zg{W2|m&^#+vQjRQ`!yv(NY-t2cK4h;d-}0I-uFG{{q;QOeV*q{pi-9>K7Ky~KuE49jb_{cAhbo%=;}~)OVTF_ zN``HRnvuq0qcP|mX^9e8hRCgwz#hD>?#D5^cnL-kPhL~xgEX`ioB?k3cs*qk1nW&U|>}yRFa}P}g+32nn;H^RRq1(?vmi|2NU7V!5xEjHQC!-9FFKa+kH!sjR8a zbw_{q^+OBvTmr>io6T{C(&@+gyB_imgv`D6;+^N^Ti~>bH1SKE)@)yNN6A%DcFJy5 zJBw2)p2fa}axCw~t8v%O{R-sxMIG07*thj8;Xw<#3{2Tb{BqRSoTTg*sK}E8PK(a# z2OaVgm+va}rbZ{_(f#Wi43yJK1YO~8#qfkB7zCNag!#ZWTm}I+C=1|FfD{slhePCl ztus~>?)&ZWa*#U>O$Lc`FFQEaTT(-NHa~v+h(o3V1bO<4C%*ko@`-WhWEnC-)PV11 zcX!76LQmd)P8-iBXNh%5gXF0GjNmSaVB1#ZO)M#E@4=5_r5_yor`h;Vd8J-D54scTMrRlCO#orXO+q?AO=XnKm#q^diDE>$#W57F*+_)GwINireaX+CtDM1`U{BtI)NIYGeU_9bZcwr|o%EqhaFRS#NHuGLm}h9!H+>kwTXKaY-Et*))DRCYXj@To$Y zU*F)X-sxW4+z!g?K*u&u>bOuetQ7D~_+{SAQ(bqUkb~k!&4|?Pb`y;`UJ2x`!xW%8 zB@{qeo*s#QaA~N!~bUn_>e9yrioF+jwJTzAv{z zMR1I&cMH%G>tzlfO|%S{L=<(qY#p-In{%#d$jlCx+|cM*!~HTb*kJU~cbD^lQtg<4 z0I5eA&Zz`=eeP_3JC61%vD9h|c+ddOx>*hy_tzmyKe12*g z9vs}LXy@4I6h zv6;&p<0mVdH__RZ{euw;7ugEcOq>KLXfGe|sNf=aTn0uuwv+w#sS3nRZq znA%pzAVF9Ck%Vx~`%6lOLswZ-Rpw@}_q3&&-vs|7B)*p&k$~st`%g+vmo9HV3c$va KVo`2Ri}@2+SIj2> literal 0 HcmV?d00001 diff --git a/src/antigravity_provider/router/web/static/brands/openrouter.svg b/src/antigravity_provider/router/web/static/brands/openrouter.svg new file mode 100644 index 0000000..029070c --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/openrouter.svg @@ -0,0 +1 @@ +OpenRouter \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/qwen-color.svg b/src/antigravity_provider/router/web/static/brands/qwen-color.svg new file mode 100644 index 0000000..f2d0ada --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/qwen-color.svg @@ -0,0 +1 @@ +Qwen \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/unknown.svg b/src/antigravity_provider/router/web/static/brands/unknown.svg new file mode 100644 index 0000000..38f80ad --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/unknown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/brands/vllm-color.svg b/src/antigravity_provider/router/web/static/brands/vllm-color.svg new file mode 100644 index 0000000..54acc3d --- /dev/null +++ b/src/antigravity_provider/router/web/static/brands/vllm-color.svg @@ -0,0 +1 @@ +vLLM \ No newline at end of file diff --git a/src/antigravity_provider/router/web/static/style.css b/src/antigravity_provider/router/web/static/style.css index b677047..0f593bb 100644 --- a/src/antigravity_provider/router/web/static/style.css +++ b/src/antigravity_provider/router/web/static/style.css @@ -1915,3 +1915,12 @@ body[data-theme="medium"] .nav-item.active .nav-icon { stroke:var(--text-accent) .status-dot.not-ready { background:var(--status-error); } .status-dot.ready { background:var(--status-healthy); } .resource-value { font-size:clamp(18px,1.7vw,26px); } +/* Brand marks are local assets, separate for a provider and the model it hosts. */ +.brand-logo,.account-provider-tag img,.available-account-card>img { width:24px; height:24px; object-fit:contain; padding:3px; border-radius:4px; background:#fff; flex:none; } +.model-brand { display:inline-flex; align-items:center; gap:6px; min-width:0; } +.model-brand>span { overflow-wrap:anywhere; } +.account-models { display:flex; gap:8px; flex-wrap:wrap; margin:10px 0; font-size:11px; } +.account-models:empty { display:none; } +.route-model-with-logo { display:flex; align-items:center; gap:6px; min-width:0; } +.route-model-with-logo select { min-width:0; } +.agent-node-icon .brand-logo { width:27px; height:27px; } diff --git a/src/antigravity_provider/router/web/static/workflow.js b/src/antigravity_provider/router/web/static/workflow.js index 9495d01..fdb750d 100644 --- a/src/antigravity_provider/router/web/static/workflow.js +++ b/src/antigravity_provider/router/web/static/workflow.js @@ -212,7 +212,7 @@ function renderWorkflowNodes(workflow) { const assignment = `${cfg.model || 'Модель: Н/Д'} • ${cfg.account || 'Аккаунт: Н/Д'}`; return `
-

${wfEscape(agent.name)}

${wfEscape(agent.agent_file?.split('/').pop() || 'Agent File: Н/Д')}

${wfEscape(assignment)}

+

${wfEscape(agent.name)}

${wfEscape(agent.agent_file?.split('/').pop() || 'Agent File: Н/Д')}

${wfEscape(assignment)}

${wfEscape(runtimeStateLabel(agent.runtime_state))}
`; }).join(''); diff --git a/src/antigravity_provider/router/web/static/workspace.js b/src/antigravity_provider/router/web/static/workspace.js index edb881e..0e8514e 100644 --- a/src/antigravity_provider/router/web/static/workspace.js +++ b/src/antigravity_provider/router/web/static/workspace.js @@ -135,7 +135,7 @@ function renderAccountRouting() { const profile = profiles[node.profile_id] || {profile_id:node.profile_id,provider:node.provider}; const quota = profile.quota_snapshot || snapshot.quotas?.[node.profile_id] || {}; const reset = (quota.buckets || []).map(b => b.reset_time_formatted || b.reset_after_formatted).filter(Boolean).join('; '); - return ``; + return ``; }).join(''); return `

${escapeHtml(agent?.name || pipeline.role_name_ru || roleId)}

${escapeHtml(agent?.description || role?.role_description_ru || '')}

ПриоритетАккаунтМодельКвота · остатокСбросСтатус
${rows || '

Аккаунты не назначены. Добавьте подключённый аккаунт.

'}
+ Перетащите аккаунт в конец маршрута

Session Affinity: ${pipeline.session_affinity ? 'включена' : 'отключена'} · Порядок применяется к следующим назначениям

`; }).join('') || '

Агенты ещё не созданы. Добавьте агента на «Обзоре».

'; diff --git a/tests/test_brand_icons.js b/tests/test_brand_icons.js new file mode 100644 index 0000000..c74bb62 --- /dev/null +++ b/tests/test_brand_icons.js @@ -0,0 +1,13 @@ +const assert=require('node:assert/strict'),fs=require('node:fs'),vm=require('node:vm'); +const root='src/antigravity_provider/router/web/static/'; +const source=fs.readFileSync(root+'app.js','utf8'); +const context=vm.createContext({}); +vm.runInContext(source.slice(source.indexOf('function getProviderIcon('),source.indexOf('function modelBrandLabel(')),context); +for(const provider of ['openai-codex','antigravity','google-antigravity','opencode-go','claude','anthropic-claude','grok','ollama','local','vllm','openrouter','nvidia','unknown'])assert(fs.existsSync(root+context.getProviderIcon(provider)),provider); +for(const model of ['gemini-3.7-flash','claude-opus-4-6','gpt-oss:20b','qwen3:32b','org/deepseek-r1','meta-llama/llama-3.3','grok-4','mistral-small','unknown',''])assert(fs.existsSync(root+context.getModelIcon(model)),model); +assert(context.getModelIcon('qwen3:32b').includes('qwen')); +assert(context.getModelIcon('gemini-3.7-flash').includes('gemini')); +assert(!context.getModelIcon('gemini-3.7-flash').includes('ollama')); +assert(context.getModelIcon('custom-model').includes('unknown')); +assert(context.getProviderIcon('custom-provider').includes('unknown')); +console.log('Brand assets: provider aliases, model families, unknown fallback and all referenced files verified');