diff --git a/cheddahbot/agent.py b/cheddahbot/agent.py index 30a6f6e..73aae28 100644 --- a/cheddahbot/agent.py +++ b/cheddahbot/agent.py @@ -9,7 +9,7 @@ import uuid from collections.abc import Generator from pathlib import Path -from .config import Config +from .config import AgentConfig, Config from .db import Database from .llm import LLMAdapter from .router import build_system_prompt, format_messages_for_llm @@ -63,15 +63,26 @@ def _build_file_content_parts(files: list[str]) -> list[dict]: class Agent: - def __init__(self, config: Config, db: Database, llm: LLMAdapter): + def __init__( + self, + config: Config, + db: Database, + llm: LLMAdapter, + agent_config: AgentConfig | None = None, + ): self.config = config self.db = db self.llm = llm + self.agent_config = agent_config or AgentConfig() self.conv_id: str | None = None self._memory = None # set by app after memory system init self._tools = None # set by app after tool system init self._skills_registry = None # set by app after skills init + @property + def name(self) -> str: + return self.agent_config.name + def set_memory(self, memory): self._memory = memory @@ -104,18 +115,29 @@ class Agent: if self._memory: memory_context = self._memory.get_context(user_input) + # Apply tool whitelist from agent config + tool_filter = self.agent_config.tools + tools_schema = [] tools_description = "" if self._tools: - tools_schema = self._tools.get_tools_schema() - tools_description = self._tools.get_tools_description() + tools_schema = self._tools.get_tools_schema(filter_names=tool_filter) + tools_description = self._tools.get_tools_description(filter_names=tool_filter) skills_context = "" if self._skills_registry: - skills_context = self._skills_registry.get_prompt_section() + skills_context = self._skills_registry.get_prompt_section(self.name) + + # Use agent-specific personality file if configured + identity_dir = self.config.identity_dir + personality_file = self.agent_config.personality_file + if personality_file: + pf = Path(personality_file) + if pf.exists(): + identity_dir = pf.parent system_prompt = build_system_prompt( - identity_dir=self.config.identity_dir, + identity_dir=identity_dir, memory_context=memory_context, tools_description=tools_description, skills_context=skills_context, diff --git a/cheddahbot/tools/__init__.py b/cheddahbot/tools/__init__.py index 565c5a4..ae16429 100644 --- a/cheddahbot/tools/__init__.py +++ b/cheddahbot/tools/__init__.py @@ -118,15 +118,20 @@ class ToolRegistry: except Exception as e: log.warning("Failed to load tool module %s: %s", module_name, e) - def get_tools_schema(self) -> list[dict]: - """Get all tools in OpenAI function-calling format.""" - return [t.to_openai_schema() for t in _TOOLS.values()] + def get_tools_schema(self, filter_names: list[str] | None = None) -> list[dict]: + """Get tools in OpenAI function-calling format, optionally filtered.""" + tools = _TOOLS.values() + if filter_names is not None: + tools = [t for t in tools if t.name in filter_names] + return [t.to_openai_schema() for t in tools] - def get_tools_description(self) -> str: - """Human-readable tool list for system prompt.""" + def get_tools_description(self, filter_names: list[str] | None = None) -> str: + """Human-readable tool list for system prompt, optionally filtered.""" lines = [] by_cat: dict[str, list[ToolDef]] = {} for t in _TOOLS.values(): + if filter_names is not None and t.name not in filter_names: + continue by_cat.setdefault(t.category, []).append(t) for cat, tools in sorted(by_cat.items()):