content_json.go

   1package fantasy
   2
   3import (
   4	"encoding/json"
   5	"errors"
   6	"fmt"
   7)
   8
   9// contentJSON is a helper type for JSON serialization of Content in Response.
  10type contentJSON struct {
  11	Type string          `json:"type"`
  12	Data json.RawMessage `json:"data"`
  13}
  14
  15// messagePartJSON is a helper type for JSON serialization of MessagePart.
  16type messagePartJSON struct {
  17	Type string          `json:"type"`
  18	Data json.RawMessage `json:"data"`
  19}
  20
  21// toolResultOutputJSON is a helper type for JSON serialization of ToolResultOutputContent.
  22type toolResultOutputJSON struct {
  23	Type string          `json:"type"`
  24	Data json.RawMessage `json:"data"`
  25}
  26
  27// toolJSON is a helper type for JSON serialization of Tool.
  28type toolJSON struct {
  29	Type string          `json:"type"`
  30	Data json.RawMessage `json:"data"`
  31}
  32
  33// MarshalJSON implements json.Marshaler for TextContent.
  34func (t TextContent) MarshalJSON() ([]byte, error) {
  35	dataBytes, err := json.Marshal(struct {
  36		Text             string           `json:"text"`
  37		ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
  38	}{
  39		Text:             t.Text,
  40		ProviderMetadata: t.ProviderMetadata,
  41	})
  42	if err != nil {
  43		return nil, err
  44	}
  45
  46	return json.Marshal(contentJSON{
  47		Type: string(ContentTypeText),
  48		Data: json.RawMessage(dataBytes),
  49	})
  50}
  51
  52// UnmarshalJSON implements json.Unmarshaler for TextContent.
  53func (t *TextContent) UnmarshalJSON(data []byte) error {
  54	var cj contentJSON
  55	if err := json.Unmarshal(data, &cj); err != nil {
  56		return err
  57	}
  58
  59	var aux struct {
  60		Text             string                     `json:"text"`
  61		ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
  62	}
  63
  64	if err := json.Unmarshal(cj.Data, &aux); err != nil {
  65		return err
  66	}
  67
  68	t.Text = aux.Text
  69
  70	if len(aux.ProviderMetadata) > 0 {
  71		metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
  72		if err != nil {
  73			return err
  74		}
  75		t.ProviderMetadata = metadata
  76	}
  77
  78	return nil
  79}
  80
  81// MarshalJSON implements json.Marshaler for ReasoningContent.
  82func (r ReasoningContent) MarshalJSON() ([]byte, error) {
  83	dataBytes, err := json.Marshal(struct {
  84		Text             string           `json:"text"`
  85		ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
  86	}{
  87		Text:             r.Text,
  88		ProviderMetadata: r.ProviderMetadata,
  89	})
  90	if err != nil {
  91		return nil, err
  92	}
  93
  94	return json.Marshal(contentJSON{
  95		Type: string(ContentTypeReasoning),
  96		Data: json.RawMessage(dataBytes),
  97	})
  98}
  99
 100// UnmarshalJSON implements json.Unmarshaler for ReasoningContent.
 101func (r *ReasoningContent) UnmarshalJSON(data []byte) error {
 102	var cj contentJSON
 103	if err := json.Unmarshal(data, &cj); err != nil {
 104		return err
 105	}
 106
 107	var aux struct {
 108		Text             string                     `json:"text"`
 109		ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
 110	}
 111
 112	if err := json.Unmarshal(cj.Data, &aux); err != nil {
 113		return err
 114	}
 115
 116	r.Text = aux.Text
 117
 118	if len(aux.ProviderMetadata) > 0 {
 119		metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
 120		if err != nil {
 121			return err
 122		}
 123		r.ProviderMetadata = metadata
 124	}
 125
 126	return nil
 127}
 128
 129// MarshalJSON implements json.Marshaler for FileContent.
 130func (f FileContent) MarshalJSON() ([]byte, error) {
 131	dataBytes, err := json.Marshal(struct {
 132		MediaType        string           `json:"media_type"`
 133		Data             []byte           `json:"data"`
 134		ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
 135	}{
 136		MediaType:        f.MediaType,
 137		Data:             f.Data,
 138		ProviderMetadata: f.ProviderMetadata,
 139	})
 140	if err != nil {
 141		return nil, err
 142	}
 143
 144	return json.Marshal(contentJSON{
 145		Type: string(ContentTypeFile),
 146		Data: json.RawMessage(dataBytes),
 147	})
 148}
 149
 150// UnmarshalJSON implements json.Unmarshaler for FileContent.
 151func (f *FileContent) UnmarshalJSON(data []byte) error {
 152	var cj contentJSON
 153	if err := json.Unmarshal(data, &cj); err != nil {
 154		return err
 155	}
 156
 157	var aux struct {
 158		MediaType        string                     `json:"media_type"`
 159		Data             []byte                     `json:"data"`
 160		ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
 161	}
 162
 163	if err := json.Unmarshal(cj.Data, &aux); err != nil {
 164		return err
 165	}
 166
 167	f.MediaType = aux.MediaType
 168	f.Data = aux.Data
 169
 170	if len(aux.ProviderMetadata) > 0 {
 171		metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
 172		if err != nil {
 173			return err
 174		}
 175		f.ProviderMetadata = metadata
 176	}
 177
 178	return nil
 179}
 180
 181// MarshalJSON implements json.Marshaler for SourceContent.
 182func (s SourceContent) MarshalJSON() ([]byte, error) {
 183	dataBytes, err := json.Marshal(struct {
 184		SourceType       SourceType       `json:"source_type"`
 185		ID               string           `json:"id"`
 186		URL              string           `json:"url,omitempty"`
 187		Title            string           `json:"title,omitempty"`
 188		MediaType        string           `json:"media_type,omitempty"`
 189		Filename         string           `json:"filename,omitempty"`
 190		ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
 191	}{
 192		SourceType:       s.SourceType,
 193		ID:               s.ID,
 194		URL:              s.URL,
 195		Title:            s.Title,
 196		MediaType:        s.MediaType,
 197		Filename:         s.Filename,
 198		ProviderMetadata: s.ProviderMetadata,
 199	})
 200	if err != nil {
 201		return nil, err
 202	}
 203
 204	return json.Marshal(contentJSON{
 205		Type: string(ContentTypeSource),
 206		Data: json.RawMessage(dataBytes),
 207	})
 208}
 209
 210// UnmarshalJSON implements json.Unmarshaler for SourceContent.
 211func (s *SourceContent) UnmarshalJSON(data []byte) error {
 212	var cj contentJSON
 213	if err := json.Unmarshal(data, &cj); err != nil {
 214		return err
 215	}
 216
 217	var aux struct {
 218		SourceType       SourceType                 `json:"source_type"`
 219		ID               string                     `json:"id"`
 220		URL              string                     `json:"url,omitempty"`
 221		Title            string                     `json:"title,omitempty"`
 222		MediaType        string                     `json:"media_type,omitempty"`
 223		Filename         string                     `json:"filename,omitempty"`
 224		ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
 225	}
 226
 227	if err := json.Unmarshal(cj.Data, &aux); err != nil {
 228		return err
 229	}
 230
 231	s.SourceType = aux.SourceType
 232	s.ID = aux.ID
 233	s.URL = aux.URL
 234	s.Title = aux.Title
 235	s.MediaType = aux.MediaType
 236	s.Filename = aux.Filename
 237
 238	if len(aux.ProviderMetadata) > 0 {
 239		metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
 240		if err != nil {
 241			return err
 242		}
 243		s.ProviderMetadata = metadata
 244	}
 245
 246	return nil
 247}
 248
 249// MarshalJSON implements json.Marshaler for ToolCallContent.
 250func (t ToolCallContent) MarshalJSON() ([]byte, error) {
 251	var validationErrMsg *string
 252	if t.ValidationError != nil {
 253		msg := t.ValidationError.Error()
 254		validationErrMsg = &msg
 255	}
 256	dataBytes, err := json.Marshal(struct {
 257		ToolCallID       string           `json:"tool_call_id"`
 258		ToolName         string           `json:"tool_name"`
 259		Input            string           `json:"input"`
 260		ProviderExecuted bool             `json:"provider_executed"`
 261		ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
 262		Invalid          bool             `json:"invalid,omitempty"`
 263		ValidationError  *string          `json:"validation_error,omitempty"`
 264	}{
 265		ToolCallID:       t.ToolCallID,
 266		ToolName:         t.ToolName,
 267		Input:            t.Input,
 268		ProviderExecuted: t.ProviderExecuted,
 269		ProviderMetadata: t.ProviderMetadata,
 270		Invalid:          t.Invalid,
 271		ValidationError:  validationErrMsg,
 272	})
 273	if err != nil {
 274		return nil, err
 275	}
 276
 277	return json.Marshal(contentJSON{
 278		Type: string(ContentTypeToolCall),
 279		Data: json.RawMessage(dataBytes),
 280	})
 281}
 282
 283// UnmarshalJSON implements json.Unmarshaler for ToolCallContent.
 284func (t *ToolCallContent) UnmarshalJSON(data []byte) error {
 285	var cj contentJSON
 286	if err := json.Unmarshal(data, &cj); err != nil {
 287		return err
 288	}
 289
 290	var aux struct {
 291		ToolCallID       string                     `json:"tool_call_id"`
 292		ToolName         string                     `json:"tool_name"`
 293		Input            string                     `json:"input"`
 294		ProviderExecuted bool                       `json:"provider_executed"`
 295		ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
 296		Invalid          bool                       `json:"invalid,omitempty"`
 297		ValidationError  *string                    `json:"validation_error,omitempty"`
 298	}
 299
 300	if err := json.Unmarshal(cj.Data, &aux); err != nil {
 301		return err
 302	}
 303
 304	t.ToolCallID = aux.ToolCallID
 305	t.ToolName = aux.ToolName
 306	t.Input = aux.Input
 307	t.ProviderExecuted = aux.ProviderExecuted
 308	t.Invalid = aux.Invalid
 309	if aux.ValidationError != nil {
 310		t.ValidationError = errors.New(*aux.ValidationError)
 311	}
 312
 313	if len(aux.ProviderMetadata) > 0 {
 314		metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
 315		if err != nil {
 316			return err
 317		}
 318		t.ProviderMetadata = metadata
 319	}
 320
 321	return nil
 322}
 323
 324// MarshalJSON implements json.Marshaler for ToolResultContent.
 325func (t ToolResultContent) MarshalJSON() ([]byte, error) {
 326	dataBytes, err := json.Marshal(struct {
 327		ToolCallID       string                  `json:"tool_call_id"`
 328		ToolName         string                  `json:"tool_name"`
 329		Result           ToolResultOutputContent `json:"result"`
 330		ClientMetadata   string                  `json:"client_metadata,omitempty"`
 331		ProviderExecuted bool                    `json:"provider_executed"`
 332		ProviderMetadata ProviderMetadata        `json:"provider_metadata,omitempty"`
 333	}{
 334		ToolCallID:       t.ToolCallID,
 335		ToolName:         t.ToolName,
 336		Result:           t.Result,
 337		ClientMetadata:   t.ClientMetadata,
 338		ProviderExecuted: t.ProviderExecuted,
 339		ProviderMetadata: t.ProviderMetadata,
 340	})
 341	if err != nil {
 342		return nil, err
 343	}
 344
 345	return json.Marshal(contentJSON{
 346		Type: string(ContentTypeToolResult),
 347		Data: json.RawMessage(dataBytes),
 348	})
 349}
 350
 351// UnmarshalJSON implements json.Unmarshaler for ToolResultContent.
 352func (t *ToolResultContent) UnmarshalJSON(data []byte) error {
 353	var cj contentJSON
 354	if err := json.Unmarshal(data, &cj); err != nil {
 355		return err
 356	}
 357
 358	var aux struct {
 359		ToolCallID       string                     `json:"tool_call_id"`
 360		ToolName         string                     `json:"tool_name"`
 361		Result           json.RawMessage            `json:"result"`
 362		ClientMetadata   string                     `json:"client_metadata,omitempty"`
 363		ProviderExecuted bool                       `json:"provider_executed"`
 364		ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
 365	}
 366
 367	if err := json.Unmarshal(cj.Data, &aux); err != nil {
 368		return err
 369	}
 370
 371	t.ToolCallID = aux.ToolCallID
 372	t.ToolName = aux.ToolName
 373	t.ClientMetadata = aux.ClientMetadata
 374	t.ProviderExecuted = aux.ProviderExecuted
 375
 376	// Unmarshal the Result field
 377	result, err := UnmarshalToolResultOutputContent(aux.Result)
 378	if err != nil {
 379		return fmt.Errorf("failed to unmarshal tool result output: %w", err)
 380	}
 381	t.Result = result
 382
 383	if len(aux.ProviderMetadata) > 0 {
 384		metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
 385		if err != nil {
 386			return err
 387		}
 388		t.ProviderMetadata = metadata
 389	}
 390
 391	return nil
 392}
 393
 394// MarshalJSON implements json.Marshaler for ToolResultOutputContentText.
 395func (t ToolResultOutputContentText) MarshalJSON() ([]byte, error) {
 396	dataBytes, err := json.Marshal(struct {
 397		Text string `json:"text"`
 398	}{
 399		Text: t.Text,
 400	})
 401	if err != nil {
 402		return nil, err
 403	}
 404
 405	return json.Marshal(toolResultOutputJSON{
 406		Type: string(ToolResultContentTypeText),
 407		Data: json.RawMessage(dataBytes),
 408	})
 409}
 410
 411// UnmarshalJSON implements json.Unmarshaler for ToolResultOutputContentText.
 412func (t *ToolResultOutputContentText) UnmarshalJSON(data []byte) error {
 413	var tr toolResultOutputJSON
 414	if err := json.Unmarshal(data, &tr); err != nil {
 415		return err
 416	}
 417
 418	var temp struct {
 419		Text string `json:"text"`
 420	}
 421
 422	if err := json.Unmarshal(tr.Data, &temp); err != nil {
 423		return err
 424	}
 425
 426	t.Text = temp.Text
 427	return nil
 428}
 429
 430// MarshalJSON implements json.Marshaler for ToolResultOutputContentError.
 431func (t ToolResultOutputContentError) MarshalJSON() ([]byte, error) {
 432	errMsg := ""
 433	if t.Error != nil {
 434		errMsg = t.Error.Error()
 435	}
 436	dataBytes, err := json.Marshal(struct {
 437		Error string `json:"error"`
 438	}{
 439		Error: errMsg,
 440	})
 441	if err != nil {
 442		return nil, err
 443	}
 444
 445	return json.Marshal(toolResultOutputJSON{
 446		Type: string(ToolResultContentTypeError),
 447		Data: json.RawMessage(dataBytes),
 448	})
 449}
 450
 451// UnmarshalJSON implements json.Unmarshaler for ToolResultOutputContentError.
 452func (t *ToolResultOutputContentError) UnmarshalJSON(data []byte) error {
 453	var tr toolResultOutputJSON
 454	if err := json.Unmarshal(data, &tr); err != nil {
 455		return err
 456	}
 457
 458	var temp struct {
 459		Error string `json:"error"`
 460	}
 461
 462	if err := json.Unmarshal(tr.Data, &temp); err != nil {
 463		return err
 464	}
 465	if temp.Error != "" {
 466		t.Error = errors.New(temp.Error)
 467	}
 468	return nil
 469}
 470
 471// MarshalJSON implements json.Marshaler for ToolResultOutputContentMedia.
 472func (t ToolResultOutputContentMedia) MarshalJSON() ([]byte, error) {
 473	dataBytes, err := json.Marshal(struct {
 474		Data      string `json:"data"`
 475		MediaType string `json:"media_type"`
 476	}{
 477		Data:      t.Data,
 478		MediaType: t.MediaType,
 479	})
 480	if err != nil {
 481		return nil, err
 482	}
 483
 484	return json.Marshal(toolResultOutputJSON{
 485		Type: string(ToolResultContentTypeMedia),
 486		Data: json.RawMessage(dataBytes),
 487	})
 488}
 489
 490// UnmarshalJSON implements json.Unmarshaler for ToolResultOutputContentMedia.
 491func (t *ToolResultOutputContentMedia) UnmarshalJSON(data []byte) error {
 492	var tr toolResultOutputJSON
 493	if err := json.Unmarshal(data, &tr); err != nil {
 494		return err
 495	}
 496
 497	var temp struct {
 498		Data      string `json:"data"`
 499		MediaType string `json:"media_type"`
 500	}
 501
 502	if err := json.Unmarshal(tr.Data, &temp); err != nil {
 503		return err
 504	}
 505
 506	t.Data = temp.Data
 507	t.MediaType = temp.MediaType
 508	return nil
 509}
 510
 511// MarshalJSON implements json.Marshaler for TextPart.
 512func (t TextPart) MarshalJSON() ([]byte, error) {
 513	dataBytes, err := json.Marshal(struct {
 514		Text            string          `json:"text"`
 515		ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
 516	}{
 517		Text:            t.Text,
 518		ProviderOptions: t.ProviderOptions,
 519	})
 520	if err != nil {
 521		return nil, err
 522	}
 523
 524	return json.Marshal(messagePartJSON{
 525		Type: string(ContentTypeText),
 526		Data: json.RawMessage(dataBytes),
 527	})
 528}
 529
 530// UnmarshalJSON implements json.Unmarshaler for TextPart.
 531func (t *TextPart) UnmarshalJSON(data []byte) error {
 532	var mpj messagePartJSON
 533	if err := json.Unmarshal(data, &mpj); err != nil {
 534		return err
 535	}
 536
 537	var aux struct {
 538		Text            string                     `json:"text"`
 539		ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
 540	}
 541
 542	if err := json.Unmarshal(mpj.Data, &aux); err != nil {
 543		return err
 544	}
 545
 546	t.Text = aux.Text
 547
 548	if len(aux.ProviderOptions) > 0 {
 549		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 550		if err != nil {
 551			return err
 552		}
 553		t.ProviderOptions = options
 554	}
 555
 556	return nil
 557}
 558
 559// MarshalJSON implements json.Marshaler for ReasoningPart.
 560func (r ReasoningPart) MarshalJSON() ([]byte, error) {
 561	dataBytes, err := json.Marshal(struct {
 562		Text            string          `json:"text"`
 563		ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
 564	}{
 565		Text:            r.Text,
 566		ProviderOptions: r.ProviderOptions,
 567	})
 568	if err != nil {
 569		return nil, err
 570	}
 571
 572	return json.Marshal(messagePartJSON{
 573		Type: string(ContentTypeReasoning),
 574		Data: json.RawMessage(dataBytes),
 575	})
 576}
 577
 578// UnmarshalJSON implements json.Unmarshaler for ReasoningPart.
 579func (r *ReasoningPart) UnmarshalJSON(data []byte) error {
 580	var mpj messagePartJSON
 581	if err := json.Unmarshal(data, &mpj); err != nil {
 582		return err
 583	}
 584
 585	var aux struct {
 586		Text            string                     `json:"text"`
 587		ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
 588	}
 589
 590	if err := json.Unmarshal(mpj.Data, &aux); err != nil {
 591		return err
 592	}
 593
 594	r.Text = aux.Text
 595
 596	if len(aux.ProviderOptions) > 0 {
 597		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 598		if err != nil {
 599			return err
 600		}
 601		r.ProviderOptions = options
 602	}
 603
 604	return nil
 605}
 606
 607// MarshalJSON implements json.Marshaler for FilePart.
 608func (f FilePart) MarshalJSON() ([]byte, error) {
 609	dataBytes, err := json.Marshal(struct {
 610		Filename        string          `json:"filename"`
 611		Data            []byte          `json:"data"`
 612		MediaType       string          `json:"media_type"`
 613		ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
 614	}{
 615		Filename:        f.Filename,
 616		Data:            f.Data,
 617		MediaType:       f.MediaType,
 618		ProviderOptions: f.ProviderOptions,
 619	})
 620	if err != nil {
 621		return nil, err
 622	}
 623
 624	return json.Marshal(messagePartJSON{
 625		Type: string(ContentTypeFile),
 626		Data: json.RawMessage(dataBytes),
 627	})
 628}
 629
 630// UnmarshalJSON implements json.Unmarshaler for FilePart.
 631func (f *FilePart) UnmarshalJSON(data []byte) error {
 632	var mpj messagePartJSON
 633	if err := json.Unmarshal(data, &mpj); err != nil {
 634		return err
 635	}
 636
 637	var aux struct {
 638		Filename        string                     `json:"filename"`
 639		Data            []byte                     `json:"data"`
 640		MediaType       string                     `json:"media_type"`
 641		ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
 642	}
 643
 644	if err := json.Unmarshal(mpj.Data, &aux); err != nil {
 645		return err
 646	}
 647
 648	f.Filename = aux.Filename
 649	f.Data = aux.Data
 650	f.MediaType = aux.MediaType
 651
 652	if len(aux.ProviderOptions) > 0 {
 653		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 654		if err != nil {
 655			return err
 656		}
 657		f.ProviderOptions = options
 658	}
 659
 660	return nil
 661}
 662
 663// MarshalJSON implements json.Marshaler for ToolCallPart.
 664func (t ToolCallPart) MarshalJSON() ([]byte, error) {
 665	dataBytes, err := json.Marshal(struct {
 666		ToolCallID       string          `json:"tool_call_id"`
 667		ToolName         string          `json:"tool_name"`
 668		Input            string          `json:"input"`
 669		ProviderExecuted bool            `json:"provider_executed"`
 670		ProviderOptions  ProviderOptions `json:"provider_options,omitempty"`
 671	}{
 672		ToolCallID:       t.ToolCallID,
 673		ToolName:         t.ToolName,
 674		Input:            t.Input,
 675		ProviderExecuted: t.ProviderExecuted,
 676		ProviderOptions:  t.ProviderOptions,
 677	})
 678	if err != nil {
 679		return nil, err
 680	}
 681
 682	return json.Marshal(messagePartJSON{
 683		Type: string(ContentTypeToolCall),
 684		Data: json.RawMessage(dataBytes),
 685	})
 686}
 687
 688// UnmarshalJSON implements json.Unmarshaler for ToolCallPart.
 689func (t *ToolCallPart) UnmarshalJSON(data []byte) error {
 690	var mpj messagePartJSON
 691	if err := json.Unmarshal(data, &mpj); err != nil {
 692		return err
 693	}
 694
 695	var aux struct {
 696		ToolCallID       string                     `json:"tool_call_id"`
 697		ToolName         string                     `json:"tool_name"`
 698		Input            string                     `json:"input"`
 699		ProviderExecuted bool                       `json:"provider_executed"`
 700		ProviderOptions  map[string]json.RawMessage `json:"provider_options,omitempty"`
 701	}
 702
 703	if err := json.Unmarshal(mpj.Data, &aux); err != nil {
 704		return err
 705	}
 706
 707	t.ToolCallID = aux.ToolCallID
 708	t.ToolName = aux.ToolName
 709	t.Input = aux.Input
 710	t.ProviderExecuted = aux.ProviderExecuted
 711
 712	if len(aux.ProviderOptions) > 0 {
 713		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 714		if err != nil {
 715			return err
 716		}
 717		t.ProviderOptions = options
 718	}
 719
 720	return nil
 721}
 722
 723// MarshalJSON implements json.Marshaler for ToolResultPart.
 724func (t ToolResultPart) MarshalJSON() ([]byte, error) {
 725	dataBytes, err := json.Marshal(struct {
 726		ToolCallID      string                  `json:"tool_call_id"`
 727		Output          ToolResultOutputContent `json:"output"`
 728		ProviderOptions ProviderOptions         `json:"provider_options,omitempty"`
 729	}{
 730		ToolCallID:      t.ToolCallID,
 731		Output:          t.Output,
 732		ProviderOptions: t.ProviderOptions,
 733	})
 734	if err != nil {
 735		return nil, err
 736	}
 737
 738	return json.Marshal(messagePartJSON{
 739		Type: string(ContentTypeToolResult),
 740		Data: json.RawMessage(dataBytes),
 741	})
 742}
 743
 744// UnmarshalJSON implements json.Unmarshaler for ToolResultPart.
 745func (t *ToolResultPart) UnmarshalJSON(data []byte) error {
 746	var mpj messagePartJSON
 747	if err := json.Unmarshal(data, &mpj); err != nil {
 748		return err
 749	}
 750
 751	var aux struct {
 752		ToolCallID      string                     `json:"tool_call_id"`
 753		Output          json.RawMessage            `json:"output"`
 754		ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
 755	}
 756
 757	if err := json.Unmarshal(mpj.Data, &aux); err != nil {
 758		return err
 759	}
 760
 761	t.ToolCallID = aux.ToolCallID
 762
 763	// Unmarshal the Output field
 764	output, err := UnmarshalToolResultOutputContent(aux.Output)
 765	if err != nil {
 766		return fmt.Errorf("failed to unmarshal tool result output: %w", err)
 767	}
 768	t.Output = output
 769
 770	if len(aux.ProviderOptions) > 0 {
 771		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 772		if err != nil {
 773			return err
 774		}
 775		t.ProviderOptions = options
 776	}
 777
 778	return nil
 779}
 780
 781// UnmarshalJSON implements json.Unmarshaler for Message.
 782func (m *Message) UnmarshalJSON(data []byte) error {
 783	var aux struct {
 784		Role            MessageRole                `json:"role"`
 785		Content         []json.RawMessage          `json:"content"`
 786		ProviderOptions map[string]json.RawMessage `json:"provider_options"`
 787	}
 788
 789	if err := json.Unmarshal(data, &aux); err != nil {
 790		return err
 791	}
 792
 793	m.Role = aux.Role
 794
 795	m.Content = make([]MessagePart, len(aux.Content))
 796	for i, rawPart := range aux.Content {
 797		part, err := UnmarshalMessagePart(rawPart)
 798		if err != nil {
 799			return fmt.Errorf("failed to unmarshal message part at index %d: %w", i, err)
 800		}
 801		m.Content[i] = part
 802	}
 803
 804	if len(aux.ProviderOptions) > 0 {
 805		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 806		if err != nil {
 807			return err
 808		}
 809		m.ProviderOptions = options
 810	}
 811
 812	return nil
 813}
 814
 815// MarshalJSON implements json.Marshaler for FunctionTool.
 816func (f FunctionTool) MarshalJSON() ([]byte, error) {
 817	dataBytes, err := json.Marshal(struct {
 818		Name            string          `json:"name"`
 819		Description     string          `json:"description"`
 820		InputSchema     map[string]any  `json:"input_schema"`
 821		ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
 822	}{
 823		Name:            f.Name,
 824		Description:     f.Description,
 825		InputSchema:     f.InputSchema,
 826		ProviderOptions: f.ProviderOptions,
 827	})
 828	if err != nil {
 829		return nil, err
 830	}
 831
 832	return json.Marshal(toolJSON{
 833		Type: string(ToolTypeFunction),
 834		Data: json.RawMessage(dataBytes),
 835	})
 836}
 837
 838// UnmarshalJSON implements json.Unmarshaler for FunctionTool.
 839func (f *FunctionTool) UnmarshalJSON(data []byte) error {
 840	var tj toolJSON
 841	if err := json.Unmarshal(data, &tj); err != nil {
 842		return err
 843	}
 844
 845	var aux struct {
 846		Name            string                     `json:"name"`
 847		Description     string                     `json:"description"`
 848		InputSchema     map[string]any             `json:"input_schema"`
 849		ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
 850	}
 851
 852	if err := json.Unmarshal(tj.Data, &aux); err != nil {
 853		return err
 854	}
 855
 856	f.Name = aux.Name
 857	f.Description = aux.Description
 858	f.InputSchema = aux.InputSchema
 859
 860	if len(aux.ProviderOptions) > 0 {
 861		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 862		if err != nil {
 863			return err
 864		}
 865		f.ProviderOptions = options
 866	}
 867
 868	return nil
 869}
 870
 871// MarshalJSON implements json.Marshaler for ProviderDefinedTool.
 872func (p ProviderDefinedTool) MarshalJSON() ([]byte, error) {
 873	dataBytes, err := json.Marshal(struct {
 874		ID   string         `json:"id"`
 875		Name string         `json:"name"`
 876		Args map[string]any `json:"args"`
 877	}{
 878		ID:   p.ID,
 879		Name: p.Name,
 880		Args: p.Args,
 881	})
 882	if err != nil {
 883		return nil, err
 884	}
 885
 886	return json.Marshal(toolJSON{
 887		Type: string(ToolTypeProviderDefined),
 888		Data: json.RawMessage(dataBytes),
 889	})
 890}
 891
 892// UnmarshalJSON implements json.Unmarshaler for ProviderDefinedTool.
 893func (p *ProviderDefinedTool) UnmarshalJSON(data []byte) error {
 894	var tj toolJSON
 895	if err := json.Unmarshal(data, &tj); err != nil {
 896		return err
 897	}
 898
 899	var aux struct {
 900		ID   string         `json:"id"`
 901		Name string         `json:"name"`
 902		Args map[string]any `json:"args"`
 903	}
 904
 905	if err := json.Unmarshal(tj.Data, &aux); err != nil {
 906		return err
 907	}
 908
 909	p.ID = aux.ID
 910	p.Name = aux.Name
 911	p.Args = aux.Args
 912
 913	return nil
 914}
 915
 916// UnmarshalTool unmarshals JSON into the appropriate Tool type.
 917func UnmarshalTool(data []byte) (Tool, error) {
 918	var tj toolJSON
 919	if err := json.Unmarshal(data, &tj); err != nil {
 920		return nil, err
 921	}
 922
 923	switch ToolType(tj.Type) {
 924	case ToolTypeFunction:
 925		var tool FunctionTool
 926		if err := tool.UnmarshalJSON(data); err != nil {
 927			return nil, err
 928		}
 929		return tool, nil
 930	case ToolTypeProviderDefined:
 931		var tool ProviderDefinedTool
 932		if err := tool.UnmarshalJSON(data); err != nil {
 933			return nil, err
 934		}
 935		return tool, nil
 936	default:
 937		return nil, fmt.Errorf("unknown tool type: %s", tj.Type)
 938	}
 939}
 940
 941// UnmarshalContent unmarshals JSON into the appropriate Content type.
 942func UnmarshalContent(data []byte) (Content, error) {
 943	var cj contentJSON
 944	if err := json.Unmarshal(data, &cj); err != nil {
 945		return nil, err
 946	}
 947
 948	switch ContentType(cj.Type) {
 949	case ContentTypeText:
 950		var content TextContent
 951		if err := content.UnmarshalJSON(data); err != nil {
 952			return nil, err
 953		}
 954		return content, nil
 955	case ContentTypeReasoning:
 956		var content ReasoningContent
 957		if err := content.UnmarshalJSON(data); err != nil {
 958			return nil, err
 959		}
 960		return content, nil
 961	case ContentTypeFile:
 962		var content FileContent
 963		if err := content.UnmarshalJSON(data); err != nil {
 964			return nil, err
 965		}
 966		return content, nil
 967	case ContentTypeSource:
 968		var content SourceContent
 969		if err := content.UnmarshalJSON(data); err != nil {
 970			return nil, err
 971		}
 972		return content, nil
 973	case ContentTypeToolCall:
 974		var content ToolCallContent
 975		if err := content.UnmarshalJSON(data); err != nil {
 976			return nil, err
 977		}
 978		return content, nil
 979	case ContentTypeToolResult:
 980		var content ToolResultContent
 981		if err := content.UnmarshalJSON(data); err != nil {
 982			return nil, err
 983		}
 984		return content, nil
 985	default:
 986		return nil, fmt.Errorf("unknown content type: %s", cj.Type)
 987	}
 988}
 989
 990// UnmarshalMessagePart unmarshals JSON into the appropriate MessagePart type.
 991func UnmarshalMessagePart(data []byte) (MessagePart, error) {
 992	var mpj messagePartJSON
 993	if err := json.Unmarshal(data, &mpj); err != nil {
 994		return nil, err
 995	}
 996
 997	switch ContentType(mpj.Type) {
 998	case ContentTypeText:
 999		var part TextPart
1000		if err := part.UnmarshalJSON(data); err != nil {
1001			return nil, err
1002		}
1003		return part, nil
1004	case ContentTypeReasoning:
1005		var part ReasoningPart
1006		if err := part.UnmarshalJSON(data); err != nil {
1007			return nil, err
1008		}
1009		return part, nil
1010	case ContentTypeFile:
1011		var part FilePart
1012		if err := part.UnmarshalJSON(data); err != nil {
1013			return nil, err
1014		}
1015		return part, nil
1016	case ContentTypeToolCall:
1017		var part ToolCallPart
1018		if err := part.UnmarshalJSON(data); err != nil {
1019			return nil, err
1020		}
1021		return part, nil
1022	case ContentTypeToolResult:
1023		var part ToolResultPart
1024		if err := part.UnmarshalJSON(data); err != nil {
1025			return nil, err
1026		}
1027		return part, nil
1028	default:
1029		return nil, fmt.Errorf("unknown message part type: %s", mpj.Type)
1030	}
1031}
1032
1033// UnmarshalToolResultOutputContent unmarshals JSON into the appropriate ToolResultOutputContent type.
1034func UnmarshalToolResultOutputContent(data []byte) (ToolResultOutputContent, error) {
1035	var troj toolResultOutputJSON
1036	if err := json.Unmarshal(data, &troj); err != nil {
1037		return nil, err
1038	}
1039
1040	switch ToolResultContentType(troj.Type) {
1041	case ToolResultContentTypeText:
1042		var content ToolResultOutputContentText
1043		if err := content.UnmarshalJSON(data); err != nil {
1044			return nil, err
1045		}
1046		return content, nil
1047	case ToolResultContentTypeError:
1048		var content ToolResultOutputContentError
1049		if err := content.UnmarshalJSON(data); err != nil {
1050			return nil, err
1051		}
1052		return content, nil
1053	case ToolResultContentTypeMedia:
1054		var content ToolResultOutputContentMedia
1055		if err := content.UnmarshalJSON(data); err != nil {
1056			return nil, err
1057		}
1058		return content, nil
1059	default:
1060		return nil, fmt.Errorf("unknown tool result output content type: %s", troj.Type)
1061	}
1062}