The context sets, the packaged knowledge bases and the example bundles are replaced by one fictitious example set about IT operations in an invented organisation: three context sets (serverrom-2027, driftsavtale-2027 and the two-base drift-og-avtale-2027), two synthetic knowledge bases under src/portfolio_optimiser/data/kunnskapsbaser and two example bundles under src/portfolio_optimiser/data/bundles. Numbers, codes and structural values in tests and fixtures are kept; names, ids and wording change. Dated measurement documents that only recorded runs on the replaced material are deleted. Gate figures measured on the new set are not comparable with earlier ones. The exclusion gate from the previous commit is green: 0 tracked files hit outside the shared/ subtree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
1.9 KiB
Python
55 lines
1.9 KiB
Python
"""Step 7 tests — the retriever exposed as a citation-bearing data source.
|
|
|
|
The in-process GA tool path and the (GA-present) MCP path both wrap the same retrieve()
|
|
core, so their structuredContent shape is identical and every chunk maps into a
|
|
provenance.Citation. Pattern: tests/test_retrieval.py + tests/test_backends.py.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from agent_framework import FunctionTool
|
|
|
|
from portfolio_optimiser.datasource import (
|
|
build_mcp_server,
|
|
chunk_dict_to_citation,
|
|
make_retrieval_tool,
|
|
retrieve_chunks,
|
|
)
|
|
from portfolio_optimiser.provenance import Citation
|
|
|
|
|
|
@pytest.fixture()
|
|
def docs(tmp_path):
|
|
d = tmp_path / "docs"
|
|
d.mkdir()
|
|
(d / "licence.txt").write_text(
|
|
"Licence unit price renegotiation reduced the office-suite cost for the head office.",
|
|
encoding="utf-8",
|
|
)
|
|
return d
|
|
|
|
|
|
def test_in_process_tool_returns_citation_ready_chunks(docs) -> None:
|
|
chunks = retrieve_chunks("licence office-suite cost", str(docs), top_k=3)
|
|
assert chunks # at least one citation-ready chunk
|
|
for d in chunks:
|
|
assert set(d) >= {"file", "locator", "snippet", "score"}
|
|
cit = chunk_dict_to_citation(d)
|
|
assert isinstance(cit, Citation)
|
|
assert cit.locator.start_index <= cit.locator.end_index
|
|
assert cit.snippet
|
|
|
|
|
|
def test_make_retrieval_tool_builds_ga_function_tool(docs) -> None:
|
|
t = make_retrieval_tool(str(docs))
|
|
assert isinstance(t, FunctionTool)
|
|
assert t.name == "retrieve_cost_docs"
|
|
|
|
|
|
async def test_mcp_wrapper_returns_same_structuredcontent_shape(docs) -> None:
|
|
query = "licence office-suite cost"
|
|
expected = retrieve_chunks(query, str(docs), top_k=3)
|
|
server = build_mcp_server(str(docs), top_k=3)
|
|
_content, structured = await server.call_tool("retrieve_cost_docs", {"query": query})
|
|
# FastMCP wraps a list return as {"result": [...]} structuredContent.
|
|
assert structured["result"] == expected
|