@@ -58,10 +58,11 @@ func (m *anthropicChatMessage) GetUsage() *uctypes.AIUsage {
5858 }
5959
6060 return & uctypes.AIUsage {
61- APIType : uctypes .APIType_AnthropicMessages ,
62- Model : m .Usage .Model ,
63- InputTokens : m .Usage .InputTokens ,
64- OutputTokens : m .Usage .OutputTokens ,
61+ APIType : uctypes .APIType_AnthropicMessages ,
62+ Model : m .Usage .Model ,
63+ InputTokens : m .Usage .InputTokens ,
64+ OutputTokens : m .Usage .OutputTokens ,
65+ NativeWebSearchCount : m .Usage .NativeWebSearchCount ,
6566 }
6667}
6768
@@ -181,10 +182,15 @@ type anthropicStreamRequest struct {
181182 Stream bool `json:"stream"`
182183 System []anthropicMessageContentBlock `json:"system,omitempty"`
183184 ToolChoice any `json:"tool_choice,omitempty"`
184- Tools []uctypes. ToolDefinition `json:"tools,omitempty"`
185+ Tools []any `json:"tools,omitempty"` // *uctypes.ToolDefinition or *anthropicWebSearchTool
185186 Thinking * anthropicThinkingOpts `json:"thinking,omitempty"`
186187}
187188
189+ type anthropicWebSearchTool struct {
190+ Type string `json:"type"` // "web_search_20250305"
191+ Name string `json:"name"` // "web_search"
192+ }
193+
188194type anthropicCacheControl struct {
189195 Type string `json:"type"` // "ephemeral"
190196 TTL string `json:"ttl"` // "5m" or "1h"
@@ -232,8 +238,9 @@ type anthropicUsageType struct {
232238 CacheCreationInputTokens int `json:"cache_creation_input_tokens,omitempty"`
233239 CacheReadInputTokens int `json:"cache_read_input_tokens,omitempty"`
234240
235- // internal field for Wave use (not sent to API)
236- Model string `json:"model,omitempty"`
241+ // internal fields for Wave use (not sent to API)
242+ Model string `json:"model,omitempty"`
243+ NativeWebSearchCount int `json:"nativewebsearchcount,omitempty"`
237244
238245 // for reference, but we dont keep thsese up to date or track them
239246 CacheCreation * anthropicCacheCreationType `json:"cache_creation,omitempty"` // breakdown of cached tokens by TTL
@@ -294,15 +301,16 @@ type partialJSON struct {
294301}
295302
296303type streamingState struct {
297- blockMap map [int ]* blockState
298- toolCalls []uctypes.WaveToolCall
299- stopFromDelta string
300- msgID string
301- model string
302- stepStarted bool
303- rtnMessage * anthropicChatMessage
304- usage * anthropicUsageType
305- chatOpts uctypes.WaveChatOpts
304+ blockMap map [int ]* blockState
305+ toolCalls []uctypes.WaveToolCall
306+ stopFromDelta string
307+ msgID string
308+ model string
309+ stepStarted bool
310+ rtnMessage * anthropicChatMessage
311+ usage * anthropicUsageType
312+ chatOpts uctypes.WaveChatOpts
313+ webSearchCount int
306314}
307315
308316func (p * partialJSON ) Write (s string ) {
@@ -547,8 +555,10 @@ func handleAnthropicStreamingResp(
547555 defer func () {
548556 // Set usage in the returned message
549557 if state .usage != nil {
550- // Set model in usage for internal use
551558 state .usage .Model = state .model
559+ if state .webSearchCount > 0 {
560+ state .usage .NativeWebSearchCount = state .webSearchCount
561+ }
552562 state .rtnMessage .Usage = state .usage
553563 }
554564
@@ -759,6 +769,10 @@ func handleAnthropicEvent(
759769 }
760770 state .blockMap [idx ] = st
761771 _ = sse .AiMsgToolInputStart (tcID , tName )
772+ case "server_tool_use" :
773+ if ev .ContentBlock .Name == "web_search" {
774+ state .webSearchCount ++
775+ }
762776 default :
763777 // ignore other block types gracefully per Anthropic guidance :contentReference[oaicite:18]{index=18}
764778 }
0 commit comments