composeCoreText builds Block 1 of the agent system prompt (the stable core behavior block): persona/coder/default base plus the language and gateway directives. Split out of Run to keep its cyclomatic complexity in check.
(isCoder, hasActivePersona bool)
| 942 | // behavior block): persona/coder/default base plus the language and gateway |
| 943 | // directives. Split out of Run to keep its cyclomatic complexity in check. |
| 944 | func (a *AgentMode) composeCoreText(isCoder, hasActivePersona bool) string { |
| 945 | var coreText string |
| 946 | if hasActivePersona { |
| 947 | personaPrompt := a.cli.personaHandler.GetManager().GetSystemPrompt() |
| 948 | activeAgent := a.cli.personaHandler.GetManager().GetActiveAgent() |
| 949 | if isCoder { |
| 950 | coreText = personaPrompt + "\n\n" + CoderFormatInstructions |
| 951 | a.logger.Info("Usando persona ativa + modo coder", zap.String("agent", activeAgent.Name)) |
| 952 | } else { |
| 953 | coreText = personaPrompt + "\n\n" + AgentFormatInstructions |
| 954 | a.logger.Info("Usando persona ativa + modo agent", zap.String("agent", activeAgent.Name)) |
| 955 | } |
| 956 | } else if isCoder { |
| 957 | // The gateway answers through a chat app: use the dedicated |
| 958 | // conversational base (same tools, friendlier voice) instead of the |
| 959 | // terse coder prompt. Only when no persona owns the core text. |
| 960 | coreText = coderBaseSystemPrompt(a.gatewayPersona) |
| 961 | } else { |
| 962 | osName := runtime.GOOS |
| 963 | shellName := utils.GetUserShell() |
| 964 | currentDir, _ := os.Getwd() |
| 965 | coreText = i18n.T("agent.system_prompt.default.base", osName, shellName, currentDir) |
| 966 | } |
| 967 | // Language directive. The interactive CLI pins the daemon/user locale; the |
| 968 | // gateway must instead MIRROR each incoming message's language (every user |
| 969 | // writes in their own). Apply the dynamic directive on EVERY gateway path — |
| 970 | // including when an active persona owns the core text and the |
| 971 | // GatewaySystemPrompt (which also says this) isn't used — so the reply is |
| 972 | // never statically pinned to one language. |
| 973 | if a.gatewayPersona { |
| 974 | coreText += "\n\n" + GatewayLanguageDirective |
| 975 | // The daemon answers strangers' questions about the user unless told |
| 976 | // the injected Memory Index is real knowledge — applied on every |
| 977 | // gateway path, including persona-owned core text. |
| 978 | coreText += "\n\n" + GatewayMemoryDirective |
| 979 | } else { |
| 980 | coreText += "\n\n" + i18n.T("ai.response_language") |
| 981 | } |
| 982 | |
| 983 | // Gateway persona reinforcement: only needed when the core text is NOT |
| 984 | // already the dedicated GatewaySystemPrompt — i.e. when an active persona |
| 985 | // (or a non-coder profile) owns the core block. Steers those toward concise, |
| 986 | // plain-text chat replies. The GatewaySystemPrompt path already embeds this. |
| 987 | if a.gatewayPersona && (hasActivePersona || !isCoder) { |
| 988 | coreText += "\n\n" + i18n.T("gateway.persona_prompt") |
| 989 | } |
| 990 | // Output-token reduction: append the (static, cache-friendly) verbosity |
| 991 | // directive so the model drops preamble/restatement/ceremony. Empty when |
| 992 | // CHATCLI_OUTPUT_VERBOSITY=full. |
| 993 | coreText += verbosityDirectiveBlock() |
| 994 | return coreText |
| 995 | } |
| 996 | |
| 997 | // buildWorkspaceBlocks builds Block 3 of the agent system prompt: the |
| 998 | // workspace/retrieval context plus the separately-cached dynamic (wall-clock) |
no test coverage detected