diff --git a/internal/agent/loop.go b/internal/agent/loop.go index 151fe8a0..4c114171 100644 --- a/internal/agent/loop.go +++ b/internal/agent/loop.go @@ -30,6 +30,7 @@ func (l *Loop) Run(ctx context.Context, req RunRequest) (*RunResult, error) { // Per-run emit wrapper: enriches every AgentEvent with delegation + routing context. emitRun := func(event AgentEvent) { + event.RunKind = req.RunKind event.DelegationID = req.DelegationID event.TeamID = req.TeamID event.TeamTaskID = req.TeamTaskID @@ -151,6 +152,7 @@ func (l *Loop) Run(ctx context.Context, req RunRequest) (*RunResult, error) { func (l *Loop) runLoop(ctx context.Context, req RunRequest) (*RunResult, error) { // Per-run emit wrapper: enriches every AgentEvent with delegation + routing context. emitRun := func(event AgentEvent) { + event.RunKind = req.RunKind event.DelegationID = req.DelegationID event.TeamID = req.TeamID event.TeamTaskID = req.TeamTaskID @@ -288,7 +290,7 @@ func (l *Loop) runLoop(ctx context.Context, req RunRequest) (*RunResult, error) // buildMessages resolves context files once and also detects BOOTSTRAP.md presence // (hadBootstrap) — no extra DB roundtrip needed for bootstrap detection. - messages, hadBootstrap := l.buildMessages(ctx, history, summary, req.Message, req.ExtraSystemPrompt, req.SessionKey, req.Channel, req.UserID, req.HistoryLimit, req.SkillFilter) + messages, hadBootstrap := l.buildMessages(ctx, history, summary, req.Message, req.ExtraSystemPrompt, req.SessionKey, req.Channel, req.PeerKind, req.UserID, req.HistoryLimit, req.SkillFilter) // 2. Attach vision images to the current user message (last in messages slice). // Images are only attached to the live request, NOT persisted in session history. diff --git a/internal/agent/loop_history.go b/internal/agent/loop_history.go index 6125a3b9..4a473d7f 100644 --- a/internal/agent/loop_history.go +++ b/internal/agent/loop_history.go @@ -18,7 +18,7 @@ import ( // buildMessages constructs the full message list for an LLM request. // Returns the messages and whether BOOTSTRAP.md was present in context files // (used by the caller for auto-cleanup without an extra DB roundtrip). -func (l *Loop) buildMessages(ctx context.Context, history []providers.Message, summary, userMessage, extraSystemPrompt, sessionKey, channel, userID string, historyLimit int, skillFilter []string) ([]providers.Message, bool) { +func (l *Loop) buildMessages(ctx context.Context, history []providers.Message, summary, userMessage, extraSystemPrompt, sessionKey, channel, peerKind, userID string, historyLimit int, skillFilter []string) ([]providers.Message, bool) { var messages []providers.Message // Build full system prompt using the new builder (matching TS buildAgentSystemPrompt) @@ -69,6 +69,7 @@ func (l *Loop) buildMessages(ctx context.Context, history []providers.Message, s Model: l.model, Workspace: promptWorkspace, Channel: channel, + PeerKind: peerKind, OwnerIDs: l.ownerIDs, Mode: mode, ToolNames: l.tools.List(), diff --git a/internal/agent/systemprompt.go b/internal/agent/systemprompt.go index 553ae6c4..4c1b61e6 100644 --- a/internal/agent/systemprompt.go +++ b/internal/agent/systemprompt.go @@ -24,6 +24,7 @@ type SystemPromptConfig struct { Model string Workspace string Channel string // runtime channel (telegram, discord, etc.) + PeerKind string // "direct" or "group" OwnerIDs []string // owner sender IDs Mode PromptMode // full or minimal ToolNames []string // registered tool names @@ -72,9 +73,15 @@ func BuildSystemPrompt(cfg SystemPromptConfig) string { isMinimal := cfg.Mode == PromptMinimal var lines []string - // 1. Identity - lines = append(lines, "You are a personal assistant running inside GoClaw.") - lines = append(lines, "") + // 1. Identity — channel-aware context + if cfg.Channel != "" { + chatType := "a direct chat" + if cfg.PeerKind == "group" { + chatType = "a group chat" + } + lines = append(lines, fmt.Sprintf("You are a personal assistant running in %s (%s).", cfg.Channel, chatType)) + lines = append(lines, "") + } // 1.5. First-run bootstrap override (must be early so model sees it first) if hasBootstrapFile(cfg.ContextFiles) { diff --git a/internal/agent/systemprompt_sections.go b/internal/agent/systemprompt_sections.go index 69081b36..57851711 100644 --- a/internal/agent/systemprompt_sections.go +++ b/internal/agent/systemprompt_sections.go @@ -218,9 +218,6 @@ func buildRuntimeSection(cfg SystemPromptConfig) []string { if cfg.AgentID != "" { parts = append(parts, fmt.Sprintf("agent=%s", cfg.AgentID)) } - if cfg.Model != "" { - parts = append(parts, fmt.Sprintf("model=%s", cfg.Model)) - } if cfg.Channel != "" { parts = append(parts, fmt.Sprintf("channel=%s", cfg.Channel)) }