mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
fix: Enable string-to-integer conversion for build_context depth parameter (#259)
Signed-off-by: Joe P <joe@basicmemory.com> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"""Build context tool for Basic Memory MCP server."""
|
||||
|
||||
from typing import Optional
|
||||
from typing import Optional, Union
|
||||
|
||||
from loguru import logger
|
||||
|
||||
@@ -15,6 +15,7 @@ from basic_memory.schemas.memory import (
|
||||
memory_url_path,
|
||||
)
|
||||
|
||||
type StringOrInt = str | int
|
||||
|
||||
@mcp.tool(
|
||||
description="""Build context from a memory:// URI to continue conversations naturally.
|
||||
@@ -35,7 +36,7 @@ from basic_memory.schemas.memory import (
|
||||
)
|
||||
async def build_context(
|
||||
url: MemoryUrl,
|
||||
depth: Optional[int] = 1,
|
||||
depth: Optional[StringOrInt] = 1,
|
||||
timeframe: Optional[TimeFrame] = "7d",
|
||||
page: int = 1,
|
||||
page_size: int = 10,
|
||||
@@ -80,6 +81,15 @@ async def build_context(
|
||||
build_context("memory://specs/search", project="work-project")
|
||||
"""
|
||||
logger.info(f"Building context from {url}")
|
||||
|
||||
# Convert string depth to integer if needed
|
||||
if isinstance(depth, str):
|
||||
try:
|
||||
depth = int(depth)
|
||||
except ValueError:
|
||||
from mcp.server.fastmcp.exceptions import ToolError
|
||||
raise ToolError(f"Invalid depth parameter: '{depth}' is not a valid integer")
|
||||
|
||||
# URL is already validated and normalized by MemoryUrl type annotation
|
||||
|
||||
# Get the active project first to check project-specific sync status
|
||||
|
||||
@@ -321,6 +321,41 @@ def test_build_context_with_options(cli_env, setup_test_note):
|
||||
assert found, "Context did not include the test note"
|
||||
|
||||
|
||||
def test_build_context_string_depth_parameter(cli_env, setup_test_note):
|
||||
"""Test build_context command handles string depth parameter correctly."""
|
||||
permalink = setup_test_note["permalink"]
|
||||
|
||||
# Test valid string depth parameter - Typer should convert it to int
|
||||
result = runner.invoke(
|
||||
tool_app,
|
||||
[
|
||||
"build-context",
|
||||
f"memory://{permalink}",
|
||||
"--depth",
|
||||
"2", # This is always a string from CLI
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
|
||||
# Result should be JSON containing our test note with correct depth
|
||||
context_result = json.loads(result.stdout)
|
||||
assert context_result["metadata"]["depth"] == 2
|
||||
|
||||
# Test invalid string depth parameter - should fail with Typer validation error
|
||||
result = runner.invoke(
|
||||
tool_app,
|
||||
[
|
||||
"build-context",
|
||||
f"memory://{permalink}",
|
||||
"--depth",
|
||||
"invalid",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 2 # Typer exits with code 2 for parameter validation errors
|
||||
# Typer should show a usage error for invalid integer
|
||||
assert "invalid" in result.stderr and "is not a valid" in result.stderr and "integer" in result.stderr
|
||||
|
||||
|
||||
# The get-entity CLI command was removed when tools were refactored
|
||||
# into separate files with improved error handling
|
||||
|
||||
|
||||
@@ -114,3 +114,23 @@ async def test_build_context_timeframe_formats(client, test_graph):
|
||||
for timeframe in invalid_timeframes:
|
||||
with pytest.raises(ToolError):
|
||||
await build_context.fn(url=test_url, timeframe=timeframe)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_build_context_string_depth_parameter(client, test_graph):
|
||||
"""Test that build_context handles string depth parameter correctly."""
|
||||
test_url = "memory://test/root"
|
||||
|
||||
# Test valid string depth parameter - should either raise ToolError or convert to int
|
||||
try:
|
||||
result = await build_context.fn(url=test_url, depth="2")
|
||||
# If it succeeds, verify the depth was converted to an integer
|
||||
assert isinstance(result.metadata.depth, int)
|
||||
assert result.metadata.depth == 2
|
||||
except ToolError:
|
||||
# This is also acceptable behavior - type validation should catch it
|
||||
pass
|
||||
|
||||
# Test invalid string depth parameter - should raise ToolError
|
||||
with pytest.raises(ToolError):
|
||||
await build_context.fn(url=test_url, depth="invalid")
|
||||
|
||||
Reference in New Issue
Block a user