mirror of
https://github.com/NCBM/plyngent.git
synced 2026-11-07 23:47:54 +08:00
config: add [agent] mcp_instructions and variadic system compose
This commit is contained in:
@@ -70,19 +70,15 @@ call `todo_clear` (or pop finished TOP groups) so no hygiene noise is left behin
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def compose_agent_system_content(
|
def compose_agent_system_content(*parts: str) -> str | None:
|
||||||
system_prompt: str,
|
"""Join persona + tool playbook + extra blocks into one system body.
|
||||||
tool_directives: str,
|
|
||||||
) -> str | None:
|
|
||||||
"""Join persona + tool playbook into one system body, or ``None`` if both empty.
|
|
||||||
|
|
||||||
Non-empty parts are stripped and joined with a blank line. Either field may
|
Returns ``None`` when every part is empty. Non-empty parts are stripped and
|
||||||
be ``""`` to disable that part while keeping the other.
|
joined with a blank line. Any part may be ``""`` to disable that block
|
||||||
|
(e.g. ``system_prompt = ""`` keeps the tool playbook).
|
||||||
"""
|
"""
|
||||||
parts = [part.strip() for part in (system_prompt, tool_directives) if part and part.strip()]
|
joined = "\n\n".join(part.strip() for part in parts if part and part.strip())
|
||||||
if not parts:
|
return joined or None
|
||||||
return None
|
|
||||||
return "\n\n".join(parts)
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseConfig(Struct, omit_defaults=True):
|
class DatabaseConfig(Struct, omit_defaults=True):
|
||||||
@@ -106,6 +102,9 @@ class AgentConfig(Struct, omit_defaults=True):
|
|||||||
system_prompt: str = DEFAULT_SYSTEM_PROMPT
|
system_prompt: str = DEFAULT_SYSTEM_PROMPT
|
||||||
# Tool how-to (omit → DEFAULT_TOOL_DIRECTIVES; "" disables playbook only).
|
# Tool how-to (omit → DEFAULT_TOOL_DIRECTIVES; "" disables playbook only).
|
||||||
tool_directives: str = DEFAULT_TOOL_DIRECTIVES
|
tool_directives: str = DEFAULT_TOOL_DIRECTIVES
|
||||||
|
# Fold connected MCP servers' initialize ``instructions`` (usage guidance)
|
||||||
|
# into the agent system prompt when tools are on. false = ignore server text.
|
||||||
|
mcp_instructions: bool = True
|
||||||
max_tool_result_chars: int = 32_000
|
max_tool_result_chars: int = 32_000
|
||||||
parallel_tools: bool = True
|
parallel_tools: bool = True
|
||||||
confirm_destructive: bool = True
|
confirm_destructive: bool = True
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ def test_agent_section_defaults(tmp_path: Path) -> None:
|
|||||||
store = load(path)
|
store = load(path)
|
||||||
assert store.agent_config.system_prompt == DEFAULT_SYSTEM_PROMPT
|
assert store.agent_config.system_prompt == DEFAULT_SYSTEM_PROMPT
|
||||||
assert store.agent_config.tool_directives == DEFAULT_TOOL_DIRECTIVES
|
assert store.agent_config.tool_directives == DEFAULT_TOOL_DIRECTIVES
|
||||||
|
assert store.agent_config.mcp_instructions is True
|
||||||
assert "professional coding agent" in store.agent_config.system_prompt
|
assert "professional coding agent" in store.agent_config.system_prompt
|
||||||
assert "### Workspace" in store.agent_config.tool_directives
|
assert "### Workspace" in store.agent_config.tool_directives
|
||||||
assert store.agent_config.max_tool_result_chars == 32_000
|
assert store.agent_config.max_tool_result_chars == 32_000
|
||||||
@@ -64,6 +65,9 @@ def test_compose_empty_combinations() -> None:
|
|||||||
assert compose_agent_system_content("Only persona", "") == "Only persona"
|
assert compose_agent_system_content("Only persona", "") == "Only persona"
|
||||||
assert compose_agent_system_content("", "Only tools") == "Only tools"
|
assert compose_agent_system_content("", "Only tools") == "Only tools"
|
||||||
assert compose_agent_system_content("Persona", "Tools") == "Persona\n\nTools"
|
assert compose_agent_system_content("Persona", "Tools") == "Persona\n\nTools"
|
||||||
|
assert compose_agent_system_content("", "", "") is None
|
||||||
|
assert compose_agent_system_content("Persona", "Tools", "Extra") == "Persona\n\nTools\n\nExtra"
|
||||||
|
assert compose_agent_system_content("Persona", "", "Extra") == "Persona\n\nExtra"
|
||||||
|
|
||||||
|
|
||||||
def test_agent_section_parse(tmp_path: Path) -> None:
|
def test_agent_section_parse(tmp_path: Path) -> None:
|
||||||
@@ -158,6 +162,19 @@ tool_directives = ""
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_agent_mcp_instructions_flag(tmp_path: Path) -> None:
|
||||||
|
path = tmp_path / "c.toml"
|
||||||
|
_ = path.write_text(
|
||||||
|
"""
|
||||||
|
[agent]
|
||||||
|
mcp_instructions = false
|
||||||
|
""",
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
store = load(path)
|
||||||
|
assert store.agent_config.mcp_instructions is False
|
||||||
|
|
||||||
|
|
||||||
def test_plugins_section_parse(tmp_path: Path) -> None:
|
def test_plugins_section_parse(tmp_path: Path) -> None:
|
||||||
path = tmp_path / "c.toml"
|
path = tmp_path / "c.toml"
|
||||||
_ = path.write_text(
|
_ = path.write_text(
|
||||||
|
|||||||
Reference in New Issue
Block a user