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	dataBytes, err := json.Marshal(struct {
 252		ToolCallID       string           `json:"tool_call_id"`
 253		ToolName         string           `json:"tool_name"`
 254		Input            string           `json:"input"`
 255		ProviderExecuted bool             `json:"provider_executed"`
 256		ProviderMetadata ProviderMetadata `json:"provider_metadata,omitempty"`
 257		Invalid          bool             `json:"invalid,omitempty"`
 258		ValidationError  error            `json:"validation_error,omitempty"`
 259	}{
 260		ToolCallID:       t.ToolCallID,
 261		ToolName:         t.ToolName,
 262		Input:            t.Input,
 263		ProviderExecuted: t.ProviderExecuted,
 264		ProviderMetadata: t.ProviderMetadata,
 265		Invalid:          t.Invalid,
 266		ValidationError:  t.ValidationError,
 267	})
 268	if err != nil {
 269		return nil, err
 270	}
 271
 272	return json.Marshal(contentJSON{
 273		Type: string(ContentTypeToolCall),
 274		Data: json.RawMessage(dataBytes),
 275	})
 276}
 277
 278// UnmarshalJSON implements json.Unmarshaler for ToolCallContent.
 279func (t *ToolCallContent) UnmarshalJSON(data []byte) error {
 280	var cj contentJSON
 281	if err := json.Unmarshal(data, &cj); err != nil {
 282		return err
 283	}
 284
 285	var aux struct {
 286		ToolCallID       string                     `json:"tool_call_id"`
 287		ToolName         string                     `json:"tool_name"`
 288		Input            string                     `json:"input"`
 289		ProviderExecuted bool                       `json:"provider_executed"`
 290		ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
 291		Invalid          bool                       `json:"invalid,omitempty"`
 292		ValidationError  error                      `json:"validation_error,omitempty"`
 293	}
 294
 295	if err := json.Unmarshal(cj.Data, &aux); err != nil {
 296		return err
 297	}
 298
 299	t.ToolCallID = aux.ToolCallID
 300	t.ToolName = aux.ToolName
 301	t.Input = aux.Input
 302	t.ProviderExecuted = aux.ProviderExecuted
 303	t.Invalid = aux.Invalid
 304	t.ValidationError = aux.ValidationError
 305
 306	if len(aux.ProviderMetadata) > 0 {
 307		metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
 308		if err != nil {
 309			return err
 310		}
 311		t.ProviderMetadata = metadata
 312	}
 313
 314	return nil
 315}
 316
 317// MarshalJSON implements json.Marshaler for ToolResultContent.
 318func (t ToolResultContent) MarshalJSON() ([]byte, error) {
 319	dataBytes, err := json.Marshal(struct {
 320		ToolCallID       string                  `json:"tool_call_id"`
 321		ToolName         string                  `json:"tool_name"`
 322		Result           ToolResultOutputContent `json:"result"`
 323		ClientMetadata   string                  `json:"client_metadata,omitempty"`
 324		ProviderExecuted bool                    `json:"provider_executed"`
 325		ProviderMetadata ProviderMetadata        `json:"provider_metadata,omitempty"`
 326	}{
 327		ToolCallID:       t.ToolCallID,
 328		ToolName:         t.ToolName,
 329		Result:           t.Result,
 330		ClientMetadata:   t.ClientMetadata,
 331		ProviderExecuted: t.ProviderExecuted,
 332		ProviderMetadata: t.ProviderMetadata,
 333	})
 334	if err != nil {
 335		return nil, err
 336	}
 337
 338	return json.Marshal(contentJSON{
 339		Type: string(ContentTypeToolResult),
 340		Data: json.RawMessage(dataBytes),
 341	})
 342}
 343
 344// UnmarshalJSON implements json.Unmarshaler for ToolResultContent.
 345func (t *ToolResultContent) UnmarshalJSON(data []byte) error {
 346	var cj contentJSON
 347	if err := json.Unmarshal(data, &cj); err != nil {
 348		return err
 349	}
 350
 351	var aux struct {
 352		ToolCallID       string                     `json:"tool_call_id"`
 353		ToolName         string                     `json:"tool_name"`
 354		Result           json.RawMessage            `json:"result"`
 355		ClientMetadata   string                     `json:"client_metadata,omitempty"`
 356		ProviderExecuted bool                       `json:"provider_executed"`
 357		ProviderMetadata map[string]json.RawMessage `json:"provider_metadata,omitempty"`
 358	}
 359
 360	if err := json.Unmarshal(cj.Data, &aux); err != nil {
 361		return err
 362	}
 363
 364	t.ToolCallID = aux.ToolCallID
 365	t.ToolName = aux.ToolName
 366	t.ClientMetadata = aux.ClientMetadata
 367	t.ProviderExecuted = aux.ProviderExecuted
 368
 369	// Unmarshal the Result field
 370	result, err := UnmarshalToolResultOutputContent(aux.Result)
 371	if err != nil {
 372		return fmt.Errorf("failed to unmarshal tool result output: %w", err)
 373	}
 374	t.Result = result
 375
 376	if len(aux.ProviderMetadata) > 0 {
 377		metadata, err := UnmarshalProviderMetadata(aux.ProviderMetadata)
 378		if err != nil {
 379			return err
 380		}
 381		t.ProviderMetadata = metadata
 382	}
 383
 384	return nil
 385}
 386
 387// MarshalJSON implements json.Marshaler for ToolResultOutputContentText.
 388func (t ToolResultOutputContentText) MarshalJSON() ([]byte, error) {
 389	dataBytes, err := json.Marshal(struct {
 390		Text string `json:"text"`
 391	}{
 392		Text: t.Text,
 393	})
 394	if err != nil {
 395		return nil, err
 396	}
 397
 398	return json.Marshal(toolResultOutputJSON{
 399		Type: string(ToolResultContentTypeText),
 400		Data: json.RawMessage(dataBytes),
 401	})
 402}
 403
 404// UnmarshalJSON implements json.Unmarshaler for ToolResultOutputContentText.
 405func (t *ToolResultOutputContentText) UnmarshalJSON(data []byte) error {
 406	var tr toolResultOutputJSON
 407	if err := json.Unmarshal(data, &tr); err != nil {
 408		return err
 409	}
 410
 411	var temp struct {
 412		Text string `json:"text"`
 413	}
 414
 415	if err := json.Unmarshal(tr.Data, &temp); err != nil {
 416		return err
 417	}
 418
 419	t.Text = temp.Text
 420	return nil
 421}
 422
 423// MarshalJSON implements json.Marshaler for ToolResultOutputContentError.
 424func (t ToolResultOutputContentError) MarshalJSON() ([]byte, error) {
 425	errMsg := ""
 426	if t.Error != nil {
 427		errMsg = t.Error.Error()
 428	}
 429	dataBytes, err := json.Marshal(struct {
 430		Error string `json:"error"`
 431	}{
 432		Error: errMsg,
 433	})
 434	if err != nil {
 435		return nil, err
 436	}
 437
 438	return json.Marshal(toolResultOutputJSON{
 439		Type: string(ToolResultContentTypeError),
 440		Data: json.RawMessage(dataBytes),
 441	})
 442}
 443
 444// UnmarshalJSON implements json.Unmarshaler for ToolResultOutputContentError.
 445func (t *ToolResultOutputContentError) UnmarshalJSON(data []byte) error {
 446	var tr toolResultOutputJSON
 447	if err := json.Unmarshal(data, &tr); err != nil {
 448		return err
 449	}
 450
 451	var temp struct {
 452		Error string `json:"error"`
 453	}
 454
 455	if err := json.Unmarshal(tr.Data, &temp); err != nil {
 456		return err
 457	}
 458	if temp.Error != "" {
 459		t.Error = errors.New(temp.Error)
 460	}
 461	return nil
 462}
 463
 464// MarshalJSON implements json.Marshaler for ToolResultOutputContentMedia.
 465func (t ToolResultOutputContentMedia) MarshalJSON() ([]byte, error) {
 466	dataBytes, err := json.Marshal(struct {
 467		Data      string `json:"data"`
 468		MediaType string `json:"media_type"`
 469	}{
 470		Data:      t.Data,
 471		MediaType: t.MediaType,
 472	})
 473	if err != nil {
 474		return nil, err
 475	}
 476
 477	return json.Marshal(toolResultOutputJSON{
 478		Type: string(ToolResultContentTypeMedia),
 479		Data: json.RawMessage(dataBytes),
 480	})
 481}
 482
 483// UnmarshalJSON implements json.Unmarshaler for ToolResultOutputContentMedia.
 484func (t *ToolResultOutputContentMedia) UnmarshalJSON(data []byte) error {
 485	var tr toolResultOutputJSON
 486	if err := json.Unmarshal(data, &tr); err != nil {
 487		return err
 488	}
 489
 490	var temp struct {
 491		Data      string `json:"data"`
 492		MediaType string `json:"media_type"`
 493	}
 494
 495	if err := json.Unmarshal(tr.Data, &temp); err != nil {
 496		return err
 497	}
 498
 499	t.Data = temp.Data
 500	t.MediaType = temp.MediaType
 501	return nil
 502}
 503
 504// MarshalJSON implements json.Marshaler for TextPart.
 505func (t TextPart) MarshalJSON() ([]byte, error) {
 506	dataBytes, err := json.Marshal(struct {
 507		Text            string          `json:"text"`
 508		ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
 509	}{
 510		Text:            t.Text,
 511		ProviderOptions: t.ProviderOptions,
 512	})
 513	if err != nil {
 514		return nil, err
 515	}
 516
 517	return json.Marshal(messagePartJSON{
 518		Type: string(ContentTypeText),
 519		Data: json.RawMessage(dataBytes),
 520	})
 521}
 522
 523// UnmarshalJSON implements json.Unmarshaler for TextPart.
 524func (t *TextPart) UnmarshalJSON(data []byte) error {
 525	var mpj messagePartJSON
 526	if err := json.Unmarshal(data, &mpj); err != nil {
 527		return err
 528	}
 529
 530	var aux struct {
 531		Text            string                     `json:"text"`
 532		ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
 533	}
 534
 535	if err := json.Unmarshal(mpj.Data, &aux); err != nil {
 536		return err
 537	}
 538
 539	t.Text = aux.Text
 540
 541	if len(aux.ProviderOptions) > 0 {
 542		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 543		if err != nil {
 544			return err
 545		}
 546		t.ProviderOptions = options
 547	}
 548
 549	return nil
 550}
 551
 552// MarshalJSON implements json.Marshaler for ReasoningPart.
 553func (r ReasoningPart) MarshalJSON() ([]byte, error) {
 554	dataBytes, err := json.Marshal(struct {
 555		Text            string          `json:"text"`
 556		ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
 557	}{
 558		Text:            r.Text,
 559		ProviderOptions: r.ProviderOptions,
 560	})
 561	if err != nil {
 562		return nil, err
 563	}
 564
 565	return json.Marshal(messagePartJSON{
 566		Type: string(ContentTypeReasoning),
 567		Data: json.RawMessage(dataBytes),
 568	})
 569}
 570
 571// UnmarshalJSON implements json.Unmarshaler for ReasoningPart.
 572func (r *ReasoningPart) UnmarshalJSON(data []byte) error {
 573	var mpj messagePartJSON
 574	if err := json.Unmarshal(data, &mpj); err != nil {
 575		return err
 576	}
 577
 578	var aux struct {
 579		Text            string                     `json:"text"`
 580		ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
 581	}
 582
 583	if err := json.Unmarshal(mpj.Data, &aux); err != nil {
 584		return err
 585	}
 586
 587	r.Text = aux.Text
 588
 589	if len(aux.ProviderOptions) > 0 {
 590		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 591		if err != nil {
 592			return err
 593		}
 594		r.ProviderOptions = options
 595	}
 596
 597	return nil
 598}
 599
 600// MarshalJSON implements json.Marshaler for FilePart.
 601func (f FilePart) MarshalJSON() ([]byte, error) {
 602	dataBytes, err := json.Marshal(struct {
 603		Filename        string          `json:"filename"`
 604		Data            []byte          `json:"data"`
 605		MediaType       string          `json:"media_type"`
 606		ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
 607	}{
 608		Filename:        f.Filename,
 609		Data:            f.Data,
 610		MediaType:       f.MediaType,
 611		ProviderOptions: f.ProviderOptions,
 612	})
 613	if err != nil {
 614		return nil, err
 615	}
 616
 617	return json.Marshal(messagePartJSON{
 618		Type: string(ContentTypeFile),
 619		Data: json.RawMessage(dataBytes),
 620	})
 621}
 622
 623// UnmarshalJSON implements json.Unmarshaler for FilePart.
 624func (f *FilePart) UnmarshalJSON(data []byte) error {
 625	var mpj messagePartJSON
 626	if err := json.Unmarshal(data, &mpj); err != nil {
 627		return err
 628	}
 629
 630	var aux struct {
 631		Filename        string                     `json:"filename"`
 632		Data            []byte                     `json:"data"`
 633		MediaType       string                     `json:"media_type"`
 634		ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
 635	}
 636
 637	if err := json.Unmarshal(mpj.Data, &aux); err != nil {
 638		return err
 639	}
 640
 641	f.Filename = aux.Filename
 642	f.Data = aux.Data
 643	f.MediaType = aux.MediaType
 644
 645	if len(aux.ProviderOptions) > 0 {
 646		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 647		if err != nil {
 648			return err
 649		}
 650		f.ProviderOptions = options
 651	}
 652
 653	return nil
 654}
 655
 656// MarshalJSON implements json.Marshaler for ToolCallPart.
 657func (t ToolCallPart) MarshalJSON() ([]byte, error) {
 658	dataBytes, err := json.Marshal(struct {
 659		ToolCallID       string          `json:"tool_call_id"`
 660		ToolName         string          `json:"tool_name"`
 661		Input            string          `json:"input"`
 662		ProviderExecuted bool            `json:"provider_executed"`
 663		ProviderOptions  ProviderOptions `json:"provider_options,omitempty"`
 664	}{
 665		ToolCallID:       t.ToolCallID,
 666		ToolName:         t.ToolName,
 667		Input:            t.Input,
 668		ProviderExecuted: t.ProviderExecuted,
 669		ProviderOptions:  t.ProviderOptions,
 670	})
 671	if err != nil {
 672		return nil, err
 673	}
 674
 675	return json.Marshal(messagePartJSON{
 676		Type: string(ContentTypeToolCall),
 677		Data: json.RawMessage(dataBytes),
 678	})
 679}
 680
 681// UnmarshalJSON implements json.Unmarshaler for ToolCallPart.
 682func (t *ToolCallPart) UnmarshalJSON(data []byte) error {
 683	var mpj messagePartJSON
 684	if err := json.Unmarshal(data, &mpj); err != nil {
 685		return err
 686	}
 687
 688	var aux struct {
 689		ToolCallID       string                     `json:"tool_call_id"`
 690		ToolName         string                     `json:"tool_name"`
 691		Input            string                     `json:"input"`
 692		ProviderExecuted bool                       `json:"provider_executed"`
 693		ProviderOptions  map[string]json.RawMessage `json:"provider_options,omitempty"`
 694	}
 695
 696	if err := json.Unmarshal(mpj.Data, &aux); err != nil {
 697		return err
 698	}
 699
 700	t.ToolCallID = aux.ToolCallID
 701	t.ToolName = aux.ToolName
 702	t.Input = aux.Input
 703	t.ProviderExecuted = aux.ProviderExecuted
 704
 705	if len(aux.ProviderOptions) > 0 {
 706		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 707		if err != nil {
 708			return err
 709		}
 710		t.ProviderOptions = options
 711	}
 712
 713	return nil
 714}
 715
 716// MarshalJSON implements json.Marshaler for ToolResultPart.
 717func (t ToolResultPart) MarshalJSON() ([]byte, error) {
 718	dataBytes, err := json.Marshal(struct {
 719		ToolCallID      string                  `json:"tool_call_id"`
 720		Output          ToolResultOutputContent `json:"output"`
 721		ProviderOptions ProviderOptions         `json:"provider_options,omitempty"`
 722	}{
 723		ToolCallID:      t.ToolCallID,
 724		Output:          t.Output,
 725		ProviderOptions: t.ProviderOptions,
 726	})
 727	if err != nil {
 728		return nil, err
 729	}
 730
 731	return json.Marshal(messagePartJSON{
 732		Type: string(ContentTypeToolResult),
 733		Data: json.RawMessage(dataBytes),
 734	})
 735}
 736
 737// UnmarshalJSON implements json.Unmarshaler for ToolResultPart.
 738func (t *ToolResultPart) UnmarshalJSON(data []byte) error {
 739	var mpj messagePartJSON
 740	if err := json.Unmarshal(data, &mpj); err != nil {
 741		return err
 742	}
 743
 744	var aux struct {
 745		ToolCallID      string                     `json:"tool_call_id"`
 746		Output          json.RawMessage            `json:"output"`
 747		ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
 748	}
 749
 750	if err := json.Unmarshal(mpj.Data, &aux); err != nil {
 751		return err
 752	}
 753
 754	t.ToolCallID = aux.ToolCallID
 755
 756	// Unmarshal the Output field
 757	output, err := UnmarshalToolResultOutputContent(aux.Output)
 758	if err != nil {
 759		return fmt.Errorf("failed to unmarshal tool result output: %w", err)
 760	}
 761	t.Output = output
 762
 763	if len(aux.ProviderOptions) > 0 {
 764		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 765		if err != nil {
 766			return err
 767		}
 768		t.ProviderOptions = options
 769	}
 770
 771	return nil
 772}
 773
 774// UnmarshalJSON implements json.Unmarshaler for Message.
 775func (m *Message) UnmarshalJSON(data []byte) error {
 776	var aux struct {
 777		Role            MessageRole                `json:"role"`
 778		Content         []json.RawMessage          `json:"content"`
 779		ProviderOptions map[string]json.RawMessage `json:"provider_options"`
 780	}
 781
 782	if err := json.Unmarshal(data, &aux); err != nil {
 783		return err
 784	}
 785
 786	m.Role = aux.Role
 787
 788	m.Content = make([]MessagePart, len(aux.Content))
 789	for i, rawPart := range aux.Content {
 790		part, err := UnmarshalMessagePart(rawPart)
 791		if err != nil {
 792			return fmt.Errorf("failed to unmarshal message part at index %d: %w", i, err)
 793		}
 794		m.Content[i] = part
 795	}
 796
 797	if len(aux.ProviderOptions) > 0 {
 798		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 799		if err != nil {
 800			return err
 801		}
 802		m.ProviderOptions = options
 803	}
 804
 805	return nil
 806}
 807
 808// MarshalJSON implements json.Marshaler for FunctionTool.
 809func (f FunctionTool) MarshalJSON() ([]byte, error) {
 810	dataBytes, err := json.Marshal(struct {
 811		Name            string          `json:"name"`
 812		Description     string          `json:"description"`
 813		InputSchema     map[string]any  `json:"input_schema"`
 814		ProviderOptions ProviderOptions `json:"provider_options,omitempty"`
 815	}{
 816		Name:            f.Name,
 817		Description:     f.Description,
 818		InputSchema:     f.InputSchema,
 819		ProviderOptions: f.ProviderOptions,
 820	})
 821	if err != nil {
 822		return nil, err
 823	}
 824
 825	return json.Marshal(toolJSON{
 826		Type: string(ToolTypeFunction),
 827		Data: json.RawMessage(dataBytes),
 828	})
 829}
 830
 831// UnmarshalJSON implements json.Unmarshaler for FunctionTool.
 832func (f *FunctionTool) UnmarshalJSON(data []byte) error {
 833	var tj toolJSON
 834	if err := json.Unmarshal(data, &tj); err != nil {
 835		return err
 836	}
 837
 838	var aux struct {
 839		Name            string                     `json:"name"`
 840		Description     string                     `json:"description"`
 841		InputSchema     map[string]any             `json:"input_schema"`
 842		ProviderOptions map[string]json.RawMessage `json:"provider_options,omitempty"`
 843	}
 844
 845	if err := json.Unmarshal(tj.Data, &aux); err != nil {
 846		return err
 847	}
 848
 849	f.Name = aux.Name
 850	f.Description = aux.Description
 851	f.InputSchema = aux.InputSchema
 852
 853	if len(aux.ProviderOptions) > 0 {
 854		options, err := UnmarshalProviderOptions(aux.ProviderOptions)
 855		if err != nil {
 856			return err
 857		}
 858		f.ProviderOptions = options
 859	}
 860
 861	return nil
 862}
 863
 864// MarshalJSON implements json.Marshaler for ProviderDefinedTool.
 865func (p ProviderDefinedTool) MarshalJSON() ([]byte, error) {
 866	dataBytes, err := json.Marshal(struct {
 867		ID   string         `json:"id"`
 868		Name string         `json:"name"`
 869		Args map[string]any `json:"args"`
 870	}{
 871		ID:   p.ID,
 872		Name: p.Name,
 873		Args: p.Args,
 874	})
 875	if err != nil {
 876		return nil, err
 877	}
 878
 879	return json.Marshal(toolJSON{
 880		Type: string(ToolTypeProviderDefined),
 881		Data: json.RawMessage(dataBytes),
 882	})
 883}
 884
 885// UnmarshalJSON implements json.Unmarshaler for ProviderDefinedTool.
 886func (p *ProviderDefinedTool) UnmarshalJSON(data []byte) error {
 887	var tj toolJSON
 888	if err := json.Unmarshal(data, &tj); err != nil {
 889		return err
 890	}
 891
 892	var aux struct {
 893		ID   string         `json:"id"`
 894		Name string         `json:"name"`
 895		Args map[string]any `json:"args"`
 896	}
 897
 898	if err := json.Unmarshal(tj.Data, &aux); err != nil {
 899		return err
 900	}
 901
 902	p.ID = aux.ID
 903	p.Name = aux.Name
 904	p.Args = aux.Args
 905
 906	return nil
 907}
 908
 909// UnmarshalTool unmarshals JSON into the appropriate Tool type.
 910func UnmarshalTool(data []byte) (Tool, error) {
 911	var tj toolJSON
 912	if err := json.Unmarshal(data, &tj); err != nil {
 913		return nil, err
 914	}
 915
 916	switch ToolType(tj.Type) {
 917	case ToolTypeFunction:
 918		var tool FunctionTool
 919		if err := tool.UnmarshalJSON(data); err != nil {
 920			return nil, err
 921		}
 922		return tool, nil
 923	case ToolTypeProviderDefined:
 924		var tool ProviderDefinedTool
 925		if err := tool.UnmarshalJSON(data); err != nil {
 926			return nil, err
 927		}
 928		return tool, nil
 929	default:
 930		return nil, fmt.Errorf("unknown tool type: %s", tj.Type)
 931	}
 932}
 933
 934// UnmarshalContent unmarshals JSON into the appropriate Content type.
 935func UnmarshalContent(data []byte) (Content, error) {
 936	var cj contentJSON
 937	if err := json.Unmarshal(data, &cj); err != nil {
 938		return nil, err
 939	}
 940
 941	switch ContentType(cj.Type) {
 942	case ContentTypeText:
 943		var content TextContent
 944		if err := content.UnmarshalJSON(data); err != nil {
 945			return nil, err
 946		}
 947		return content, nil
 948	case ContentTypeReasoning:
 949		var content ReasoningContent
 950		if err := content.UnmarshalJSON(data); err != nil {
 951			return nil, err
 952		}
 953		return content, nil
 954	case ContentTypeFile:
 955		var content FileContent
 956		if err := content.UnmarshalJSON(data); err != nil {
 957			return nil, err
 958		}
 959		return content, nil
 960	case ContentTypeSource:
 961		var content SourceContent
 962		if err := content.UnmarshalJSON(data); err != nil {
 963			return nil, err
 964		}
 965		return content, nil
 966	case ContentTypeToolCall:
 967		var content ToolCallContent
 968		if err := content.UnmarshalJSON(data); err != nil {
 969			return nil, err
 970		}
 971		return content, nil
 972	case ContentTypeToolResult:
 973		var content ToolResultContent
 974		if err := content.UnmarshalJSON(data); err != nil {
 975			return nil, err
 976		}
 977		return content, nil
 978	default:
 979		return nil, fmt.Errorf("unknown content type: %s", cj.Type)
 980	}
 981}
 982
 983// UnmarshalMessagePart unmarshals JSON into the appropriate MessagePart type.
 984func UnmarshalMessagePart(data []byte) (MessagePart, error) {
 985	var mpj messagePartJSON
 986	if err := json.Unmarshal(data, &mpj); err != nil {
 987		return nil, err
 988	}
 989
 990	switch ContentType(mpj.Type) {
 991	case ContentTypeText:
 992		var part TextPart
 993		if err := part.UnmarshalJSON(data); err != nil {
 994			return nil, err
 995		}
 996		return part, nil
 997	case ContentTypeReasoning:
 998		var part ReasoningPart
 999		if err := part.UnmarshalJSON(data); err != nil {
1000			return nil, err
1001		}
1002		return part, nil
1003	case ContentTypeFile:
1004		var part FilePart
1005		if err := part.UnmarshalJSON(data); err != nil {
1006			return nil, err
1007		}
1008		return part, nil
1009	case ContentTypeToolCall:
1010		var part ToolCallPart
1011		if err := part.UnmarshalJSON(data); err != nil {
1012			return nil, err
1013		}
1014		return part, nil
1015	case ContentTypeToolResult:
1016		var part ToolResultPart
1017		if err := part.UnmarshalJSON(data); err != nil {
1018			return nil, err
1019		}
1020		return part, nil
1021	default:
1022		return nil, fmt.Errorf("unknown message part type: %s", mpj.Type)
1023	}
1024}
1025
1026// UnmarshalToolResultOutputContent unmarshals JSON into the appropriate ToolResultOutputContent type.
1027func UnmarshalToolResultOutputContent(data []byte) (ToolResultOutputContent, error) {
1028	var troj toolResultOutputJSON
1029	if err := json.Unmarshal(data, &troj); err != nil {
1030		return nil, err
1031	}
1032
1033	switch ToolResultContentType(troj.Type) {
1034	case ToolResultContentTypeText:
1035		var content ToolResultOutputContentText
1036		if err := content.UnmarshalJSON(data); err != nil {
1037			return nil, err
1038		}
1039		return content, nil
1040	case ToolResultContentTypeError:
1041		var content ToolResultOutputContentError
1042		if err := content.UnmarshalJSON(data); err != nil {
1043			return nil, err
1044		}
1045		return content, nil
1046	case ToolResultContentTypeMedia:
1047		var content ToolResultOutputContentMedia
1048		if err := content.UnmarshalJSON(data); err != nil {
1049			return nil, err
1050		}
1051		return content, nil
1052	default:
1053		return nil, fmt.Errorf("unknown tool result output content type: %s", troj.Type)
1054	}
1055}