test_automatic_template_resolution.py
1 """ 2 Test that template resolution happens automatically when resolving late embeds. 3 """ 4 5 import pytest 6 from solace_agent_mesh.common.utils.embeds import ( 7 LATE_EMBED_TYPES, 8 evaluate_embed, 9 resolve_embeds_recursively_in_string, 10 ) 11 from solace_agent_mesh.common.utils.embeds.types import ResolutionMode 12 from tests.integration.conftest import TestInMemoryArtifactService 13 14 15 @pytest.mark.asyncio 16 async def test_template_resolution_automatic_with_late_embeds(): 17 """ 18 Test that templates are automatically resolved when resolving late embeds 19 without needing a separate call to resolve_template_blocks_in_string. 20 """ 21 artifact_service = TestInMemoryArtifactService() 22 23 # Create a CSV data artifact 24 csv_content = """name,age,department 25 Alice,30,Engineering 26 Bob,25,Sales""" 27 28 await artifact_service.save_artifact( 29 app_name="test_app", 30 user_id="test_user", 31 session_id="test_session", 32 filename="employees.csv", 33 artifact=type('Part', (), {'inline_data': type('InlineData', (), { 34 'data': csv_content.encode('utf-8'), 35 'mime_type': 'text/csv' 36 })})() 37 ) 38 39 # Create an artifact with a template block 40 artifact_content = """# Employee Report 41 42 Here are all our employees: 43 44 «««template: data="employees.csv" 45 | {% for h in headers %}{{ h }} | {% endfor %} 46 |{% for h in headers %}---|{% endfor %} 47 {% for row in data_rows %}| {% for cell in row %}{{ cell }} | {% endfor %} 48 {% endfor %} 49 »»» 50 51 End of report.""" 52 53 await artifact_service.save_artifact( 54 app_name="test_app", 55 user_id="test_user", 56 session_id="test_session", 57 filename="report.md", 58 artifact=type('Part', (), {'inline_data': type('InlineData', (), { 59 'data': artifact_content.encode('utf-8'), 60 'mime_type': 'text/markdown' 61 })})() 62 ) 63 64 # Now embed the artifact using artifact_content (a late embed) 65 text_with_embed = "Here's the report: «artifact_content:report.md»" 66 67 context = { 68 "artifact_service": artifact_service, 69 "session_context": { 70 "app_name": "test_app", 71 "user_id": "test_user", 72 "session_id": "test_session", 73 } 74 } 75 76 config = { 77 "gateway_max_artifact_resolve_size_bytes": -1, 78 "gateway_recursive_embed_depth": 12, 79 } 80 81 # Resolve late embeds - templates should be resolved automatically 82 result = await resolve_embeds_recursively_in_string( 83 text=text_with_embed, 84 context=context, 85 resolver_func=evaluate_embed, 86 types_to_resolve=LATE_EMBED_TYPES, 87 resolution_mode=ResolutionMode.RECURSIVE_ARTIFACT_CONTENT, 88 log_identifier="[Test]", 89 config=config, 90 max_depth=12, 91 max_total_size=-1, 92 ) 93 94 # Verify the template was resolved (should contain the CSV data as a table) 95 assert "Alice" in result 96 assert "Bob" in result 97 assert "Engineering" in result 98 assert "Sales" in result 99 assert "| name | age | department |" in result 100 101 # The template block delimiters should be gone 102 assert "«««template:" not in result 103 assert "»»»" not in result 104 105 print("\n=== Result ===") 106 print(result) 107 print("=== End Result ===") 108 109 110 @pytest.mark.asyncio 111 async def test_no_template_resolution_with_early_embeds_only(): 112 """ 113 Test that templates are NOT resolved when only early embeds are being resolved 114 (since templates are considered late embeds). 115 """ 116 from solace_agent_mesh.common.utils.embeds import EARLY_EMBED_TYPES, resolve_embeds_recursively_in_string 117 118 artifact_service = TestInMemoryArtifactService() 119 120 # Create a text artifact with a template block 121 artifact_content = """Report generated at «datetime:iso» 122 123 «««template: data="data.csv" 124 Some template content 125 »»»""" 126 127 # Resolve only early embeds (datetime) 128 # Templates should NOT be resolved since they're late embeds 129 context = { 130 "artifact_service": artifact_service, 131 "session_context": { 132 "app_name": "test_app", 133 "user_id": "test_user", 134 "session_id": "test_session", 135 } 136 } 137 138 result = await resolve_embeds_recursively_in_string( 139 text=artifact_content, 140 context=context, 141 resolver_func=evaluate_embed, 142 types_to_resolve=EARLY_EMBED_TYPES, 143 resolution_mode=ResolutionMode.A2A_MESSAGE_TO_USER, 144 log_identifier="[Test]", 145 config={}, 146 max_depth=12, 147 max_total_size=-1, 148 ) 149 150 # datetime should be resolved 151 assert "«datetime:iso»" not in result 152 153 # But template block should still be present (not resolved) 154 assert "«««template:" in result 155 assert "»»»" in result 156 157 print("\n=== Result (Early Embeds Only) ===") 158 print(result) 159 print("=== End Result ===")