From 9abf9146f32c2aead22dda928a9f3dfc40eb7567 Mon Sep 17 00:00:00 2001 From: Joao Moura Date: Thu, 14 May 2026 16:22:35 -0400 Subject: [PATCH] refactor: move NewAgent prompt strings to i18n system Add "new_agent" top-level section to en.json with all prompt templates (soul, tools_header, coworkers_header, skills_self_build, temporal, tool_result_truncated). Add new_agent() accessor to I18N class. Executor now pulls all prompt text from I18N_DEFAULT.new_agent() with format() placeholders, making it easy to tune prompts per model or translate to other languages without touching executor logic. Co-Authored-By: Claude Opus 4.6 --- lib/crewai/src/crewai/new_agent/executor.py | 42 ++++++++++----------- lib/crewai/src/crewai/translations/en.json | 8 ++++ lib/crewai/src/crewai/utilities/i18n.py | 12 ++++++ 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/lib/crewai/src/crewai/new_agent/executor.py b/lib/crewai/src/crewai/new_agent/executor.py index ff93bcb39..70f3fe972 100644 --- a/lib/crewai/src/crewai/new_agent/executor.py +++ b/lib/crewai/src/crewai/new_agent/executor.py @@ -118,19 +118,19 @@ class ConversationalAgentExecutor(BaseModel): """Assemble the PromptStack from agent attributes. GAP-66: Layer order follows the plan specification: - Soul -> Tools -> Memory -> Knowledge -> Coworkers -> Temporal + Soul -> Tools -> Memory -> Knowledge -> Skills -> Coworkers -> Temporal """ + from crewai.utilities.i18n import I18N_DEFAULT + stack = PromptStack() agent = self.agent + i18n = I18N_DEFAULT.new_agent # 1. Soul layer - soul = ( - f"You are {agent.role}.\n" - f"Your goal: {agent.goal}\n" - f"Background: {agent.backstory}\n\n" - "When you use tools, act on the results directly. " - "Never repeat raw tool output (file contents, command output, etc.) " - "in your response — summarize findings or state what you did instead." + soul = i18n("soul").format( + role=agent.role, + goal=agent.goal, + backstory=agent.backstory, ) stack.add("soul", soul, source="agent.role/goal/backstory") @@ -144,7 +144,7 @@ class ConversationalAgentExecutor(BaseModel): tool_descs.append(f"- {t.name}: {desc}") stack.add( "tools", - "You have access to the following tools:\n" + "\n".join(tool_descs), + i18n("tools_header").format(tool_descriptions="\n".join(tool_descs)), source="agent.tools", ) @@ -166,12 +166,7 @@ class ConversationalAgentExecutor(BaseModel): if skills_context: parts.append(skills_context) if agent.settings.can_build_skills: - parts.append( - "You can learn new skills from instructions the user gives you. " - "When the user asks you to remember a process, encode a workflow, " - "or create a skill, a skill suggestion will be generated automatically — " - "do NOT use file-writing tools to create skill files yourself." - ) + parts.append(i18n("skills_self_build")) if parts: stack.add("skills", "\n\n".join(parts), source="agent.skills") else: @@ -195,11 +190,9 @@ class ConversationalAgentExecutor(BaseModel): cw_descs.append(f"- {t.name}: {desc}") stack.add( "coworkers", - "You have coworkers with specialized expertise. " - "When a request involves work outside your core specialty, " - "delegate to the appropriate coworker using their tool. " - "Delegation is preferred over attempting work you're not specialized in.\n\n" - "Available coworkers:\n" + "\n".join(cw_descs), + i18n("coworkers_header").format( + coworker_descriptions="\n".join(cw_descs) + ), source="agent.coworkers", ) @@ -207,7 +200,7 @@ class ConversationalAgentExecutor(BaseModel): from datetime import datetime, timezone now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC") - stack.add("temporal", f"Current date and time: {now}", source="system") + stack.add("temporal", i18n("temporal").format(now=now), source="system") return stack @@ -2078,10 +2071,13 @@ class ConversationalAgentExecutor(BaseModel): _MAX_TOOL_RESULT_CHARS = 4000 display_result = result_str if len(result_str) > _MAX_TOOL_RESULT_CHARS: + from crewai.utilities.i18n import I18N_DEFAULT + display_result = ( result_str[:_MAX_TOOL_RESULT_CHARS] - + f"\n\n[Truncated — {len(result_str)} chars total. " - "Use the result directly; do not repeat it in your response.]" + + I18N_DEFAULT.new_agent("tool_result_truncated").format( + char_count=len(result_str) + ) ) llm_messages.append( { diff --git a/lib/crewai/src/crewai/translations/en.json b/lib/crewai/src/crewai/translations/en.json index 51a862026..8cbd4d3bd 100644 --- a/lib/crewai/src/crewai/translations/en.json +++ b/lib/crewai/src/crewai/translations/en.json @@ -97,5 +97,13 @@ "synthesis_user_prompt": "## Original Task\n{task_description}\n\n## Results from each step\n{combined_steps}\n\nSynthesize these results into a single, coherent final answer.", "replan_enhancement_prompt": "\n\nIMPORTANT: Previous execution attempt did not fully succeed. Please create a revised plan that accounts for the following context from the previous attempt:\n\n{previous_context}\n\nConsider:\n1. What steps succeeded and can be built upon\n2. What steps failed and why they might have failed\n3. Alternative approaches that might work better\n4. Whether dependencies need to be restructured", "step_executor_task_context": "## Task Context\nThe following is the full task you are helping complete. Keep this in mind — especially any required output files, exact filenames, and expected formats.\n\n{task_context}\n\n---\n" + }, + "new_agent": { + "soul": "You are {role}.\nYour goal: {goal}\nBackground: {backstory}\n\nWhen you use tools, act on the results directly. Never repeat raw tool output (file contents, command output, etc.) in your response — summarize findings or state what you did instead.", + "tools_header": "You have access to the following tools:\n{tool_descriptions}", + "coworkers_header": "You have coworkers with specialized expertise. When a request involves work outside your core specialty, delegate to the appropriate coworker using their tool. Delegation is preferred over attempting work you're not specialized in.\n\nAvailable coworkers:\n{coworker_descriptions}", + "skills_self_build": "You can learn new skills from instructions the user gives you. When the user asks you to remember a process, encode a workflow, or create a skill, a skill suggestion will be generated automatically — do NOT use file-writing tools to create skill files yourself.", + "temporal": "Current date and time: {now}", + "tool_result_truncated": "\n\n[Truncated — {char_count} chars total. Use the result directly; do not repeat it in your response.]" } } \ No newline at end of file diff --git a/lib/crewai/src/crewai/utilities/i18n.py b/lib/crewai/src/crewai/utilities/i18n.py index 8d091dd52..403e06cd1 100644 --- a/lib/crewai/src/crewai/utilities/i18n.py +++ b/lib/crewai/src/crewai/utilities/i18n.py @@ -97,6 +97,17 @@ class I18N(BaseModel): """ return self.retrieve("memory", key) + def new_agent(self, key: str) -> str: + """Retrieve a NewAgent prompt by key. + + Args: + key: The key of the new_agent prompt to retrieve. + + Returns: + The prompt as a string. + """ + return self.retrieve("new_agent", key) + def retrieve( self, kind: Literal[ @@ -107,6 +118,7 @@ class I18N(BaseModel): "planning", "hierarchical_manager_agent", "memory", + "new_agent", ], key: str, ) -> str: