github.com/anthropics/anthropic-sdk-go@v1.70.1/betamessageutil.go (about) 1 package anthropic 2 3 import ( 4 "encoding/json" 5 "fmt" 6 7 "github.com/tidwall/sjson" 8 9 "github.com/anthropics/anthropic-sdk-go/internal/paramutil" 10 "github.com/anthropics/anthropic-sdk-go/packages/param" 11 ) 12 13 // Accumulate builds up the Message incrementally from a MessageStreamEvent. The Message then can be used as 14 // any other Message, including the Message.JSON field, which holds the wire JSON with the streamed deltas 15 // applied and is complete once message_stop arrives. 16 // 17 // message := anthropic.Message{} 18 // for stream.Next() { 19 // event := stream.Current() 20 // message.Accumulate(event) 21 // } 22 func (acc *BetaMessage) Accumulate(event BetaRawMessageStreamEventUnion) error { 23 if acc == nil { 24 return fmt.Errorf("accumulate: cannot accumulate into nil Message") 25 } 26 27 switch event.Type { 28 case "message_start": 29 *acc = event.Message 30 case "message_delta": 31 // stop_reason, stop_sequence and stop_details are always sent and null is 32 // their final value when the turn carries no such detail. 33 acc.StopReason = event.Delta.StopReason 34 acc.StopSequence = event.Delta.StopSequence 35 acc.StopDetails = event.Delta.StopDetails 36 if event.Delta.JSON.Container.Valid() { 37 acc.Container = event.Delta.Container 38 } 39 // Every usage count here is a cumulative whole-message total, so it 40 // overwrites rather than adds; the ones that do not apply are omitted, and 41 // message_start keeps the last word on those. 42 acc.Usage.OutputTokens = event.Usage.OutputTokens 43 if event.Usage.JSON.InputTokens.Valid() { 44 acc.Usage.InputTokens = event.Usage.InputTokens 45 } 46 if event.Usage.JSON.CacheCreationInputTokens.Valid() { 47 acc.Usage.CacheCreationInputTokens = event.Usage.CacheCreationInputTokens 48 } 49 if event.Usage.JSON.CacheReadInputTokens.Valid() { 50 acc.Usage.CacheReadInputTokens = event.Usage.CacheReadInputTokens 51 } 52 if event.Usage.JSON.ServerToolUse.Valid() { 53 acc.Usage.ServerToolUse = event.Usage.ServerToolUse 54 } 55 if event.Usage.JSON.OutputTokensDetails.Valid() { 56 acc.Usage.OutputTokensDetails = event.Usage.OutputTokensDetails 57 } 58 if event.Usage.JSON.FallbackCredit.Valid() { 59 acc.Usage.FallbackCredit = event.Usage.FallbackCredit 60 } 61 if event.Usage.JSON.Iterations.Valid() { 62 acc.Usage.Iterations = event.Usage.Iterations 63 } 64 if event.JSON.ContextManagement.Valid() { 65 acc.ContextManagement = event.ContextManagement 66 acc.JSON.raw, _ = sjson.SetRaw(acc.JSON.raw, "context_management", event.ContextManagement.RawJSON()) 67 } 68 // Sent only when a mid-stream model fallback served the response; it then 69 // replaces the list from message_start, even when empty. 70 if event.JSON.InputTransformations.Valid() { 71 acc.InputTransformations = event.InputTransformations 72 acc.JSON.InputTransformations = event.JSON.InputTransformations 73 acc.JSON.raw, _ = sjson.SetRaw(acc.JSON.raw, "input_transformations", event.JSON.InputTransformations.Raw()) 74 } 75 acc.JSON.raw = mergeRaw(acc.JSON.raw, "", event.Delta.JSON.raw) 76 acc.JSON.raw = mergeRaw(acc.JSON.raw, "usage", event.Usage.RawJSON()) 77 case "content_block_start": 78 // Content blocks start in index order with no gaps: a start event always 79 // addresses the slot right after the previous block, even when deltas and 80 // stops for still-open blocks interleave after it. 81 if event.Index != int64(len(acc.Content)) { 82 return fmt.Errorf("received event of type %s for content block at index %d, expected index %d", event.Type, event.Index, len(acc.Content)) 83 } 84 acc.Content = append(acc.Content, BetaContentBlockUnion{}) 85 err := acc.Content[event.Index].UnmarshalJSON([]byte(event.ContentBlock.RawJSON())) 86 if err != nil { 87 return err 88 } 89 // The final hop's fallback block names the model that served the response; 90 // non-streaming responses already report that model, so relabel the 91 // accumulated snapshot to match. Last block wins on multi-hop chains. 92 if fallback, ok := acc.Content[event.Index].AsAny().(BetaFallbackBlock); ok { 93 acc.Model = fallback.To.Model 94 acc.JSON.raw, _ = sjson.SetRaw(acc.JSON.raw, "model", jsonString(string(fallback.To.Model))) 95 } 96 case "content_block_delta": 97 if err := checkContentBlockIndex(event.Type, event.Index, len(acc.Content)); err != nil { 98 return err 99 } 100 cb := &acc.Content[event.Index] 101 switch event.Delta.Type { 102 case "text_delta": 103 cb.Text += event.Delta.Text 104 case "input_json_delta": 105 if len(event.Delta.PartialJSON) != 0 { 106 if string(cb.Input) == "{}" { 107 cb.Input = []byte(event.Delta.PartialJSON) 108 } else { 109 cb.Input = append(cb.Input, event.Delta.PartialJSON...) 110 } 111 } 112 case "thinking_delta": 113 cb.Thinking += event.Delta.Thinking 114 case "signature_delta": 115 cb.Signature += event.Delta.Signature 116 case "citations_delta": 117 citation := BetaTextCitationUnion{} 118 err := citation.UnmarshalJSON([]byte(event.Delta.Citation.RawJSON())) 119 if err != nil { 120 return fmt.Errorf("could not unmarshal citation delta into citation type: %w", err) 121 } 122 cb.Citations = append(cb.Citations, citation) 123 case "compaction_delta": 124 cb.Content.OfString = event.Delta.Content 125 cb.EncryptedContent = event.Delta.EncryptedContent 126 } 127 case "message_stop": 128 // A block whose stop event never arrived has not been refreshed yet. 129 for i := range acc.Content { 130 refreshBetaContentBlockRaw(&acc.Content[i]) 131 } 132 acc.JSON.raw, _ = sjson.SetRaw(acc.JSON.raw, "content", rawArray(acc.Content)) 133 case "content_block_stop": 134 if err := checkContentBlockIndex(event.Type, event.Index, len(acc.Content)); err != nil { 135 return err 136 } 137 refreshBetaContentBlockRaw(&acc.Content[event.Index]) 138 } 139 140 return nil 141 } 142 143 // refreshBetaContentBlockRaw overlays the delta-mutated fields onto the block's 144 // wire JSON, leaving a block that received no deltas byte for byte. 145 func refreshBetaContentBlockRaw(cb *BetaContentBlockUnion) { 146 raw := cb.JSON.raw 147 if cb.Text != "" { 148 raw, _ = sjson.SetRaw(raw, "text", jsonString(cb.Text)) 149 } 150 if cb.Thinking != "" { 151 raw, _ = sjson.SetRaw(raw, "thinking", jsonString(cb.Thinking)) 152 } 153 if cb.Signature != "" { 154 raw, _ = sjson.SetRaw(raw, "signature", jsonString(cb.Signature)) 155 } 156 if json.Valid(cb.Input) { 157 raw, _ = sjson.SetRaw(raw, "input", string(cb.Input)) 158 } else if len(cb.Input) > 0 { 159 // A cut-off tool call left non-JSON input; empty it so the block marshals. 160 cb.Input = json.RawMessage(`{}`) 161 } 162 if len(cb.Citations) > 0 { 163 raw, _ = sjson.SetRaw(raw, "citations", rawArray(cb.Citations)) 164 } 165 if cb.Content.OfString != "" { 166 raw, _ = sjson.SetRaw(raw, "content", jsonString(cb.Content.OfString)) 167 } 168 if cb.EncryptedContent != "" { 169 raw, _ = sjson.SetRaw(raw, "encrypted_content", jsonString(cb.EncryptedContent)) 170 } 171 cb.JSON.raw = raw 172 } 173 174 // ParseOutput finds the first text content block in the message and unmarshals it 175 // into dest. This is useful for streaming workflows where you accumulate the message 176 // first and then parse the structured output. 177 // 178 // var msg anthropic.BetaMessage 179 // for stream.Next() { msg.Accumulate(stream.Current()) } 180 // msg.ParseOutput(&myStruct) 181 func (r *BetaMessage) ParseOutput(dest any) error { 182 return parseOutputContent(r, dest) 183 } 184 185 // Param converters 186 187 func (r BetaContentBlockUnion) ToParam() BetaContentBlockParamUnion { 188 return r.AsAny().toParamUnion() 189 } 190 191 func (variant BetaTextBlock) toParamUnion() BetaContentBlockParamUnion { 192 p := variant.ToParam() 193 return BetaContentBlockParamUnion{OfText: &p} 194 } 195 196 func (variant BetaToolUseBlock) toParamUnion() BetaContentBlockParamUnion { 197 p := variant.ToParam() 198 return BetaContentBlockParamUnion{OfToolUse: &p} 199 } 200 201 func (variant BetaThinkingBlock) toParamUnion() BetaContentBlockParamUnion { 202 p := variant.ToParam() 203 return BetaContentBlockParamUnion{OfThinking: &p} 204 } 205 206 func (variant BetaRedactedThinkingBlock) toParamUnion() BetaContentBlockParamUnion { 207 p := variant.ToParam() 208 return BetaContentBlockParamUnion{OfRedactedThinking: &p} 209 } 210 211 func (variant BetaWebSearchToolResultBlock) toParamUnion() BetaContentBlockParamUnion { 212 p := variant.ToParam() 213 return BetaContentBlockParamUnion{OfWebSearchToolResult: &p} 214 } 215 216 func (variant BetaBashCodeExecutionToolResultBlock) toParamUnion() BetaContentBlockParamUnion { 217 p := variant.ToParam() 218 return BetaContentBlockParamUnion{OfBashCodeExecutionToolResult: &p} 219 } 220 221 func (variant BetaCodeExecutionToolResultBlock) toParamUnion() BetaContentBlockParamUnion { 222 p := variant.ToParam() 223 return BetaContentBlockParamUnion{OfCodeExecutionToolResult: &p} 224 } 225 226 func (variant BetaContainerUploadBlock) toParamUnion() BetaContentBlockParamUnion { 227 p := variant.ToParam() 228 return BetaContentBlockParamUnion{OfContainerUpload: &p} 229 } 230 231 func (variant BetaAdvisorToolResultBlock) toParamUnion() BetaContentBlockParamUnion { 232 p := variant.ToParam() 233 return BetaContentBlockParamUnion{OfAdvisorToolResult: &p} 234 } 235 236 func (r BetaAdvisorToolResultBlock) ToParam() BetaAdvisorToolResultBlockParam { 237 var p BetaAdvisorToolResultBlockParam 238 p.Type = r.Type 239 p.ToolUseID = r.ToolUseID 240 switch { 241 case r.Content.JSON.ErrorCode.Valid(): 242 p.Content.OfRequestAdvisorToolResultError = &BetaAdvisorToolResultErrorParam{ 243 ErrorCode: BetaAdvisorToolResultErrorParamErrorCode(r.Content.ErrorCode), 244 } 245 case r.Content.JSON.EncryptedContent.Valid(): 246 p.Content.OfRequestAdvisorRedactedResultBlock = &BetaAdvisorRedactedResultBlockParam{ 247 EncryptedContent: r.Content.EncryptedContent, 248 StopReason: paramutil.ToOpt(r.Content.StopReason, r.Content.JSON.StopReason), 249 } 250 default: 251 p.Content.OfRequestAdvisorResultBlock = &BetaAdvisorResultBlockParam{ 252 Text: r.Content.Text, 253 StopReason: paramutil.ToOpt(r.Content.StopReason, r.Content.JSON.StopReason), 254 } 255 } 256 return p 257 } 258 259 func (variant BetaMCPToolResultBlock) toParamUnion() BetaContentBlockParamUnion { 260 p := variant.ToParam() 261 return BetaContentBlockParamUnion{OfMCPToolResult: &p} 262 } 263 264 func (variant BetaMCPToolUseBlock) toParamUnion() BetaContentBlockParamUnion { 265 p := variant.ToParam() 266 return BetaContentBlockParamUnion{OfMCPToolUse: &p} 267 } 268 269 func (variant BetaServerToolUseBlock) toParamUnion() BetaContentBlockParamUnion { 270 p := variant.ToParam() 271 return BetaContentBlockParamUnion{OfServerToolUse: &p} 272 } 273 274 func (variant BetaTextEditorCodeExecutionToolResultBlock) toParamUnion() BetaContentBlockParamUnion { 275 p := variant.ToParam() 276 return BetaContentBlockParamUnion{OfTextEditorCodeExecutionToolResult: &p} 277 } 278 279 func (variant BetaWebFetchToolResultBlock) toParamUnion() BetaContentBlockParamUnion { 280 p := variant.ToParam() 281 return BetaContentBlockParamUnion{OfWebFetchToolResult: &p} 282 } 283 284 func (variant BetaToolSearchToolResultBlock) toParamUnion() BetaContentBlockParamUnion { 285 p := variant.ToParam() 286 return BetaContentBlockParamUnion{OfToolSearchToolResult: &p} 287 } 288 289 func (variant BetaCompactionBlock) toParamUnion() BetaContentBlockParamUnion { 290 p := variant.ToParam() 291 return BetaContentBlockParamUnion{OfCompaction: &p} 292 } 293 294 func (variant BetaFallbackBlock) toParamUnion() BetaContentBlockParamUnion { 295 p := variant.ToParam() 296 return BetaContentBlockParamUnion{OfFallback: &p} 297 } 298 299 func (r BetaMessage) ToParam() BetaMessageParam { 300 var p BetaMessageParam 301 p.Role = BetaMessageParamRole(r.Role) 302 p.Content = make([]BetaContentBlockParamUnion, len(r.Content)) 303 for i, c := range r.Content { 304 contentParams := c.ToParam() 305 p.Content[i] = contentParams 306 } 307 return p 308 } 309 310 func (r BetaRedactedThinkingBlock) ToParam() BetaRedactedThinkingBlockParam { 311 var p BetaRedactedThinkingBlockParam 312 p.Type = r.Type 313 p.Data = r.Data 314 return p 315 } 316 317 func (r BetaTextBlock) ToParam() BetaTextBlockParam { 318 var p BetaTextBlockParam 319 p.Type = r.Type 320 p.Text = r.Text 321 322 // Distinguish between a nil and zero length slice, since some compatible 323 // APIs may not require citations. 324 if r.Citations != nil { 325 p.Citations = make([]BetaTextCitationParamUnion, 0, len(r.Citations)) 326 } 327 for _, citation := range r.Citations { 328 p.Citations = append(p.Citations, citation.AsAny().toParamUnion()) 329 } 330 return p 331 } 332 333 func (r BetaCitationCharLocation) toParamUnion() BetaTextCitationParamUnion { 334 var citationParam BetaCitationCharLocationParam 335 citationParam.Type = r.Type 336 citationParam.DocumentTitle = paramutil.ToOpt(r.DocumentTitle, r.JSON.DocumentTitle) 337 citationParam.CitedText = r.CitedText 338 citationParam.DocumentIndex = r.DocumentIndex 339 citationParam.EndCharIndex = r.EndCharIndex 340 citationParam.StartCharIndex = r.StartCharIndex 341 return BetaTextCitationParamUnion{OfCharLocation: &citationParam} 342 } 343 344 func (citationVariant BetaCitationPageLocation) toParamUnion() BetaTextCitationParamUnion { 345 var citationParam BetaCitationPageLocationParam 346 citationParam.Type = citationVariant.Type 347 citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) 348 citationParam.CitedText = citationVariant.CitedText 349 citationParam.DocumentIndex = citationVariant.DocumentIndex 350 citationParam.EndPageNumber = citationVariant.EndPageNumber 351 citationParam.StartPageNumber = citationVariant.StartPageNumber 352 return BetaTextCitationParamUnion{OfPageLocation: &citationParam} 353 } 354 355 func (citationVariant BetaCitationContentBlockLocation) toParamUnion() BetaTextCitationParamUnion { 356 var citationParam BetaCitationContentBlockLocationParam 357 citationParam.Type = citationVariant.Type 358 citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) 359 citationParam.CitedText = citationVariant.CitedText 360 citationParam.DocumentIndex = citationVariant.DocumentIndex 361 citationParam.EndBlockIndex = citationVariant.EndBlockIndex 362 citationParam.StartBlockIndex = citationVariant.StartBlockIndex 363 return BetaTextCitationParamUnion{OfContentBlockLocation: &citationParam} 364 } 365 366 func (citationVariant BetaCitationsWebSearchResultLocation) toParamUnion() BetaTextCitationParamUnion { 367 var citationParam BetaCitationWebSearchResultLocationParam 368 citationParam.Type = citationVariant.Type 369 citationParam.CitedText = citationVariant.CitedText 370 citationParam.Title = paramutil.ToOpt(citationVariant.Title, citationVariant.JSON.Title) 371 citationParam.EncryptedIndex = citationVariant.EncryptedIndex 372 citationParam.URL = citationVariant.URL 373 return BetaTextCitationParamUnion{OfWebSearchResultLocation: &citationParam} 374 } 375 376 func (citationVariant BetaCitationSearchResultLocation) toParamUnion() BetaTextCitationParamUnion { 377 var citationParam BetaCitationSearchResultLocationParam 378 citationParam.Type = citationVariant.Type 379 citationParam.CitedText = citationVariant.CitedText 380 citationParam.Title = paramutil.ToOpt(citationVariant.Title, citationVariant.JSON.Title) 381 citationParam.EndBlockIndex = citationVariant.EndBlockIndex 382 citationParam.SearchResultIndex = citationVariant.SearchResultIndex 383 citationParam.Source = citationVariant.Source 384 citationParam.StartBlockIndex = citationVariant.StartBlockIndex 385 return BetaTextCitationParamUnion{OfSearchResultLocation: &citationParam} 386 } 387 388 func (r BetaThinkingBlock) ToParam() BetaThinkingBlockParam { 389 var p BetaThinkingBlockParam 390 p.Type = r.Type 391 p.Signature = r.Signature 392 p.Thinking = r.Thinking 393 return p 394 } 395 396 func (r BetaToolUseBlock) ToParam() BetaToolUseBlockParam { 397 var p BetaToolUseBlockParam 398 p.Type = r.Type 399 p.ID = r.ID 400 p.Input = r.Input 401 p.Name = r.Name 402 p.ToolsetName = paramutil.ToOpt(r.ToolsetName, r.JSON.ToolsetName) 403 if r.JSON.Caller.Valid() { 404 p.Caller = r.Caller.toParam() 405 } 406 return p 407 } 408 409 // toParam converts a caller. The other three caller unions share this layout 410 // and convert through it. 411 func (r BetaToolUseBlockCallerUnion) toParam() BetaToolUseBlockParamCallerUnion { 412 var p BetaToolUseBlockParamCallerUnion 413 switch v := r.AsAny().(type) { 414 case BetaDirectCaller: 415 c := v.ToParam() 416 p.OfDirect = &c 417 case BetaServerToolCaller: 418 c := v.ToParam() 419 p.OfCodeExecution20250825 = &c 420 case BetaServerToolCaller20260120: 421 c := v.ToParam() 422 p.OfCodeExecution20260120 = &c 423 default: 424 p = param.Override[BetaToolUseBlockParamCallerUnion](json.RawMessage(r.RawJSON())) 425 } 426 return p 427 } 428 429 func (r BetaServerToolUseBlockCallerUnion) toParam() BetaServerToolUseBlockParamCallerUnion { 430 return BetaServerToolUseBlockParamCallerUnion(BetaToolUseBlockCallerUnion(r).toParam()) 431 } 432 433 func (r BetaWebSearchToolResultBlockCallerUnion) toParam() BetaWebSearchToolResultBlockParamCallerUnion { 434 return BetaWebSearchToolResultBlockParamCallerUnion(BetaToolUseBlockCallerUnion(r).toParam()) 435 } 436 437 func (r BetaWebFetchToolResultBlockCallerUnion) toParam() BetaWebFetchToolResultBlockParamCallerUnion { 438 return BetaWebFetchToolResultBlockParamCallerUnion(BetaToolUseBlockCallerUnion(r).toParam()) 439 } 440 441 func (r BetaWebSearchResultBlock) ToParam() BetaWebSearchResultBlockParam { 442 var p BetaWebSearchResultBlockParam 443 p.Type = r.Type 444 p.EncryptedContent = r.EncryptedContent 445 p.Title = r.Title 446 p.URL = r.URL 447 p.PageAge = paramutil.ToOpt(r.PageAge, r.JSON.PageAge) 448 return p 449 } 450 451 func (r BetaWebSearchToolResultBlock) ToParam() BetaWebSearchToolResultBlockParam { 452 var p BetaWebSearchToolResultBlockParam 453 p.Type = r.Type 454 p.ToolUseID = r.ToolUseID 455 456 if r.Content.JSON.OfBetaWebSearchResultBlockArray.Valid() { 457 // content is required, so send [] rather than omitting it. 458 p.Content.OfResultBlock = make([]BetaWebSearchResultBlockParam, 0, len(r.Content.OfBetaWebSearchResultBlockArray)) 459 for _, block := range r.Content.OfBetaWebSearchResultBlockArray { 460 p.Content.OfResultBlock = append(p.Content.OfResultBlock, block.ToParam()) 461 } 462 } else { 463 p.Content.OfError = &BetaWebSearchToolRequestErrorParam{ 464 Type: r.Content.Type, 465 ErrorCode: r.Content.ErrorCode, 466 } 467 } 468 if r.JSON.Caller.Valid() { 469 p.Caller = r.Caller.toParam() 470 } 471 return p 472 } 473 474 func (r BetaWebFetchToolResultBlock) ToParam() BetaWebFetchToolResultBlockParam { 475 var p BetaWebFetchToolResultBlockParam 476 p.Type = r.Type 477 p.ToolUseID = r.ToolUseID 478 if r.Content.JSON.ErrorCode.Valid() { 479 p.Content.OfRequestWebFetchToolResultError = &BetaWebFetchToolResultErrorBlockParam{ 480 ErrorCode: r.Content.ErrorCode, 481 } 482 } else { 483 p.Content = param.Override[BetaWebFetchToolResultBlockParamContentUnion](json.RawMessage(r.Content.RawJSON())) 484 } 485 if r.JSON.Caller.Valid() { 486 p.Caller = r.Caller.toParam() 487 } 488 return p 489 } 490 491 func (r BetaMCPToolUseBlock) ToParam() BetaMCPToolUseBlockParam { 492 var p BetaMCPToolUseBlockParam 493 p.Type = r.Type 494 p.ID = r.ID 495 p.Input = r.Input 496 p.Name = r.Name 497 p.ServerName = r.ServerName 498 return p 499 } 500 501 func (r BetaContainerUploadBlock) ToParam() BetaContainerUploadBlockParam { 502 var p BetaContainerUploadBlockParam 503 p.Type = r.Type 504 p.FileID = r.FileID 505 return p 506 } 507 508 func (r BetaServerToolUseBlock) ToParam() BetaServerToolUseBlockParam { 509 var p BetaServerToolUseBlockParam 510 p.Type = r.Type 511 p.ID = r.ID 512 p.Input = r.Input 513 p.Name = BetaServerToolUseBlockParamName(r.Name) 514 if r.JSON.Caller.Valid() { 515 p.Caller = r.Caller.toParam() 516 } 517 return p 518 } 519 520 func (r BetaTextEditorCodeExecutionToolResultBlock) ToParam() BetaTextEditorCodeExecutionToolResultBlockParam { 521 var p BetaTextEditorCodeExecutionToolResultBlockParam 522 p.Type = r.Type 523 p.ToolUseID = r.ToolUseID 524 if r.Content.JSON.ErrorCode.Valid() { 525 p.Content.OfRequestTextEditorCodeExecutionToolResultError = &BetaTextEditorCodeExecutionToolResultErrorParam{ 526 ErrorCode: BetaTextEditorCodeExecutionToolResultErrorParamErrorCode(r.Content.ErrorCode), 527 ErrorMessage: paramutil.ToOpt(r.Content.ErrorMessage, r.Content.JSON.ErrorMessage), 528 } 529 } else { 530 p.Content = param.Override[BetaTextEditorCodeExecutionToolResultBlockParamContentUnion](json.RawMessage(r.Content.RawJSON())) 531 } 532 return p 533 } 534 535 func (r BetaMCPToolResultBlock) ToParam() BetaRequestMCPToolResultBlockParam { 536 var p BetaRequestMCPToolResultBlockParam 537 p.Type = r.Type 538 p.ToolUseID = r.ToolUseID 539 p.IsError = paramutil.ToOpt(r.IsError, r.JSON.IsError) 540 if r.Content.JSON.OfString.Valid() { 541 p.Content.OfString = paramutil.ToOpt(r.Content.OfString, r.Content.JSON.OfString) 542 } else if r.Content.JSON.OfBetaMCPToolResultBlockContent.Valid() { 543 // Send [] for an empty result rather than omitting content. 544 p.Content.OfBetaMCPToolResultBlockContent = make([]BetaTextBlockParam, 0, len(r.Content.OfBetaMCPToolResultBlockContent)) 545 for _, block := range r.Content.OfBetaMCPToolResultBlockContent { 546 p.Content.OfBetaMCPToolResultBlockContent = append(p.Content.OfBetaMCPToolResultBlockContent, block.ToParam()) 547 } 548 } 549 return p 550 } 551 552 func (r BetaBashCodeExecutionToolResultBlock) ToParam() BetaBashCodeExecutionToolResultBlockParam { 553 var p BetaBashCodeExecutionToolResultBlockParam 554 p.Type = r.Type 555 p.ToolUseID = r.ToolUseID 556 557 if r.Content.JSON.ErrorCode.Valid() { 558 p.Content.OfRequestBashCodeExecutionToolResultError = &BetaBashCodeExecutionToolResultErrorParam{ 559 ErrorCode: BetaBashCodeExecutionToolResultErrorParamErrorCode(r.Content.ErrorCode), 560 } 561 } else { 562 requestBashContentResult := &BetaBashCodeExecutionResultBlockParam{ 563 // content is required, so send [] rather than omitting it. 564 Content: make([]BetaBashCodeExecutionOutputBlockParam, 0, len(r.Content.Content)), 565 ReturnCode: r.Content.ReturnCode, 566 Stderr: r.Content.Stderr, 567 Stdout: r.Content.Stdout, 568 } 569 for _, block := range r.Content.Content { 570 requestBashContentResult.Content = append(requestBashContentResult.Content, block.ToParam()) 571 } 572 p.Content.OfRequestBashCodeExecutionResultBlock = requestBashContentResult 573 } 574 575 return p 576 } 577 578 func (r BetaBashCodeExecutionOutputBlock) ToParam() BetaBashCodeExecutionOutputBlockParam { 579 var p BetaBashCodeExecutionOutputBlockParam 580 p.Type = r.Type 581 p.FileID = r.FileID 582 return p 583 } 584 585 func (r BetaCodeExecutionToolResultBlock) ToParam() BetaCodeExecutionToolResultBlockParam { 586 var p BetaCodeExecutionToolResultBlockParam 587 p.Type = r.Type 588 p.ToolUseID = r.ToolUseID 589 // content is required, so send [] rather than omitting it. 590 files := make([]BetaCodeExecutionOutputBlockParam, 0, len(r.Content.Content)) 591 for _, block := range r.Content.Content { 592 files = append(files, block.ToParam()) 593 } 594 switch { 595 case r.Content.JSON.ErrorCode.Valid(): 596 p.Content.OfError = &BetaCodeExecutionToolResultErrorParam{ 597 ErrorCode: r.Content.ErrorCode, 598 } 599 case r.Content.JSON.EncryptedStdout.Valid(): 600 p.Content.OfRequestEncryptedCodeExecutionResultBlock = &BetaEncryptedCodeExecutionResultBlockParam{ 601 Content: files, 602 EncryptedStdout: r.Content.EncryptedStdout, 603 ReturnCode: r.Content.ReturnCode, 604 Stderr: r.Content.Stderr, 605 } 606 default: 607 p.Content.OfResultBlock = &BetaCodeExecutionResultBlockParam{ 608 Content: files, 609 ReturnCode: r.Content.ReturnCode, 610 Stderr: r.Content.Stderr, 611 Stdout: r.Content.Stdout, 612 } 613 } 614 return p 615 } 616 617 func (r BetaCodeExecutionOutputBlock) ToParam() BetaCodeExecutionOutputBlockParam { 618 var p BetaCodeExecutionOutputBlockParam 619 p.Type = r.Type 620 p.FileID = r.FileID 621 return p 622 } 623 624 func (r BetaToolSearchToolResultBlock) ToParam() BetaToolSearchToolResultBlockParam { 625 var p BetaToolSearchToolResultBlockParam 626 p.Type = r.Type 627 p.ToolUseID = r.ToolUseID 628 if r.Content.JSON.ErrorCode.Valid() { 629 p.Content.OfRequestToolSearchToolResultError = &BetaToolSearchToolResultErrorParam{ 630 ErrorCode: BetaToolSearchToolResultErrorParamErrorCode(r.Content.ErrorCode), 631 ErrorMessage: paramutil.ToOpt(r.Content.ErrorMessage, r.Content.JSON.ErrorMessage), 632 } 633 } else { 634 p.Content.OfRequestToolSearchToolSearchResultBlock = &BetaToolSearchToolSearchResultBlockParam{ 635 // tool_references is required, so send [] rather than omitting it. 636 ToolReferences: make([]BetaToolReferenceBlockParam, 0, len(r.Content.ToolReferences)), 637 } 638 for _, block := range r.Content.ToolReferences { 639 p.Content.OfRequestToolSearchToolSearchResultBlock.ToolReferences = append( 640 p.Content.OfRequestToolSearchToolSearchResultBlock.ToolReferences, 641 block.ToParam(), 642 ) 643 } 644 } 645 return p 646 } 647 648 func (r BetaToolReferenceBlock) ToParam() BetaToolReferenceBlockParam { 649 var p BetaToolReferenceBlockParam 650 p.Type = r.Type 651 p.ToolName = r.ToolName 652 return p 653 } 654 655 func (r BetaCompactionBlock) ToParam() BetaCompactionBlockParam { 656 var p BetaCompactionBlockParam 657 p.Type = r.Type 658 // A failed compaction has null content, which must stay null rather than 659 // become "". 660 p.Content = paramutil.ToOpt(r.Content, r.JSON.Content) 661 p.EncryptedContent = paramutil.ToOpt(r.EncryptedContent, r.JSON.EncryptedContent) 662 return p 663 } 664 665 func (r BetaFallbackBlock) ToParam() BetaFallbackBlockParam { 666 var p BetaFallbackBlockParam 667 p.Type = r.Type 668 p.From = BetaFallbackInfoParam{Model: r.From.Model} 669 p.To = BetaFallbackInfoParam{Model: r.To.Model} 670 if r.JSON.Trigger.Valid() { 671 p.Trigger = json.RawMessage(r.Trigger.RawJSON()) 672 } 673 return p 674 }