feat(ai): Implement configurable base system prompt and expose in UI

This commit is contained in:
2026-05-02 14:49:47 -04:00
parent b654c7c733
commit 4f1bcea381
3 changed files with 41 additions and 14 deletions
+13 -5
View File
@@ -143,7 +143,8 @@ _SYSTEM_PROMPT: str = (
) )
_custom_system_prompt: str = "" _custom_system_prompt: str = ""
_global_tool_instructions: str = "" _base_system_prompt_override: str = ""
_use_default_base_system_prompt: bool = True
_project_context_marker: str = "" _project_context_marker: str = ""
def set_custom_system_prompt(prompt: str) -> None: def set_custom_system_prompt(prompt: str) -> None:
@@ -151,9 +152,13 @@ def set_custom_system_prompt(prompt: str) -> None:
global _custom_system_prompt global _custom_system_prompt
_custom_system_prompt = prompt _custom_system_prompt = prompt
def set_global_tool_instructions(instructions: str) -> None: def set_base_system_prompt(prompt: str) -> None:
global _global_tool_instructions global _base_system_prompt_override
_global_tool_instructions = instructions _base_system_prompt_override = prompt
def set_use_default_base_prompt(use_default: bool) -> None:
global _use_default_base_system_prompt
_use_default_base_system_prompt = use_default
def set_project_context_marker(marker: str) -> None: def set_project_context_marker(marker: str) -> None:
global _project_context_marker global _project_context_marker
@@ -165,7 +170,10 @@ def _get_context_marker() -> str:
def _get_combined_system_prompt(preset: Optional[ToolPreset] = None, bias: Optional[BiasProfile] = None) -> str: def _get_combined_system_prompt(preset: Optional[ToolPreset] = None, bias: Optional[BiasProfile] = None) -> str:
if preset is None: preset = _active_tool_preset if preset is None: preset = _active_tool_preset
if bias is None: bias = _active_bias_profile if bias is None: bias = _active_bias_profile
base = _global_tool_instructions if _global_tool_instructions.strip() else _SYSTEM_PROMPT if _use_default_base_system_prompt:
base = _SYSTEM_PROMPT
else:
base = _base_system_prompt_override
if _custom_system_prompt.strip(): if _custom_system_prompt.strip():
base = f"{base}\n\n[USER SYSTEM PROMPT]\n{_custom_system_prompt}" base = f"{base}\n\n[USER SYSTEM PROMPT]\n{_custom_system_prompt}"
if preset and bias: if preset and bias:
+14 -5
View File
@@ -233,7 +233,8 @@ class AppController:
self.ui_auto_add_history: bool = False self.ui_auto_add_history: bool = False
self.ui_active_tool_preset: str | None = None self.ui_active_tool_preset: str | None = None
self.ui_global_system_prompt: str = "" self.ui_global_system_prompt: str = ""
self.ui_global_tool_instructions: str = "" self.ui_base_system_prompt: str = ""
self.ui_use_default_base_prompt: bool = True
self.ui_project_context_marker: str = "" self.ui_project_context_marker: str = ""
self.ui_agent_tools: Dict[str, bool] = {} self.ui_agent_tools: Dict[str, bool] = {}
self.available_models: List[str] = [] self.available_models: List[str] = []
@@ -355,6 +356,8 @@ class AppController:
'manual_approve': 'ui_manual_approve', 'manual_approve': 'ui_manual_approve',
'global_system_prompt': 'ui_global_system_prompt', 'global_system_prompt': 'ui_global_system_prompt',
'project_system_prompt': 'ui_project_system_prompt', 'project_system_prompt': 'ui_project_system_prompt',
'base_system_prompt': 'ui_base_system_prompt',
'use_default_base_prompt': 'ui_use_default_base_prompt',
'global_preset_name': 'ui_global_preset_name', 'global_preset_name': 'ui_global_preset_name',
'project_preset_name': 'ui_project_preset_name', 'project_preset_name': 'ui_project_preset_name',
'ui_active_tool_preset': 'ui_active_tool_preset', 'ui_active_tool_preset': 'ui_active_tool_preset',
@@ -409,6 +412,8 @@ class AppController:
'bg_shader_enabled': 'bg_shader_enabled', 'bg_shader_enabled': 'bg_shader_enabled',
'global_system_prompt': 'ui_global_system_prompt', 'global_system_prompt': 'ui_global_system_prompt',
'project_system_prompt': 'ui_project_system_prompt', 'project_system_prompt': 'ui_project_system_prompt',
'base_system_prompt': 'ui_base_system_prompt',
'use_default_base_prompt': 'ui_use_default_base_prompt',
'global_preset_name': 'ui_global_preset_name', 'global_preset_name': 'ui_global_preset_name',
'project_preset_name': 'ui_project_preset_name', 'project_preset_name': 'ui_project_preset_name',
'ui_active_tool_preset': 'ui_active_tool_preset', 'ui_active_tool_preset': 'ui_active_tool_preset',
@@ -915,7 +920,8 @@ class AppController:
self.ui_word_wrap = proj_meta.get("word_wrap", True) self.ui_word_wrap = proj_meta.get("word_wrap", True)
self.ui_auto_add_history = disc_sec.get("auto_add", False) self.ui_auto_add_history = disc_sec.get("auto_add", False)
self.ui_global_system_prompt = self.config.get("ai", {}).get("system_prompt", "") self.ui_global_system_prompt = self.config.get("ai", {}).get("system_prompt", "")
self.ui_global_tool_instructions = self.config.get("ai", {}).get("tool_instructions", "") self.ui_base_system_prompt = self.config.get("ai", {}).get("base_system_prompt", "")
self.ui_use_default_base_prompt = self.config.get("ai", {}).get("use_default_base_prompt", True)
self.ui_project_context_marker = proj_meta.get("context_marker", "") self.ui_project_context_marker = proj_meta.get("context_marker", "")
self.preset_manager = presets.PresetManager(Path(self.active_project_path).parent if self.active_project_path else None) self.preset_manager = presets.PresetManager(Path(self.active_project_path).parent if self.active_project_path else None)
@@ -1408,7 +1414,8 @@ class AppController:
self.ai_response = "" self.ai_response = ""
csp = filter(bool, [self.ui_global_system_prompt.strip(), self.ui_project_system_prompt.strip()]) csp = filter(bool, [self.ui_global_system_prompt.strip(), self.ui_project_system_prompt.strip()])
ai_client.set_custom_system_prompt("\n\n".join(csp)) ai_client.set_custom_system_prompt("\n\n".join(csp))
ai_client.set_global_tool_instructions(self.ui_global_tool_instructions) ai_client.set_base_system_prompt(self.ui_base_system_prompt)
ai_client.set_use_default_base_prompt(self.ui_use_default_base_prompt)
ai_client.set_project_context_marker(self.ui_project_context_marker) ai_client.set_project_context_marker(self.ui_project_context_marker)
ai_client.set_model_params(self.temperature, self.max_tokens, self.history_trunc_limit, self.top_p) ai_client.set_model_params(self.temperature, self.max_tokens, self.history_trunc_limit, self.top_p)
ai_client.set_agent_tools(self.ui_agent_tools) # Force update adapter path right before send to bypass potential duplication issues ai_client.set_agent_tools(self.ui_agent_tools) # Force update adapter path right before send to bypass potential duplication issues
@@ -1828,7 +1835,8 @@ class AppController:
base_dir = self.active_project_root base_dir = self.active_project_root
csp = filter(bool, [self.ui_global_system_prompt.strip(), self.ui_project_system_prompt.strip()]) csp = filter(bool, [self.ui_global_system_prompt.strip(), self.ui_project_system_prompt.strip()])
ai_client.set_custom_system_prompt("\n\n".join(csp)) ai_client.set_custom_system_prompt("\n\n".join(csp))
ai_client.set_global_tool_instructions(self.ui_global_tool_instructions) ai_client.set_base_system_prompt(self.ui_base_system_prompt)
ai_client.set_use_default_base_prompt(self.ui_use_default_base_prompt)
ai_client.set_project_context_marker(self.ui_project_context_marker) ai_client.set_project_context_marker(self.ui_project_context_marker)
temp = req.temperature if req.temperature is not None else self.temperature temp = req.temperature if req.temperature is not None else self.temperature
top_p = req.top_p if req.top_p is not None else self.top_p top_p = req.top_p if req.top_p is not None else self.top_p
@@ -2496,7 +2504,8 @@ class AppController:
"active_preset": self.ui_global_preset_name, "active_preset": self.ui_global_preset_name,
} }
self.config["ai"]["system_prompt"] = self.ui_global_system_prompt self.config["ai"]["system_prompt"] = self.ui_global_system_prompt
self.config["ai"]["tool_instructions"] = self.ui_global_tool_instructions self.config["ai"]["base_system_prompt"] = self.ui_base_system_prompt
self.config["ai"]["use_default_base_prompt"] = self.ui_use_default_base_prompt
self.config["projects"] = {"paths": self.project_paths, "active": self.active_project_path} self.config["projects"] = {"paths": self.project_paths, "active": self.active_project_path}
from src import bg_shader from src import bg_shader
# Update gui section while preserving other keys like bg_shader_enabled # Update gui section while preserving other keys like bg_shader_enabled
+14 -4
View File
@@ -4275,10 +4275,20 @@ def hello():
imgui.set_item_tooltip("Open preset management modal") imgui.set_item_tooltip("Open preset management modal")
ch, self.ui_global_system_prompt = imgui.input_text_multiline("##gsp", self.ui_global_system_prompt, imgui.ImVec2(-1, 100)) ch, self.ui_global_system_prompt = imgui.input_text_multiline("##gsp", self.ui_global_system_prompt, imgui.ImVec2(-1, 100))
imgui.separator() imgui.separator()
imgui.text("Global Tool Instructions") imgui.text("Base System Prompt")
ch, self.ui_global_tool_instructions = imgui.input_text_multiline("##gti", getattr(self, "ui_global_tool_instructions", ""), imgui.ImVec2(-1, 100)) imgui.same_line()
if imgui.is_item_hovered(): _, self.ui_use_default_base_prompt = imgui.checkbox("Use Default Base System Prompt", self.ui_use_default_base_prompt)
imgui.set_tooltip("Instructions given to the agent about how to use its tools.") imgui.same_line()
if imgui.button("Reset to Default"):
self.ui_base_system_prompt = ai_client._SYSTEM_PROMPT
self.ui_use_default_base_prompt = False
if self.ui_use_default_base_prompt:
imgui.begin_disabled()
imgui.input_text_multiline("##base_prompt_def", ai_client._SYSTEM_PROMPT, imgui.ImVec2(-1, 100), imgui.InputTextFlags_.read_only)
imgui.end_disabled()
else:
ch, self.ui_base_system_prompt = imgui.input_text_multiline("##base_prompt", self.ui_base_system_prompt, imgui.ImVec2(-1, 150))
imgui.separator() imgui.separator()
imgui.text("Project System Prompt") imgui.text("Project System Prompt")
current_project = self.controller.ui_project_preset_name or "Select Preset..." current_project = self.controller.ui_project_preset_name or "Select Preset..."