From e7ec1251343743d20d8a0d88180ada8c1561bf83 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sat, 24 Oct 2026 00:50:36 -0700 Subject: [PATCH 1/3] fix: prefer resolved agent label in pod inspector Co-authored-by: Polish Agent-Model: codex/gpt-6-sol/medium --- frontend/src/v2/__tests__/V2Inspector.test.tsx | 10 ++++++++++ frontend/src/v2/components/V2Inspector.tsx | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/frontend/src/v2/__tests__/V2Inspector.test.tsx b/frontend/src/v2/__tests__/V2Inspector.test.tsx index 65c02cf04b..6bd0c5471c 100644 --- a/frontend/src/v2/__tests__/V2Inspector.test.tsx +++ b/frontend/src/v2/__tests__/V2Inspector.test.tsx @@ -141,6 +141,16 @@ describe('V2Inspector', () => { expect(screen.queryByRole('tab')).not.toBeInTheDocument(); }); + test('uses the resolved agent label ahead of an old profile ID', () => { + renderInspector({ detail: { ...detail, agents: [{ + agentName: 'scout', instanceId: 'default', displayName: 'Scout', + profile: { displayName: 'u1a9e5ecede' }, + }] } as any, attentionCount: 0, attentionItems: [] }); + + expect(screen.getByText('Scout')).toBeInTheDocument(); + expect(screen.queryByText('u1a9e5ecede')).not.toBeInTheDocument(); + }); + test('uses the short lowercase room name in the single-line agents label', () => { renderInspector({ detail: { ...detail, pod: { ...detail.pod, name: 'Sharpen · decision loop' } } as any }); diff --git a/frontend/src/v2/components/V2Inspector.tsx b/frontend/src/v2/components/V2Inspector.tsx index 6f1c4c3080..cc30f2eccd 100644 --- a/frontend/src/v2/components/V2Inspector.tsx +++ b/frontend/src/v2/components/V2Inspector.tsx @@ -48,7 +48,9 @@ const isWorkingTask = (task: TaskItem): boolean => ( const labelForAgent = (agent: V2Agent): string => ( - agent.profile?.displayName || agent.displayName || agent.agentName + // The roster's displayName is resolved from the agent User identity. A + // profile name may be an older generated ID, so it is only a fallback. + agent.displayName || agent.profile?.displayName || agent.agentName ); // Pods often carry a longer descriptive title, while the compact inspector From f48a86d06bf4e9adf5e92d444be9b9fae795562b Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sat, 24 Oct 2026 00:54:45 -0700 Subject: [PATCH 2/3] fix: match legacy agent labels in inspector attention Co-authored-by: Polish Agent-Model: codex/gpt-6-sol/medium --- frontend/src/v2/__tests__/V2Inspector.test.tsx | 10 +++++++--- frontend/src/v2/components/V2Inspector.tsx | 10 +++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/frontend/src/v2/__tests__/V2Inspector.test.tsx b/frontend/src/v2/__tests__/V2Inspector.test.tsx index 6bd0c5471c..402dc66987 100644 --- a/frontend/src/v2/__tests__/V2Inspector.test.tsx +++ b/frontend/src/v2/__tests__/V2Inspector.test.tsx @@ -141,13 +141,17 @@ describe('V2Inspector', () => { expect(screen.queryByRole('tab')).not.toBeInTheDocument(); }); - test('uses the resolved agent label ahead of an old profile ID', () => { + test('uses the resolved agent label while matching attention under an old profile ID', () => { renderInspector({ detail: { ...detail, agents: [{ agentName: 'scout', instanceId: 'default', displayName: 'Scout', profile: { displayName: 'u1a9e5ecede' }, - }] } as any, attentionCount: 0, attentionItems: [] }); + }] } as any, attentionItems: [{ + id: 'legacy-request', kind: 'decision', title: 'Legacy request', + actorName: 'u1a9e5ecede', podId: 'pod-1', + }] }); - expect(screen.getByText('Scout')).toBeInTheDocument(); + expect(screen.getAllByText('Scout')).toHaveLength(2); + expect(screen.getByRole('button', { name: /Scout needs you · Legacy request/ })).toBeInTheDocument(); expect(screen.queryByText('u1a9e5ecede')).not.toBeInTheDocument(); }); diff --git a/frontend/src/v2/components/V2Inspector.tsx b/frontend/src/v2/components/V2Inspector.tsx index cc30f2eccd..a337cac29a 100644 --- a/frontend/src/v2/components/V2Inspector.tsx +++ b/frontend/src/v2/components/V2Inspector.tsx @@ -63,9 +63,17 @@ const matchesAgent = (agent: V2Agent, value?: string): boolean => { const candidate = (value || '').toLowerCase(); return candidate === (agent.agentName || '').toLowerCase() || candidate === labelForAgent(agent).toLowerCase() + || candidate === (agent.profile?.displayName || '').toLowerCase() || candidate === (agent.instanceId || '').toLowerCase(); }; +const labelForAttentionActor = (agents: V2Agent[], actorName: string): string => { + const legacyAgent = agents.find((agent) => ( + agent.profile?.displayName?.toLowerCase() === actorName.toLowerCase() + )); + return legacyAgent ? labelForAgent(legacyAgent) : actorName; +}; + const agentState = ( agent: V2Agent, attention: V2AttentionItem[], @@ -187,7 +195,7 @@ const V2Inspector: React.FC = ({ detail, currentUserId, onPodC {attention.map((item) => ( ))} From da8034d01d3e136ff571e831d6a9f35e762feef4 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sat, 24 Oct 2026 00:57:10 -0700 Subject: [PATCH 3/3] fix: ignore empty actor and assignee names Co-authored-by: Polish Agent-Model: codex/gpt-6-sol/medium --- .../src/v2/__tests__/V2Inspector.test.tsx | 23 +++++++++++++++++++ frontend/src/v2/components/V2Inspector.tsx | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/frontend/src/v2/__tests__/V2Inspector.test.tsx b/frontend/src/v2/__tests__/V2Inspector.test.tsx index 402dc66987..f64389bad7 100644 --- a/frontend/src/v2/__tests__/V2Inspector.test.tsx +++ b/frontend/src/v2/__tests__/V2Inspector.test.tsx @@ -155,6 +155,29 @@ describe('V2Inspector', () => { expect(screen.queryByText('u1a9e5ecede')).not.toBeInTheDocument(); }); + test('does not assign anonymous attention to an agent without a profile name', () => { + renderInspector({ detail: { ...detail, agents: [{ + agentName: 'scout', instanceId: 'default', displayName: 'Scout', + }] } as any, attentionItems: [{ + id: 'human-question', kind: 'decision', title: 'Human question', podId: 'pod-1', + }] }); + + expect(screen.getByText('Human question')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /Scout idle/ })).toBeInTheDocument(); + }); + + test('does not assign an unowned active task to an agent without a profile name', async () => { + mockGet.mockImplementation((url: string) => Promise.resolve(url === '/api/v1/tasks/pod-1' + ? { tasks: [{ taskId: 'TASK-1', title: 'Unowned work', status: 'claimed' }] } + : { items: [], total: 0 })); + renderInspector({ detail: { ...detail, agents: [{ + agentName: 'scout', instanceId: 'default', displayName: 'Scout', + }] } as any, attentionCount: 0, attentionItems: [] }); + + await screen.findByText('no files yet'); + expect(screen.getByRole('button', { name: /Scout idle/ })).toBeInTheDocument(); + }); + test('uses the short lowercase room name in the single-line agents label', () => { renderInspector({ detail: { ...detail, pod: { ...detail.pod, name: 'Sharpen · decision loop' } } as any }); diff --git a/frontend/src/v2/components/V2Inspector.tsx b/frontend/src/v2/components/V2Inspector.tsx index a337cac29a..b8e0ae5180 100644 --- a/frontend/src/v2/components/V2Inspector.tsx +++ b/frontend/src/v2/components/V2Inspector.tsx @@ -60,7 +60,8 @@ const shortRoomName = (name: string): string => ( ); const matchesAgent = (agent: V2Agent, value?: string): boolean => { - const candidate = (value || '').toLowerCase(); + const candidate = (value || '').trim().toLowerCase(); + if (!candidate) return false; return candidate === (agent.agentName || '').toLowerCase() || candidate === labelForAgent(agent).toLowerCase() || candidate === (agent.profile?.displayName || '').toLowerCase()