@@ -188,6 +188,205 @@ public void CreateAIAgent_WithNullOptions_ThrowsArgumentNullException()
188188 Assert . Equal ( "options" , exception . ParamName ) ;
189189 }
190190
191+ /// <summary>
192+ /// Verify that CreateAIAgent with tools correctly assigns tools to ChatOptions.
193+ /// </summary>
194+ [ Fact ]
195+ public void CreateAIAgent_WithTools_AssignsToolsCorrectly ( )
196+ {
197+ // Arrange
198+ var chatClient = new TestAnthropicChatClient ( ) ;
199+ IList < AITool > tools = [ AIFunctionFactory . Create ( ( ) => "test result" , "TestFunction" , "A test function" ) ] ;
200+
201+ // Act
202+ var agent = chatClient . Beta . AsAIAgent (
203+ model : "test-model" ,
204+ name : "Test Agent" ,
205+ tools : tools ) ;
206+
207+ // Assert
208+ Assert . NotNull ( agent ) ;
209+ Assert . Equal ( "Test Agent" , agent . Name ) ;
210+ // When tools are provided, ChatOptions is created but instructions remain null
211+ Assert . Null ( agent . Instructions ) ;
212+
213+ // Verify that tools are registered in the FunctionInvokingChatClient
214+ var functionInvokingClient = agent . GetService < FunctionInvokingChatClient > ( ) ;
215+ Assert . NotNull ( functionInvokingClient ) ;
216+ Assert . NotNull ( functionInvokingClient . AdditionalTools ) ;
217+ Assert . Contains ( functionInvokingClient . AdditionalTools , t => t is AIFunction func && func . Name == "TestFunction" ) ;
218+ }
219+
220+ /// <summary>
221+ /// Verify that CreateAIAgent with explicit defaultMaxTokens uses the provided value.
222+ /// </summary>
223+ [ Fact ]
224+ public async Task CreateAIAgent_WithExplicitMaxTokens_UsesProvidedValueAsync ( )
225+ {
226+ // Arrange
227+ int capturedMaxTokens = 0 ;
228+ var handler = new CapturingHttpHandler ( request =>
229+ {
230+ // Parse the request body to capture max_tokens
231+ var content = request . Content ? . ReadAsStringAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
232+ if ( content is not null )
233+ {
234+ var json = System . Text . Json . JsonDocument . Parse ( content ) ;
235+ if ( json . RootElement . TryGetProperty ( "max_tokens" , out var maxTokens ) )
236+ {
237+ capturedMaxTokens = maxTokens . GetInt32 ( ) ;
238+ }
239+ }
240+ } ) ;
241+
242+ var client = new AnthropicClient
243+ {
244+ HttpClient = new HttpClient ( handler ) { BaseAddress = new Uri ( "http://localhost" ) } ,
245+ APIKey = "test-key"
246+ } ;
247+
248+ // Act
249+ var agent = client . Beta . AsAIAgent (
250+ model : "claude-haiku-4-5" ,
251+ name : "Test Agent" ,
252+ defaultMaxTokens : 8192 ) ;
253+
254+ // Invoke the agent to trigger the request
255+ var thread = await agent . GetNewThreadAsync ( ) ;
256+ try
257+ {
258+ await agent . RunAsync ( "Test message" , thread ) ;
259+ }
260+ catch
261+ {
262+ // Expected to fail since we're using a test handler
263+ }
264+
265+ // Assert
266+ Assert . Equal ( 8192 , capturedMaxTokens ) ;
267+ }
268+
269+ /// <summary>
270+ /// HTTP handler that captures requests for verification.
271+ /// </summary>
272+ private sealed class CapturingHttpHandler : HttpMessageHandler
273+ {
274+ private readonly Action < HttpRequestMessage > _captureRequest ;
275+
276+ public CapturingHttpHandler ( Action < HttpRequestMessage > captureRequest )
277+ {
278+ this . _captureRequest = captureRequest ;
279+ }
280+
281+ protected override Task < HttpResponseMessage > SendAsync ( HttpRequestMessage request , CancellationToken cancellationToken )
282+ {
283+ this . _captureRequest ( request ) ;
284+ return Task . FromResult ( new HttpResponseMessage ( System . Net . HttpStatusCode . BadRequest )
285+ {
286+ Content = new StringContent ( "{\" error\" : \" test\" }" )
287+ } ) ;
288+ }
289+ }
290+
291+ /// <summary>
292+ /// Verify that CreateAIAgent with tools and instructions correctly assigns both.
293+ /// </summary>
294+ [ Fact ]
295+ public void CreateAIAgent_WithToolsAndInstructions_AssignsBothCorrectly ( )
296+ {
297+ // Arrange
298+ var chatClient = new TestAnthropicChatClient ( ) ;
299+ IList < AITool > tools = [ AIFunctionFactory . Create ( ( ) => "test result" , "TestFunction" , "A test function" ) ] ;
300+
301+ // Act
302+ var agent = chatClient . Beta . AsAIAgent (
303+ model : "test-model" ,
304+ name : "Test Agent" ,
305+ instructions : "Test instructions" ,
306+ tools : tools ) ;
307+
308+ // Assert
309+ Assert . NotNull ( agent ) ;
310+ Assert . Equal ( "Test Agent" , agent . Name ) ;
311+ Assert . Equal ( "Test instructions" , agent . Instructions ) ;
312+
313+ // Verify that tools are registered in the FunctionInvokingChatClient
314+ var functionInvokingClient = agent . GetService < FunctionInvokingChatClient > ( ) ;
315+ Assert . NotNull ( functionInvokingClient ) ;
316+ Assert . NotNull ( functionInvokingClient . AdditionalTools ) ;
317+ Assert . Contains ( functionInvokingClient . AdditionalTools , t => t is AIFunction func && func . Name == "TestFunction" ) ;
318+ }
319+
320+ /// <summary>
321+ /// Verify that CreateAIAgent with empty tools list does not assign tools.
322+ /// </summary>
323+ [ Fact ]
324+ public void CreateAIAgent_WithEmptyTools_DoesNotAssignTools ( )
325+ {
326+ // Arrange
327+ var chatClient = new TestAnthropicChatClient ( ) ;
328+ IList < AITool > tools = [ ] ;
329+
330+ // Act
331+ var agent = chatClient . Beta . AsAIAgent (
332+ model : "test-model" ,
333+ name : "Test Agent" ,
334+ tools : tools ) ;
335+
336+ // Assert
337+ Assert . NotNull ( agent ) ;
338+ Assert . Equal ( "Test Agent" , agent . Name ) ;
339+ // With empty tools and no instructions, agent instructions remain null
340+ Assert . Null ( agent . Instructions ) ;
341+
342+ // Verify that FunctionInvokingChatClient has no additional tools assigned
343+ var functionInvokingClient = agent . GetService < FunctionInvokingChatClient > ( ) ;
344+ Assert . NotNull ( functionInvokingClient ) ;
345+ Assert . True ( functionInvokingClient . AdditionalTools is null or { Count : 0 } ) ;
346+ }
347+
348+ /// <summary>
349+ /// Verify that CreateAIAgent with null instructions does not set instructions.
350+ /// </summary>
351+ [ Fact ]
352+ public void CreateAIAgent_WithNullInstructions_DoesNotSetInstructions ( )
353+ {
354+ // Arrange
355+ var chatClient = new TestAnthropicChatClient ( ) ;
356+
357+ // Act
358+ var agent = chatClient . Beta . AsAIAgent (
359+ model : "test-model" ,
360+ name : "Test Agent" ,
361+ instructions : null ) ;
362+
363+ // Assert
364+ Assert . NotNull ( agent ) ;
365+ Assert . Equal ( "Test Agent" , agent . Name ) ;
366+ Assert . Null ( agent . Instructions ) ;
367+ }
368+
369+ /// <summary>
370+ /// Verify that CreateAIAgent with whitespace instructions does not set instructions.
371+ /// </summary>
372+ [ Fact ]
373+ public void CreateAIAgent_WithWhitespaceInstructions_DoesNotSetInstructions ( )
374+ {
375+ // Arrange
376+ var chatClient = new TestAnthropicChatClient ( ) ;
377+
378+ // Act
379+ var agent = chatClient . Beta . AsAIAgent (
380+ model : "test-model" ,
381+ name : "Test Agent" ,
382+ instructions : " " ) ;
383+
384+ // Assert
385+ Assert . NotNull ( agent ) ;
386+ Assert . Equal ( "Test Agent" , agent . Name ) ;
387+ Assert . Null ( agent . Instructions ) ;
388+ }
389+
191390 /// <summary>
192391 /// Test custom chat client that can be used to verify clientFactory functionality.
193392 /// </summary>
0 commit comments