From 68a3d16d9e4f807763b99cb35a9f33c192220415 Mon Sep 17 00:00:00 2001
From: Nahiyan Khan
Date: Wed, 8 Apr 2026 19:41:08 -0400
Subject: [PATCH] Fun bot names from persona name pools (#273)
Co-authored-by: Claude Opus 4.6 (1M context)
---
desktop/scripts/check-file-sizes.mjs | 2 +-
.../src-tauri/src/commands/agent_models.rs | 6 ++
desktop/src-tauri/src/commands/personas.rs | 17 +++-
.../src/managed_agents/persona_card.rs | 43 +++++++---
.../src-tauri/src/managed_agents/personas.rs | 23 ++++++
desktop/src-tauri/src/managed_agents/teams.rs | 1 +
desktop/src-tauri/src/managed_agents/types.rs | 11 +++
.../src/features/agents/lib/pickBotName.ts | 79 +++++++++++++++++++
.../src/features/agents/ui/PersonaDialog.tsx | 36 +++++++++
.../channels/ui/ChannelMembersBar.tsx | 46 +++++------
.../src/features/channels/ui/ChannelPane.tsx | 4 +
.../features/channels/ui/ChannelScreen.tsx | 53 +++++++++++--
.../src/features/channels/ui/QuickBotBar.tsx | 2 +-
.../messages/lib/formatTimelineMessages.ts | 9 ++-
.../src/features/messages/lib/useMentions.ts | 43 ++++++++--
desktop/src/features/messages/types.ts | 2 +
.../messages/ui/MentionAutocomplete.tsx | 7 +-
.../src/features/messages/ui/MessageRow.tsx | 15 ++--
.../features/messages/ui/MessageTimeline.tsx | 4 +
.../features/messages/ui/SystemMessageRow.tsx | 25 +++++-
.../messages/ui/TimelineMessageList.tsx | 4 +
desktop/src/shared/api/tauriPersonas.ts | 7 ++
desktop/src/shared/api/types.ts | 6 ++
23 files changed, 388 insertions(+), 57 deletions(-)
create mode 100644 desktop/src/features/agents/lib/pickBotName.ts
diff --git a/desktop/scripts/check-file-sizes.mjs b/desktop/scripts/check-file-sizes.mjs
index 6ec4113dc..720c11f0b 100644
--- a/desktop/scripts/check-file-sizes.mjs
+++ b/desktop/scripts/check-file-sizes.mjs
@@ -31,7 +31,7 @@ const rules = [
// Exceptions should stay rare and temporary. Prefer splitting files instead.
const overrides = new Map([
["src-tauri/src/managed_agents/personas.rs", 600], // built-in persona system prompts (Solo, Ralph, Strategist) are long string literals
- ["src-tauri/src/managed_agents/persona_card.rs", 772], // PNG/ZIP persona card codec + provider/model fields + 27 unit tests (~350 lines of tests); rustfmt adds line breaks around long literals/builders
+ ["src-tauri/src/managed_agents/persona_card.rs", 800], // PNG/ZIP persona card codec + provider/model/namePool fields + 27 unit tests (~350 lines of tests); rustfmt adds line breaks around long literals/builders
["src/app/AppShell.tsx", 860], // message edit state + handlers + ChannelPane edit prop threading + scrollback pagination + workflows view + memory-leak safeguards
["src/features/channels/hooks.ts", 550], // canvas query + mutation hooks + DM hide mutation
["src/features/channels/ui/ChannelManagementSheet.tsx", 800],
diff --git a/desktop/src-tauri/src/commands/agent_models.rs b/desktop/src-tauri/src/commands/agent_models.rs
index 7aed05678..c11742243 100644
--- a/desktop/src-tauri/src/commands/agent_models.rs
+++ b/desktop/src-tauri/src/commands/agent_models.rs
@@ -117,6 +117,12 @@ pub fn update_managed_agent(
let record = find_managed_agent_mut(&mut records, &input.pubkey)?;
+ if let Some(name_update) = input.name {
+ let trimmed = name_update.trim().to_string();
+ if !trimmed.is_empty() {
+ record.name = trimmed;
+ }
+ }
// Tri-state: None = don't touch, Some(None) = clear, Some(Some(v)) = set
if let Some(model_update) = input.model {
record.model = model_update;
diff --git a/desktop/src-tauri/src/commands/personas.rs b/desktop/src-tauri/src/commands/personas.rs
index 14128b813..75afaeca2 100644
--- a/desktop/src-tauri/src/commands/personas.rs
+++ b/desktop/src-tauri/src/commands/personas.rs
@@ -57,6 +57,12 @@ pub fn create_persona(
.lock()
.map_err(|error| error.to_string())?;
let mut personas = load_personas(&app)?;
+ let name_pool: Vec = input
+ .name_pool
+ .into_iter()
+ .map(|s| s.trim().to_string())
+ .filter(|s| !s.is_empty())
+ .collect();
let persona = PersonaRecord {
id: Uuid::new_v4().to_string(),
display_name,
@@ -64,6 +70,7 @@ pub fn create_persona(
system_prompt,
provider,
model,
+ name_pool,
is_builtin: false,
created_at: now.clone(),
updated_at: now,
@@ -104,6 +111,12 @@ pub fn update_persona(
persona.system_prompt = system_prompt;
persona.provider = provider;
persona.model = model;
+ persona.name_pool = input
+ .name_pool
+ .into_iter()
+ .map(|s| s.trim().to_string())
+ .filter(|s| !s.is_empty())
+ .collect();
persona.updated_at = now_iso();
save_personas(&app, &personas)?;
@@ -226,7 +239,7 @@ pub async fn export_persona_to_json(
state: State<'_, AppState>,
) -> Result {
// Load persona data under lock, then drop lock before dialog.
- let (display_name, system_prompt, avatar_url, provider, model) = {
+ let (display_name, system_prompt, avatar_url, provider, model, name_pool) = {
let _store_guard = state
.managed_agents_store_lock
.lock()
@@ -242,6 +255,7 @@ pub async fn export_persona_to_json(
persona.avatar_url.clone(),
persona.provider.clone(),
persona.model.clone(),
+ persona.name_pool.clone(),
)
};
@@ -251,6 +265,7 @@ pub async fn export_persona_to_json(
avatar_url.as_deref(),
provider.as_deref(),
model.as_deref(),
+ &name_pool,
)?;
let slug = crate::util::slugify(&display_name, "persona", 50);
diff --git a/desktop/src-tauri/src/managed_agents/persona_card.rs b/desktop/src-tauri/src/managed_agents/persona_card.rs
index 07c1a6861..6204a863d 100644
--- a/desktop/src-tauri/src/managed_agents/persona_card.rs
+++ b/desktop/src-tauri/src/managed_agents/persona_card.rs
@@ -15,6 +15,8 @@ pub struct ParsedPersonaPreview {
pub avatar_data_url: Option,
pub provider: Option,
pub model: Option,
+ #[serde(default, skip_serializing_if = "Vec::is_empty")]
+ pub name_pool: Vec,
pub source_file: String,
}
@@ -80,6 +82,7 @@ pub fn parse_png_persona(png_bytes: &[u8]) -> Result,
provider: Option,
model: Option,
+ name_pool: Vec,
}
/// Extract and validate fields from a Sprout persona JSON value
@@ -143,12 +147,24 @@ fn extract_sprout_fields(v: &Value) -> Result {
.map(|s| s.trim())
.filter(|s| !s.is_empty())
.map(|s| s.to_string());
+ let name_pool = v
+ .get("namePool")
+ .and_then(|v| v.as_array())
+ .map(|arr| {
+ arr.iter()
+ .filter_map(|item| item.as_str())
+ .map(|s| s.trim().to_string())
+ .filter(|s| !s.is_empty())
+ .collect()
+ })
+ .unwrap_or_default();
Ok(SproutPersonaFields {
display_name: name,
system_prompt: prompt,
avatar_url,
provider,
model,
+ name_pool,
})
}
@@ -192,6 +208,7 @@ fn parse_chara_payload(b64: &str) -> Result {
avatar_url: None,
provider: None,
model: None,
+ name_pool: Vec::new(),
})
}
@@ -209,6 +226,7 @@ pub fn parse_json_persona(json_bytes: &[u8]) -> Result,
provider: Option<&str>,
model: Option<&str>,
+ name_pool: &[String],
) -> Result, String> {
let mut map = serde_json::Map::new();
map.insert("version".to_string(), serde_json::json!(1));
@@ -233,6 +252,9 @@ pub fn encode_persona_json(
if let Some(m) = model {
map.insert("model".to_string(), serde_json::json!(m));
}
+ if !name_pool.is_empty() {
+ map.insert("namePool".to_string(), serde_json::json!(name_pool));
+ }
serde_json::to_vec_pretty(&map).map_err(|e| format!("Failed to serialize JSON: {e}"))
}
@@ -614,6 +636,7 @@ mod tests {
Some("https://example.com/ada.png"),
None,
None,
+ &[],
)
.unwrap();
let result = parse_json_persona(&bytes).unwrap();
@@ -628,7 +651,7 @@ mod tests {
#[test]
fn parse_json_round_trip_no_avatar() {
- let bytes = encode_persona_json("Bob", "You are Bob.", None, None, None).unwrap();
+ let bytes = encode_persona_json("Bob", "You are Bob.", None, None, None, &[]).unwrap();
let result = parse_json_persona(&bytes).unwrap();
assert_eq!(result.display_name, "Bob");
assert_eq!(result.system_prompt, "You are Bob.");
@@ -638,8 +661,8 @@ mod tests {
#[test]
fn parse_json_round_trip_data_uri_avatar() {
let data_uri = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg==";
- let bytes =
- encode_persona_json("Carol", "You are Carol.", Some(data_uri), None, None).unwrap();
+ let bytes = encode_persona_json("Carol", "You are Carol.", Some(data_uri), None, None, &[])
+ .unwrap();
let result = parse_json_persona(&bytes).unwrap();
assert_eq!(result.display_name, "Carol");
assert_eq!(result.avatar_data_url.as_deref(), Some(data_uri));
@@ -653,6 +676,7 @@ mod tests {
None,
Some("goose"),
Some("claude-sonnet-4"),
+ &[],
)
.unwrap();
let result = parse_json_persona(&bytes).unwrap();
@@ -665,7 +689,7 @@ mod tests {
#[test]
fn parse_json_round_trip_without_provider_and_model() {
- let bytes = encode_persona_json("Bob", "You are Bob.", None, None, None).unwrap();
+ let bytes = encode_persona_json("Bob", "You are Bob.", None, None, None, &[]).unwrap();
let result = parse_json_persona(&bytes).unwrap();
assert_eq!(result.display_name, "Bob");
assert!(result.provider.is_none());
@@ -727,8 +751,8 @@ mod tests {
#[test]
fn parse_zip_with_json() {
- let j1 = encode_persona_json("Alice", "Prompt A", None, None, None).unwrap();
- let j2 = encode_persona_json("Bob", "Prompt B", None, None, None).unwrap();
+ let j1 = encode_persona_json("Alice", "Prompt A", None, None, None, &[]).unwrap();
+ let j2 = encode_persona_json("Bob", "Prompt B", None, None, None, &[]).unwrap();
let zip = make_test_zip(&[("alice.persona.json", &j1), ("bob.persona.json", &j2)]);
let result = parse_zip_personas(&zip).unwrap();
assert_eq!(result.personas.len(), 2);
@@ -740,7 +764,8 @@ mod tests {
#[test]
fn parse_zip_mixed_png_and_json() {
let png = make_test_persona_png("PngPersona", "PNG prompt");
- let json = encode_persona_json("JsonPersona", "JSON prompt", None, None, None).unwrap();
+ let json =
+ encode_persona_json("JsonPersona", "JSON prompt", None, None, None, &[]).unwrap();
let zip = make_test_zip(&[
("persona.png", &png),
("persona.json", &json),
@@ -755,8 +780,8 @@ mod tests {
#[test]
fn parse_zip_ignores_macos_resource_forks() {
- let j1 = encode_persona_json("Frank", "You are Frank.", None, None, None).unwrap();
- let j2 = encode_persona_json("Jackie", "You are Jackie.", None, None, None).unwrap();
+ let j1 = encode_persona_json("Frank", "You are Frank.", None, None, None, &[]).unwrap();
+ let j2 = encode_persona_json("Jackie", "You are Jackie.", None, None, None, &[]).unwrap();
let zip = make_test_zip(&[
("frank-costanza.persona.json", &j1),
("jackie-chiles.persona.json", &j2),
diff --git a/desktop/src-tauri/src/managed_agents/personas.rs b/desktop/src-tauri/src/managed_agents/personas.rs
index b4428bfb4..611bdaf08 100644
--- a/desktop/src-tauri/src/managed_agents/personas.rs
+++ b/desktop/src-tauri/src/managed_agents/personas.rs
@@ -12,6 +12,7 @@ struct BuiltInPersona {
display_name: &'static str,
avatar_url: Option<&'static str>,
system_prompt: &'static str,
+ name_pool: &'static [&'static str],
}
const SOLO_AVATAR: &str = "data:image/png;base64,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";
@@ -240,11 +241,20 @@ const BUILT_IN_PERSONAS: &[BuiltInPersona] = &[
display_name: "Solo",
avatar_url: Some(SOLO_AVATAR),
system_prompt: SOLO_SYSTEM_PROMPT,
+ name_pool: &[
+ "Atlas", "Ember", "Flint", "Sage", "Drift", "Quill", "Wren", "Cedar", "Pike", "Lark",
+ "Birch", "Dune", "Fern", "Moss", "Reed", "Slate", "Ash", "Brook", "Glen", "Stone",
+ ],
},
BuiltInPersona {
id: "builtin:ralph",
display_name: "Ralph",
avatar_url: Some(RALPH_AVATAR),
+ name_pool: &[
+ "Loop", "Orbit", "Gears", "Crank", "Cycle", "Anvil", "Piston", "Bolt", "Forge",
+ "Pulley", "Turbo", "Hinge", "Torque", "Lever", "Axle", "Cam", "Rivet", "Lathe",
+ "Ratchet", "Flywheel",
+ ],
system_prompt: r#"You are an autonomous iteration agent implementing the Ralph Loop pattern. Your core behavior is to repeatedly cycle through tasks until every item is objectively complete, using disk-based state rather than conversation memory.
## Iteration Cycle
@@ -277,6 +287,11 @@ Each time you are invoked, follow this loop:
id: "builtin:scout",
display_name: "Scout",
avatar_url: Some(SCOUT_AVATAR),
+ name_pool: &[
+ "Compass", "Ridge", "Thistle", "Flare", "Mica", "Cairn", "Bramble", "Beacon", "Blaze",
+ "Summit", "Crest", "Spur", "Trail", "Ledge", "Cliff", "Harbor", "Delta", "Inlet",
+ "Pebble", "Thicket",
+ ],
system_prompt: r#"You are a methodical agent implementing the Research-Plan-Implement (RPI) pattern. You trade speed for clarity, predictability, and correctness by separating work into three distinct phases. Never skip phases or jump ahead to implementation.
## Phase 1: Research
@@ -327,6 +342,11 @@ Execute the plan mechanically, phase by phase.
id: "builtin:reviewer",
display_name: "Reviewer",
avatar_url: None,
+ name_pool: &[
+ "Lens", "Prism", "Gauge", "Sieve", "Probe", "Caliper", "Loupe", "Ruler", "Level",
+ "Plumb", "Square", "Chisel", "Awl", "Rasp", "Clamp", "Vise", "Trowel", "Mallet",
+ "Bevel", "Scalpel",
+ ],
system_prompt: r#"You are a thorough code reviewer. Your job is to catch bugs, security issues, and design problems before they ship.
## How You Review
@@ -381,6 +401,7 @@ fn built_in_persona_records(now: &str) -> Vec {
system_prompt: persona.system_prompt.to_string(),
provider: None,
model: None,
+ name_pool: persona.name_pool.iter().map(|s| s.to_string()).collect(),
is_builtin: true,
created_at: now.to_string(),
updated_at: now.to_string(),
@@ -426,6 +447,7 @@ fn merge_personas(mut stored: Vec, now: &str) -> (Vec,
+ /// Pool of short, thematic names for bot instances created from this persona.
+ /// When a new copy is added to a channel, a random unused name is picked from this pool.
+ #[serde(default, skip_serializing_if = "Vec::is_empty")]
+ pub name_pool: Vec,
#[serde(default)]
pub is_builtin: bool,
pub created_at: String,
@@ -177,6 +181,8 @@ pub struct CreatePersonaRequest {
pub provider: Option,
#[serde(default)]
pub model: Option,
+ #[serde(default)]
+ pub name_pool: Vec,
}
#[derive(Debug, Deserialize)]
@@ -190,6 +196,8 @@ pub struct UpdatePersonaRequest {
pub provider: Option,
#[serde(default)]
pub model: Option,
+ #[serde(default)]
+ pub name_pool: Vec,
}
#[derive(Debug, Deserialize)]
@@ -253,6 +261,9 @@ pub struct ManagedAgentPrereqsInfo {
#[serde(rename_all = "camelCase")]
pub struct UpdateManagedAgentRequest {
pub pubkey: String,
+ /// Absent = don't touch. Present = rename the agent.
+ #[serde(default)]
+ pub name: Option,
/// Absent = don't touch. null = clear to agent default. "id" = set.
#[serde(default)]
pub model: Option
+
+
+
setNamePoolText(event.target.value)}
+ placeholder="Birch, Compass, Ridge, Thistle, ..."
+ spellCheck={false}
+ value={namePoolText}
+ />
+
+ Comma-separated names for bot copies. Each instance gets a
+ random name from this pool. Leave empty to use generic defaults.
+
+
+
{error ? (
{error.message}
diff --git a/desktop/src/features/channels/ui/ChannelMembersBar.tsx b/desktop/src/features/channels/ui/ChannelMembersBar.tsx
index 940ea5058..caf088bf2 100644
--- a/desktop/src/features/channels/ui/ChannelMembersBar.tsx
+++ b/desktop/src/features/channels/ui/ChannelMembersBar.tsx
@@ -8,6 +8,7 @@ import {
usePersonasQuery,
useRelayAgentsQuery,
} from "@/features/agents/hooks";
+import { pickBotName } from "@/features/agents/lib/pickBotName";
import {
useBotRecents,
DEFAULT_PERSONA_NAMES,
@@ -68,9 +69,9 @@ export function ChannelMembersBar({
const { recentIds, pushRecent } = useBotRecents();
const quickDrop = useQuickBotDrop(channel.id);
- // Track in-flight instance numbers so rapid clicks don't produce duplicates.
+ // Track in-flight instance names so rapid clicks don't produce duplicates.
// Cleared when the members query refetches with the new member.
- const inflightCountRef = React.useRef>({});
+ const inflightNamesRef = React.useRef>({});
// Resolve the 3 personas to show in the quick bar.
// Use recents if available, otherwise fall back to default names.
@@ -99,35 +100,34 @@ export function ChannelMembersBar({
}
}
- // Reset in-flight counts when members list updates (the new bot appeared).
- inflightCountRef.current = {};
+ // Reset in-flight names when members list updates (the new bot appeared).
+ inflightNamesRef.current = {};
- // Compute instance names from current members
+ // Build the set of names already used in this channel
+ const usedNames = new Set(
+ members.map((m) => m.displayName ?? "").filter((n) => n.length > 0),
+ );
+
+ // Compute instance names from persona name pools
return resolved.map((persona) => {
- const prefix = `${persona.displayName}::`;
- let maxNum = 0;
- for (const member of members) {
- const label = member.displayName ?? "";
- if (label.startsWith(prefix)) {
- const num = Number.parseInt(label.slice(prefix.length), 10);
- if (!Number.isNaN(num) && num > maxNum) maxNum = num;
- }
- }
- const inflight = inflightCountRef.current[persona.id] ?? 0;
- const next = maxNum + 1 + inflight;
- return {
- persona,
- instanceName: `${persona.displayName}::${String(next).padStart(2, "0")}`,
- };
+ // Include in-flight names to avoid duplicates on rapid clicks
+ const inflight = inflightNamesRef.current[persona.id] ?? [];
+ const combinedUsed = new Set(usedNames);
+ for (const n of inflight) combinedUsed.add(n);
+
+ const instanceName = pickBotName(persona.namePool ?? [], combinedUsed);
+ return { persona, instanceName };
});
}, [allPersonas, recentIds, members]);
const addBot = quickDrop.addBot;
const handleQuickAdd = React.useCallback(
async (persona: AgentPersona, instanceName: string) => {
- // Optimistically bump the in-flight counter to avoid duplicate names.
- inflightCountRef.current[persona.id] =
- (inflightCountRef.current[persona.id] ?? 0) + 1;
+ // Optimistically track the chosen name to avoid duplicates on rapid clicks.
+ inflightNamesRef.current[persona.id] = [
+ ...(inflightNamesRef.current[persona.id] ?? []),
+ instanceName,
+ ];
pushRecent(persona.id);
await addBot(persona, instanceName);
},
diff --git a/desktop/src/features/channels/ui/ChannelPane.tsx b/desktop/src/features/channels/ui/ChannelPane.tsx
index 01961a6a3..e8693019c 100644
--- a/desktop/src/features/channels/ui/ChannelPane.tsx
+++ b/desktop/src/features/channels/ui/ChannelPane.tsx
@@ -38,6 +38,8 @@ type ChannelPaneProps = {
emoji: string,
remove: boolean,
) => Promise;
+ /** Map from lowercase pubkey → persona display name for bot members. */
+ personaLookup?: Map;
profiles?: UserProfileLookup;
replyTargetId: string | null;
replyTargetMessage: TimelineMessage | null;
@@ -64,6 +66,7 @@ export const ChannelPane = React.memo(function ChannelPane({
onSend,
onTargetReached,
onToggleReaction,
+ personaLookup,
profiles,
replyTargetId,
replyTargetMessage,
@@ -79,6 +82,7 @@ export const ChannelPane = React.memo(function ChannelPane({
fetchOlder={fetchOlder}
hasOlderMessages={hasOlderMessages}
isFetchingOlder={isFetchingOlder}
+ personaLookup={personaLookup}
profiles={profiles}
emptyDescription={
activeChannel?.channelType === "forum"
diff --git a/desktop/src/features/channels/ui/ChannelScreen.tsx b/desktop/src/features/channels/ui/ChannelScreen.tsx
index 30d6f46e8..dc3a5c054 100644
--- a/desktop/src/features/channels/ui/ChannelScreen.tsx
+++ b/desktop/src/features/channels/ui/ChannelScreen.tsx
@@ -8,6 +8,10 @@ import { useChannelPaneHandlers } from "@/features/channels/useChannelPaneHandle
import { useChannelMembersQuery } from "@/features/channels/hooks";
import { ChannelMembersBar } from "@/features/channels/ui/ChannelMembersBar";
import { MembersSidebar } from "@/features/channels/ui/MembersSidebar";
+import {
+ useManagedAgentsQuery,
+ usePersonasQuery,
+} from "@/features/agents/hooks";
import {
mergeMessages,
useChannelMessagesQuery,
@@ -140,16 +144,52 @@ export function ChannelScreen({
const messageProfilesQuery = useUsersBatchQuery(messageProfilePubkeys, {
enabled: messageProfilePubkeys.length > 0,
});
- const messageProfiles = React.useMemo(
- () =>
+ const managedAgentsQuery = useManagedAgentsQuery();
+ const messageProfiles = React.useMemo(() => {
+ const base =
mergeCurrentProfileIntoLookup(
messageProfilesQuery.data?.profiles,
currentProfile,
- ),
- [currentProfile, messageProfilesQuery.data?.profiles],
- );
+ ) ?? {};
+ // Merge managed agent names so system messages resolve instantly
+ // (without waiting for the relay profile batch query).
+ const agents = managedAgentsQuery.data ?? [];
+ const merged = { ...base };
+ for (const agent of agents) {
+ const key = agent.pubkey.toLowerCase();
+ if (!merged[key]?.displayName) {
+ merged[key] = {
+ ...merged[key],
+ displayName: agent.name,
+ avatarUrl: null,
+ nip05Handle: null,
+ };
+ }
+ }
+ return merged;
+ }, [
+ currentProfile,
+ managedAgentsQuery.data,
+ messageProfilesQuery.data?.profiles,
+ ]);
const channelMembersQuery = useChannelMembersQuery(activeChannel?.id ?? null);
const channelMembers = channelMembersQuery.data;
+ const personasQuery = usePersonasQuery();
+ const personaLookup = React.useMemo(() => {
+ const agents = managedAgentsQuery.data ?? [];
+ const personas = personasQuery.data ?? [];
+ const personaById = new Map(personas.map((p) => [p.id, p.displayName]));
+ const lookup = new Map();
+ for (const agent of agents) {
+ if (agent.personaId) {
+ const personaName = personaById.get(agent.personaId);
+ if (personaName) {
+ lookup.set(agent.pubkey.toLowerCase(), personaName);
+ }
+ }
+ }
+ return lookup;
+ }, [managedAgentsQuery.data, personasQuery.data]);
const timelineMessages = React.useMemo(
() =>
formatTimelineMessages(
@@ -159,6 +199,7 @@ export function ChannelScreen({
currentProfile?.avatarUrl ?? null,
messageProfiles,
channelMembers,
+ personaLookup,
),
[
activeChannel,
@@ -166,6 +207,7 @@ export function ChannelScreen({
currentProfile?.avatarUrl,
currentPubkey,
messageProfiles,
+ personaLookup,
resolvedMessages,
],
);
@@ -403,6 +445,7 @@ export function ChannelScreen({
onReply={handleReply}
onSend={handleSend}
onToggleReaction={effectiveToggleReaction}
+ personaLookup={personaLookup}
profiles={messageProfiles}
replyTargetId={replyTargetId}
replyTargetMessage={replyTargetMessage}
diff --git a/desktop/src/features/channels/ui/QuickBotBar.tsx b/desktop/src/features/channels/ui/QuickBotBar.tsx
index 670448695..52dc8addd 100644
--- a/desktop/src/features/channels/ui/QuickBotBar.tsx
+++ b/desktop/src/features/channels/ui/QuickBotBar.tsx
@@ -87,7 +87,7 @@ export function QuickBotBar({ personas, pending, onAdd }: QuickBotBarProps) {
- Add {persona.displayName} → {instanceName}
+ Add {instanceName} ({persona.displayName})
);
diff --git a/desktop/src/features/messages/lib/formatTimelineMessages.ts b/desktop/src/features/messages/lib/formatTimelineMessages.ts
index 83360bd97..dd90d2845 100644
--- a/desktop/src/features/messages/lib/formatTimelineMessages.ts
+++ b/desktop/src/features/messages/lib/formatTimelineMessages.ts
@@ -114,6 +114,8 @@ export function formatTimelineMessages(
currentUserAvatarUrl: string | null,
profiles?: UserProfileLookup,
members?: ChannelMember[],
+ /** Map from lowercase pubkey → persona display name for bot messages. */
+ personaLookup?: Map,
): TimelineMessage[] {
const currentPubkeyLower = currentPubkey?.toLowerCase();
const roleByPubkey = new Map();
@@ -291,6 +293,7 @@ export function formatTimelineMessages(
});
const thread = getThreadReference(event.tags);
const edit = editsByTargetId.get(event.id);
+ const role = roleByPubkey.get(authorPubkey.toLowerCase());
return {
id: event.id,
createdAt: event.created_at,
@@ -302,7 +305,11 @@ export function formatTimelineMessages(
currentUserAvatarUrl,
profiles,
}),
- role: roleByPubkey.get(authorPubkey.toLowerCase()),
+ role,
+ personaDisplayName:
+ role === "bot"
+ ? personaLookup?.get(authorPubkey.toLowerCase())
+ : undefined,
time: formatTime(event.created_at),
body: edit ? edit.content : event.content,
parentId: thread.parentId,
diff --git a/desktop/src/features/messages/lib/useMentions.ts b/desktop/src/features/messages/lib/useMentions.ts
index 66d1f4867..158ef8ba0 100644
--- a/desktop/src/features/messages/lib/useMentions.ts
+++ b/desktop/src/features/messages/lib/useMentions.ts
@@ -1,6 +1,9 @@
import * as React from "react";
-import { useManagedAgentsQuery } from "@/features/agents/hooks";
+import {
+ useManagedAgentsQuery,
+ usePersonasQuery,
+} from "@/features/agents/hooks";
import { useChannelMembersQuery } from "@/features/channels/hooks";
import type { MentionSuggestion } from "@/features/messages/ui/MentionAutocomplete";
import { detectPrefixQuery } from "@/shared/lib/detectPrefixQuery";
@@ -17,6 +20,7 @@ export function useMentions(channelId: string | null) {
const membersQuery = useChannelMembersQuery(channelId);
const members = membersQuery.data;
const managedAgentsQuery = useManagedAgentsQuery();
+ const personasQuery = usePersonasQuery();
const managedAgentNamesByPubkey = React.useMemo(
() =>
new Map(
@@ -27,20 +31,41 @@ export function useMentions(channelId: string | null) {
),
[managedAgentsQuery.data],
);
+ const personaNameByPubkey = React.useMemo(() => {
+ const agents = managedAgentsQuery.data ?? [];
+ const personas = personasQuery.data ?? [];
+ const personaById = new Map(personas.map((p) => [p.id, p.displayName]));
+ const lookup = new Map();
+ for (const agent of agents) {
+ if (agent.personaId) {
+ const name = personaById.get(agent.personaId);
+ if (name) lookup.set(agent.pubkey.toLowerCase(), name);
+ }
+ }
+ return lookup;
+ }, [managedAgentsQuery.data, personasQuery.data]);
const knownNames = React.useMemo(() => {
if (!members) return [];
const names: string[] = [];
+ const seen = new Set();
for (const member of members) {
const name =
member.displayName ??
managedAgentNamesByPubkey.get(member.pubkey.toLowerCase());
if (name) {
names.push(name);
+ seen.add(name.toLowerCase());
+ }
+ // Also include persona names so typing @Scout triggers the dropdown
+ const personaName = personaNameByPubkey.get(member.pubkey.toLowerCase());
+ if (personaName && !seen.has(personaName.toLowerCase())) {
+ names.push(personaName);
+ seen.add(personaName.toLowerCase());
}
}
return names;
- }, [members, managedAgentNamesByPubkey]);
+ }, [members, managedAgentNamesByPubkey, personaNameByPubkey]);
/** Lower-cased version of knownNames, used for case-insensitive prefix matching. */
const knownNamesLower = React.useMemo(
@@ -78,27 +103,31 @@ export function useMentions(channelId: string | null) {
const lowerQuery = mentionQuery.toLowerCase();
return (members ?? [])
.map((member) => {
+ const pubkeyLower = member.pubkey.toLowerCase();
const fallbackName =
- managedAgentNamesByPubkey.get(member.pubkey.toLowerCase()) ??
+ managedAgentNamesByPubkey.get(pubkeyLower) ??
member.pubkey.slice(0, 8);
return {
member,
label: member.displayName ?? fallbackName,
+ personaName: personaNameByPubkey.get(pubkeyLower) ?? null,
};
})
.filter(
- ({ label, member }) =>
+ ({ label, member, personaName }) =>
label.toLowerCase().includes(lowerQuery) ||
- member.pubkey.toLowerCase().includes(lowerQuery),
+ member.pubkey.toLowerCase().includes(lowerQuery) ||
+ personaName?.toLowerCase().includes(lowerQuery),
)
.slice(0, 8)
- .map(({ member, label }) => ({
+ .map(({ member, label, personaName }) => ({
pubkey: member.pubkey,
displayName: label,
role: member.role === "admin" ? "admin" : null,
+ personaName,
}));
- }, [managedAgentNamesByPubkey, members, mentionQuery]);
+ }, [managedAgentNamesByPubkey, members, mentionQuery, personaNameByPubkey]);
const isMentionOpen = mentionQuery !== null && suggestions.length > 0;
diff --git a/desktop/src/features/messages/types.ts b/desktop/src/features/messages/types.ts
index b58957eca..79fc14f30 100644
--- a/desktop/src/features/messages/types.ts
+++ b/desktop/src/features/messages/types.ts
@@ -12,6 +12,8 @@ export type TimelineMessage = {
author: string;
avatarUrl?: string | null;
role?: string;
+ /** For bot messages, the display name of the persona this bot was created from. */
+ personaDisplayName?: string;
time: string;
body: string;
parentId?: string | null;
diff --git a/desktop/src/features/messages/ui/MentionAutocomplete.tsx b/desktop/src/features/messages/ui/MentionAutocomplete.tsx
index d44e3c858..d20f9ffce 100644
--- a/desktop/src/features/messages/ui/MentionAutocomplete.tsx
+++ b/desktop/src/features/messages/ui/MentionAutocomplete.tsx
@@ -6,6 +6,7 @@ export type MentionSuggestion = {
pubkey: string;
displayName: string;
role?: string | null;
+ personaName?: string | null;
};
type MentionAutocompleteProps = {
@@ -57,7 +58,11 @@ export const MentionAutocomplete = React.memo(function MentionAutocomplete({
{suggestion.displayName}
- {suggestion.role ? (
+ {suggestion.personaName ? (
+
+ ({suggestion.personaName})
+
+ ) : suggestion.role ? (
{suggestion.role}
diff --git a/desktop/src/features/messages/ui/MessageRow.tsx b/desktop/src/features/messages/ui/MessageRow.tsx
index 690886574..b1d5b00ce 100644
--- a/desktop/src/features/messages/ui/MessageRow.tsx
+++ b/desktop/src/features/messages/ui/MessageRow.tsx
@@ -14,9 +14,9 @@ import { BotIdenticon } from "./BotIdenticon";
import { MessageActionBar } from "./MessageActionBar";
import { MessageTimestamp } from "./MessageTimestamp";
-/** Returns true if the author name looks like a numbered bot copy (e.g. "Scout::01") */
-function isNumberedBot(author: string, role?: string): boolean {
- return Boolean(role) && author.includes("::");
+/** Returns true if this message is from a bot instance. */
+function isBotInstance(role?: string): boolean {
+ return role === "bot";
}
const DiffMessage = React.lazy(() => import("./DiffMessage"));
@@ -178,7 +178,7 @@ export const MessageRow = React.memo(
data-testid="message-row"
>
- {isNumberedBot(message.author, message.role) ? (
+ {isBotInstance(message.role) ? (
)}
- {message.role ? (
+ {message.personaDisplayName ? (
+
+ {message.personaDisplayName}
+
+ ) : message.role ? (
{message.role}
@@ -353,6 +357,7 @@ export const MessageRow = React.memo(
prev.message.reactions === next.message.reactions &&
prev.message.tags === next.message.tags &&
prev.message.role === next.message.role &&
+ prev.message.personaDisplayName === next.message.personaDisplayName &&
prev.highlighted === next.highlighted &&
prev.activeReplyTargetId === next.activeReplyTargetId &&
prev.profiles === next.profiles,
diff --git a/desktop/src/features/messages/ui/MessageTimeline.tsx b/desktop/src/features/messages/ui/MessageTimeline.tsx
index c99478674..469785503 100644
--- a/desktop/src/features/messages/ui/MessageTimeline.tsx
+++ b/desktop/src/features/messages/ui/MessageTimeline.tsx
@@ -23,6 +23,8 @@ type MessageTimelineProps = {
fetchOlder?: () => Promise;
hasOlderMessages?: boolean;
isFetchingOlder?: boolean;
+ /** Map from lowercase pubkey → persona display name for bot members. */
+ personaLookup?: Map;
profiles?: UserProfileLookup;
onDelete?: (message: TimelineMessage) => void;
onEdit?: (message: TimelineMessage) => void;
@@ -47,6 +49,7 @@ export const MessageTimeline = React.memo(function MessageTimeline({
fetchOlder,
hasOlderMessages = true,
isFetchingOlder = false,
+ personaLookup,
profiles,
onDelete,
onEdit,
@@ -158,6 +161,7 @@ export const MessageTimeline = React.memo(function MessageTimeline({
onEdit={onEdit}
onReply={onReply}
onToggleReaction={onToggleReaction}
+ personaLookup={personaLookup}
profiles={profiles}
/>
) : null}
diff --git a/desktop/src/features/messages/ui/SystemMessageRow.tsx b/desktop/src/features/messages/ui/SystemMessageRow.tsx
index e27fac42f..4018c1004 100644
--- a/desktop/src/features/messages/ui/SystemMessageRow.tsx
+++ b/desktop/src/features/messages/ui/SystemMessageRow.tsx
@@ -23,20 +23,31 @@ function resolveLabel(
return resolveUserLabel({ pubkey, currentPubkey, profiles });
}
+function resolvePersonaSuffix(
+ pubkey: string | undefined,
+ personaLookup: Map | undefined,
+): string {
+ if (!pubkey || !personaLookup) return "";
+ const personaName = personaLookup.get(pubkey.toLowerCase());
+ return personaName ? ` (${personaName})` : "";
+}
+
function describeSystemEvent(
payload: SystemMessagePayload,
currentPubkey: string | undefined,
profiles: UserProfileLookup | undefined,
+ personaLookup?: Map,
): string | null {
const actor = resolveLabel(payload.actor, currentPubkey, profiles);
switch (payload.type) {
case "member_joined": {
const target = resolveLabel(payload.target, currentPubkey, profiles);
+ const personaSuffix = resolvePersonaSuffix(payload.target, personaLookup);
if (payload.actor === payload.target) {
- return `${actor} joined the channel`;
+ return `${actor}${personaSuffix} joined the channel`;
}
- return `${actor} added ${target} to the channel`;
+ return `${actor} added ${target}${personaSuffix} to the channel`;
}
case "member_left": {
return `${actor} left the channel`;
@@ -62,12 +73,15 @@ export function SystemMessageRow({
time,
currentPubkey,
profiles,
+ personaLookup,
}: {
body: string;
createdAt: number;
time: string;
currentPubkey?: string;
profiles?: UserProfileLookup;
+ /** Map from lowercase pubkey → persona display name for bot members. */
+ personaLookup?: Map;
}) {
let payload: SystemMessagePayload;
try {
@@ -76,7 +90,12 @@ export function SystemMessageRow({
return null;
}
- const description = describeSystemEvent(payload, currentPubkey, profiles);
+ const description = describeSystemEvent(
+ payload,
+ currentPubkey,
+ profiles,
+ personaLookup,
+ );
if (!description) {
return null;
}
diff --git a/desktop/src/features/messages/ui/TimelineMessageList.tsx b/desktop/src/features/messages/ui/TimelineMessageList.tsx
index a802b110b..90ca5d0c4 100644
--- a/desktop/src/features/messages/ui/TimelineMessageList.tsx
+++ b/desktop/src/features/messages/ui/TimelineMessageList.tsx
@@ -24,6 +24,8 @@ type TimelineMessageListProps = {
emoji: string,
remove: boolean,
) => Promise;
+ /** Map from lowercase pubkey → persona display name for bot members. */
+ personaLookup?: Map;
profiles?: UserProfileLookup;
};
@@ -36,6 +38,7 @@ export const TimelineMessageList = React.memo(function TimelineMessageList({
onEdit,
onReply,
onToggleReaction,
+ personaLookup,
profiles,
}: TimelineMessageListProps) {
const elements: React.ReactNode[] = [];
@@ -60,6 +63,7 @@ export const TimelineMessageList = React.memo(function TimelineMessageList({
body={message.body}
createdAt={message.createdAt}
currentPubkey={currentPubkey}
+ personaLookup={personaLookup}
profiles={profiles}
time={message.time}
/>,
diff --git a/desktop/src/shared/api/tauriPersonas.ts b/desktop/src/shared/api/tauriPersonas.ts
index aaa06658a..d105ebaeb 100644
--- a/desktop/src/shared/api/tauriPersonas.ts
+++ b/desktop/src/shared/api/tauriPersonas.ts
@@ -12,6 +12,7 @@ type RawParsedPersonaPreview = {
avatar_data_url: string | null;
provider: string | null;
model: string | null;
+ name_pool?: string[];
source_file: string;
};
@@ -32,6 +33,7 @@ export type ParsedPersonaPreview = {
avatarDataUrl: string | null;
provider: string | null;
model: string | null;
+ namePool: string[];
sourceFile: string;
};
@@ -52,6 +54,7 @@ type RawPersona = {
system_prompt: string;
provider?: string | null;
model?: string | null;
+ name_pool?: string[];
is_builtin: boolean;
created_at: string;
updated_at: string;
@@ -65,6 +68,7 @@ function fromRawPersona(persona: RawPersona): AgentPersona {
systemPrompt: persona.system_prompt,
provider: persona.provider ?? null,
model: persona.model ?? null,
+ namePool: persona.name_pool ?? [],
isBuiltIn: persona.is_builtin,
createdAt: persona.created_at,
updatedAt: persona.updated_at,
@@ -86,6 +90,7 @@ export async function createPersona(
systemPrompt: input.systemPrompt,
provider: input.provider,
model: input.model,
+ namePool: input.namePool ?? [],
},
}),
);
@@ -103,6 +108,7 @@ export async function updatePersona(
systemPrompt: input.systemPrompt,
provider: input.provider,
model: input.model,
+ namePool: input.namePool ?? [],
},
}),
);
@@ -127,6 +133,7 @@ export async function parsePersonaFiles(
avatarDataUrl: p.avatar_data_url,
provider: p.provider,
model: p.model,
+ namePool: p.name_pool ?? [],
sourceFile: p.source_file,
})),
skipped: raw.skipped.map((s) => ({
diff --git a/desktop/src/shared/api/types.ts b/desktop/src/shared/api/types.ts
index cda23f68c..7b4cc2d82 100644
--- a/desktop/src/shared/api/types.ts
+++ b/desktop/src/shared/api/types.ts
@@ -404,6 +404,7 @@ export type AgentModelInfo = {
};
export type UpdateManagedAgentInput = {
pubkey: string;
+ name?: string;
model?: string | null;
systemPrompt?: string | null;
};
@@ -416,6 +417,7 @@ export type AgentPersona = {
provider: string | null;
/** Preferred model ID (e.g. "gpt-4o", "claude-sonnet-4-20250514"). */
model: string | null;
+ namePool: string[];
isBuiltIn: boolean;
createdAt: string;
updatedAt: string;
@@ -427,6 +429,7 @@ export type CreatePersonaInput = {
systemPrompt: string;
provider?: string;
model?: string;
+ namePool?: string[];
};
export type UpdatePersonaInput = {
@@ -436,7 +439,10 @@ export type UpdatePersonaInput = {
systemPrompt: string;
provider?: string;
model?: string;
+ namePool?: string[];
};
+
+// ── Team types ────────────────────────────────────────────────────────────────
export type AgentTeam = {
id: string;
name: string;