@@ -1592,7 +1592,7 @@ def test_evaluate_model_hints(
15921592 assert model_id == expected_model
15931593
15941594
1595- def testprocess_knowledge_search_content_with_valid_metadata (mocker ):
1595+ def test_process_knowledge_search_content_with_valid_metadata (mocker ):
15961596 """Test process_knowledge_search_content with valid metadata."""
15971597 # Mock tool response with valid metadata
15981598 text_content_item = mocker .Mock ()
@@ -1613,7 +1613,7 @@ def testprocess_knowledge_search_content_with_valid_metadata(mocker):
16131613 assert metadata_map ["doc-1" ]["document_id" ] == "doc-1"
16141614
16151615
1616- def testprocess_knowledge_search_content_with_invalid_metadata_syntax_error (mocker ):
1616+ def test_process_knowledge_search_content_with_invalid_metadata_syntax_error (mocker ):
16171617 """Test process_knowledge_search_content gracefully handles SyntaxError."""
16181618 # Mock tool response with invalid metadata (invalid Python syntax)
16191619 text_content_item = mocker .Mock ()
@@ -1631,7 +1631,7 @@ def testprocess_knowledge_search_content_with_invalid_metadata_syntax_error(mock
16311631 assert len (metadata_map ) == 0
16321632
16331633
1634- def testprocess_knowledge_search_content_with_invalid_metadata_value_error (mocker ):
1634+ def test_process_knowledge_search_content_with_invalid_metadata_value_error (mocker ):
16351635 """Test process_knowledge_search_content gracefully handles ValueError from invalid metadata."""
16361636 # Mock tool response with invalid metadata containing complex expressions
16371637 text_content_item = mocker .Mock ()
@@ -1649,7 +1649,7 @@ def testprocess_knowledge_search_content_with_invalid_metadata_value_error(mocke
16491649 assert len (metadata_map ) == 0
16501650
16511651
1652- def testprocess_knowledge_search_content_with_non_dict_metadata (mocker ):
1652+ def test_process_knowledge_search_content_with_non_dict_metadata (mocker ):
16531653 """Test process_knowledge_search_content handles non-dict metadata gracefully."""
16541654 mock_logger = mocker .patch ("app.endpoints.query.logger" )
16551655
@@ -1672,7 +1672,7 @@ def testprocess_knowledge_search_content_with_non_dict_metadata(mocker):
16721672 mock_logger .exception .assert_not_called ()
16731673
16741674
1675- def testprocess_knowledge_search_content_with_metadata_missing_document_id (mocker ):
1675+ def test_process_knowledge_search_content_with_metadata_missing_document_id (mocker ):
16761676 """Test process_knowledge_search_content skips metadata without document_id."""
16771677 # Mock tool response with valid metadata but missing document_id
16781678 text_content_item = mocker .Mock ()
@@ -1690,7 +1690,7 @@ def testprocess_knowledge_search_content_with_metadata_missing_document_id(mocke
16901690 assert len (metadata_map ) == 0
16911691
16921692
1693- def testprocess_knowledge_search_content_with_no_text_attribute (mocker ):
1693+ def test_process_knowledge_search_content_with_no_text_attribute (mocker ):
16941694 """Test process_knowledge_search_content skips content items without text attribute."""
16951695 # Mock tool response with content item that has no text attribute
16961696 text_content_item = mocker .Mock (spec = []) # spec=[] means no attributes
@@ -1704,7 +1704,7 @@ def testprocess_knowledge_search_content_with_no_text_attribute(mocker):
17041704 assert len (metadata_map ) == 0
17051705
17061706
1707- def testprocess_knowledge_search_content_with_none_content (mocker ):
1707+ def test_process_knowledge_search_content_with_none_content (mocker ):
17081708 """Test process_knowledge_search_content handles tool_response with content=None."""
17091709 # Mock tool response with content = None
17101710 tool_response = mocker .Mock ()
@@ -1716,7 +1716,7 @@ def testprocess_knowledge_search_content_with_none_content(mocker):
17161716 assert len (metadata_map ) == 0
17171717
17181718
1719- def testprocess_knowledge_search_content_duplicate_document_id_last_wins (mocker ):
1719+ def test_process_knowledge_search_content_duplicate_document_id_last_wins (mocker ):
17201720 """The last metadata block for a given document_id should win."""
17211721 text_items = [
17221722 mocker .Mock (
@@ -1747,7 +1747,7 @@ def testprocess_knowledge_search_content_duplicate_document_id_last_wins(mocker)
17471747 assert docs [0 ].doc_title == "Second"
17481748
17491749
1750- def testprocess_knowledge_search_content_with_braces_inside_strings (mocker ):
1750+ def test_process_knowledge_search_content_with_braces_inside_strings (mocker ):
17511751 """Test that braces inside strings are handled correctly."""
17521752 text_content_item = mocker .Mock ()
17531753 text_content_item .text = (
@@ -1766,7 +1766,7 @@ def testprocess_knowledge_search_content_with_braces_inside_strings(mocker):
17661766 assert metadata_map ["doc-100" ]["extra" ]["note" ] == "contains {braces}"
17671767
17681768
1769- def testprocess_knowledge_search_content_with_nested_objects (mocker ):
1769+ def test_process_knowledge_search_content_with_nested_objects (mocker ):
17701770 """Test that nested objects are parsed correctly."""
17711771 text_content_item = mocker .Mock ()
17721772 text_content_item .text = (
@@ -1785,6 +1785,33 @@ def testprocess_knowledge_search_content_with_nested_objects(mocker):
17851785 assert metadata_map ["doc-200" ]["meta" ]["k" ]["inner" ] == 1
17861786
17871787
1788+ def test_process_knowledge_search_content_with_string_fallback_parsing (mocker ):
1789+ """Test that string content uses parse_knowledge_search_metadata as fallback."""
1790+ # Create a tool response with string content containing metadata
1791+ string_content = """Result 1
1792+ Content: Test content
1793+ Metadata: {'docs_url': 'https://example.com/fallback', 'title': 'Fallback Doc', 'document_id': 'fallback-1'}
1794+
1795+ Result 2
1796+ Content: More content
1797+ Metadata: {'docs_url': 'https://example.com/fallback2', 'title': 'Fallback Doc 2', 'document_id': 'fallback-2'}
1798+ """
1799+
1800+ tool_response = mocker .Mock ()
1801+ tool_response .content = string_content # String instead of list
1802+
1803+ metadata_map = process_knowledge_search_content (tool_response )
1804+
1805+ # Verify fallback parsing worked correctly
1806+ assert len (metadata_map ) == 2
1807+ assert "fallback-1" in metadata_map
1808+ assert "fallback-2" in metadata_map
1809+ assert metadata_map ["fallback-1" ]["title" ] == "Fallback Doc"
1810+ assert metadata_map ["fallback-1" ]["docs_url" ] == "https://example.com/fallback"
1811+ assert metadata_map ["fallback-2" ]["title" ] == "Fallback Doc 2"
1812+ assert metadata_map ["fallback-2" ]["docs_url" ] == "https://example.com/fallback2"
1813+
1814+
17881815@pytest .mark .asyncio
17891816async def test_retrieve_response_with_none_content (prepare_agent_mocks , mocker ):
17901817 """Test retrieve_response handles None content gracefully."""
0 commit comments