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}