From eeadde4cffe29112ae6c63548e47dfaf14d649c1 Mon Sep 17 00:00:00 2001 From: sciapanCA Date: Thu, 10 Sep 2026 23:42:31 +0200 Subject: [PATCH 1/2] Add call sites --- src/tests/test_tool_metadata.py | 19 +++++++++++++++++++ src/tools/artifact_relationships.py | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/tests/test_tool_metadata.py b/src/tests/test_tool_metadata.py index 3be8832..1902b7c 100644 --- a/src/tests/test_tool_metadata.py +++ b/src/tests/test_tool_metadata.py @@ -79,3 +79,22 @@ def test_server_advertises_codealive_version_and_compact_instructions(): assert len(mcp.instructions.split()) <= 150 assert "DISCOVER → SEARCH → READ → EXPAND" in mcp.instructions assert "chat only when the user explicitly requests" in mcp.instructions.lower() + +@pytest.mark.asyncio +async def test_relationships_description_states_the_call_site_contract(): + """The three call-site rules are only enforceable through the tool description: the backend can + omit positions for a repository indexed before call sites shipped, and a model that reads a + missing position as "no call" draws the opposite conclusion from the truth.""" + # Arrange / Act + async with Client(mcp) as client: + tools = await client.list_tools() + + # Assert + description = {tool.name: tool for tool in tools}["get_artifact_relationships"].description + assert description is not None + assert "call_sites" in description + assert "call_site_count" in description + # Missing position means "not indexed yet", never "no call". + assert "never" in description.lower() + # No parameter enables them, so the model must not go hunting for one. + assert "no parameter" in description.lower() diff --git a/src/tools/artifact_relationships.py b/src/tools/artifact_relationships.py index 545a2db..c8cc565 100644 --- a/src/tools/artifact_relationships.py +++ b/src/tools/artifact_relationships.py @@ -33,6 +33,17 @@ async def get_artifact_relationships( This is a graph expansion tool, not a search tool. Use identifiers returned by semantic_search, grep_search, fetch_artifacts, read_file, or prior relationship results. + + Call relationships also carry `call_sites` — the file and 1-based line where + each call is actually written — plus `call_site_count` for how many exist in + total. Read those exact lines instead of fetching the whole caller. There is + no parameter for this: positions come back whenever they are known, so do not + look for a flag. A call item with no `call_sites` means the position is not + indexed yet (the repository was indexed before call sites shipped, or that one + edge could not be located); it never means the call does not happen — the item + being listed at all is what says the call exists. A `confidence` on a site + appears only when the position is approximate; its absence means exact. For + incoming calls the file shown is the caller's file, not this artifact's. """ tool_name = "get_artifact_relationships" require_text(identifier, tool_name, "identifier") From a57a89c687c57fcc6334d402fb417e6b976a1d77 Mon Sep 17 00:00:00 2001 From: sciapanCA Date: Sat, 12 Sep 2026 19:37:31 +0200 Subject: [PATCH 2/2] Replace CallSite file+line with position --- src/tools/artifact_relationships.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tools/artifact_relationships.py b/src/tools/artifact_relationships.py index c8cc565..8327c76 100644 --- a/src/tools/artifact_relationships.py +++ b/src/tools/artifact_relationships.py @@ -34,11 +34,11 @@ async def get_artifact_relationships( by semantic_search, grep_search, fetch_artifacts, read_file, or prior relationship results. - Call relationships also carry `call_sites` — the file and 1-based line where - each call is actually written — plus `call_site_count` for how many exist in - total. Read those exact lines instead of fetching the whole caller. There is - no parameter for this: positions come back whenever they are known, so do not - look for a flag. A call item with no `call_sites` means the position is not + Call relationships also carry `call_sites` — each one a `position` written as + `path:line`, where the call is actually written — plus `call_site_count` for + how many exist in total. Read those exact lines instead of fetching the whole + caller. There is no parameter for this: positions come back whenever they are + known, so do not look for a flag. A call item with no `call_sites` means the position is not indexed yet (the repository was indexed before call sites shipped, or that one edge could not be located); it never means the call does not happen — the item being listed at all is what says the call exists. A `confidence` on a site