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