|
34 | 34 | AzureFunctionTool,
|
35 | 35 | CodeInterpreterTool,
|
36 | 36 | CodeInterpreterToolResource,
|
| 37 | + DeepResearchTool, |
37 | 38 | FilePurpose,
|
38 | 39 | FileSearchTool,
|
39 | 40 | FileSearchToolCallContent,
|
|
81 | 82 | handler = logging.StreamHandler(stream=sys.stdout)
|
82 | 83 | logger.addHandler(handler)
|
83 | 84 |
|
84 |
| - |
85 | 85 | agentClientPreparer = functools.partial(
|
86 | 86 | EnvironmentVariableLoader,
|
87 | 87 | "azure_ai_agents",
|
88 | 88 | # TODO: uncomment this endpoint when re running with 1DP
|
89 | 89 | # azure_ai_agents_tests_project_endpoint="https://aiservices-id.services.ai.azure.com/api/projects/project-name",
|
90 | 90 | # TODO: remove this endpoint when re running with 1DP
|
91 |
| - azure_ai_agents_tests_project_endpoint="https://Sanitized.api.azureml.ms/agents/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/", |
| 91 | + azure_ai_agents_tests_project_connection_string="https://Sanitized.api.azureml.ms/agents/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/", |
| 92 | + azure_ai_agents_tests_project_endpoint="https://Sanitized.services.ai.azure.com/api/projects/00000", |
92 | 93 | azure_ai_agents_tests_data_path="azureml://subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-resour-cegr-oupfoo1/workspaces/abcd-abcdabcdabcda-abcdefghijklm/datastores/workspaceblobstore/paths/LocalUpload/000000000000/product_info_1.md",
|
93 | 94 | azure_ai_agents_tests_storage_queue="https://foobar.queue.core.windows.net",
|
94 | 95 | azure_ai_agents_tests_search_index_name="sample_index",
|
95 | 96 | azure_ai_agents_tests_search_connection_id="/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/connections/someindex",
|
| 97 | + azure_ai_agents_tests_bing_connection_id="/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.CognitiveServices/accounts/00000/projects/00000/connections/00000", |
| 98 | + azure_ai_agents_tests_deep_research_model="gpt-4o-deep-research", |
96 | 99 | azure_ai_agents_tests_is_test_run="True",
|
97 | 100 | )
|
98 | 101 |
|
@@ -131,9 +134,11 @@ def fetch_current_datetime_recordings():
|
131 | 134 | class TestAgentClient(AzureRecordedTestCase):
|
132 | 135 |
|
133 | 136 | # helper function: create client using environment variables
|
134 |
| - def create_client(self, **kwargs) -> AgentsClient: |
| 137 | + def create_client(self, by_endpoint=False, **kwargs) -> AgentsClient: |
135 | 138 | # fetch environment variables
|
136 |
| - endpoint = kwargs.pop("azure_ai_agents_tests_project_endpoint") |
| 139 | + endpoint = kwargs.pop("azure_ai_agents_tests_project_connection_string") |
| 140 | + if by_endpoint: |
| 141 | + endpoint = kwargs.pop("azure_ai_agents_tests_project_endpoint") |
137 | 142 | credential = self.get_credential(AgentsClient, is_async=False)
|
138 | 143 |
|
139 | 144 | # create and return client
|
@@ -3151,6 +3156,112 @@ def test_azure_function_call(self, **kwargs):
|
3151 | 3156 | # Delete the agent once done
|
3152 | 3157 | client.delete_agent(agent.id)
|
3153 | 3158 |
|
| 3159 | + @agentClientPreparer() |
| 3160 | + @recorded_by_proxy |
| 3161 | + def test_deep_research_tool(self, **kwargs): |
| 3162 | + """Test using the DeepResearchTool with an agent.""" |
| 3163 | + # create client |
| 3164 | + with self.create_client(by_endpoint=True, **kwargs) as client: |
| 3165 | + assert isinstance(client, AgentsClient) |
| 3166 | + |
| 3167 | + # Get connection ID and model name from test environment |
| 3168 | + bing_conn_id = kwargs.pop("azure_ai_agents_tests_bing_connection_id") |
| 3169 | + deep_research_model = kwargs.pop("azure_ai_agents_tests_deep_research_model") |
| 3170 | + |
| 3171 | + # Create DeepResearchTool |
| 3172 | + deep_research_tool = DeepResearchTool( |
| 3173 | + bing_grounding_connection_id=bing_conn_id, |
| 3174 | + deep_research_model=deep_research_model, |
| 3175 | + ) |
| 3176 | + |
| 3177 | + # Create agent with the deep research tool |
| 3178 | + agent = client.create_agent( |
| 3179 | + model="gpt-4o", |
| 3180 | + name="deep-research-agent", |
| 3181 | + instructions="You are a helpful agent that assists in researching scientific topics.", |
| 3182 | + tools=deep_research_tool.definitions, |
| 3183 | + ) |
| 3184 | + assert agent.id |
| 3185 | + print(f"Created agent with ID: {agent.id}") |
| 3186 | + |
| 3187 | + # Create thread |
| 3188 | + thread = client.threads.create() |
| 3189 | + assert thread.id |
| 3190 | + print(f"Created thread with ID: {thread.id}") |
| 3191 | + |
| 3192 | + # Create message with a simple research query |
| 3193 | + message = client.messages.create( |
| 3194 | + thread_id=thread.id, |
| 3195 | + role="user", |
| 3196 | + content="Research the benefits of renewable energy sources. Keep the response brief.", |
| 3197 | + ) |
| 3198 | + assert message.id |
| 3199 | + print(f"Created message with ID: {message.id}") |
| 3200 | + |
| 3201 | + # Create and process run |
| 3202 | + print("Starting deep research... this may take several minutes.") |
| 3203 | + run = client.runs.create(thread_id=thread.id, agent_id=agent.id) |
| 3204 | + |
| 3205 | + # Poll the run until completion |
| 3206 | + while run.status in ("queued", "in_progress"): |
| 3207 | + if os.environ.get("AZURE_TEST_RUN_LIVE") == "true": |
| 3208 | + print(f"Update in a min. Current run status: {run.status}") |
| 3209 | + time.sleep(60) # Check every 1 minute |
| 3210 | + run = client.runs.get(thread_id=thread.id, run_id=run.id) |
| 3211 | + |
| 3212 | + # Verify the run completed successfully |
| 3213 | + if run.status == RunStatus.COMPLETED: |
| 3214 | + print("Deep research completed successfully") |
| 3215 | + |
| 3216 | + # List messages to verify the tool was used and got a response |
| 3217 | + messages = list(client.messages.list(thread_id=thread.id)) |
| 3218 | + assert len(messages) >= 2 # At least user message + agent response |
| 3219 | + |
| 3220 | + # Find the agent's response |
| 3221 | + agent_messages = [msg for msg in messages if msg.role == MessageRole.AGENT] |
| 3222 | + assert len(agent_messages) > 0, "No agent response found" |
| 3223 | + |
| 3224 | + # Verify the response contains some content |
| 3225 | + agent_response = agent_messages[0] |
| 3226 | + assert agent_response.content, "Agent response has no content" |
| 3227 | + |
| 3228 | + # Check if response has text content |
| 3229 | + text_messages = agent_response.text_messages |
| 3230 | + assert len(text_messages) > 0, "No text content in agent response" |
| 3231 | + assert len(text_messages[0].text.value) > 50, "Response too short - may not have completed research" |
| 3232 | + |
| 3233 | + print(f"Research completed with {len(text_messages)} text blocks") |
| 3234 | + |
| 3235 | + # Verify that DeepResearchTool was actually used by checking run steps |
| 3236 | + run_steps = list(client.run_steps.list(thread_id=thread.id, run_id=run.id)) |
| 3237 | + assert len(run_steps) > 0, "No run steps found" |
| 3238 | + |
| 3239 | + # Look for tool calls in the run steps |
| 3240 | + tool_calls_found = False |
| 3241 | + deep_research_tool_used = False |
| 3242 | + for step in run_steps: |
| 3243 | + if hasattr(step.step_details, "tool_calls") and step.step_details.tool_calls: |
| 3244 | + tool_calls_found = True |
| 3245 | + for tool_call in step.step_details.tool_calls: |
| 3246 | + if hasattr(tool_call, "type") and tool_call.type == "deep_research": |
| 3247 | + deep_research_tool_used = True |
| 3248 | + print(f"Found DeepResearchTool usage in step {step.id}") |
| 3249 | + break |
| 3250 | + |
| 3251 | + assert tool_calls_found, "No tool calls found in run steps" |
| 3252 | + assert deep_research_tool_used, "DeepResearchTool was not used during the run" |
| 3253 | + print("Verified DeepResearchTool was used successfully") |
| 3254 | + |
| 3255 | + elif run.status == RunStatus.FAILED: |
| 3256 | + pytest.fail(f"Deep research run failed: {run.last_error}") |
| 3257 | + else: |
| 3258 | + # Handle unexpected status |
| 3259 | + pytest.fail(f"Deep research run ended with unexpected status: {run.status}") |
| 3260 | + |
| 3261 | + # Clean up |
| 3262 | + client.delete_agent(agent.id) |
| 3263 | + print("Deleted agent") |
| 3264 | + |
3154 | 3265 | @agentClientPreparer()
|
3155 | 3266 | @pytest.mark.skip("Recordings not yet implemented.")
|
3156 | 3267 | @recorded_by_proxy
|
|
0 commit comments