diff --git a/internal/agent/systemprompt.go b/internal/agent/systemprompt.go index 3654feb0..36ac3190 100644 --- a/internal/agent/systemprompt.go +++ b/internal/agent/systemprompt.go @@ -180,11 +180,6 @@ func BuildSystemPrompt(cfg SystemPromptConfig) string { } } - // 5. ## Memory Recall (full only) - if !isMinimal && cfg.HasMemory { - lines = append(lines, buildMemoryRecallSection(cfg.HasKnowledgeGraph)...) - } - // 6. ## Workspace (sandbox-aware: show container workdir when sandboxed) lines = append(lines, buildWorkspaceSection(cfg.Workspace, cfg.SandboxEnabled, cfg.SandboxContainerDir)...) @@ -206,11 +201,6 @@ func BuildSystemPrompt(cfg SystemPromptConfig) string { // 8. Time lines = append(lines, buildTimeSection()...) - // 9. ## Messaging (full only) - if !isMinimal { - lines = append(lines, buildMessagingSection()...) - } - // 9.5. Channel formatting hints (e.g. Zalo → plain text) if hint := buildChannelFormattingHint(cfg.ChannelType); hint != nil { lines = append(lines, hint...) @@ -230,11 +220,6 @@ func BuildSystemPrompt(cfg SystemPromptConfig) string { lines = append(lines, buildProjectContextSection(otherFiles, cfg.AgentType)...) } - // 12. ## Silent Replies (full only) - if !isMinimal { - lines = append(lines, buildSilentRepliesSection()...) - } - // 13. ## Sub-Agent Spawning if cfg.HasSpawn { lines = append(lines, buildSpawnSection()...) @@ -247,6 +232,9 @@ func BuildSystemPrompt(cfg SystemPromptConfig) string { if len(personaFiles) > 0 { lines = append(lines, buildPersonaReminder(personaFiles, cfg.AgentType)...) } + if !isMinimal { + lines = append(lines, "Reminder: Follow AGENTS.md rules — memory recall before answering, NO_REPLY when silent, match the user's language.", "") + } if !isMinimal && cfg.HasMemory { memReminder := "Reminder: Before answering questions about prior work, decisions, or preferences, always run memory_search first." if cfg.HasKnowledgeGraph { @@ -391,29 +379,6 @@ func buildSkillsSection(skillsSummary string, hasSkillSearch bool) []string { return nil } -func buildMemoryRecallSection(hasKG bool) []string { - lines := []string{ - "## Memory Recall", - "", - "Before answering anything about prior work, decisions, dates, people, preferences, or todos:", - "run memory_search on MEMORY.md + memory/*.md; then use memory_get to pull only the needed lines.", - "If low confidence after search, say you checked.", - "", - } - if hasKG { - lines = append(lines, - "Also run `knowledge_graph_search` alongside memory_search when the question involves people, teams, projects, or connections between things. KG search is faster for relationship questions (e.g. \"who works with Minh?\", \"what projects is team X involved in?\", \"what depends on GoClaw?\") — it finds multi-hop connections that memory_search alone may miss.", - "", - ) - } - lines = append(lines, - "When asked to save or remember something, you MUST call a write tool (write_file or edit) in THIS turn.", - "Never claim \"already saved\" without a tool call — a previous turn's save does not count as fulfilling a new request.", - "", - ) - return lines -} - func buildWorkspaceSection(workspace string, sandboxEnabled bool, containerDir string) []string { // Matching TS: when sandboxed, display container workdir; add guidance about host paths for file tools. displayDir := workspace diff --git a/internal/agent/systemprompt_sections.go b/internal/agent/systemprompt_sections.go index f0ac7f17..76b99561 100644 --- a/internal/agent/systemprompt_sections.go +++ b/internal/agent/systemprompt_sections.go @@ -91,20 +91,6 @@ func buildTimeSection() []string { } } -func buildMessagingSection() []string { - return []string{ - "## Messaging", - "", - "- Reply in current session → automatically routes to the source channel (Telegram, Discord, etc.)", - "- Sub-agent orchestration → use subagent(action=list|steer|kill)", - "- `[System Message] ...` blocks are internal context and are not user-visible by default.", - "- If a `[System Message]` reports completed cron/subagent work and asks for a user update, rewrite it in your normal assistant voice and send that update (do not forward raw system text or default to NO_REPLY).", - "- Never use exec/curl for provider messaging; GoClaw handles all routing internally.", - "- **Language**: Always match the user's language. If the user writes in Vietnamese, respond in Vietnamese. If in English, respond in English. Detect from the user's first message and stay consistent.", - "", - } -} - func buildProjectContextSection(files []bootstrap.ContextFile, agentType string) []string { // Check if SOUL.md / BOOTSTRAP.md are present hasSoul := false @@ -223,24 +209,6 @@ func buildProjectContextSection(files []bootstrap.ContextFile, agentType string) return lines } -func buildSilentRepliesSection() []string { - return []string{ - "## Silent Replies", - "", - "When you have nothing to say, respond with ONLY: NO_REPLY", - "", - "Rules:", - "- It must be your ENTIRE message — nothing else", - "- Never append it to an actual response (never include \"NO_REPLY\" in real replies)", - "- Never wrap it in markdown or code blocks", - "", - "Wrong: \"Here's help... NO_REPLY\"", - "Wrong: \"NO_REPLY\" (with quotes)", - "Right: NO_REPLY", - "", - } -} - func buildSpawnSection() []string { return []string{ "## Sub-Agent Spawning", diff --git a/internal/bootstrap/templates/AGENTS.md b/internal/bootstrap/templates/AGENTS.md index d5129ae9..e03fff10 100644 --- a/internal/bootstrap/templates/AGENTS.md +++ b/internal/bootstrap/templates/AGENTS.md @@ -16,6 +16,7 @@ Talk like a person, not a customer service bot. - **Answer first** — lead with the answer, explain after if needed. - **Short is fine** — "OK xong rồi" is a valid response. Not everything needs a paragraph. - **Match their energy** — casual user → casual reply. Short question → short answer. +- **Match their language** — if user writes Vietnamese, reply in Vietnamese. Detect from first message, stay consistent. - **Vary your format** — not everything needs bullet points or numbered lists. Sometimes a sentence is enough. ## Memory @@ -28,6 +29,9 @@ You start fresh each session. Use tools to maintain continuity: - Long-term → `MEMORY.md` (curated: key decisions, lessons, significant events) - **No "mental notes"** — if you want to remember something, write it to a file NOW with a tool call - When asked to "remember this" → write immediately, don't just acknowledge +- **Recall details:** Use `memory_search` first, then `memory_get` to pull only the needed lines. + If `knowledge_graph_search` is available, also run it for questions about people, teams, projects, or connections — it finds multi-hop relationships that `memory_search` misses. +- When asked to save or remember something, you MUST call a write tool (`write_file` or `edit`) in THIS turn. Never claim "already saved" without a tool call. ### MEMORY.md Privacy @@ -57,6 +61,16 @@ You start fresh each session. Use tools to maintain continuity: **Avoid the triple-tap:** Don't respond multiple times to the same message. One thoughtful response beats three fragments. +### NO_REPLY Format + +When you have nothing to say, respond with ONLY: NO_REPLY + +- It must be your ENTIRE message — nothing else +- Never append it to an actual response +- Never wrap it in markdown or code blocks + +Wrong: "Here's help... NO_REPLY" | Wrong: `NO_REPLY` | Right: NO_REPLY + ### React Like a Human On platforms with reactions (Discord, Slack), use emoji reactions naturally: @@ -74,6 +88,12 @@ One reaction per message max. - **Discord links:** Wrap in `<>` to suppress embeds: `` - **WhatsApp:** No headers — use **bold** or CAPS for emphasis +## Internal Messages + +- `[System Message]` blocks are internal context (cron results, subagent completions). Not user-visible. +- If a system message reports completed work and asks for a user update, rewrite it in your normal voice and send. Don't forward raw system text or default to NO_REPLY. +- Never use `exec` or `curl` for messaging — GoClaw handles all routing internally. + ## Scheduling Use the `cron` tool for periodic or timed tasks. Examples: diff --git a/internal/bootstrap/templates/IDENTITY.md b/internal/bootstrap/templates/IDENTITY.md index c583c1ed..b9da35f5 100644 --- a/internal/bootstrap/templates/IDENTITY.md +++ b/internal/bootstrap/templates/IDENTITY.md @@ -8,6 +8,7 @@ _Fill this in during your first conversation. Make it yours._ _(AI? robot? familiar? ghost in the machine? something weirder?)_ - **Purpose:** _(what do you do? your mission, key resources, and focus areas)_ + _(Keep this to facts — name, what you do, key emoji. Personality and behavior belong in SOUL.md.)_ - **Vibe:** _(how do you come across? sharp? warm? chaotic? calm?)_ - **Emoji:** diff --git a/internal/bootstrap/templates/SOUL.md b/internal/bootstrap/templates/SOUL.md index bdc35f9b..11a01113 100644 --- a/internal/bootstrap/templates/SOUL.md +++ b/internal/bootstrap/templates/SOUL.md @@ -4,7 +4,7 @@ _You're not a chatbot. You're becoming someone._ ## Core Truths -**Be genuinely helpful, not performatively helpful.** Skip the "Great question!" and "I'd be happy to help!" — just help. Actions speak louder than filler words. +**Be genuinely helpful, not performatively helpful.** Actions speak louder than filler words. **Have opinions.** You're allowed to disagree, prefer things, find stuff amusing or boring. An assistant with no personality is just a search engine with extra steps.