@@ -2186,3 +2186,59 @@ func TestNativeBedrockSimple(t *testing.T) {
21862186 // Verify interception lifecycle.
21872187 bridgeServer .Recorder .VerifyAllInterceptionsEnded (t )
21882188}
2189+
2190+ func TestNativeBedrockSingleBuiltinTool (t * testing.T ) {
2191+ t .Parallel ()
2192+
2193+ const bedrockModel = "us.anthropic.claude-sonnet-4-5-20250929-v1:0"
2194+
2195+ ctx , cancel := context .WithTimeout (t .Context (), testutil .WaitLong )
2196+ t .Cleanup (cancel )
2197+
2198+ fix := fixtures.BedrockFixture {
2199+ Request : fixtures .BedrockSingleBuiltinToolReq ,
2200+ Response : fixtures .BedrockSingleBuiltinToolResp ,
2201+ }
2202+
2203+ upstream := newMockUpstream (ctx , t , upstreamResponse {
2204+ Streaming : fix .Response ,
2205+ })
2206+
2207+ bridgeServer := newBridgeTestServer (ctx , t , upstream .URL )
2208+
2209+ path := "/bedrock/model/" + bedrockModel + "/invoke-with-response-stream"
2210+ resp , err := bridgeServer .makeRequest (t , http .MethodPost , path , fix .Request )
2211+ require .NoError (t , err )
2212+ defer resp .Body .Close ()
2213+ require .Equal (t , http .StatusOK , resp .StatusCode )
2214+
2215+ // Verify non-empty response.
2216+ bodyBytes , err := io .ReadAll (resp .Body )
2217+ require .NoError (t , err )
2218+ assert .NotEmpty (t , bodyBytes )
2219+
2220+ // Verify token usage: message_start (input=583, output=1) + message_delta (output=56).
2221+ tokenUsages := bridgeServer .Recorder .RecordedTokenUsages ()
2222+ require .Len (t , tokenUsages , 2 )
2223+ assert .EqualValues (t , 583 , bridgeServer .Recorder .TotalInputTokens (), "input tokens" )
2224+ assert .EqualValues (t , 57 , bridgeServer .Recorder .TotalOutputTokens (), "output tokens (1 + 56)" )
2225+
2226+ // Verify tool usage.
2227+ toolUsages := bridgeServer .Recorder .RecordedToolUsages ()
2228+ require .Len (t , toolUsages , 1 )
2229+ assert .Equal (t , "Read" , toolUsages [0 ].Tool )
2230+ assert .Equal (t , "toolu_bdrk_01K3c5nvHfTPbUTdKyt2XdiD" , toolUsages [0 ].ToolCallID )
2231+ require .IsType (t , json.RawMessage {}, toolUsages [0 ].Args )
2232+ var args map [string ]any
2233+ require .NoError (t , json .Unmarshal (toolUsages [0 ].Args .(json.RawMessage ), & args ))
2234+ require .Contains (t , args , "file_path" )
2235+ assert .Equal (t , "/tmp/foo" , args ["file_path" ])
2236+
2237+ // Verify prompt.
2238+ promptUsages := bridgeServer .Recorder .RecordedPromptUsages ()
2239+ require .Len (t , promptUsages , 1 )
2240+ assert .Equal (t , "read the /tmp/foo file" , promptUsages [0 ].Prompt )
2241+
2242+ // Verify interception lifecycle.
2243+ bridgeServer .Recorder .VerifyAllInterceptionsEnded (t )
2244+ }
0 commit comments