diff --git a/internal/http/summoner.go b/internal/http/summoner.go index e633900e1..2a50d80f0 100644 --- a/internal/http/summoner.go +++ b/internal/http/summoner.go @@ -190,8 +190,19 @@ func (s *AgentSummoner) finishSummon(ctx context.Context, agentID, tenantID uuid if frontmatter != "" { updates["frontmatter"] = frontmatter } + // Only derive display_name from IDENTITY.md if the user did not already set one. + // If the user DID set a name, patch IDENTITY.md so the agent knows its real name. if name := extractIdentityName(identityContent); name != "" { - updates["display_name"] = name + current, err := s.agents.GetByID(ctx, agentID) + if err != nil || current.DisplayName == "" { + updates["display_name"] = name + } else if current.DisplayName != name { + // User set a custom name — rewrite IDENTITY.md to use it. + patched := replaceIdentityName(identityContent, current.DisplayName) + if err := s.agents.SetAgentContextFile(ctx, agentID, bootstrap.IdentityFile, patched); err != nil { + slog.Warn("summoning: failed to patch IDENTITY.md name", "agent", agentID, "error", err) + } + } } if len(updates) > 0 { if err := s.agents.Update(ctx, agentID, updates); err != nil { diff --git a/internal/http/summoner_utils.go b/internal/http/summoner_utils.go index e686d9839..e64470f67 100644 --- a/internal/http/summoner_utils.go +++ b/internal/http/summoner_utils.go @@ -82,6 +82,24 @@ func trimMarkdownWrapper(value string) string { return value } +// replaceIdentityName rewrites the Name field in IDENTITY.md content to newName. +// Handles both "- **Name:** ..." and "Name: ..." formats. +func replaceIdentityName(content, newName string) string { + lines := strings.Split(content, "\n") + for i, line := range lines { + trimmed := strings.TrimSpace(line) + if strings.HasPrefix(trimmed, "- **Name:**") { + lines[i] = strings.Replace(line, trimmed, "- **Name:** "+newName, 1) + return strings.Join(lines, "\n") + } + if strings.HasPrefix(trimmed, "Name:") { + lines[i] = strings.Replace(line, trimmed, "Name: "+newName, 1) + return strings.Join(lines, "\n") + } + } + return content +} + // suffixString returns the last n runes of s. func suffixString(s string, n int) string { runes := []rune(s)