From 6c63bddd41b4e6d82ff3197e81f5c66d878abae9 Mon Sep 17 00:00:00 2001 From: Dillon Jones Date: Sat, 7 Mar 2026 01:01:37 -0500 Subject: [PATCH 1/2] fix: add docstrings to semantic search tools to prevent null description pydantic-ai uses function docstrings as the tool description field. Without a docstring, it sends null, which LM Studio's OpenAI-compatible API rejects with: tools.N.type: invalid_string. Add docstrings to semantic_search_functions and get_function_source_by_id so both tools have a valid description string. --- codebase_rag/tools/semantic_search.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/codebase_rag/tools/semantic_search.py b/codebase_rag/tools/semantic_search.py index e7aa9c5b2..a59f13297 100644 --- a/codebase_rag/tools/semantic_search.py +++ b/codebase_rag/tools/semantic_search.py @@ -120,6 +120,7 @@ def get_function_source_code(node_id: int) -> str | None: def create_semantic_search_tool() -> Tool: async def semantic_search_functions(query: str, top_k: int = 5) -> str: + """Search for functions and classes in the codebase using semantic similarity.""" logger.info(ls.SEMANTIC_TOOL_SEARCH.format(query=query)) results = semantic_code_search(query, top_k) @@ -144,6 +145,7 @@ async def semantic_search_functions(query: str, top_k: int = 5) -> str: def create_get_function_source_tool() -> Tool: async def get_function_source_by_id(node_id: int) -> str: + """Retrieves the source code of a function or class by its graph node ID.""" logger.info(ls.SEMANTIC_TOOL_SOURCE.format(id=node_id)) source_code = get_function_source_code(node_id) From 6d41f4cfc96cbc9dea2613ff9ad468f0cbce248e Mon Sep 17 00:00:00 2001 From: Dillon Jones Date: Sat, 7 Mar 2026 11:27:49 -0500 Subject: [PATCH 2/2] fix: pass description constants to Tool() constructors Use the existing td.SEMANTIC_SEARCH and td.GET_FUNCTION_SOURCE constants as explicit description= arguments to the Tool() constructor, consistent with every other tool factory in the codebase. Remove docstrings added in the previous commit, which violated the project no-docstrings rule. This ensures LM Studio and other strict OpenAI-compatible backends receive a valid non-null description field in the tool schema. --- codebase_rag/tools/semantic_search.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/codebase_rag/tools/semantic_search.py b/codebase_rag/tools/semantic_search.py index a59f13297..8897a4e5c 100644 --- a/codebase_rag/tools/semantic_search.py +++ b/codebase_rag/tools/semantic_search.py @@ -120,7 +120,6 @@ def get_function_source_code(node_id: int) -> str | None: def create_semantic_search_tool() -> Tool: async def semantic_search_functions(query: str, top_k: int = 5) -> str: - """Search for functions and classes in the codebase using semantic similarity.""" logger.info(ls.SEMANTIC_TOOL_SEARCH.format(query=query)) results = semantic_code_search(query, top_k) @@ -140,12 +139,11 @@ async def semantic_search_functions(query: str, top_k: int = 5) -> str: return response - return Tool(semantic_search_functions, name=td.AgenticToolName.SEMANTIC_SEARCH) + return Tool(semantic_search_functions, name=td.AgenticToolName.SEMANTIC_SEARCH, description=td.SEMANTIC_SEARCH) def create_get_function_source_tool() -> Tool: async def get_function_source_by_id(node_id: int) -> str: - """Retrieves the source code of a function or class by its graph node ID.""" logger.info(ls.SEMANTIC_TOOL_SOURCE.format(id=node_id)) source_code = get_function_source_code(node_id) @@ -155,4 +153,4 @@ async def get_function_source_by_id(node_id: int) -> str: return cs.MSG_SEMANTIC_SOURCE_FORMAT.format(id=node_id, code=source_code) - return Tool(get_function_source_by_id, name=td.AgenticToolName.GET_FUNCTION_SOURCE) + return Tool(get_function_source_by_id, name=td.AgenticToolName.GET_FUNCTION_SOURCE, description=td.GET_FUNCTION_SOURCE)