build_system_prompt(tool_names: Optional[List[str]] = None, *, tools: Optional[List['BaseTool']] = None) -> str
Build the complete system prompt for the given tools.
Args:
tool_names: Tool names to include. If None, uses all
tools from :data:TOOL_DESCRIPTIONS. This path is kept for
backward compatibility with training pipelines.
tools: Optional list of BaseTool instances. When provided,
rich descriptions are auto-generated from ToolSpec,
replacing the hardcoded :data:TOOL_DESCRIPTIONS lookup.
Unknown / MCP tools get full descriptions instead of
"Tool: {name}".
Returns:
Complete system prompt string.
Source code in src/openjarvis/learning/orchestrator/prompt_registry.py
| def build_system_prompt(
tool_names: Optional[List[str]] = None,
*,
tools: Optional[List["BaseTool"]] = None,
) -> str:
"""Build the complete system prompt for the given tools.
Args:
tool_names: Tool names to include. If ``None``, uses all
tools from :data:`TOOL_DESCRIPTIONS`. This path is kept for
backward compatibility with training pipelines.
tools: Optional list of ``BaseTool`` instances. When provided,
rich descriptions are auto-generated from ``ToolSpec``,
replacing the hardcoded :data:`TOOL_DESCRIPTIONS` lookup.
Unknown / MCP tools get full descriptions instead of
``"Tool: {name}"``.
Returns:
Complete system prompt string.
"""
# When BaseTool instances are provided, generate descriptions from spec
if tools is not None:
from openjarvis.tools._stubs import build_tool_descriptions
desc_text = build_tool_descriptions(tools, include_cost=True)
# Auto-generate tool selection guide by grouping tools by category
by_cat: Dict[str, List[str]] = {}
for t in tools:
cat = t.spec.category or "llm"
by_cat.setdefault(cat, []).append(t.spec.name)
guide: list[str] = ["Choose tools based on task type:\n"]
for cat, names in by_cat.items():
label = _CAT_LABELS.get(cat, cat.upper())
guide.append(f"{label}:")
for n in names:
guide.append(f"- {n}")
guide.append("")
return SYSTEM_PROMPT_TEMPLATE.format(
tools_description=desc_text,
tool_selection_guide="\n".join(guide),
)
# Backward-compat: tool_names-only path (used by training pipelines)
if tool_names is None:
tool_names = list(TOOL_DESCRIPTIONS)
# Tool descriptions
desc_lines: list[str] = []
for name in tool_names:
if name in TOOL_DESCRIPTIONS:
desc = TOOL_DESCRIPTIONS[name]["description"]
else:
desc = f"Tool: {name}"
desc_lines.append(f"- {name}: {desc}")
# Group tools by category
by_cat_names: Dict[str, List[str]] = {}
for name in tool_names:
cat = (
TOOL_DESCRIPTIONS[name]["category"]
if name in TOOL_DESCRIPTIONS
else "llm"
)
by_cat_names.setdefault(cat, []).append(name)
guide = [
"Choose tools based on task type:\n",
]
# Math
math_lines: list[str] = []
if "calculator" in tool_names:
math_lines.append(
"- Simple arithmetic/algebra -> calculator (instant, accurate)"
)
if "code_interpreter" in tool_names:
math_lines.append(
"- Numerical algorithms -> code_interpreter (programmable)"
)
if math_lines:
guide.append("MATH PROBLEMS:")
guide.extend(math_lines)
guide.append("")
# Coding
code_lines: list[str] = []
if "code_interpreter" in tool_names:
code_lines.append(
"- Algorithm implementation/execution -> code_interpreter"
)
if code_lines:
guide.append("CODING TASKS:")
guide.extend(code_lines)
guide.append("")
# Reasoning
reasoning_lines: list[str] = []
if "think" in tool_names:
reasoning_lines.append(
"- Step-by-step analysis -> think (organize thoughts first)"
)
llm_tools = by_cat_names.get("llm", [])
if llm_tools:
reasoning_lines.append(
f"- Complex reasoning -> {', '.join(llm_tools)}"
)
if reasoning_lines:
guide.append("REASONING/LOGIC:")
guide.extend(reasoning_lines)
guide.append("")
# General Q&A
general_lines: list[str] = []
if "web_search" in tool_names:
general_lines.append("- Current events/recent info -> web_search")
memory_tools = by_cat_names.get("memory", [])
if memory_tools:
general_lines.append(
f"- Stored knowledge -> {', '.join(memory_tools)}"
)
if general_lines:
guide.append("GENERAL Q&A / FACTUAL:")
guide.extend(general_lines)
guide.append("")
return SYSTEM_PROMPT_TEMPLATE.format(
tools_description="\n".join(desc_lines),
tool_selection_guide="\n".join(guide),
)
|