@@ -264,6 +264,59 @@ describe("structured output handling", () => {
264264 expect ( result . messages . at ( - 1 ) ?. content ) . toContain ( '{"answer": "Paris"}' ) ;
265265 expect ( ( result . messages . at ( - 1 ) as AIMessage ) . tool_calls ?. length ) . toBe ( 0 ) ;
266266 } ) ;
267+
268+ it ( "should return structured output with Claude Opus 4.6 end-to-end" , async ( ) => {
269+ const model = new ChatAnthropic ( {
270+ model : "claude-opus-4-6" ,
271+ } ) ;
272+
273+ const { tool : weatherTool , mock : weatherMock } = makeTool (
274+ ( { city } : { city : string } ) =>
275+ `The weather in ${ city } is 22°C and partly cloudy.` ,
276+ {
277+ name : "get_weather" ,
278+ description : "Get the current weather for a city" ,
279+ schema : z . object ( {
280+ city : z . string ( ) . describe ( "The city name" ) ,
281+ } ) ,
282+ }
283+ ) ;
284+
285+ const ResponseSchema = z . object ( {
286+ city : z . string ( ) . describe ( "The city that was queried" ) ,
287+ temperature : z . number ( ) . describe ( "The temperature" ) ,
288+ summary : z . string ( ) . describe ( "A brief weather summary" ) ,
289+ } ) ;
290+
291+ const agent = createAgent ( {
292+ model,
293+ tools : [ weatherTool ] ,
294+ systemPrompt :
295+ "You are a weather assistant. Use the get_weather tool to answer questions about weather. Return exact values from the tool." ,
296+ responseFormat : providerStrategy ( ResponseSchema ) ,
297+ } ) ;
298+
299+ const result = await agent . invoke ( {
300+ messages : [ new HumanMessage ( "What is the weather in Berlin?" ) ] ,
301+ } ) ;
302+
303+ // Verify tool was called
304+ expect ( weatherMock ) . toHaveBeenCalledTimes ( 1 ) ;
305+
306+ // Verify structured response is present and correctly parsed
307+ expect ( result . structuredResponse ) . toBeDefined ( ) ;
308+ expect ( result . structuredResponse . temperature ) . toBe ( 22 ) ;
309+ expect ( result . structuredResponse . city ) . toBe ( "Berlin" ) ;
310+ expect ( typeof result . structuredResponse . summary ) . toBe ( "string" ) ;
311+
312+ // Verify no extract- tool calls (providerStrategy uses native structured output)
313+ const hasExtractToolCalls = result . messages . some (
314+ ( msg ) =>
315+ AIMessage . isInstance ( msg ) &&
316+ msg . tool_calls ?. some ( ( tc ) => tc . name . startsWith ( "extract-" ) )
317+ ) ;
318+ expect ( hasExtractToolCalls ) . toBe ( false ) ;
319+ } ) ;
267320 } ) ;
268321} ) ;
269322
0 commit comments