From 371d71a262b94028879eb6c0dc977339a98f03eb Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Sun, 12 Jul 2026 22:10:09 -0700 Subject: [PATCH] fix(agents): bundle agent icons instead of loading them from Google's favicon service (#8451) (#8474) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(agents): bundle agent icons instead of loading them from Google's favicon service (#8451) Agents without a hand-authored SVG glyph loaded their icon live from Google's favicon service (www.google.com/s2/favicons). That service is unreachable in some regions (e.g. mainland China) and offline, so ~23 agent icons rendered as broken images on the agent settings page, the terminal title bar, and the status bar. Bundle each favicon as a build-time asset under resources/agent-icons/ and render it via a new agent id -> URL map (agent-favicon-assets.ts). The remote favicon service now only serves as a last-resort fallback for any future agent that lacks a bundled icon. Follows the same pattern as #7373, which bundled the OpenCode mark. * fix(agents): bundle mobile agent icons too; drop dead omp faviconDomain (#8451) Mobile had the same offline/region bug: MobileAgentIcon rendered every non-glyph agent from Google's favicon service. It actually affected more agents than desktop, since mobile lacks hand-authored glyphs for Copilot, OpenCode, Kilocode, Droid, and OpenClaude — all fell through to the favicon path. Bundle the 28 favicon-path icons under mobile/assets/agent-icons/ and render them via a Metro static require() map (mobile-agent-icon-assets.ts). A node-env invariant test asserts every favicon-path agent ships a bundled PNG and is wired into the map. Also remove omp's vestigial faviconDomain from the desktop catalog — omp renders the hand-authored OmpIcon glyph, so the favicon fallback was never reachable. * refactor(agents): share one set of bundled agent icons between desktop and mobile Desktop and mobile each shipped their own copy of the favicon PNGs (23 + 28, with 23 byte-identical duplicates). Consolidate them into a single source of truth at src/shared/agent-icons/, reachable by both bundlers: - Desktop (Vite) imports them via `?url`. - Mobile (Metro) requires them; Metro already watches src/shared via metro.config.js sharedRoot, so no config change is needed. The two per-platform maps stay separate because the import syntax differs (`?url` string vs `require()` asset ref), but they now point at the same files. Verified with a real `expo export`: Metro bundles all 28 shared icons from src/shared/agent-icons. --- mobile/src/components/MobileAgentIcon.tsx | 13 ++++ .../mobile-agent-icon-assets.test.ts | 45 ++++++++++++++ .../components/mobile-agent-icon-assets.ts | 41 +++++++++++++ .../components/agent/AgentCombobox.test.tsx | 12 ++++ src/renderer/src/lib/agent-catalog.tsx | 21 +++++-- src/renderer/src/lib/agent-favicon-assets.ts | 57 ++++++++++++++++++ src/shared/agent-icons/amp.png | Bin 0 -> 1346 bytes src/shared/agent-icons/ante.png | Bin 0 -> 579 bytes src/shared/agent-icons/antigravity.png | Bin 0 -> 1446 bytes src/shared/agent-icons/aug.png | Bin 0 -> 587 bytes src/shared/agent-icons/autohand.png | Bin 0 -> 495 bytes src/shared/agent-icons/cline.png | Bin 0 -> 915 bytes src/shared/agent-icons/codebuff.png | Bin 0 -> 380 bytes src/shared/agent-icons/command-code.png | Bin 0 -> 394 bytes src/shared/agent-icons/continue.png | Bin 0 -> 813 bytes src/shared/agent-icons/copilot.png | Bin 0 -> 519 bytes src/shared/agent-icons/crush.png | Bin 0 -> 6150 bytes src/shared/agent-icons/cursor.png | Bin 0 -> 757 bytes src/shared/agent-icons/devin.png | Bin 0 -> 582 bytes src/shared/agent-icons/droid.png | Bin 0 -> 685 bytes src/shared/agent-icons/gemini.png | Bin 0 -> 1445 bytes src/shared/agent-icons/goose.png | Bin 0 -> 1359 bytes src/shared/agent-icons/grok.png | Bin 0 -> 590 bytes src/shared/agent-icons/hermes.png | Bin 0 -> 1278 bytes src/shared/agent-icons/kilo.png | Bin 0 -> 571 bytes src/shared/agent-icons/kimi.png | Bin 0 -> 1664 bytes src/shared/agent-icons/kiro.png | Bin 0 -> 652 bytes src/shared/agent-icons/mimo-code.png | Bin 0 -> 551 bytes src/shared/agent-icons/mistral-vibe.png | Bin 0 -> 377 bytes src/shared/agent-icons/openclaude.png | Bin 0 -> 726 bytes src/shared/agent-icons/openclaw.png | Bin 0 -> 822 bytes src/shared/agent-icons/opencode.png | Bin 0 -> 181 bytes src/shared/agent-icons/qwen-code.png | Bin 0 -> 1261 bytes src/shared/agent-icons/rovo.png | Bin 0 -> 988 bytes 34 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 mobile/src/components/mobile-agent-icon-assets.test.ts create mode 100644 mobile/src/components/mobile-agent-icon-assets.ts create mode 100644 src/renderer/src/lib/agent-favicon-assets.ts create mode 100644 src/shared/agent-icons/amp.png create mode 100644 src/shared/agent-icons/ante.png create mode 100644 src/shared/agent-icons/antigravity.png create mode 100644 src/shared/agent-icons/aug.png create mode 100644 src/shared/agent-icons/autohand.png create mode 100644 src/shared/agent-icons/cline.png create mode 100644 src/shared/agent-icons/codebuff.png create mode 100644 src/shared/agent-icons/command-code.png create mode 100644 src/shared/agent-icons/continue.png create mode 100644 src/shared/agent-icons/copilot.png create mode 100644 src/shared/agent-icons/crush.png create mode 100644 src/shared/agent-icons/cursor.png create mode 100644 src/shared/agent-icons/devin.png create mode 100644 src/shared/agent-icons/droid.png create mode 100644 src/shared/agent-icons/gemini.png create mode 100644 src/shared/agent-icons/goose.png create mode 100644 src/shared/agent-icons/grok.png create mode 100644 src/shared/agent-icons/hermes.png create mode 100644 src/shared/agent-icons/kilo.png create mode 100644 src/shared/agent-icons/kimi.png create mode 100644 src/shared/agent-icons/kiro.png create mode 100644 src/shared/agent-icons/mimo-code.png create mode 100644 src/shared/agent-icons/mistral-vibe.png create mode 100644 src/shared/agent-icons/openclaude.png create mode 100644 src/shared/agent-icons/openclaw.png create mode 100644 src/shared/agent-icons/opencode.png create mode 100644 src/shared/agent-icons/qwen-code.png create mode 100644 src/shared/agent-icons/rovo.png diff --git a/mobile/src/components/MobileAgentIcon.tsx b/mobile/src/components/MobileAgentIcon.tsx index ade35feda45..6c47fce7a5b 100644 --- a/mobile/src/components/MobileAgentIcon.tsx +++ b/mobile/src/components/MobileAgentIcon.tsx @@ -1,8 +1,11 @@ import { Image, StyleSheet, Text, View } from 'react-native' +import type { ImageSourcePropType } from 'react-native' import { Terminal } from 'lucide-react-native' +import type { TuiAgent } from '../../../src/shared/types' import Svg, { Defs, G, LinearGradient, Path, Stop } from 'react-native-svg' import { colors } from '../theme/mobile-theme' import { MOBILE_AGENT_CATALOG } from '../tasks/mobile-agent-catalog' +import { MOBILE_AGENT_ICON_ASSETS } from './mobile-agent-icon-assets' import { ClaudeIcon, OpenAIIcon } from './AgentIcons' // Why: agent branding should match the desktop/new-worktree picker everywhere @@ -49,6 +52,10 @@ function AiderIcon({ size = 16 }: { size?: number }) { ) } +function BundledIcon({ source, size = 16 }: { source: ImageSourcePropType; size?: number }) { + return +} + function FaviconIcon({ domain, size = 16 }: { domain: string; size?: number }) { return ( } + // Why: prefer the favicon bundled into the app over Google's favicon service, + // which is unreachable in some regions and offline (#8451). + const bundledIcon = MOBILE_AGENT_ICON_ASSETS[agentId as TuiAgent] + if (bundledIcon) { + return + } const agent = MOBILE_AGENT_CATALOG.find((entry) => entry.id === agentId) if (agent?.faviconDomain) { return diff --git a/mobile/src/components/mobile-agent-icon-assets.test.ts b/mobile/src/components/mobile-agent-icon-assets.test.ts new file mode 100644 index 00000000000..edbe71760c7 --- /dev/null +++ b/mobile/src/components/mobile-agent-icon-assets.test.ts @@ -0,0 +1,45 @@ +import { existsSync, readFileSync } from 'node:fs' +import path from 'node:path' +import { describe, expect, it } from 'vitest' +import type { TuiAgent } from '../../../src/shared/types' +import { MOBILE_TUI_AGENT_FAVICON_DOMAINS } from '../tasks/mobile-tui-agents' + +// Agents that render a hand-authored glyph in MobileAgentIcon and therefore +// never reach the favicon/bundled-asset path. +const GLYPH_AGENT_IDS = new Set([ + 'claude', + 'claude-agent-teams', + 'codex', + 'pi', + 'omp', + 'aider' +]) + +const dirname = import.meta.dirname +const assetsDir = path.resolve(dirname, '../../../src/shared/agent-icons') +const assetsModuleSource = readFileSync(path.join(dirname, 'mobile-agent-icon-assets.ts'), 'utf8') + +// Why: these agents previously loaded from Google's favicon service, which is +// unreachable in some regions/offline (#8451). Every one that lacks a glyph +// must ship a bundled PNG so the icon renders without a network request. +const agentsNeedingBundledIcon = Object.keys(MOBILE_TUI_AGENT_FAVICON_DOMAINS).filter( + (id): id is TuiAgent => !GLYPH_AGENT_IDS.has(id as TuiAgent) +) + +describe('mobile bundled agent icons', () => { + it('ships a bundled PNG on disk for every favicon-path agent', () => { + for (const id of agentsNeedingBundledIcon) { + expect(existsSync(path.join(assetsDir, `${id}.png`)), `missing bundled icon for ${id}`).toBe( + true + ) + } + }) + + it('wires every favicon-path agent into the bundled asset map', () => { + for (const id of agentsNeedingBundledIcon) { + expect(assetsModuleSource, `${id} not mapped in mobile-agent-icon-assets.ts`).toContain( + `agent-icons/${id}.png` + ) + } + }) +}) diff --git a/mobile/src/components/mobile-agent-icon-assets.ts b/mobile/src/components/mobile-agent-icon-assets.ts new file mode 100644 index 00000000000..52615e89df8 --- /dev/null +++ b/mobile/src/components/mobile-agent-icon-assets.ts @@ -0,0 +1,41 @@ +import type { ImageSourcePropType } from 'react-native' +import type { TuiAgent } from '../../../src/shared/types' + +// Why: mobile previously rendered these agent icons from Google's favicon +// service, which is unreachable in some regions (e.g. mainland China) and +// offline, leaving broken images in the agent picker (#8451). Bundle each +// favicon so Metro packages it into the app and the icon renders without any +// network request. The PNGs are shared with desktop in src/shared/agent-icons +// (Metro watches src/shared via metro.config.js sharedRoot). Metro requires +// static literal require() paths, so keep this as an explicit map rather than +// building the path from the agent id. +export const MOBILE_AGENT_ICON_ASSETS: Partial> = { + openclaude: require('../../../src/shared/agent-icons/openclaude.png'), + grok: require('../../../src/shared/agent-icons/grok.png'), + copilot: require('../../../src/shared/agent-icons/copilot.png'), + opencode: require('../../../src/shared/agent-icons/opencode.png'), + 'mimo-code': require('../../../src/shared/agent-icons/mimo-code.png'), + ante: require('../../../src/shared/agent-icons/ante.png'), + gemini: require('../../../src/shared/agent-icons/gemini.png'), + antigravity: require('../../../src/shared/agent-icons/antigravity.png'), + goose: require('../../../src/shared/agent-icons/goose.png'), + amp: require('../../../src/shared/agent-icons/amp.png'), + kilo: require('../../../src/shared/agent-icons/kilo.png'), + kiro: require('../../../src/shared/agent-icons/kiro.png'), + crush: require('../../../src/shared/agent-icons/crush.png'), + aug: require('../../../src/shared/agent-icons/aug.png'), + autohand: require('../../../src/shared/agent-icons/autohand.png'), + cline: require('../../../src/shared/agent-icons/cline.png'), + codebuff: require('../../../src/shared/agent-icons/codebuff.png'), + 'command-code': require('../../../src/shared/agent-icons/command-code.png'), + continue: require('../../../src/shared/agent-icons/continue.png'), + cursor: require('../../../src/shared/agent-icons/cursor.png'), + droid: require('../../../src/shared/agent-icons/droid.png'), + kimi: require('../../../src/shared/agent-icons/kimi.png'), + 'mistral-vibe': require('../../../src/shared/agent-icons/mistral-vibe.png'), + 'qwen-code': require('../../../src/shared/agent-icons/qwen-code.png'), + rovo: require('../../../src/shared/agent-icons/rovo.png'), + hermes: require('../../../src/shared/agent-icons/hermes.png'), + devin: require('../../../src/shared/agent-icons/devin.png'), + openclaw: require('../../../src/shared/agent-icons/openclaw.png') +} diff --git a/src/renderer/src/components/agent/AgentCombobox.test.tsx b/src/renderer/src/components/agent/AgentCombobox.test.tsx index 6547c3704bd..d6fe7590f49 100644 --- a/src/renderer/src/components/agent/AgentCombobox.test.tsx +++ b/src/renderer/src/components/agent/AgentCombobox.test.tsx @@ -1,6 +1,8 @@ import { renderToStaticMarkup } from 'react-dom/server' import { describe, expect, it, vi } from 'vitest' +import type { TuiAgent } from '../../../../shared/types' import { AGENT_CATALOG, AgentIcon } from '@/lib/agent-catalog' +import { AGENT_FAVICON_ASSETS } from '@/lib/agent-favicon-assets' import AgentCombobox from './AgentCombobox' describe('AgentCombobox', () => { @@ -37,4 +39,14 @@ describe('AgentCombobox', () => { expect(markup).not.toContain('https://www.google.com/s2/favicons') expect(markup).not.toContain(' { + // Why: previously loaded from Google's favicon service (#8451). Iterate the + // full asset map so missing files/key mismatches fail the test. + for (const agent of Object.keys(AGENT_FAVICON_ASSETS) as TuiAgent[]) { + const markup = renderToStaticMarkup() + expect(markup).toContain(`/shared/agent-icons/${agent}.png`) + expect(markup).not.toContain('https://www.google.com/s2/favicons') + } + }) }) diff --git a/src/renderer/src/lib/agent-catalog.tsx b/src/renderer/src/lib/agent-catalog.tsx index d43401e502f..f9536dc1c34 100644 --- a/src/renderer/src/lib/agent-catalog.tsx +++ b/src/renderer/src/lib/agent-catalog.tsx @@ -14,6 +14,7 @@ import { } from './agent-icon-glyphs' import { translate } from '@/i18n/i18n' import { createLocalizedCatalog } from '@/i18n/localized-catalog' +import { AGENT_FAVICON_ASSETS } from './agent-favicon-assets' export type AgentCatalogEntry = { id: TuiAgent @@ -113,7 +114,8 @@ export const getAgentCatalog = createLocalizedCatalog((): AgentCatalogEntry[] => id: 'omp', label: translate('auto.lib.agent.catalog.09973b4d84', 'OMP'), cmd: 'omp', - faviconDomain: 'omp.sh', + // Why: no faviconDomain — omp renders the hand-authored OmpIcon glyph, so a + // favicon fallback would never be reached. homepageUrl: 'https://omp.sh' }, { @@ -340,20 +342,29 @@ export function AgentIcon({ return } const catalogEntry = getAgentCatalog().find((a) => a.id === agent) - if (catalogEntry?.iconUrl) { + // Why: prefer the favicon bundled at build time so the icon renders without a + // live network request — Google's favicon service is unreachable in some + // regions and offline, which left these icons broken (#8451). + const bundledFaviconUrl = AGENT_FAVICON_ASSETS[agent] + // Why: one resolved src for guard + attribute so empty `iconUrl` cannot pass + // a truthy `||` check while `??` still renders a broken ``. + const iconSrc = catalogEntry?.iconUrl ?? bundledFaviconUrl + if (iconSrc) { return ( ) } if (catalogEntry?.faviconDomain) { - // Why: agents without a published SVG icon use their site favicon via - // Google's favicon service — same source the README uses for the agent badge list. + // Why: agents without a published SVG icon or bundled favicon fall back to + // their site favicon via Google's favicon service — same source the README + // uses for the agent badge list. return ( > = { + grok: grokUrl, + 'mimo-code': mimoCodeUrl, + ante: anteUrl, + gemini: geminiUrl, + antigravity: antigravityUrl, + goose: gooseUrl, + amp: ampUrl, + kiro: kiroUrl, + crush: crushUrl, + aug: augUrl, + autohand: autohandUrl, + cline: clineUrl, + codebuff: codebuffUrl, + 'command-code': commandCodeUrl, + continue: continueUrl, + cursor: cursorUrl, + kimi: kimiUrl, + 'mistral-vibe': mistralVibeUrl, + 'qwen-code': qwenCodeUrl, + rovo: rovoUrl, + hermes: hermesUrl, + devin: devinUrl, + openclaw: openclawUrl +} diff --git a/src/shared/agent-icons/amp.png b/src/shared/agent-icons/amp.png new file mode 100644 index 0000000000000000000000000000000000000000..9b57e20ff0f2b111c59b41a4def914311dd3858c GIT binary patch literal 1346 zcmV-I1-<%-P)P-N}afdp79F*9nsL}P*%-l&9lVKhXzF-Ex% zh!>b>qBHKJAZF{fwhTedh!Ig^B4Q$BFoxUOvaj|%UbNlbmACEYM?81$^Z%dc{Lk|~ z=bZNy7HP>AUl+o#B0bDxdOask4KH>NtI1->W33O@8dH_SfMHp_h;m#E3A@G^kZ5%B zKNFB>X?y}PKPy3*08XoF#Nlv6YC8JQ3FyBkAm~2?x@QqCLkbZ?v`3Bfm!9^ot`!mt zJFjBqu9|vTM7D^?L12(F*#Y$e&#KBXGR`A*grX-fzALc8k;$yC*$_P^uVdPA61yH* zMW(_BGy~g#J4%QdbB{}%M5F122?+Uji|SEe1n2`IX+ye~cSJ80^BLXo=o*K^(VP>s z4e(fTQ;dyEJNv(0kbp$c_c8Fa4RjHR6rjPuIzrW;MJ+=s!di0C%|}%?`?sEB0Zi2XY)5z+S)Q?%WV)ic&*j% zu9;>d(5$L0z&cwQA_3sj?1T1#+%t=rW+0bLma47mD^pW-Hxyg|0x5+v3+ZN~k2kG# znC2G2+^NV83v|)b6~tXy_t;7WC8GDbJLBiI zb$w-Ws%`{u=P`#ec{&}Ej1OTM%!n9^D zG6I)?qf=(K1vpCyP>^KEcL?Q$5~Kj|27s#eipbpj5DftD02qesGbR0!r+wg;c?pyZ z9`wIw^8s=hxShE!I-Q!Vs;%$tPEBlYx-0F>T(WQz?)u~kIWkzZgBE=Ssi5zGP4KHY zbPMpkWv$X(J-r!V$rpXU1HW1@PvWZU!D2Cr3P`pzyruBUEy2ZX^0dc)QqhPNFs;2r zWgccNxdjPGgnau|WN*RpHPi@rI#2xwV5m{Fu5T?l8W$`e5o~x9WnTejn2ZEG;rHtTLlV|6sav3JJ&@t;64$vj#MN(cry`f zI1A#-CnBPaK$|xly$;-6DyY?FPe4H3ov{}|-_I?L8iujW-5Eb`>nYMV@43voE-PSG z#D@4Dly?oZ$<@(6SjQxu&M*#f){`>s->Q4y8v1lCt000McQchF&`SCj6*;xZ=q@!tXYk6U23WM$Etd)aH>H80H8F;2-2klNQ0~i>2d_91{p!P z8~}zv*2L&?09XcD4T}fJmO%y>_GJff46-JAmmJ_4WQ5LTSAl1cH8B|#pwa*VNGJqU z0ZM`p*EI@kmm_aMR8Ur;GFnyzB7@Q_YSCC3h?9_N+_?4t$3i~`=hXJ|?aV=+BilEb z1?f&A{~poA7Up*h{$AkK@`ZSAva8*AR@)Y0&K+2u?IQqdwJoVUZ?R_H^1VKhic6vd zHL3D3E`*2I{gT78e>gsPzJR{~_yI0kbNlDq RDboM|002ovPDHLkV1lBK2ZR6s literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/antigravity.png b/src/shared/agent-icons/antigravity.png new file mode 100644 index 0000000000000000000000000000000000000000..be2992716b566e6d162a31f7db46d5526558d08c GIT binary patch literal 1446 zcmV;X1zGxuP)Q9bfzs=T zE;WhpG>H2?n8Ho2p6gghFp2o!uPWSDVtB!D;!;_Uc)*6mVziTp5#_%(8h@o1CzQ%f0pRHF@prMj`i>`NXq;Q4h zlP;2*ZN8{Oa;JXGhe(I3YG0;~t(jM@hhoyRF^PtW$(BNvi*;T*U5@|&04;P8Sq|IFb00YKJ zL_t(og`JoAKVnf7z+XL;RD>ADj4@-3F*Cdpg=`f{vM-g$Qnrdw`2XkJ?JeHgoFCoy z{oZrVJ@@v(aRxCs(bKct*73pU8zcPm^Z^9hZEdmtQcRqJ;DHEY9j)_!noUsvhTpC7 zUz$YlxJ^=MHHX2Ai)OQS`uh3^hCDWWZAoweQLELkpqy{p2SMy(D+R~|+g2(Dy?wS6nYG?Y%KcXrkRzqvU)yn;AG zhFxs1P($}H=GOs70x%S>&d#=|!AcEXB7cbD`np&wf?;bH8_fA}%&)F4E^cfb_5m+5 z?8ev3XQ^M}`}zun0y69&!#PgE{8E2Y@`X~Vw70jnQcO{Usethd3v+Y8=a?atI>!dH zgB+6h!rbiaY%Z5uDwQ_DKoq+_%vvDrkMQ{%GAwOMhR6`P=-24lWk z&PSs&y}iB1$Hz-cI0^i(x#;eXsZg6YS5Dq#( zz;~)wU08q&k?%T!QSktLTFU{JLL{Pnkanqong?YUi->r%);X8h0KayIF43S}!zjB! zA-yj9#5QQHdbKA&9&{SQ+BG=D8=ybyJTqt&$xcu`0#eunW*AYec~}BTeV*e6m_fbE z04qRm%y4)GWIzhl3M+s&;yKRG4Da{xvjp@nI}W=*4evJcGCp9;!(kCYFswYu0Pxf3 z4bz(;DSR{sMG77|f<{Nk!X^krA^*0Q@&o2Pyj#p5W!p)9M649Ria-jnUv9>0-%?e0 z1!|y|#>;*L^k3U|;h_cr4}+cY8qb(sxR?P=4Nvpec}29t!3^D;tM&cmIXF0es_I^eL_W%F@07*qoM6N<$g6oaQ A0{{R3 literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/aug.png b/src/shared/agent-icons/aug.png new file mode 100644 index 0000000000000000000000000000000000000000..1664844ad7f8e5fb4155951887b34f885e426af9 GIT binary patch literal 587 zcmV-R0<`^!P)i&d$zPS66m+c3xgy@bK`br>ED~ z*NBLSva+&lY;2pGn`C5UEG#TaN=gq84@5*nfq{X?$HylpCl?nN(0ud~0004|NklzMCJega$CwJq&U0QogHU~ymZop)1+-qgX8>b$=&uOhqK@8 z?ErirmIHvo4&Vsna<~GC9YC!CF2LOyK*jC?2Ri_vV{d_z9l%Wk$gK$N0M0sjnTh2w z#ya*A$m{?r9lP8L&kn%3_nQ|bmRs=0Qq+M<#24H__|zWMtUTmpVZyF|VmP$aTp4D5 za+&E-5wk2@l;NI8WF$$gp}ZULiBSRmXse!mA+_CW0J{xf1NcyY2T`9w2RDCpzf5V(#pv*SAHu!iCVMCh%&DcF^&z_pYtf3x&HEjwXgwf0KWq8 zUW3u$#lMog=aN}&;L`9<8pGvAte#>0zRg>5URE;em2qlxWe&pV;3JQUnfAhLc7dC` ZAzw{|4+;tTb20z`002ovPDHLkV1fWk5}5!1 literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/autohand.png b/src/shared/agent-icons/autohand.png new file mode 100644 index 0000000000000000000000000000000000000000..0c3326a570582f7a5f55a849539b0f78a3634c0a GIT binary patch literal 495 zcmVUh#v&j78nm=aTQ5>N8C+15ZJ=Cxw%!OJTAYB^t~h>Ww=WLFD`V@fGlzi l)>m_-STn7&^&0P)m8CK8y#N3J40KXXQviSc z8lU#S)I8^2ucn1iSpWb6*-1n}R9JrE; z@=03f0@ba35sE}8hMZi-+a#T{ptFzTlWb#g-mpNB2W3i0BTiphQHsft_*RsD62#E0 zu5U%@!9%Dwg`{O%-xxzZgv84t@712ZLFjNCvQvW`xbN7%q!iP#!Ii-KT?b|p5J2wL z@{zg`H9&;|0f@gt4~!3g0s&MJ07C^}H+W!I2v9`;m^MUo50dp`ze4x`mkL9CV;v09a4}KnyF34ge^7 z)pQEeNZ$pZFBc#Wgv-+rfO>EM0H`eVn-+j1pjr?Q_X*^I+VB7vU;scl3$ZlBwd8|L z)W870A1vjw)Iy7EArOHH0Jbz&jb@@x!)ei%dagzpV6tgxO#s0B4ZYno=m)o0KWK1U z2OUYm_Nrv8BV}l?yw?+v3ke!+VmKHp768qr8V^^|9nJ-+(Of9;cz;nTDhjV$XK%p} z`?GZt^gZ!coWn5U5ZV>T8_!R*V}ryroR=(b!{C1%i{wJG?vC}-II&Y@YZ(&rZnLK4KW+QOE!#Wm{(%%f9voynyna1-em}atvH_iazaO5bk4|3_ pIDPH$^V{+5Q1JOb9l5*b|36sVzNhb?SYZGF002ovPDHLkV1l8mnSB5N literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/codebuff.png b/src/shared/agent-icons/codebuff.png new file mode 100644 index 0000000000000000000000000000000000000000..b81a6fa9c21cd833045d70a89bb9a85e245479a6 GIT binary patch literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!)B}7%T-^(NfJ`*-|Ns9LD^{4B zn;$xK=;zO$U%q_N^}WOcRK!*iw!JY5_^B3j>0zsc9EAmF;N z;qbTr_oG>|MLeEZZR6*CKJkg%@kCFzj+RT8bQIjORL$ZtejHx??<47goEv zK;mbM(5|>oVuCNWG2c^W(wy~oaRW!sig1~U&OE&bgdBY{Sf)JSc%$XuwSuM3$U$7o zQHLo(*^fy)Lz(Y-fk=dv!L9b#2Yw&dNUU1Kv4_9Z#<*Zj_kmw|c04g_+Uph`$WB_P z^zP{WTgQ%EJ8dCV|4(DHzVLsm&+;PQCQmbCI$6$gWAi^=#uG~ylzS^WzF+ubZNp#g zaG!%BK=fxagPg>9iE|gWE8Skm?fm(;-L(giZTEl28ho1haJKos{fyOS37%6QS$Bd0 N(9_k=Wt~$(69B48oq+%V literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/command-code.png b/src/shared/agent-icons/command-code.png new file mode 100644 index 0000000000000000000000000000000000000000..2066461b996b05928fc45ee7a1afebad82a597b3 GIT binary patch literal 394 zcmV;50d@X~P)K`;_GUDXXE1;1(2Zuh8jbY&iG(8!BhGPUgzJD?dI@^V_XqsfTtJ1YV*PjXW9WM}Q zyIEk(1;_$)Fo6*uXYGwKbOymBkf>WJ4UE8+GAF3H_W$9(Qy3U@~xa%w~DB_YPE~;BurwxBn*2RrQ o+}h;LRovc{_y?n)px{UG1n#8?cYBnkssI2007*qoM6N<$f~7RL&j0`b literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/continue.png b/src/shared/agent-icons/continue.png new file mode 100644 index 0000000000000000000000000000000000000000..cd2599d6e63360cd0a7a0fd02ffb79d7cce1a06b GIT binary patch literal 813 zcmV+|1JeA7P))=V>7|7`+gL~ z0bcL&QPmAXOHDNZ+TCXZ#@u@Jd{wPNAg!Ih6DhS0l#m(=cA&17&KcNCE zrd$b*dQ9!d8c_<2IhweFB0NJAl7&;O7mmf!PY%Y7%Ou1&Gc2Gn+fak9r<8S@d654= zQc_B#jbsui(F9R!U1&^Z9-i+RW3)5Q-GB%to7TmkjhdgUx4fO9dH3W0Pz|b!5bB zH{J*&9StNH$~>m&E|h_8Wh|M(ygN&#m6n)xLP*Cts*hoQH!h#YlX{#-13Y0X- z@ER*=hedV5pQ?IQRD-f^@{Zmq>tSOVtqFIHrN3w_@zyr}U|SnLZEaz5m0oidm(4ZW z-v2+>?LC~3k_L?Zlmtf{a&yEfUhylZ@P@4HF)x46%pZ00hwc1vKY!s!_QlEGmAiBm r*=wJ(MBd_Qk-7R>WG>$hsq6nAh*O^(>8qA;00000NkvXXu0mjfus?!% literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/copilot.png b/src/shared/agent-icons/copilot.png new file mode 100644 index 0000000000000000000000000000000000000000..52126e047d040ca1f136b026971bb02b9db81355 GIT binary patch literal 519 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 Y0v$_m|NUCo_W%F@07*qoM6N<$f;A@;0{{R3 literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/cursor.png b/src/shared/agent-icons/cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..426cbfa4d0dc59725ee31cd884c5e94bdbd5f4fc GIT binary patch literal 757 zcmVP)t-sM{rC+ zK|2%@3+?ReLP0x0KsrG{IzT@;K|ne|Kspc(1pxp6@$m5X_V(G>*Cr(&zP-ISHZbYv z=+Mv2si&rnjf-MnUV3?VM{rEX(--Oh000?uQchCiysJ46H=mL}RzPFSarE?{dlP ze$`q^wPR9heZ5~uyKB{Z-!zTcG5p#4Ug<64CVM}9P&E9^_wu&%|5N^u^B3aPU+%B_ z=9GUtMz3@KlkN#I6aIejkA!y=H^uuKfE~D+GAY^o8SvxS0895W)t?OjV6{7z2KK;aGl>E^hK`!esq@dPmFCU#?G@g0BqJdSRDcoqQYTzkXukV;qsNF}TQOeL%UWEb@(z`KMMfFP;> zpA!BGFiqYkKLDmC_#J=`sW<@Wc)+ll^&}t;78(%WvCN+vEaYg50F#w)HQE|g8m4R6=f8 zC8@eEG(&vHc7-M@bxo4GVYDTwTM*l>D7LHRJ}w;G7lnnxycdq@m8X8`N`$j(Uz7XS nFP`Px!5C$^I zz`)GL$*-oN9TFP;`}dy@A3i!bIxk$f=)#2y_wL`{vSn*_PTr)+Q`*`)YHI6$vabW# z!&MUG7tAp0|9{gzbI!ym-Ot+|#lXP0z|+MsB%<}~^tbDp6?ocYEuOy;?`ry9zm(l& zE*HxZ>y!85PbbN1Y*~7CQ*7!-mB1>o)HKcdqmubmPt$)Nw=G_K{NSJ3;-96$@9)|j zjmcJ4S-by@;?4iQr!Akn{MPbBf_=*tVTo#|kUtL@Qo|lFxQa>sx3it-zJTxHdl7s+NCI*(PQl3ZDWEf^xWnDS-K`n=Y=ZmtR6AO31)h{d5p0qMw_@}bq)4Vhe z1#t#}!0K&6OeIz-iDCc0zPrG4m+5Vaaq;KuB1M_P3&Ha(Hgm4?NQu@cW!|rl)5N^M zsF3qnUf4bV^oH8i^Kw`&&T`&uA;NuuqxkcION__lC%rgyWND$J8iQ6b|DM3x32$o| zCKUdykzn`AXLgVivt7SF>EbUNiBntVAB}qC5~2}5Y315dqn8OErrZ#4m{GFs__1KY zMciHMjsB+i^2F3|I6R18-u3I-;YH`X-}rrbc>Utf9qTsAe6_3IG_la1x0hu_P1*`J zXXQm__Fq(9c-y9Aac5rX#j|Gn?z;2KyqL&tU-Iy{-IoWQ^0oU7YL@r^uV;Fyb7pq7 SLMbo?89ZJ6T-G@yGywp`PWglY literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/droid.png b/src/shared/agent-icons/droid.png new file mode 100644 index 0000000000000000000000000000000000000000..014b63332beb9cdca46d241e40ebba0c2ae1a873 GIT binary patch literal 685 zcmV;e0#f~nP)LMZ{rlzL5yStZ{mqJ297#J9SetwLM zj5<0xV`F0y5)vvZD$>%@O-)TRGc%u`pGQYWgoK2UkdSwGcN-fU$;ruXZf?N9z*tyV z+}zw$R8(qeYAr1-K8`Nb0005-Nkl zyERUD-mTFCsGw!FT9SqMvH!$w#ke_goXT+@e*l7t-c=m~i1!0Jf}Mpm0n!BMcJV!e z7|Nvgx)lpB?FNMExTHuLxv@L$;VWf?sGm$qV4a8e0gYOOuqj&dWrBI?5KZk1a7Hxp zoIQh?o;O^WR{@0HkQ_nY1U7QH$GCP8#N>mpd}mD_#^W*?la z)Q-Q9&4sJE=NdX}Dlx~_ACRf*)3YH*L}rxkfaKMHoFfJd^{Sj;Ug3lLZMZ-HDW;hf)m%M!d{BAB4M)=jrW5NmpYLi_)>BgYF4mSxri=8d{Qk`cdyWY z$IFO*&f7^LjrAGax51SU7*7C^4>$J!>d5FCC&Z+b+rjTPP>RyYvEqXcNVm2W#@JV7>NgpaomqwIs3x`xVem4!>tJ^Gw8#{iF5^o<|sI TrT;hd00000NkvXXu0mjfUJ^qV literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/gemini.png b/src/shared/agent-icons/gemini.png new file mode 100644 index 0000000000000000000000000000000000000000..84976ebc7fd21e352d8ed963823b66e1b1bdf5a6 GIT binary patch literal 1445 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 RopJyG002ovPDHLkV1g+ut|0&b literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/grok.png b/src/shared/agent-icons/grok.png new file mode 100644 index 0000000000000000000000000000000000000000..954e5b40da271de5eb4c90efbc38b766daa7181f GIT binary patch literal 590 zcmV-U0UK6`1ttp^78xp`z+9>-*x1d@ z%|1RpA0Hp(<>e?SD2$AZ3=9l=dwayh#G<02y}i9xS64&u)ohx-=7%_Sj$!@dZ-#WZUI}z+Uz3vciN5Mu(PrheoQz_|Bn>fLq zzzRJ-N;aD8nUkmV2e!Mt_|jX%>ql%s;_~9a6L|br*AiI*IhuLk3h3o~I>Q;Zsw!!E z-EAp+{*c={ZW4%yP_p=+PHb6V5%#Gic%3k)Lm;&$#mA(?Q8k{Alf0 zK@K|kJ7soXEbrz6a$oU{-6W?9w*^dy(lxBOnwQN`@ekcG;Ky4aCwe$VXeValrLYeVHFnhz=<8?Xfo z`Hj}OqJ_RaUF;lI`4<5F^{})=uH_>pP?Z70O@$pjGv4&3e9ze=dK452ChI{<49k`X z^}dGLLwPa)t;Jnh1ZPP^K~z|UrI(AAoFEK915~;t z;r;*r+5}Jmoo#!{*|Vb#T=Px_e!zdNAMh(4|FP5;{8XR5jF^IV&WB9@4v0iKrQ+;Z zfbW8S08mO9+iO)i5hlGMUIBT$R|ok@`3r%61<2aotICtI-hK}tXP4#V+i>0bKLL{6 zmln-0Ei8Nsi2iY$HD^N9=dDiP0F>EJYwfF-m*)OJdyDuHpiFzuP4UiVF{&JKB8)a6 zsSrN_jMKWE(t}}0Y-Yjmf3%iOSwx%k0Z=Lvj7|J1@J<-%$SRU?NnXBL2~sG`Pg*{0hkYp=xb!qoS1TiV>P4#FdJ*<4eZ?A722J zC`Lt4eF+*Qf=uq89*o?F;DPgVXJ1T$Do*2egy0U_f~RXgB%KZt-kA zG$+V&Jz{GE(B-@Cz>T1j_HKanP-z9!OYD9itN^wMdw{{F?+XtAYzLBFZnY!{pVqDe z+yiiB(KrZo1$5on7~@`j28=6OMYvVzpZHmYQAd5Zf_V^ziZ4by7kMbQsv|)uA@77C zAnX7-H?-1Qu{fWHvsYb)4(1U^zFDeJPn6tBQCD=xFyiF2k=g;ONe5WlDH73(g?Ir1 zBKb)N+yPvVOcJAwR4W{>K$8S^xY&1<>I1+TpV21M;yhx866nPSEg0<`N^4bCHk9rl z&TKV|xI1#_@Cra{rcCWCegM!LAlt|J+rgV7(;FbMZT1$Ncfb(AzX7UM7`I{K>a2PN z=r;h^821*w7pE&7=mp>`8-KIm=EYVOCnKx?F8LVxWOCYKx1m&qE`oak_-&pWoPkLV zT=kc_B3U6)#0P-$!K#D@PHOZ#zbz>z1>i?IEC3NVsCAZVmB!#KL8~%(RMrL1woT*4 z<%FVc35G(bdrcUCJ_NS;W}RWW6X=>yT4`;7(2dXm)a!hh{Cfg=%$%dsHR)K)-3T2} zdJ4?$ne1x)6->7`ko8Rp2f&AGv+O5M=3F7)VUS@55K7DS1K`YMf_dcu;3Ac`^EPHN zSIG^)(_QF$^%}U;Z9q@Bkt*zuf8+L;nh2#Q8;k&09;e{ls2~VWSO~a;G;$NmDrQM-*@aU_ zO=5*98_7{zXC-zMcPkDe7Ydslkd(qwdXKcpNoAhX**XwmCo3XVQ6Q7TyPcAeOq2w1 zaRqes(-buBVE?k1G6hZzP$$<-{3vM^3LUe_v~_eSrL>)kwc?T9hSAg?zuN9j@8L$sJgl~H$EO1xEmvJXgcHq)$07*qoM6N<$f~$vCH~;_u literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/kilo.png b/src/shared/agent-icons/kilo.png new file mode 100644 index 0000000000000000000000000000000000000000..053dba3fd765f4e241535ef0a36ade034b1cacf5 GIT binary patch literal 571 zcmV-B0>u4^P)neA0r+gA|4+i9v>nfAme}2r~m)}3UpFVQvk5>A`ynkIb4|; zDK@hJ00F;AL_t(oh3%JtZo?o9L<0tF^8X(^+Ym}K3W2Cvr|lwDK^T7L60Te`P!Hodwz(&uC@~K_`5y9&! z3<2sO#|7Vl>ekVO10IlzQ=*zp6AlhN5t4&zccDp`abP{MVmSUZNZ0E;X<-iltxBX| z_|ifM+$c7tD>2LT0R2kL_4rl?j=20tdmv4e$KdHmIe+0dF!U-Wf z$!dqC`~Vc`lPMBY(1(fL_yA}i6W_@Vhk&Mo43L#rcVI38k^_=uQ^AshJrt2E04ZcL zJQlkSVmiO-lci21YlUYB0lS5?rPF6oO64;2ygKbXK=EK}KpMIX;OW(II+ZfSd^*1b zs1xwm{@`23q?t%N4(QK=pBbuu7;y8Y>-KBk;)~~A0dDB$0bl!UIuT>t5y1ce002ov JPDHLkV1h2{>ka?_ literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/kimi.png b/src/shared/agent-icons/kimi.png new file mode 100644 index 0000000000000000000000000000000000000000..3640a259f8deb1b556e4f53822084eb42b2ec758 GIT binary patch literal 1664 zcmV-`27md9P)ZP~Rp-zyF5O zK8xO1oz65q#%oE+4MY->M9jDpkVFuI)H4YkrbDB@3rHE;fc_ipV-$XWXlUqP1uR>& zDn0lxd{hc@lGKfo&=rx0?3@H7Nl*kPl`LYZJAdsZU#;7rAf>!n5!Gi}J07m@b znnakjZtVD65Ob}G8{7^3A6L_@xjh_u)^s8XDamQxON@; z_Wyumb#-{?_pA5SRT{h?!t0o2iQ^iPC^8z?Rq9Dm`NA5!_x4uYy*q%59uInYdNL#BNti!x9+oa$g2I9VeE8u<_;Sx4Lmns?IOn6Ru*4?E!w4%~EAVaY zo^h~8t@`?tcw^IB7#$75>2RQ}tquMC{VGHNz!-z3XlKi5uHVltw8q8IWHRB*sS}u$m-pDXb$8!{wPdl%#-B;&reK_Nu)KK-rK&*^$eTG6=Nr!e0Eh_97cQW_ z{uhjmjv^y71J61guvjdZGG&TEZ8zLaO*new2s%1CFmUglo*)KSDq!xM0!c!j0D=f9 z=4AZUc^%BqO` zQp(tj6GGrr{c$WVDgNL1t*xj)L&F(W+)q6<4K9}p<>lolEiHxBYDIf{JM4CQOj$%N zn~^t1ifAi}D9z2u!O|tASmAVFh0}q|%*;68>C>n2b6p)8fBOwLZ{8fIB6sFYBqt@o z+tU*(i-?Qa^qhRD24-ZUPo6Xht>@kNv%4GZSFd7da0q_?5bV#`QC@CGdU|?X{5&2H znwpx>+}sSG&levvLk)7y!KTf~lhJ}FAwZHK1>xoDb@=|fZ+0^MdK`ALosf-LyNrY|Nw&IiBAIBLS z7#KiSR+dtbk&%Jo;$l=*R$}?`?Px^Wl_AuuT=1=ZE-uw}~@l$4ajl}T-FEoy3N5DJCHB~PL|Ip_OWYI;@~lhl%U zBuG3SL>uv>loaI8o(&-c{_gKbU}Pi?ph_U(PIcuRB;_Io0I6wD9wb2<$k5^>2}Gxe z8ZpM*8w@c+>Ls~YYE=Dk#(n~0ul4r!-UkdP@93I1 zabnTf*w}W)*fP%f0?xT95&AgSa?VFNW4AeDb>RGn&*y73+W!y0$DvEyC>M|b0000< KMNUMnLSTYkmK{w1 literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/kiro.png b/src/shared/agent-icons/kiro.png new file mode 100644 index 0000000000000000000000000000000000000000..4a6cc6bbf8c7e4209aa5c253a86f0b73bb89cfe3 GIT binary patch literal 652 zcmV;70(1R|P)jRkSL;nc)@zD_Gan-|6M_>gA}rho#_+jWr;KA!0y?s>o`4n{0D?5#KUA) zDicnpu9Ex_I@fVBg9841q)pfF@KoSK1q78kV{P-=uYVj+LUn|EYlwu%;@A zO(P#5Ff;+RZ4rRbqww8v8y~i$B-AehDpnB8^qMPJVn^`OL>2)c+>BZV`^hC7_T@1^ zuSLznXU2|&3}dIuIgyw^%>$Mr52rl56z2h21hcC0hlRip;583rE~tP^>;fTHMZIfE z;q4~{NU=`P_a+<}d(Xp!v5)eH5hkE&#vjg?aGn6oM`6GYOu+m6qk!cq(gg0?paEl~ zh&2~~Bel;IArU@o?2W_&OaPflYKHK)_PfAG*at-R!K{5uz~0GjjPb#-){tiyA1Q&0 zmH_KRU7FBt1xLn-;90be+nXsuN2=h)$o5JgZFq&8xA7C&j-gxs8$H^h)G81Ymo>R- z=C7zr(%pqv+?I`uz9Okx6$eYTygsI=gH?s>(n|AKxsEI*gugc3)b$5HOZM%V=w6Q=kK-GJv=kfTR~2Re0000|1dHo@#O`H zHHek9BUw8F_*aL~-#3)qh!C(@3gjaXcg&6;^UyOiO3C3MFAfHUas!yUXJDzsDNrRx zh+p)sYF5rO=M^Z^?6DsuQ!nD~=xhtia0fqlRc&9?aoeam4xbOMII!~xqg--Gx{~{5 zO@Ntpg(y$C+KvhYbRT4)PTF3Ti|U65?>O`#H(hg7prBTOHc&-jHeYu#dd)2)L;B91 z=NryZu6Zwa4Rg=LjsXb@WhDTL2xYK8M`T9Otayw7V;{N`o4txrayOw)KHJe%V=-nU z#?=U!Kcznm20=Z-6y`DydJTT~(p|eQ!#9IKx=LS4k9+%OHpvT)eV(TV=P^TIbR@Wl zhL-CsunG&~ypnsCg#-&|H1`6aNZbknmq&^S&4RR8{6@IT6KjlOoueV}Gz<@=9Rm50 p^aQThjyfpw1+WkM*v>zHz5q@o5`FRQHEI9=002ovPDHLkV1kQp=RW`d literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/mistral-vibe.png b/src/shared/agent-icons/mistral-vibe.png new file mode 100644 index 0000000000000000000000000000000000000000..f0f799cf546f5ab209ccd689df4b7d277a03b871 GIT binary patch literal 377 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!q5^zET-^(N?y|7`Z(_dB!t%eB z`TumL+sqs%7^F@!ivM57c$7ire+%<52ALxavcCiP|F32I6~O=7pZ|9g15~7m z|MiT&eEI)3Ge2Np_&<;70+YxiR)+FRKKFpO2$cl+1vA_%Opjddr;B4qMC;p02l<)|1Y8=!G+14g6qYo!;D=XS4ZL zIu&yGVw;w7KV>awl6}_8aZP6j)7nzA`os?w=X=)~JZFh??=b)UV$SFGtc?qP`w0jh z2csfc{|cboFyt=akR{0Kd7Dd;kCd literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/openclaude.png b/src/shared/agent-icons/openclaude.png new file mode 100644 index 0000000000000000000000000000000000000000..1e660b740906b95894663a8785846d0c410402bc GIT binary patch literal 726 zcmV;{0xA88P)@(4yGRbW8k2Tc*C=3xZqXT^aB%>1XK{VTBTWNyDi=BLalE`YtY1tPV)B6zWI2+ zH}e})yvV)=p=E~-^0+IbgOcDLG7R;zhlO3F!> z)2iIRJEo0~^@0fz+?alB*Y%peFVsF;F6+_Wpx_m|+XR*ftW9PJiUO>xY#!{&`5f=E zExr4o#BDZn_UYn`MhNic!GUwLmCEt-;3Z!m*eO7>!wSPg9dJ}JpwrJox9AbxY-WYU zCuwJ>#{(Oi`|}K3<_toNFxYCj8lAa4O2K%Bw@d4LsFHXE2Q)D>cW#Xa&=+ISKnV<^ z7V8SQy^+h}4{!E8W(jb)TO4$Dq@6&asIh-Li09p2T|bGTff8WBCMNm?bUH29uJ!@n zOs|Ayy9F-vcwt9AgvrSP;V`d-(U+`6Rdb&8@Z^kd@9?$KY6PRBnO(K7lu!lqRap$` zga8!`M2QS{!KW_;R)gQskdb|`4k!)w5CZJ;j;!#$c9BqAXZ?MdmSKxr0XqP`b_a|{ zf}j+tu(h2dZlIYEw7DIr7p%`e{b?KO_d`x8(~{PAA@Mp(=bly$o;`nifH8PL2^hoX zJ~EQvt$&lx>{+#MK*+LR)f{KD%>7Eh=$S%>#TV8xjU-q=M9~n`rB^aMh_7Z^T-=hB zk_iFT0J)9y4E1{8;iJ{)^74jvYU-kZJjfR-z<2_wgmjR}7IG~-xAcBniDL{Vr&%~X zOp&k{){T>U*k`p=b>ggGk%cx#(#|!_ttIx-&Oe8#0rOw>?^q!lUgi3;(*OVf07*qo IM6N<$f|IpWF#rGn literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/openclaw.png b/src/shared/agent-icons/openclaw.png new file mode 100644 index 0000000000000000000000000000000000000000..03feb5b7638a54eb2ecabfdadaf5b9d8b24335cf GIT binary patch literal 822 zcmV-61Ihe}P)DK)Nd{)i^lbJUq53DaK|%jbP0uwo)i^lCFfhC8+Jw31{CIA2h{!C1NBPJRmBmuLb0P@%ae{^Nr8pi+t01I?dPE!EF=H?z} z#X_c?zn>-EnW?E9*@d)QQc4>JPQQY}jlQjb8tn1@wC7R|EQBmiuXvj&3WuVq#(2-Qld z(bzOj(^Ml=6g$dc+4#}&6IY8Wj}J}oGj9YGA$6{Sd;ZE>#7~?PP6+7=aB#u{&n<5( zIiFMdO2rBn9%Gy-1N!Q(`5$~nA>^No?*-&j6?G7BIUKyx@VxxE=TX4q?2| zCBB^n4Ds1Kzh^N9URz%i$4g1?+He#w&!0a&=Z!Z4-uDSedRIgf#)myX_XaZW3(p%% zZ*?C8CX?~c_e}NyVDD4x`GF==fXDpRIvZQV0J--!o({v1>H-Q0jFVd5?=@N=V*Q98 zQiC`xko^%aAn^^{dB!f;qY9z(2f)89;MPEg4-y$9)KOV*vTw&HK$^D#Zcpv|Z7AL_ z+`LF}0nf%g9+s{ZAn=k71@VW2rvq@~J9rlH(HD$ko<%&fZGaIk3wXxI@V>AD;NS&M zogf#U(c^vX&IapC=MQ56&jj9iA^a3vIo25 zJRepOwjXWxxBwU4ByW)OCkb*3bmDd5Xs$C0c;ZthO7jg~r_KYAS->D*c%9(QSDoWS zeBCAmU~znX^N*n_;2#n&T`1&JGxUba_=kH+omjwY1Cu*&6p>qirvj|OJfFGaG&w$d zTWp>dsDL*L4+~Vnn?Bt0g;&*Am*z|Ese2Ob*9B@z!+Qgc@4B|_I>%@4xL0!mE-1V| z0dfMu3+UexV1GeC{EK>z>%07*qoM6N<$f{5>G A{Qv*} literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/opencode.png b/src/shared/agent-icons/opencode.png new file mode 100644 index 0000000000000000000000000000000000000000..1f45b1faee0354fa4731bf84ed979ba493351c66 GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!qyv0HT!jS${{R0U6%hdxaCdQG zV_=AjiShRI)Ys8D*;nZa6bwp1=L*VUMYTxY()3}d%aHxL!ANawS zuS?+Ro1&uc{ObM;Cs=LxHTZhYGG1dkD#HFMcU7W;|70cxh8k8A)2#*{#17~;ymX(O baoH-ljidMm>+u^v3m80I{an^LB{Ts5L%KS2 literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/qwen-code.png b/src/shared/agent-icons/qwen-code.png new file mode 100644 index 0000000000000000000000000000000000000000..9a6346691d445a8acd858dde31a78c9115fbe0bb GIT binary patch literal 1261 zcmV#J~H!viXubJgNWy01k9gPE!E9>sS($IR0D2=T*#@c<66=000CK zNklw=mv5QTN?g|#gS0fO8^0D<>^!R9&%7PR*GXBT(Aoy?h;=;5%b zJmOqDdkEoX)+sF6L+fhKtyJm?Dj#x4;gayymYyy)g?H-RklhlT*vE4|*Zn^Ma+t9| zoQ^N{Ia=m_N@2c3E6MU;ZbRBkq|g;_3E2^PR|6XR&ZC;!_lKx5>%mFICwS=0TOFC- z*RjKAuuwUSF}m6}n^IKaO$KFl@GBqznAkNCl1Hwl-l;OOKQ%4^T>=R}*aBu2#afXN zA*w04P-#I`o}AVxNC0(KMp`;lHMDH$qz26xOi*p00EmEMQIv%1y-! zfU`1>*C|K>&&SSb%x-Q6*bGvza-5?0`4D2$cnWJCxM4H^#9^OSY*j%)AXOL^-Yd)# z0Guo!g^eDH_;_^)`d2S;-%10Z2&|k;3K5}_FwD?rkR^6jVgpDAurl@9fKrm#=gVMs zN5MTSEr1Tr%Gj$TgN?({9az4V29Odrm0lgA91g${heG*QS^#BmF-`6eY_yddr5WXMbkQ3U@|-BxITgnTP4fPmx1O2WWGq=pKk zyq@P;zPxUN3`qQJC7gK~%w>hR7IH&*b^yZGR!(5Ny6wz$CoU^_UBPC=9w1&>89NIJ z02Dzm+-CFvWYSg^MK4mApkmA{1^^^r!UeAYv9_`pyOJ^R>|t(OF9m3W+Zqr}wT^FV z#%z4eyzQm|(1?MZ#*_>L6PlO;^!5C3maO)pBETrXIFqHG02p;sfw^*n5nI6RuqC}z^Hsb^AO;I3*lyb&5CaK- zrK~I1&ZX<9*e=-b&3I{~H>JkHB?b#8*iCyMk}m=fJ|*BRbQ}7-6EB*XS6vTk#s9BT zuyBIiv>PwJ=Wx+QQjF+8HXHDjFcggHk|Men%LuWmeawN?~_31Z2 zrmhpU6jTa(7VavLQ&~^3)#u-WzanX29P1+NTez#sv@9-x&*Q}xnAqu+h5Pyf?Nsm& X*l5wc$$Wf|00000NkvXXu0mjfL@ib4 literal 0 HcmV?d00001 diff --git a/src/shared/agent-icons/rovo.png b/src/shared/agent-icons/rovo.png new file mode 100644 index 0000000000000000000000000000000000000000..08a2af624f81af6e328e951c02502a80a96dec81 GIT binary patch literal 988 zcmV<210(#2P)8CPnYkcPmr5)x7o8`uIZP>Q;6q^`PbQl$w@kq{eJAi-aN zKrE5iA=*lX6|g}Sv0WZwks?7siXst+J%@#zbkg`ScRT|dpUsu#-Z|&@`F9_44dWQc zIL7gRhUAtxG@T0g3}auT%~3*$@+hNuBn6lXcnx?K;i;(t$MdR_ivtHkn6mzcnQFjGdDO}Uz=YGcJ`-3Ww9M;ep0N6+9RX%~bmihg<^ZCc z?Ar$`d}1!kdU;Htrw8=SR2$juNSOl6y>0vHJ$>SFAxjrB1^B1MkzqLns?}z8YavsB z2r7vN8evv0WC|egV8U^kxsdH5R_;qWR4khvDeGOx=TqU)=>{*4S}@xw6tU?uK7u!n zh8B!cGgAN)HhjhlRIiVCI;RIXcD1N4eET8Kf3p-5^n-7jQC&z4PzYM{;`D?%eTx^r zo(GVKRo^_Lx{&TZ@LaQ0-2Zpe%*qx;nAv8#&65w!JyE|s;18hWnX%rOVwU65_LY*# zf!pqnYU*5BRZ-_q)rlaG_t!%H0A_rRDRUw*z->7HXm0-yQ{0f>y(eRm`;fO{XftEPdgsJfVV?TGKTCVHx^ zyyqvq69Uz>z;7)i2AB=4C@xrxi@jC6Iz^p6b8Sg3i*eZ>0l?3N!~i$eZ`7Q+iuMv6 zYn{_W6SW^JC>PS{XVS-oL;$m)6;<70T&xU$D5@T=pO=dUmr_C`b|DeK`sT*GI;|uT zuTF8Q73f~#(?wzzh5}5Uv685sODevzHsk<6V_B}`?ZQxi=oxphPcodU^cWOuz(1nx<~9D@fzEq#C;df)pg;ER0u;{=nK$t)QJ5} zA|ivuyPc`^+pl-r)96uXlpX0+ZvYd{_IfTNy`8wZEI@9NO(cpuA??l2P@aJ&7d*Y`Q?~G#{;~2+(5dQ)%0PirTPd(580000< KMNUMnLSTYeP}8IU literal 0 HcmV?d00001