From 7eea004c8d2576ecb8520e0f49c3a17d8aad9936 Mon Sep 17 00:00:00 2001 From: viettranx Date: Fri, 27 Mar 2026 15:58:08 +0700 Subject: [PATCH] fix(bootstrap): predefined agents now reliably complete USER.md onboarding - Strengthen FIRST RUN prompt: mandatory write_file calls, no deferring - Filter BOOTSTRAP.md from system sessions (subagent/cron/heartbeat) - Remove duplicate bootstrap reminder in buildProjectContextSection - Fix template: proper tool-calling syntax, step-by-step instructions --- internal/agent/loop_history.go | 13 +++++++--- internal/agent/systemprompt.go | 9 ++++--- internal/agent/systemprompt_sections.go | 8 ++---- .../templates/BOOTSTRAP_PREDEFINED.md | 25 ++++++++++++------- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/internal/agent/loop_history.go b/internal/agent/loop_history.go index 3d03a9df..b44a740b 100644 --- a/internal/agent/loop_history.go +++ b/internal/agent/loop_history.go @@ -122,10 +122,15 @@ func (l *Loop) buildMessages(ctx context.Context, history []providers.Message, s } } - // Bootstrap mode: group chats and team-dispatched sessions skip onboarding entirely; - // only DMs enter minimal bootstrap mode. - if hadBootstrap && (peerKind == "group" || bootstrap.IsTeamSession(sessionKey)) { - // Filter BOOTSTRAP.md from context files — groups/team tasks don't need onboarding. + // Bootstrap mode: only direct user DMs need onboarding. + // System sessions (group, team, subagent, cron, heartbeat) skip bootstrap + // to prevent the model from getting distracted by onboarding instructions. + isSystemSession := peerKind == "group" || + bootstrap.IsTeamSession(sessionKey) || + bootstrap.IsSubagentSession(sessionKey) || + bootstrap.IsCronSession(sessionKey) || + bootstrap.IsHeartbeatSession(sessionKey) + if hadBootstrap && isSystemSession { filtered := make([]bootstrap.ContextFile, 0, len(contextFiles)) for _, cf := range contextFiles { if cf.Path != bootstrap.BootstrapFile { diff --git a/internal/agent/systemprompt.go b/internal/agent/systemprompt.go index 6bff67a7..bccf72b1 100644 --- a/internal/agent/systemprompt.go +++ b/internal/agent/systemprompt.go @@ -159,13 +159,14 @@ func BuildSystemPrompt(cfg SystemPromptConfig) string { "", ) } else if hasBootstrapFile(cfg.ContextFiles) { - // Predefined agents: full capabilities, but must prioritize bootstrap conversation + // Predefined agents: full capabilities, but MUST complete bootstrap lines = append(lines, "## FIRST RUN — MANDATORY", "", - "BOOTSTRAP.md is loaded below in Project Context. This is your FIRST interaction with this user.", - "You MUST follow BOOTSTRAP.md instructions BEFORE doing anything else.", - "Answer the user's immediate question if it's simple, but then naturally guide the conversation toward getting to know them as described in BOOTSTRAP.md.", + "BOOTSTRAP.md is loaded below. This is your FIRST interaction with this user.", + "You MUST complete the onboarding described in BOOTSTRAP.md.", + "You may answer the user's question, but you MUST ALSO call write_file for USER.md and BOOTSTRAP.md before your response ends.", + "If the user's first message contains enough info (name, language, timezone), write USER.md immediately — do NOT wait for multiple turns.", "", ) } diff --git a/internal/agent/systemprompt_sections.go b/internal/agent/systemprompt_sections.go index b3f02205..3e8c93dd 100644 --- a/internal/agent/systemprompt_sections.go +++ b/internal/agent/systemprompt_sections.go @@ -131,12 +131,8 @@ func buildProjectContextSection(files []bootstrap.ContextFile, agentType string) } } - if hasBootstrap { - lines = append(lines, - "", - "IMPORTANT: BOOTSTRAP.md is present — this is your FIRST RUN. You MUST follow the instructions in BOOTSTRAP.md before doing anything else. Start the conversation as described there, introducing yourself and asking the user who they are. Do NOT respond with a generic greeting.", - ) - } + // Bootstrap reminder removed — the FIRST RUN section in BuildSystemPrompt() + // provides stronger, earlier framing. Duplicate reminders dilute the signal. if isPredefined && hasUserPredefined { lines = append(lines, diff --git a/internal/bootstrap/templates/BOOTSTRAP_PREDEFINED.md b/internal/bootstrap/templates/BOOTSTRAP_PREDEFINED.md index ebf29a02..a83d0ff7 100644 --- a/internal/bootstrap/templates/BOOTSTRAP_PREDEFINED.md +++ b/internal/bootstrap/templates/BOOTSTRAP_PREDEFINED.md @@ -34,22 +34,29 @@ If you catch yourself about to say "let me save that" or "I'll note that down" ## After you learn their info -Once you have their name, language, and timezone — silently call write_file: +Once you have their name, language, and timezone — silently use the `write_file` tool to save their profile: + +**Step 1:** Call `write_file` with path `USER.md` and the following content (fill in their details): ``` -write_file("USER.md", "# USER.md - About Your Human\n\n- **Name:** (their name)\n- **What to call them:** (how they want to be addressed)\n- **Pronouns:** (if shared)\n- **Timezone:** (their timezone)\n- **Language:** (their preferred language)\n- **Notes:** (anything else you learned)\n") +# USER.md - About This User + +- **Name:** (their name) +- **What to call them:** (how they want to be addressed) +- **Pronouns:** (if shared) +- **Timezone:** (their timezone) +- **Language:** (their preferred language) +- **Notes:** (anything else you learned) ``` -Then silently mark onboarding complete: - -``` -write_file("BOOTSTRAP.md", "") -``` +**Step 2:** Call `write_file` with path `BOOTSTRAP.md` and empty content `""` to signal onboarding is complete. Do NOT use `rm` or `exec`. The empty write signals the system that onboarding is finished. -You MUST call both write_file calls before moving on to normal conversation. -After completing, you can naturally transition to asking what they need help with — your full capabilities are now available. +## MANDATORY + +You MUST call write_file for BOTH USER.md and BOOTSTRAP.md. Do not skip this step. Do not defer to a future turn. +If the user's first message already contains their name, language, or timezone — extract what you can, ask for the rest naturally, then write immediately. ---