#22977: fix(ui): resolve agent names from config in session dropdown
app: web-ui
size: S
Cluster:
UI Enhancements and Fixes
## Summary
- **Problem:** The agent selection dropdown in the control dashboard showed mangled session keys like `agent-main-main (agent:main:main)` or delivery-context values (e.g., phone numbers) instead of the configured agent names (e.g., "Piper", "Clint").
- **Root cause:** `resolveSessionDisplayName` used `row.displayName` (populated from delivery context) as the preferred label and `parseSessionKey` returned the raw key as fallback for non-main agents — neither path looked up agent names from the loaded agents config.
- **Fix:** Extract `agentId` from session keys, look up the agent's configured name from the agents list, and use it as the preferred display name (after user-editable labels but before row `displayName`).
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [ ] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [ ] Integrations
- [ ] API / contracts
- [x] UI / DX
- [ ] CI/CD / infra
## Linked Issue/PR
- Closes #22752
## Changes
**2 files changed** in `ui/src/ui/`:
### `app-render.helpers.ts`
- Added `agentId?: string` field to `SessionKeyInfo` type
- `parseSessionKey()` now extracts `agentId` from the second segment of `agent:X:…` keys
- `resolveSessionDisplayName()` accepts an optional `agents: GatewayAgentRow[]` parameter; when an `agentId` resolves to a named agent in the config, that name is used as the display label (priority: user label → agent config name → row displayName → parsed fallback)
- `resolveSessionOptions()` threads the agents list through to `resolveSessionDisplayName()`
- `renderChatControls()` passes `state.agentsList?.agents` into `resolveSessionOptions()`
### `app-render.helpers.node.test.ts`
- Updated existing `parseSessionKey` assertions to include the new `agentId` field
- Added 2 new `parseSessionKey` tests for non-main agent keys
- Added 9 new `resolveSessionDisplayName` tests covering: agent name resolution, priority over delivery-context displayName, user label priority, typed prefixes with agent names, fallback behavior when agent has no name / is not in list / agents list not provided
## User-visible / Behavior Changes
With agents configured as:
```json
"agents": {
"list": [
{ "id": "main", "name": "Piper" },
{ "id": "clint", "name": "Clint" }
]
}
```
| Session key | Before | After |
|---|---|---|
| `agent:main:main` | `agent-main-main (agent:main:main)` | **Piper** |
| `agent:clint:main` | `+1(phone) (agent:clint:main)` | **Clint** |
| `agent:main:subagent:abc` | `Subagent:` | **Subagent: Piper** |
| `agent:main:cron:daily` | `Cron Job:` | **Cron: Piper** |
User-editable session labels still take priority over agent names.
## Security Impact (required)
- New permissions/capabilities? (`No`)
- Secrets/tokens handling changed? (`No`)
- New/changed network calls? (`No`)
- Command/tool execution surface changed? (`No`)
- Data access scope changed? (`No`)
## Test plan
- [x] All 45 existing + new tests pass (`vitest run`)
- [x] `parseSessionKey` returns `agentId` for all `agent:X:…` key patterns
- [x] `resolveSessionDisplayName` prefers agent config name over delivery-context displayName
- [x] User-editable labels still take priority over agent names
- [x] Typed prefixes (Subagent:/Cron:) correctly applied to agent names
- [x] Graceful fallback when agents list not available or agent not found
- [ ] Manual verification in dashboard with multi-agent config
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixed agent name display in session dropdown by extracting `agentId` from session keys and looking up configured agent names. Previously showed mangled keys or delivery-context values instead of friendly names like "Piper" or "Clint". The priority chain is now: user label → agent config name → row displayName → parsed fallback.
<h3>Confidence Score: 5/5</h3>
- Safe to merge - well-tested UI bug fix with comprehensive test coverage
- Clean implementation with excellent test coverage (11 new tests). Logic is straightforward: extract agentId via regex, look up agent name, apply correct priority. No security concerns, purely UI-focused change.
- No files require special attention
<sub>Last reviewed commit: e674337</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#21679: fix: Mission Control dashboard issues for agent status, stale sessi...
by thejawdoc · 2026-02-20
85.8%
#15982: fix: pass agentId to resolveSessionFilePath in reply flow (NX-003)
by automagik-genie · 2026-02-14
84.0%
#5097: fix(ui): prefer session label over displayName in dropdown
by d-init-d · 2026-01-31
82.7%
#19177: fix: use parseAgentSessionKey instead of fragile split pattern
by El-Patronum · 2026-02-17
82.5%
#14309: fix(ui): resolve chat event session key mismatch
by justonlyforyou · 2026-02-11
82.3%
#8774: Fix/frontend session key normalization
by zhaodageng · 2026-02-04
82.0%
#15792: fix: pass agentId to resolveSessionFilePath in additional call sites
by MisterGuy420 · 2026-02-13
81.1%
#16362: Update session-pruning.md - updated agents.defaults config std
by elliottb · 2026-02-14
80.3%
#7301: fix(hooks): use resolveAgentIdFromSessionKey instead of split(":")[0]
by tsukhani · 2026-02-02
80.3%
#8210: ui: show subagent labels in chat session dropdown
by pborgen · 2026-02-03
79.9%