Skip to content

Commit 6915ccf

Browse files
committed
test(genai): add integration tests for file search built-in tool
1 parent fe2fefd commit 6915ccf

1 file changed

Lines changed: 145 additions & 0 deletions

File tree

libs/genai/tests/integration_tests/test_chat_models.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,6 +1905,151 @@ def test_google_maps_grounding_invoke_direct(backend_config: dict) -> None:
19051905
assert "grounding_metadata" in response_with_location.response_metadata
19061906

19071907

1908+
def test_file_search_tool_binding(backend_config: dict) -> None:
1909+
"""Test that file_search tool can be bound to a model.
1910+
1911+
This test verifies the tool binding mechanics work correctly.
1912+
Note: Actually using file_search requires a pre-configured file search store.
1913+
"""
1914+
model = ChatGoogleGenerativeAI(model=_MODEL, **backend_config)
1915+
1916+
# Test binding with empty dict (valid but won't work without store names)
1917+
model_with_file_search = model.bind_tools([{"file_search": {}}])
1918+
assert model_with_file_search is not None
1919+
1920+
# Test binding with explicit parameters
1921+
model_with_params = model.bind_tools(
1922+
[
1923+
{
1924+
"file_search": {
1925+
"top_k": 5,
1926+
}
1927+
}
1928+
]
1929+
)
1930+
assert model_with_params is not None
1931+
1932+
1933+
@pytest.mark.extended
1934+
def test_file_search_tool(backend_config: dict) -> None:
1935+
"""Test file_search tool with a configured file search store.
1936+
1937+
This test requires a pre-configured file search store with indexed content.
1938+
Set the FILE_SEARCH_STORE_NAME environment variable to run this test.
1939+
1940+
Example store name format: `fileSearchStores/my-file-search-store-123`
1941+
1942+
To run:
1943+
FILE_SEARCH_STORE_NAME=fileSearchStores/your-store pytest --extended
1944+
"""
1945+
store_name = os.environ.get("FILE_SEARCH_STORE_NAME")
1946+
if not store_name:
1947+
pytest.skip(
1948+
"File search test requires FILE_SEARCH_STORE_NAME env var to be set"
1949+
)
1950+
1951+
model = ChatGoogleGenerativeAI(model=_MODEL, **backend_config)
1952+
model_with_file_search = model.bind_tools(
1953+
[
1954+
{
1955+
"file_search": {
1956+
"file_search_store_names": [store_name],
1957+
"top_k": 5,
1958+
}
1959+
}
1960+
]
1961+
)
1962+
1963+
# Query the file search store
1964+
response = model_with_file_search.invoke(
1965+
"What information do you have about the documents in the store?"
1966+
)
1967+
1968+
assert isinstance(response, AIMessage)
1969+
assert response.content is not None
1970+
1971+
# File search should populate grounding metadata when results are found
1972+
if "grounding_metadata" in response.response_metadata:
1973+
grounding = response.response_metadata["grounding_metadata"]
1974+
# Verify grounding structure exists (may or may not have chunks depending on
1975+
# store content)
1976+
assert isinstance(grounding, dict)
1977+
1978+
1979+
@pytest.mark.extended
1980+
def test_file_search_tool_with_metadata_filter(backend_config: dict) -> None:
1981+
"""Test file_search tool with metadata filtering.
1982+
1983+
This test requires a pre-configured file search store with indexed content
1984+
and metadata.
1985+
Set the FILE_SEARCH_STORE_NAME environment variable to run this test.
1986+
1987+
To run:
1988+
FILE_SEARCH_STORE_NAME=fileSearchStores/your-store pytest --extended
1989+
"""
1990+
store_name = os.environ.get("FILE_SEARCH_STORE_NAME")
1991+
if not store_name:
1992+
pytest.skip(
1993+
"File search test requires FILE_SEARCH_STORE_NAME env var to be set"
1994+
)
1995+
1996+
model = ChatGoogleGenerativeAI(model=_MODEL, **backend_config)
1997+
1998+
# Test with metadata filter (AIP-160 filter syntax)
1999+
# Example filter: category = "technical" AND year >= 2024
2000+
model_with_filter = model.bind_tools(
2001+
[
2002+
{
2003+
"file_search": {
2004+
"file_search_store_names": [store_name],
2005+
"top_k": 3,
2006+
"metadata_filter": 'category = "general"',
2007+
}
2008+
}
2009+
]
2010+
)
2011+
2012+
response = model_with_filter.invoke("Summarize the filtered documents.")
2013+
2014+
assert isinstance(response, AIMessage)
2015+
assert response.content is not None
2016+
2017+
2018+
@pytest.mark.extended
2019+
def test_file_search_invoke_direct(backend_config: dict) -> None:
2020+
"""Test passing file_search tool directly to invoke without binding.
2021+
2022+
This test requires a pre-configured file search store.
2023+
Set the FILE_SEARCH_STORE_NAME environment variable to run this test.
2024+
2025+
To run:
2026+
FILE_SEARCH_STORE_NAME=fileSearchStores/your-store pytest --extended
2027+
"""
2028+
store_name = os.environ.get("FILE_SEARCH_STORE_NAME")
2029+
if not store_name:
2030+
pytest.skip(
2031+
"File search test requires FILE_SEARCH_STORE_NAME env var to be set"
2032+
)
2033+
2034+
model = ChatGoogleGenerativeAI(model=_MODEL, **backend_config)
2035+
2036+
# Pass file_search tool directly to invoke
2037+
response = model.invoke(
2038+
"What documents are available?",
2039+
tools=[
2040+
{
2041+
"file_search": {
2042+
"file_search_store_names": [store_name],
2043+
"top_k": 5,
2044+
}
2045+
}
2046+
],
2047+
)
2048+
2049+
assert isinstance(response, AIMessage)
2050+
assert response.content is not None
2051+
2052+
19082053
def _check_code_execution_output(message: AIMessage, output_version: str) -> None:
19092054
if output_version == "v0":
19102055
blocks = [block for block in message.content if isinstance(block, dict)]

0 commit comments

Comments
 (0)