diff --git a/web/src/components/common/__tests__/model-pill.test.tsx b/web/src/components/common/__tests__/model-pill.test.tsx
new file mode 100644
index 00000000..3a6ee5b7
--- /dev/null
+++ b/web/src/components/common/__tests__/model-pill.test.tsx
@@ -0,0 +1,29 @@
+// Behavior test for ModelPill: known models render the brand glyph inside the
+// capsule; unknown models still render the name (never an empty pill); blank
+// input renders nothing.
+
+import '@testing-library/jest-dom/vitest'
+import { cleanup, render, screen } from '@testing-library/react'
+import { afterEach, describe, expect, it } from 'vitest'
+
+import { ModelPill } from '../model-pill'
+
+describe('ModelPill', () => {
+ afterEach(cleanup)
+
+ it('renders the brand glyph for a known model', () => {
+ const { container } = render()
+ expect(screen.getByText('gpt-4o-mini')).toBeInTheDocument()
+ expect(container.querySelector('img')).not.toBeNull()
+ })
+
+ it('renders the plain name for an unknown model', () => {
+ render()
+ expect(screen.getByText('my-custom-model-v9')).toBeInTheDocument()
+ })
+
+ it('renders nothing for a blank model', () => {
+ const { container } = render()
+ expect(container).toBeEmptyDOMElement()
+ })
+})
diff --git a/web/src/components/common/model-pill.tsx b/web/src/components/common/model-pill.tsx
new file mode 100644
index 00000000..59afeeba
--- /dev/null
+++ b/web/src/components/common/model-pill.tsx
@@ -0,0 +1,32 @@
+// metapi-go/components/common — model pill: a compact capsule that pairs a
+// model name with its brand glyph (BrandIcon) wherever model identifiers
+// appear in dense tables (proxy logs first). Token-driven surface only;
+// unknown models degrade to the plain truncated name (no empty pill).
+
+import { InlineBrandIcon } from '@/assets/brand-icons/BrandIcon'
+import { cn } from '@/lib/utils'
+
+export type ModelPillProps = {
+ /** Resolved model name shown in the pill (usually the actual upstream one). */
+ model: string
+ /** Full label for the tooltip when the cell truncates (e.g. requested→actual). */
+ title?: string
+ className?: string
+}
+
+export function ModelPill({ model, title, className }: ModelPillProps) {
+ const name = model.trim()
+ if (!name) return null
+ return (
+
+
+ {name}
+
+ )
+}
diff --git a/web/src/features/proxy-logs/components/proxy-logs-columns.tsx b/web/src/features/proxy-logs/components/proxy-logs-columns.tsx
index 21d6309f..9519372d 100644
--- a/web/src/features/proxy-logs/components/proxy-logs-columns.tsx
+++ b/web/src/features/proxy-logs/components/proxy-logs-columns.tsx
@@ -9,6 +9,7 @@ import {
import { useTranslation } from 'react-i18next'
import { HttpStatusBadge } from '@/components/common/http-status-badge'
+import { ModelPill } from '@/components/common/model-pill'
import { DataTableColumnHeader } from '@/components/data-table'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
@@ -136,15 +137,13 @@ export function useProxyLogsColumns(
/>
),
cell: ({ row }) => (
-
- {formatModelCell(
+
+ title={row.original.modelActual || row.original.modelRequested}
+ />
),
},
{