opencodekit 0.18.19 → 0.18.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/template/.opencode/memory.db +0 -0
- package/dist/template/.opencode/memory.db-shm +0 -0
- package/dist/template/.opencode/memory.db-wal +0 -0
- package/dist/template/.opencode/opencode.json +395 -101
- package/dist/template/.opencode/plugin/copilot-auth.ts +113 -45
- package/dist/template/.opencode/plugin/lib/memory-hooks.ts +31 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -40,26 +40,65 @@
|
|
|
40
40
|
"autoupdate": false,
|
|
41
41
|
"formatter": {
|
|
42
42
|
"biome": {
|
|
43
|
-
"command": [
|
|
44
|
-
|
|
43
|
+
"command": [
|
|
44
|
+
"npx",
|
|
45
|
+
"@biomejs/biome",
|
|
46
|
+
"check",
|
|
47
|
+
"--write",
|
|
48
|
+
"$FILE"
|
|
49
|
+
],
|
|
50
|
+
"extensions": [
|
|
51
|
+
".js",
|
|
52
|
+
".jsx",
|
|
53
|
+
".ts",
|
|
54
|
+
".tsx",
|
|
55
|
+
".json",
|
|
56
|
+
".jsonc"
|
|
57
|
+
]
|
|
45
58
|
},
|
|
46
59
|
"cargo-fmt": {
|
|
47
|
-
"command": [
|
|
48
|
-
|
|
60
|
+
"command": [
|
|
61
|
+
"cargo",
|
|
62
|
+
"fmt",
|
|
63
|
+
"--",
|
|
64
|
+
"$FILE"
|
|
65
|
+
],
|
|
66
|
+
"extensions": [
|
|
67
|
+
".rs"
|
|
68
|
+
]
|
|
49
69
|
},
|
|
50
70
|
"java-formatter": {
|
|
51
|
-
"command": [
|
|
71
|
+
"command": [
|
|
72
|
+
"google-java-format",
|
|
73
|
+
"--replace",
|
|
74
|
+
"$FILE"
|
|
75
|
+
],
|
|
52
76
|
"environment": {
|
|
53
77
|
"JAVA_HOME": "{env:JAVA_HOME}"
|
|
54
78
|
},
|
|
55
|
-
"extensions": [
|
|
79
|
+
"extensions": [
|
|
80
|
+
".java"
|
|
81
|
+
]
|
|
56
82
|
},
|
|
57
83
|
"laravel-pint": {
|
|
58
|
-
"command": [
|
|
59
|
-
|
|
84
|
+
"command": [
|
|
85
|
+
"npx",
|
|
86
|
+
"laravel-pint",
|
|
87
|
+
"--preset",
|
|
88
|
+
"psr12",
|
|
89
|
+
"$FILE"
|
|
90
|
+
],
|
|
91
|
+
"extensions": [
|
|
92
|
+
".php"
|
|
93
|
+
]
|
|
60
94
|
},
|
|
61
95
|
"oxfmt": {
|
|
62
|
-
"command": [
|
|
96
|
+
"command": [
|
|
97
|
+
"npx",
|
|
98
|
+
"oxfmt",
|
|
99
|
+
"--write",
|
|
100
|
+
"$FILE"
|
|
101
|
+
],
|
|
63
102
|
"extensions": [
|
|
64
103
|
".js",
|
|
65
104
|
".jsx",
|
|
@@ -101,7 +140,13 @@
|
|
|
101
140
|
"url": "https://stitch.googleapis.com/mcp"
|
|
102
141
|
},
|
|
103
142
|
"tilth": {
|
|
104
|
-
"command": [
|
|
143
|
+
"command": [
|
|
144
|
+
"npx",
|
|
145
|
+
"-y",
|
|
146
|
+
"tilth",
|
|
147
|
+
"--mcp",
|
|
148
|
+
"--edit"
|
|
149
|
+
],
|
|
105
150
|
"enabled": true,
|
|
106
151
|
"timeout": 60000,
|
|
107
152
|
"type": "local"
|
|
@@ -409,7 +454,8 @@
|
|
|
409
454
|
"attachment": true,
|
|
410
455
|
"limit": {
|
|
411
456
|
"context": 256000,
|
|
412
|
-
"output": 128000
|
|
457
|
+
"output": 128000,
|
|
458
|
+
"input": 256000
|
|
413
459
|
},
|
|
414
460
|
"options": {
|
|
415
461
|
"reasoningEffort": "medium",
|
|
@@ -423,7 +469,8 @@
|
|
|
423
469
|
"attachment": true,
|
|
424
470
|
"limit": {
|
|
425
471
|
"context": 256000,
|
|
426
|
-
"output": 128000
|
|
472
|
+
"output": 128000,
|
|
473
|
+
"input": 256000
|
|
427
474
|
},
|
|
428
475
|
"options": {
|
|
429
476
|
"reasoningEffort": "medium",
|
|
@@ -437,7 +484,8 @@
|
|
|
437
484
|
"attachment": true,
|
|
438
485
|
"limit": {
|
|
439
486
|
"context": 256000,
|
|
440
|
-
"output": 128000
|
|
487
|
+
"output": 128000,
|
|
488
|
+
"input": 256000
|
|
441
489
|
},
|
|
442
490
|
"options": {
|
|
443
491
|
"reasoningEffort": "medium",
|
|
@@ -463,7 +511,9 @@
|
|
|
463
511
|
"tool_call": true,
|
|
464
512
|
"variants": {
|
|
465
513
|
"high": {
|
|
466
|
-
"include": [
|
|
514
|
+
"include": [
|
|
515
|
+
"reasoning.encrypted_content"
|
|
516
|
+
],
|
|
467
517
|
"reasoningEffort": "high",
|
|
468
518
|
"reasoningSummary": "auto"
|
|
469
519
|
},
|
|
@@ -481,7 +531,8 @@
|
|
|
481
531
|
"attachment": true,
|
|
482
532
|
"limit": {
|
|
483
533
|
"context": 400000,
|
|
484
|
-
"output": 128000
|
|
534
|
+
"output": 128000,
|
|
535
|
+
"input": 400000
|
|
485
536
|
},
|
|
486
537
|
"options": {
|
|
487
538
|
"reasoningEffort": "medium",
|
|
@@ -496,7 +547,9 @@
|
|
|
496
547
|
"disabled": true
|
|
497
548
|
},
|
|
498
549
|
"high": {
|
|
499
|
-
"include": [
|
|
550
|
+
"include": [
|
|
551
|
+
"reasoning.encrypted_content"
|
|
552
|
+
],
|
|
500
553
|
"reasoningEffort": "high",
|
|
501
554
|
"reasoningSummary": "auto",
|
|
502
555
|
"textVerbosity": "medium"
|
|
@@ -516,7 +569,8 @@
|
|
|
516
569
|
"attachment": true,
|
|
517
570
|
"limit": {
|
|
518
571
|
"context": 400000,
|
|
519
|
-
"output": 128000
|
|
572
|
+
"output": 128000,
|
|
573
|
+
"input": 400000
|
|
520
574
|
},
|
|
521
575
|
"name": "Gpt 5 3 Codex",
|
|
522
576
|
"options": {
|
|
@@ -532,7 +586,9 @@
|
|
|
532
586
|
"disabled": true
|
|
533
587
|
},
|
|
534
588
|
"high": {
|
|
535
|
-
"include": [
|
|
589
|
+
"include": [
|
|
590
|
+
"reasoning.encrypted_content"
|
|
591
|
+
],
|
|
536
592
|
"reasoningEffort": "high",
|
|
537
593
|
"reasoningSummary": "auto",
|
|
538
594
|
"textVerbosity": "medium"
|
|
@@ -552,11 +608,17 @@
|
|
|
552
608
|
"attachment": true,
|
|
553
609
|
"limit": {
|
|
554
610
|
"context": 400000,
|
|
555
|
-
"output": 128000
|
|
611
|
+
"output": 128000,
|
|
612
|
+
"input": 400000
|
|
556
613
|
},
|
|
557
614
|
"modalities": {
|
|
558
|
-
"input": [
|
|
559
|
-
|
|
615
|
+
"input": [
|
|
616
|
+
"text",
|
|
617
|
+
"image"
|
|
618
|
+
],
|
|
619
|
+
"output": [
|
|
620
|
+
"text"
|
|
621
|
+
]
|
|
560
622
|
},
|
|
561
623
|
"options": {
|
|
562
624
|
"reasoningEffort": "medium",
|
|
@@ -568,7 +630,9 @@
|
|
|
568
630
|
"tool_call": true,
|
|
569
631
|
"variants": {
|
|
570
632
|
"high": {
|
|
571
|
-
"include": [
|
|
633
|
+
"include": [
|
|
634
|
+
"reasoning.encrypted_content"
|
|
635
|
+
],
|
|
572
636
|
"reasoningEffort": "high",
|
|
573
637
|
"reasoningSummary": "auto"
|
|
574
638
|
},
|
|
@@ -656,8 +720,14 @@
|
|
|
656
720
|
"models": {
|
|
657
721
|
"zai-org/GLM-5-FP8": {
|
|
658
722
|
"modalities": {
|
|
659
|
-
"input": [
|
|
660
|
-
|
|
723
|
+
"input": [
|
|
724
|
+
"text",
|
|
725
|
+
"image",
|
|
726
|
+
"pdf"
|
|
727
|
+
],
|
|
728
|
+
"output": [
|
|
729
|
+
"text"
|
|
730
|
+
]
|
|
661
731
|
},
|
|
662
732
|
"name": "GLM-5",
|
|
663
733
|
"options": {
|
|
@@ -688,13 +758,17 @@
|
|
|
688
758
|
"disabled": true
|
|
689
759
|
},
|
|
690
760
|
"high": {
|
|
691
|
-
"include": [
|
|
761
|
+
"include": [
|
|
762
|
+
"reasoning.encrypted_content"
|
|
763
|
+
],
|
|
692
764
|
"reasoningEffort": "high",
|
|
693
765
|
"reasoningSummary": "auto",
|
|
694
766
|
"textVerbosity": "low"
|
|
695
767
|
},
|
|
696
768
|
"medium": {
|
|
697
|
-
"include": [
|
|
769
|
+
"include": [
|
|
770
|
+
"reasoning.encrypted_content"
|
|
771
|
+
],
|
|
698
772
|
"reasoningEffort": "medium",
|
|
699
773
|
"reasoningSummary": "auto",
|
|
700
774
|
"textVerbosity": "low"
|
|
@@ -707,19 +781,25 @@
|
|
|
707
781
|
"disabled": true
|
|
708
782
|
},
|
|
709
783
|
"high": {
|
|
710
|
-
"include": [
|
|
784
|
+
"include": [
|
|
785
|
+
"reasoning.encrypted_content"
|
|
786
|
+
],
|
|
711
787
|
"reasoningEffort": "high",
|
|
712
788
|
"reasoningSummary": "auto",
|
|
713
789
|
"textVerbosity": "low"
|
|
714
790
|
},
|
|
715
791
|
"medium": {
|
|
716
|
-
"include": [
|
|
792
|
+
"include": [
|
|
793
|
+
"reasoning.encrypted_content"
|
|
794
|
+
],
|
|
717
795
|
"reasoningEffort": "medium",
|
|
718
796
|
"reasoningSummary": "auto",
|
|
719
797
|
"textVerbosity": "low"
|
|
720
798
|
},
|
|
721
799
|
"xhigh": {
|
|
722
|
-
"include": [
|
|
800
|
+
"include": [
|
|
801
|
+
"reasoning.encrypted_content"
|
|
802
|
+
],
|
|
723
803
|
"reasoningEffort": "xhigh",
|
|
724
804
|
"reasoningSummary": "auto",
|
|
725
805
|
"textVerbosity": "low"
|
|
@@ -732,19 +812,25 @@
|
|
|
732
812
|
"disabled": true
|
|
733
813
|
},
|
|
734
814
|
"high": {
|
|
735
|
-
"include": [
|
|
815
|
+
"include": [
|
|
816
|
+
"reasoning.encrypted_content"
|
|
817
|
+
],
|
|
736
818
|
"reasoningEffort": "high",
|
|
737
819
|
"reasoningSummary": "auto",
|
|
738
820
|
"textVerbosity": "low"
|
|
739
821
|
},
|
|
740
822
|
"medium": {
|
|
741
|
-
"include": [
|
|
823
|
+
"include": [
|
|
824
|
+
"reasoning.encrypted_content"
|
|
825
|
+
],
|
|
742
826
|
"reasoningEffort": "medium",
|
|
743
827
|
"reasoningSummary": "auto",
|
|
744
828
|
"textVerbosity": "low"
|
|
745
829
|
},
|
|
746
830
|
"xhigh": {
|
|
747
|
-
"include": [
|
|
831
|
+
"include": [
|
|
832
|
+
"reasoning.encrypted_content"
|
|
833
|
+
],
|
|
748
834
|
"reasoningEffort": "xhigh",
|
|
749
835
|
"reasoningSummary": "auto",
|
|
750
836
|
"textVerbosity": "low"
|
|
@@ -758,8 +844,13 @@
|
|
|
758
844
|
"output": 128000
|
|
759
845
|
},
|
|
760
846
|
"modalities": {
|
|
761
|
-
"input": [
|
|
762
|
-
|
|
847
|
+
"input": [
|
|
848
|
+
"text",
|
|
849
|
+
"image"
|
|
850
|
+
],
|
|
851
|
+
"output": [
|
|
852
|
+
"text"
|
|
853
|
+
]
|
|
763
854
|
},
|
|
764
855
|
"options": {
|
|
765
856
|
"reasoningEffort": "medium",
|
|
@@ -771,7 +862,9 @@
|
|
|
771
862
|
"tool_call": true,
|
|
772
863
|
"variants": {
|
|
773
864
|
"high": {
|
|
774
|
-
"include": [
|
|
865
|
+
"include": [
|
|
866
|
+
"reasoning.encrypted_content"
|
|
867
|
+
],
|
|
775
868
|
"reasoningEffort": "high",
|
|
776
869
|
"reasoningSummary": "auto"
|
|
777
870
|
},
|
|
@@ -808,8 +901,14 @@
|
|
|
808
901
|
"output": 64000
|
|
809
902
|
},
|
|
810
903
|
"modalities": {
|
|
811
|
-
"input": [
|
|
812
|
-
|
|
904
|
+
"input": [
|
|
905
|
+
"text",
|
|
906
|
+
"image",
|
|
907
|
+
"pdf"
|
|
908
|
+
],
|
|
909
|
+
"output": [
|
|
910
|
+
"text"
|
|
911
|
+
]
|
|
813
912
|
},
|
|
814
913
|
"name": "Claude Haiku 4 5"
|
|
815
914
|
},
|
|
@@ -819,8 +918,14 @@
|
|
|
819
918
|
"output": 64000
|
|
820
919
|
},
|
|
821
920
|
"modalities": {
|
|
822
|
-
"input": [
|
|
823
|
-
|
|
921
|
+
"input": [
|
|
922
|
+
"text",
|
|
923
|
+
"image",
|
|
924
|
+
"pdf"
|
|
925
|
+
],
|
|
926
|
+
"output": [
|
|
927
|
+
"text"
|
|
928
|
+
]
|
|
824
929
|
},
|
|
825
930
|
"name": "Claude Haiku 4 5 20251001"
|
|
826
931
|
},
|
|
@@ -830,8 +935,14 @@
|
|
|
830
935
|
"output": 64000
|
|
831
936
|
},
|
|
832
937
|
"modalities": {
|
|
833
|
-
"input": [
|
|
834
|
-
|
|
938
|
+
"input": [
|
|
939
|
+
"text",
|
|
940
|
+
"image",
|
|
941
|
+
"pdf"
|
|
942
|
+
],
|
|
943
|
+
"output": [
|
|
944
|
+
"text"
|
|
945
|
+
]
|
|
835
946
|
},
|
|
836
947
|
"name": "Claude Opus 4 6 Thinking",
|
|
837
948
|
"options": {
|
|
@@ -860,8 +971,14 @@
|
|
|
860
971
|
"output": 64000
|
|
861
972
|
},
|
|
862
973
|
"modalities": {
|
|
863
|
-
"input": [
|
|
864
|
-
|
|
974
|
+
"input": [
|
|
975
|
+
"text",
|
|
976
|
+
"image",
|
|
977
|
+
"pdf"
|
|
978
|
+
],
|
|
979
|
+
"output": [
|
|
980
|
+
"text"
|
|
981
|
+
]
|
|
865
982
|
},
|
|
866
983
|
"name": "Claude Opus 4 6"
|
|
867
984
|
},
|
|
@@ -871,8 +988,14 @@
|
|
|
871
988
|
"output": 64000
|
|
872
989
|
},
|
|
873
990
|
"modalities": {
|
|
874
|
-
"input": [
|
|
875
|
-
|
|
991
|
+
"input": [
|
|
992
|
+
"text",
|
|
993
|
+
"image",
|
|
994
|
+
"pdf"
|
|
995
|
+
],
|
|
996
|
+
"output": [
|
|
997
|
+
"text"
|
|
998
|
+
]
|
|
876
999
|
},
|
|
877
1000
|
"name": "Claude Sonnet 4"
|
|
878
1001
|
},
|
|
@@ -882,8 +1005,14 @@
|
|
|
882
1005
|
"output": 64000
|
|
883
1006
|
},
|
|
884
1007
|
"modalities": {
|
|
885
|
-
"input": [
|
|
886
|
-
|
|
1008
|
+
"input": [
|
|
1009
|
+
"text",
|
|
1010
|
+
"image",
|
|
1011
|
+
"pdf"
|
|
1012
|
+
],
|
|
1013
|
+
"output": [
|
|
1014
|
+
"text"
|
|
1015
|
+
]
|
|
887
1016
|
},
|
|
888
1017
|
"name": "Claude Sonnet 4 20250514"
|
|
889
1018
|
},
|
|
@@ -893,8 +1022,14 @@
|
|
|
893
1022
|
"output": 64000
|
|
894
1023
|
},
|
|
895
1024
|
"modalities": {
|
|
896
|
-
"input": [
|
|
897
|
-
|
|
1025
|
+
"input": [
|
|
1026
|
+
"text",
|
|
1027
|
+
"image",
|
|
1028
|
+
"pdf"
|
|
1029
|
+
],
|
|
1030
|
+
"output": [
|
|
1031
|
+
"text"
|
|
1032
|
+
]
|
|
898
1033
|
},
|
|
899
1034
|
"name": "Claude Sonnet 4 5"
|
|
900
1035
|
},
|
|
@@ -904,8 +1039,14 @@
|
|
|
904
1039
|
"output": 64000
|
|
905
1040
|
},
|
|
906
1041
|
"modalities": {
|
|
907
|
-
"input": [
|
|
908
|
-
|
|
1042
|
+
"input": [
|
|
1043
|
+
"text",
|
|
1044
|
+
"image",
|
|
1045
|
+
"pdf"
|
|
1046
|
+
],
|
|
1047
|
+
"output": [
|
|
1048
|
+
"text"
|
|
1049
|
+
]
|
|
909
1050
|
},
|
|
910
1051
|
"name": "Claude Sonnet 4 5 20250929"
|
|
911
1052
|
},
|
|
@@ -915,8 +1056,14 @@
|
|
|
915
1056
|
"output": 64000
|
|
916
1057
|
},
|
|
917
1058
|
"modalities": {
|
|
918
|
-
"input": [
|
|
919
|
-
|
|
1059
|
+
"input": [
|
|
1060
|
+
"text",
|
|
1061
|
+
"image",
|
|
1062
|
+
"pdf"
|
|
1063
|
+
],
|
|
1064
|
+
"output": [
|
|
1065
|
+
"text"
|
|
1066
|
+
]
|
|
920
1067
|
},
|
|
921
1068
|
"name": "Claude Sonnet 4 6"
|
|
922
1069
|
},
|
|
@@ -926,8 +1073,14 @@
|
|
|
926
1073
|
"output": 65536
|
|
927
1074
|
},
|
|
928
1075
|
"modalities": {
|
|
929
|
-
"input": [
|
|
930
|
-
|
|
1076
|
+
"input": [
|
|
1077
|
+
"text",
|
|
1078
|
+
"image",
|
|
1079
|
+
"pdf"
|
|
1080
|
+
],
|
|
1081
|
+
"output": [
|
|
1082
|
+
"text"
|
|
1083
|
+
]
|
|
931
1084
|
},
|
|
932
1085
|
"name": "Gemini 2 5 Flash"
|
|
933
1086
|
},
|
|
@@ -937,8 +1090,14 @@
|
|
|
937
1090
|
"output": 65536
|
|
938
1091
|
},
|
|
939
1092
|
"modalities": {
|
|
940
|
-
"input": [
|
|
941
|
-
|
|
1093
|
+
"input": [
|
|
1094
|
+
"text",
|
|
1095
|
+
"image",
|
|
1096
|
+
"pdf"
|
|
1097
|
+
],
|
|
1098
|
+
"output": [
|
|
1099
|
+
"text"
|
|
1100
|
+
]
|
|
942
1101
|
},
|
|
943
1102
|
"name": "Gemini 2 5 Flash Lite"
|
|
944
1103
|
},
|
|
@@ -948,8 +1107,14 @@
|
|
|
948
1107
|
"output": 65536
|
|
949
1108
|
},
|
|
950
1109
|
"modalities": {
|
|
951
|
-
"input": [
|
|
952
|
-
|
|
1110
|
+
"input": [
|
|
1111
|
+
"text",
|
|
1112
|
+
"image",
|
|
1113
|
+
"pdf"
|
|
1114
|
+
],
|
|
1115
|
+
"output": [
|
|
1116
|
+
"text"
|
|
1117
|
+
]
|
|
953
1118
|
},
|
|
954
1119
|
"name": "Gemini 2 5 Pro"
|
|
955
1120
|
},
|
|
@@ -959,8 +1124,14 @@
|
|
|
959
1124
|
"output": 65536
|
|
960
1125
|
},
|
|
961
1126
|
"modalities": {
|
|
962
|
-
"input": [
|
|
963
|
-
|
|
1127
|
+
"input": [
|
|
1128
|
+
"text",
|
|
1129
|
+
"image",
|
|
1130
|
+
"pdf"
|
|
1131
|
+
],
|
|
1132
|
+
"output": [
|
|
1133
|
+
"text"
|
|
1134
|
+
]
|
|
964
1135
|
},
|
|
965
1136
|
"name": "Gemini 3 Flash",
|
|
966
1137
|
"options": {
|
|
@@ -990,8 +1161,14 @@
|
|
|
990
1161
|
"output": 65536
|
|
991
1162
|
},
|
|
992
1163
|
"modalities": {
|
|
993
|
-
"input": [
|
|
994
|
-
|
|
1164
|
+
"input": [
|
|
1165
|
+
"text",
|
|
1166
|
+
"image",
|
|
1167
|
+
"pdf"
|
|
1168
|
+
],
|
|
1169
|
+
"output": [
|
|
1170
|
+
"text"
|
|
1171
|
+
]
|
|
995
1172
|
},
|
|
996
1173
|
"name": "Gemini 3 Flash Preview",
|
|
997
1174
|
"options": {
|
|
@@ -1021,8 +1198,14 @@
|
|
|
1021
1198
|
"output": 65536
|
|
1022
1199
|
},
|
|
1023
1200
|
"modalities": {
|
|
1024
|
-
"input": [
|
|
1025
|
-
|
|
1201
|
+
"input": [
|
|
1202
|
+
"text",
|
|
1203
|
+
"image",
|
|
1204
|
+
"pdf"
|
|
1205
|
+
],
|
|
1206
|
+
"output": [
|
|
1207
|
+
"text"
|
|
1208
|
+
]
|
|
1026
1209
|
},
|
|
1027
1210
|
"name": "Gemini 3 Pro High",
|
|
1028
1211
|
"options": {
|
|
@@ -1052,8 +1235,14 @@
|
|
|
1052
1235
|
"output": 65536
|
|
1053
1236
|
},
|
|
1054
1237
|
"modalities": {
|
|
1055
|
-
"input": [
|
|
1056
|
-
|
|
1238
|
+
"input": [
|
|
1239
|
+
"text",
|
|
1240
|
+
"image",
|
|
1241
|
+
"pdf"
|
|
1242
|
+
],
|
|
1243
|
+
"output": [
|
|
1244
|
+
"text"
|
|
1245
|
+
]
|
|
1057
1246
|
},
|
|
1058
1247
|
"name": "Gemini 3 Pro Low",
|
|
1059
1248
|
"options": {
|
|
@@ -1083,8 +1272,14 @@
|
|
|
1083
1272
|
"output": 65536
|
|
1084
1273
|
},
|
|
1085
1274
|
"modalities": {
|
|
1086
|
-
"input": [
|
|
1087
|
-
|
|
1275
|
+
"input": [
|
|
1276
|
+
"text",
|
|
1277
|
+
"image",
|
|
1278
|
+
"pdf"
|
|
1279
|
+
],
|
|
1280
|
+
"output": [
|
|
1281
|
+
"text"
|
|
1282
|
+
]
|
|
1088
1283
|
},
|
|
1089
1284
|
"name": "Gemini 3 Pro Preview",
|
|
1090
1285
|
"options": {
|
|
@@ -1121,8 +1316,14 @@
|
|
|
1121
1316
|
"output": 65536
|
|
1122
1317
|
},
|
|
1123
1318
|
"modalities": {
|
|
1124
|
-
"input": [
|
|
1125
|
-
|
|
1319
|
+
"input": [
|
|
1320
|
+
"text",
|
|
1321
|
+
"image",
|
|
1322
|
+
"pdf"
|
|
1323
|
+
],
|
|
1324
|
+
"output": [
|
|
1325
|
+
"text"
|
|
1326
|
+
]
|
|
1126
1327
|
},
|
|
1127
1328
|
"name": "Gemini 3 1 Flash Lite Preview",
|
|
1128
1329
|
"options": {
|
|
@@ -1152,8 +1353,14 @@
|
|
|
1152
1353
|
"output": 65536
|
|
1153
1354
|
},
|
|
1154
1355
|
"modalities": {
|
|
1155
|
-
"input": [
|
|
1156
|
-
|
|
1356
|
+
"input": [
|
|
1357
|
+
"text",
|
|
1358
|
+
"image",
|
|
1359
|
+
"pdf"
|
|
1360
|
+
],
|
|
1361
|
+
"output": [
|
|
1362
|
+
"text"
|
|
1363
|
+
]
|
|
1157
1364
|
},
|
|
1158
1365
|
"name": "Gemini 3 1 Pro High",
|
|
1159
1366
|
"options": {
|
|
@@ -1183,8 +1390,14 @@
|
|
|
1183
1390
|
"output": 65536
|
|
1184
1391
|
},
|
|
1185
1392
|
"modalities": {
|
|
1186
|
-
"input": [
|
|
1187
|
-
|
|
1393
|
+
"input": [
|
|
1394
|
+
"text",
|
|
1395
|
+
"image",
|
|
1396
|
+
"pdf"
|
|
1397
|
+
],
|
|
1398
|
+
"output": [
|
|
1399
|
+
"text"
|
|
1400
|
+
]
|
|
1188
1401
|
},
|
|
1189
1402
|
"name": "Gemini 3 1 Pro Low",
|
|
1190
1403
|
"options": {
|
|
@@ -1214,8 +1427,14 @@
|
|
|
1214
1427
|
"output": 65536
|
|
1215
1428
|
},
|
|
1216
1429
|
"modalities": {
|
|
1217
|
-
"input": [
|
|
1218
|
-
|
|
1430
|
+
"input": [
|
|
1431
|
+
"text",
|
|
1432
|
+
"image",
|
|
1433
|
+
"pdf"
|
|
1434
|
+
],
|
|
1435
|
+
"output": [
|
|
1436
|
+
"text"
|
|
1437
|
+
]
|
|
1219
1438
|
},
|
|
1220
1439
|
"name": "Gemini 3 1 Pro Preview",
|
|
1221
1440
|
"options": {
|
|
@@ -1273,8 +1492,14 @@
|
|
|
1273
1492
|
"output": 32768
|
|
1274
1493
|
},
|
|
1275
1494
|
"modalities": {
|
|
1276
|
-
"input": [
|
|
1277
|
-
|
|
1495
|
+
"input": [
|
|
1496
|
+
"text",
|
|
1497
|
+
"image",
|
|
1498
|
+
"pdf"
|
|
1499
|
+
],
|
|
1500
|
+
"output": [
|
|
1501
|
+
"text"
|
|
1502
|
+
]
|
|
1278
1503
|
},
|
|
1279
1504
|
"name": "Gpt 5",
|
|
1280
1505
|
"options": {
|
|
@@ -1288,8 +1513,14 @@
|
|
|
1288
1513
|
"output": 32768
|
|
1289
1514
|
},
|
|
1290
1515
|
"modalities": {
|
|
1291
|
-
"input": [
|
|
1292
|
-
|
|
1516
|
+
"input": [
|
|
1517
|
+
"text",
|
|
1518
|
+
"image",
|
|
1519
|
+
"pdf"
|
|
1520
|
+
],
|
|
1521
|
+
"output": [
|
|
1522
|
+
"text"
|
|
1523
|
+
]
|
|
1293
1524
|
},
|
|
1294
1525
|
"name": "Gpt 5 Codex",
|
|
1295
1526
|
"options": {
|
|
@@ -1303,8 +1534,14 @@
|
|
|
1303
1534
|
"output": 32768
|
|
1304
1535
|
},
|
|
1305
1536
|
"modalities": {
|
|
1306
|
-
"input": [
|
|
1307
|
-
|
|
1537
|
+
"input": [
|
|
1538
|
+
"text",
|
|
1539
|
+
"image",
|
|
1540
|
+
"pdf"
|
|
1541
|
+
],
|
|
1542
|
+
"output": [
|
|
1543
|
+
"text"
|
|
1544
|
+
]
|
|
1308
1545
|
},
|
|
1309
1546
|
"name": "Gpt 5 Codex Mini",
|
|
1310
1547
|
"options": {
|
|
@@ -1318,8 +1555,14 @@
|
|
|
1318
1555
|
"output": 32768
|
|
1319
1556
|
},
|
|
1320
1557
|
"modalities": {
|
|
1321
|
-
"input": [
|
|
1322
|
-
|
|
1558
|
+
"input": [
|
|
1559
|
+
"text",
|
|
1560
|
+
"image",
|
|
1561
|
+
"pdf"
|
|
1562
|
+
],
|
|
1563
|
+
"output": [
|
|
1564
|
+
"text"
|
|
1565
|
+
]
|
|
1323
1566
|
},
|
|
1324
1567
|
"name": "Gpt 5 1",
|
|
1325
1568
|
"options": {
|
|
@@ -1333,8 +1576,14 @@
|
|
|
1333
1576
|
"output": 32768
|
|
1334
1577
|
},
|
|
1335
1578
|
"modalities": {
|
|
1336
|
-
"input": [
|
|
1337
|
-
|
|
1579
|
+
"input": [
|
|
1580
|
+
"text",
|
|
1581
|
+
"image",
|
|
1582
|
+
"pdf"
|
|
1583
|
+
],
|
|
1584
|
+
"output": [
|
|
1585
|
+
"text"
|
|
1586
|
+
]
|
|
1338
1587
|
},
|
|
1339
1588
|
"name": "Gpt 5 1 Codex",
|
|
1340
1589
|
"options": {
|
|
@@ -1348,8 +1597,14 @@
|
|
|
1348
1597
|
"output": 32768
|
|
1349
1598
|
},
|
|
1350
1599
|
"modalities": {
|
|
1351
|
-
"input": [
|
|
1352
|
-
|
|
1600
|
+
"input": [
|
|
1601
|
+
"text",
|
|
1602
|
+
"image",
|
|
1603
|
+
"pdf"
|
|
1604
|
+
],
|
|
1605
|
+
"output": [
|
|
1606
|
+
"text"
|
|
1607
|
+
]
|
|
1353
1608
|
},
|
|
1354
1609
|
"name": "Gpt 5 1 Codex Max",
|
|
1355
1610
|
"options": {
|
|
@@ -1363,8 +1618,14 @@
|
|
|
1363
1618
|
"output": 32768
|
|
1364
1619
|
},
|
|
1365
1620
|
"modalities": {
|
|
1366
|
-
"input": [
|
|
1367
|
-
|
|
1621
|
+
"input": [
|
|
1622
|
+
"text",
|
|
1623
|
+
"image",
|
|
1624
|
+
"pdf"
|
|
1625
|
+
],
|
|
1626
|
+
"output": [
|
|
1627
|
+
"text"
|
|
1628
|
+
]
|
|
1368
1629
|
},
|
|
1369
1630
|
"name": "Gpt 5 1 Codex Mini",
|
|
1370
1631
|
"options": {
|
|
@@ -1378,8 +1639,14 @@
|
|
|
1378
1639
|
"output": 32768
|
|
1379
1640
|
},
|
|
1380
1641
|
"modalities": {
|
|
1381
|
-
"input": [
|
|
1382
|
-
|
|
1642
|
+
"input": [
|
|
1643
|
+
"text",
|
|
1644
|
+
"image",
|
|
1645
|
+
"pdf"
|
|
1646
|
+
],
|
|
1647
|
+
"output": [
|
|
1648
|
+
"text"
|
|
1649
|
+
]
|
|
1383
1650
|
},
|
|
1384
1651
|
"name": "Gpt 5 2",
|
|
1385
1652
|
"options": {
|
|
@@ -1393,8 +1660,14 @@
|
|
|
1393
1660
|
"output": 32768
|
|
1394
1661
|
},
|
|
1395
1662
|
"modalities": {
|
|
1396
|
-
"input": [
|
|
1397
|
-
|
|
1663
|
+
"input": [
|
|
1664
|
+
"text",
|
|
1665
|
+
"image",
|
|
1666
|
+
"pdf"
|
|
1667
|
+
],
|
|
1668
|
+
"output": [
|
|
1669
|
+
"text"
|
|
1670
|
+
]
|
|
1398
1671
|
},
|
|
1399
1672
|
"name": "Gpt 5 2 Codex",
|
|
1400
1673
|
"options": {
|
|
@@ -1408,8 +1681,14 @@
|
|
|
1408
1681
|
"output": 32768
|
|
1409
1682
|
},
|
|
1410
1683
|
"modalities": {
|
|
1411
|
-
"input": [
|
|
1412
|
-
|
|
1684
|
+
"input": [
|
|
1685
|
+
"text",
|
|
1686
|
+
"image",
|
|
1687
|
+
"pdf"
|
|
1688
|
+
],
|
|
1689
|
+
"output": [
|
|
1690
|
+
"text"
|
|
1691
|
+
]
|
|
1413
1692
|
},
|
|
1414
1693
|
"name": "Gpt 5 3 Codex",
|
|
1415
1694
|
"options": {
|
|
@@ -1423,8 +1702,14 @@
|
|
|
1423
1702
|
"output": 32768
|
|
1424
1703
|
},
|
|
1425
1704
|
"modalities": {
|
|
1426
|
-
"input": [
|
|
1427
|
-
|
|
1705
|
+
"input": [
|
|
1706
|
+
"text",
|
|
1707
|
+
"image",
|
|
1708
|
+
"pdf"
|
|
1709
|
+
],
|
|
1710
|
+
"output": [
|
|
1711
|
+
"text"
|
|
1712
|
+
]
|
|
1428
1713
|
},
|
|
1429
1714
|
"name": "Gpt 5 4",
|
|
1430
1715
|
"options": {
|
|
@@ -1438,8 +1723,14 @@
|
|
|
1438
1723
|
"output": 32768
|
|
1439
1724
|
},
|
|
1440
1725
|
"modalities": {
|
|
1441
|
-
"input": [
|
|
1442
|
-
|
|
1726
|
+
"input": [
|
|
1727
|
+
"text",
|
|
1728
|
+
"image",
|
|
1729
|
+
"pdf"
|
|
1730
|
+
],
|
|
1731
|
+
"output": [
|
|
1732
|
+
"text"
|
|
1733
|
+
]
|
|
1443
1734
|
},
|
|
1444
1735
|
"name": "Gpt 5 4 Mini",
|
|
1445
1736
|
"options": {
|
|
@@ -1656,5 +1947,8 @@
|
|
|
1656
1947
|
"*.log",
|
|
1657
1948
|
".DS_Store"
|
|
1658
1949
|
]
|
|
1950
|
+
},
|
|
1951
|
+
"compaction": {
|
|
1952
|
+
"reserved": 128000
|
|
1659
1953
|
}
|
|
1660
1954
|
}
|
|
@@ -70,12 +70,17 @@ const RESPONSES_API_ALTERNATE_INPUT_TYPES = [
|
|
|
70
70
|
// Expected ID prefixes per Responses API item type.
|
|
71
71
|
// The OpenAI Responses API validates that item IDs start with specific prefixes.
|
|
72
72
|
// GitHub Copilot's backend (especially GPT models) returns non-standard prefixes
|
|
73
|
-
// (e.g., "h_" instead of "fc_") that the API then rejects on replay.
|
|
73
|
+
// (e.g., "h_" instead of "fc_") or no prefix at all that the API then rejects on replay.
|
|
74
74
|
const RESPONSES_API_EXPECTED_PREFIXES: Record<string, string> = {
|
|
75
75
|
function_call: "fc_",
|
|
76
|
+
local_shell_call: "fc_",
|
|
76
77
|
// function_call_output.call_id prefix is validated directly in sanitizeResponseInputIds
|
|
77
78
|
};
|
|
78
79
|
|
|
80
|
+
// Role-based items (role: "assistant", "user", etc.) are internally typed as "message"
|
|
81
|
+
// by the OpenAI Responses API and their IDs must start with "msg_".
|
|
82
|
+
const RESPONSES_API_ROLE_PREFIX = "msg_";
|
|
83
|
+
|
|
79
84
|
function normalizeDomain(url: string): string {
|
|
80
85
|
return url.replace(/^https?:\/\//, "").replace(/\/$/, "");
|
|
81
86
|
}
|
|
@@ -360,75 +365,109 @@ function swapModelInBody(
|
|
|
360
365
|
|
|
361
366
|
// Maximum length for item IDs in the OpenAI Responses API
|
|
362
367
|
const MAX_RESPONSE_API_ID_LENGTH = 64;
|
|
368
|
+
// OpenAI Responses API only allows: letters, numbers, underscores, dashes
|
|
369
|
+
const INVALID_ID_CHARS = /[^a-zA-Z0-9_-]/g;
|
|
370
|
+
|
|
371
|
+
/** Check if an ID contains characters not allowed by the Responses API */
|
|
372
|
+
function hasInvalidIdChars(id: string): boolean {
|
|
373
|
+
// Use a non-global regex for .test() to avoid lastIndex state bug
|
|
374
|
+
return /[^a-zA-Z0-9_-]/.test(id);
|
|
375
|
+
}
|
|
376
|
+
|
|
363
377
|
/**
|
|
364
|
-
* Sanitize an ID
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
378
|
+
* Sanitize an ID for the Responses API.
|
|
379
|
+
* Handles three issues from GitHub Copilot:
|
|
380
|
+
* 1. Invalid characters — Copilot IDs contain +, |, /, = (base64-like encoding)
|
|
381
|
+
* 2. Wrong prefix — GPT models return "h_" instead of "fc_" for function_call items
|
|
382
|
+
* 3. Excessive length — Copilot returns 400+ char IDs (max is 64)
|
|
383
|
+
*
|
|
384
|
+
* Approach matches anomalyco/opencode: replace invalid chars with "_", preserve prefix,
|
|
385
|
+
* truncate to 64 chars, strip trailing underscores.
|
|
369
386
|
*
|
|
370
387
|
* @param id - The original ID to sanitize
|
|
371
388
|
* @param forcedPrefix - If provided, use this prefix instead of the detected one.
|
|
372
|
-
* Used when the original prefix is wrong (e.g., Copilot returns "h_" instead of "fc_").
|
|
373
389
|
* See: https://github.com/vercel/ai/issues/5171
|
|
374
390
|
*/
|
|
375
391
|
function sanitizeResponseId(id: string, forcedPrefix?: string): string {
|
|
392
|
+
if (!id) return id;
|
|
393
|
+
|
|
376
394
|
// Detect the original prefix (e.g., "fc_", "msg_", "call_", "resp_", "h_")
|
|
377
395
|
const prefixMatch = id.match(/^([a-z]+_)/);
|
|
378
396
|
const detectedPrefix = prefixMatch ? prefixMatch[1] : "";
|
|
379
397
|
const prefix = forcedPrefix ?? detectedPrefix;
|
|
380
398
|
|
|
381
|
-
// If no forced prefix and within length, return as-is
|
|
382
|
-
if (!forcedPrefix && (!id || id.length <= MAX_RESPONSE_API_ID_LENGTH)) {
|
|
383
|
-
return id;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
399
|
// Strip the original prefix to get the core ID
|
|
387
|
-
const
|
|
400
|
+
const rawCore = id.slice(detectedPrefix.length);
|
|
401
|
+
// Replace invalid characters with underscores (same as anomalyco/opencode)
|
|
402
|
+
const cleanCore = rawCore.replace(INVALID_ID_CHARS, "_").replace(/_+$/g, "");
|
|
403
|
+
|
|
404
|
+
// Check if any sanitization is actually needed
|
|
405
|
+
const needsSanitization = forcedPrefix || hasInvalidIdChars(rawCore) ||
|
|
406
|
+
id.length > MAX_RESPONSE_API_ID_LENGTH;
|
|
388
407
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
408
|
+
if (!needsSanitization) return id;
|
|
409
|
+
|
|
410
|
+
// If result fits within length and core is non-empty, use cleaned core directly
|
|
411
|
+
if (cleanCore.length > 0 && (prefix.length + cleanCore.length) <= MAX_RESPONSE_API_ID_LENGTH) {
|
|
412
|
+
return `${prefix}${cleanCore}`;
|
|
392
413
|
}
|
|
393
414
|
|
|
394
|
-
// Hash the full original ID for deterministic uniqueness
|
|
415
|
+
// Hash the full original ID for deterministic uniqueness when truncating
|
|
395
416
|
let hash = 0;
|
|
396
417
|
for (let i = 0; i < id.length; i++) {
|
|
397
418
|
hash = ((hash << 5) - hash + id.charCodeAt(i)) | 0;
|
|
398
419
|
}
|
|
399
420
|
const hashStr = Math.abs(hash).toString(36);
|
|
400
|
-
// Take some chars from the core for additional uniqueness
|
|
401
421
|
const maxMiddleLen =
|
|
402
422
|
MAX_RESPONSE_API_ID_LENGTH - prefix.length - hashStr.length - 1;
|
|
403
|
-
const middle =
|
|
423
|
+
const middle = cleanCore.slice(0, Math.max(0, maxMiddleLen));
|
|
404
424
|
// Format: prefix + middle + "_" + hash (ensure total <= 64)
|
|
405
|
-
|
|
425
|
+
const result = `${prefix}${middle}_${hashStr}`.slice(0, MAX_RESPONSE_API_ID_LENGTH);
|
|
426
|
+
// Strip trailing underscores from truncation
|
|
427
|
+
return result.replace(/_+$/, "");
|
|
406
428
|
}
|
|
407
429
|
|
|
408
430
|
/**
|
|
409
431
|
* Check if an ID has the expected prefix for its item type.
|
|
432
|
+
* Handles both type-based items (function_call → "fc_") and
|
|
433
|
+
* role-based items (assistant/user/developer/system → "msg_").
|
|
410
434
|
* Returns the expected prefix if the ID is wrong, or null if it's fine.
|
|
411
435
|
*/
|
|
412
436
|
function getExpectedPrefix(item: any): string | null {
|
|
413
|
-
if (!item || typeof item !== "object"
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
437
|
+
if (!item || typeof item !== "object") return null;
|
|
438
|
+
if (typeof item.id !== "string") return null;
|
|
439
|
+
|
|
440
|
+
// Type-based items: function_call, local_shell_call, etc.
|
|
441
|
+
if (item.type) {
|
|
442
|
+
const expected = RESPONSES_API_EXPECTED_PREFIXES[item.type];
|
|
443
|
+
if (expected && !item.id.startsWith(expected)) {
|
|
444
|
+
return expected;
|
|
445
|
+
}
|
|
418
446
|
}
|
|
447
|
+
|
|
448
|
+
// Role-based items: assistant, user, developer, system → "msg_" prefix
|
|
449
|
+
if (item.role && !item.id.startsWith(RESPONSES_API_ROLE_PREFIX)) {
|
|
450
|
+
return RESPONSES_API_ROLE_PREFIX;
|
|
451
|
+
}
|
|
452
|
+
|
|
419
453
|
return null;
|
|
420
454
|
}
|
|
421
455
|
|
|
456
|
+
/** Check if a string ID needs sanitization (invalid chars or too long) */
|
|
457
|
+
function idNeedsSanitization(id: string): boolean {
|
|
458
|
+
return id.length > MAX_RESPONSE_API_ID_LENGTH || hasInvalidIdChars(id);
|
|
459
|
+
}
|
|
460
|
+
|
|
422
461
|
/**
|
|
423
462
|
* Sanitize all IDs in a Responses API input array.
|
|
424
463
|
*
|
|
425
|
-
* Handles
|
|
426
|
-
* 1.
|
|
427
|
-
*
|
|
428
|
-
*
|
|
464
|
+
* Handles THREE classes of invalid IDs:
|
|
465
|
+
* 1. Invalid characters — Copilot IDs contain +, |, /, = (only [a-zA-Z0-9_-] allowed)
|
|
466
|
+
* 2. Wrong prefix — Copilot GPT models return IDs like "h_xxx" instead of "fc_xxx"
|
|
467
|
+
* 3. Excessive length — Copilot returns 400+ char IDs that exceed the 64-char limit.
|
|
429
468
|
*
|
|
430
469
|
* Uses a two-pass approach:
|
|
431
|
-
* - Pass 1: Build an ID remap for all invalid IDs
|
|
470
|
+
* - Pass 1: Build an ID remap for all invalid IDs
|
|
432
471
|
* - Pass 2: Apply the remap to both `id` and `call_id` fields consistently,
|
|
433
472
|
* so function_call_output.call_id stays in sync with function_call.id
|
|
434
473
|
*/
|
|
@@ -448,10 +487,10 @@ function sanitizeResponseInputIds(input: any[]): any[] {
|
|
|
448
487
|
}
|
|
449
488
|
}
|
|
450
489
|
|
|
451
|
-
// Check for excessive length on id
|
|
490
|
+
// Check for invalid chars or excessive length on id
|
|
452
491
|
if (
|
|
453
492
|
typeof item.id === "string" &&
|
|
454
|
-
item.id
|
|
493
|
+
idNeedsSanitization(item.id) &&
|
|
455
494
|
!idRemap.has(item.id)
|
|
456
495
|
) {
|
|
457
496
|
idRemap.set(item.id, sanitizeResponseId(item.id));
|
|
@@ -471,10 +510,10 @@ function sanitizeResponseInputIds(input: any[]): any[] {
|
|
|
471
510
|
}
|
|
472
511
|
}
|
|
473
512
|
|
|
474
|
-
// Check for excessive length on call_id
|
|
513
|
+
// Check for invalid chars or excessive length on call_id
|
|
475
514
|
if (
|
|
476
515
|
typeof item.call_id === "string" &&
|
|
477
|
-
item.call_id
|
|
516
|
+
idNeedsSanitization(item.call_id) &&
|
|
478
517
|
!idRemap.has(item.call_id)
|
|
479
518
|
) {
|
|
480
519
|
idRemap.set(item.call_id, sanitizeResponseId(item.call_id));
|
|
@@ -694,28 +733,57 @@ export const CopilotAuthPlugin: Plugin = async ({ client: sdk }) => {
|
|
|
694
733
|
|
|
695
734
|
// Responses API
|
|
696
735
|
if (body?.input) {
|
|
736
|
+
// Log raw IDs before sanitization for debugging
|
|
737
|
+
const rawIds = body.input
|
|
738
|
+
.filter((item: any) => item && typeof item === "object")
|
|
739
|
+
.flatMap((item: any) => [
|
|
740
|
+
item.id ? `id=${item.id}` : null,
|
|
741
|
+
item.call_id ? `call_id=${item.call_id}` : null,
|
|
742
|
+
])
|
|
743
|
+
.filter(Boolean);
|
|
744
|
+
if (rawIds.length > 0) {
|
|
745
|
+
log("debug", "[ID-SANITIZE] Raw input IDs before sanitization", {
|
|
746
|
+
ids: rawIds,
|
|
747
|
+
count: rawIds.length,
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
|
|
697
751
|
// Sanitize IDs from Copilot backend:
|
|
698
752
|
// 1. Wrong prefix — GPT models return "h_xxx" instead of "fc_xxx"
|
|
699
753
|
// 2. Excessive length — Copilot returns 400+ char IDs (max is 64)
|
|
700
754
|
const sanitizedInput = sanitizeResponseInputIds(body.input);
|
|
701
|
-
const
|
|
702
|
-
|
|
703
|
-
|
|
755
|
+
const refDiffers = sanitizedInput !== body.input;
|
|
756
|
+
const jsonDiffers = refDiffers && JSON.stringify(sanitizedInput) !== JSON.stringify(body.input);
|
|
757
|
+
const inputWasSanitized = refDiffers && jsonDiffers;
|
|
758
|
+
|
|
759
|
+
log("debug", "[ID-SANITIZE] Sanitization result", {
|
|
760
|
+
was_sanitized: inputWasSanitized,
|
|
761
|
+
ref_differs: refDiffers,
|
|
762
|
+
json_differs: jsonDiffers,
|
|
763
|
+
});
|
|
704
764
|
|
|
705
765
|
if (inputWasSanitized) {
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
766
|
+
const fixes = body.input
|
|
767
|
+
.map((item: any, i: number) => ({ item, i, si: sanitizedInput[i] }))
|
|
768
|
+
.filter(({ item, si }: any) =>
|
|
769
|
+
item && si && (item.id !== si.id || item.call_id !== si.call_id),
|
|
770
|
+
);
|
|
771
|
+
log("info", "[ID-SANITIZE] Fixed IDs in Responses API input", {
|
|
772
|
+
items_fixed: fixes.length,
|
|
773
|
+
fixes: fixes.map(({ item, si }: any) => ({
|
|
774
|
+
type: item.type,
|
|
775
|
+
old_id: item.id,
|
|
776
|
+
new_id: si?.id,
|
|
777
|
+
old_call_id: item.call_id,
|
|
778
|
+
new_call_id: si?.call_id,
|
|
779
|
+
})),
|
|
714
780
|
});
|
|
715
781
|
modifiedBody = {
|
|
716
782
|
...(modifiedBody || body),
|
|
717
783
|
input: sanitizedInput,
|
|
718
784
|
};
|
|
785
|
+
} else {
|
|
786
|
+
log("debug", "[ID-SANITIZE] No sanitization needed — all IDs valid");
|
|
719
787
|
}
|
|
720
788
|
|
|
721
789
|
isAgentCall = (sanitizedInput || body.input).some(
|
|
@@ -35,6 +35,36 @@ interface HookDeps {
|
|
|
35
35
|
log: (message: string, level?: "info" | "warn") => Promise<void>;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Extract a human-readable error message from any value.
|
|
40
|
+
* Handles: Error instances, objects with .message, strings, and arbitrary objects.
|
|
41
|
+
* Never returns "[object Object]".
|
|
42
|
+
*/
|
|
43
|
+
function extractErrorMessage(value: unknown, maxLen = 200): string {
|
|
44
|
+
if (!value) return "Unknown error";
|
|
45
|
+
if (typeof value === "string") return value.slice(0, maxLen);
|
|
46
|
+
if (value instanceof Error) return (value.message || value.name || "Error").slice(0, maxLen);
|
|
47
|
+
if (typeof value === "object" && value !== null) {
|
|
48
|
+
const obj = value as Record<string, unknown>;
|
|
49
|
+
// Common error shapes: { message }, { error }, { error: { message } }
|
|
50
|
+
if (typeof obj.message === "string") return obj.message.slice(0, maxLen);
|
|
51
|
+
if (typeof obj.error === "string") return obj.error.slice(0, maxLen);
|
|
52
|
+
if (typeof obj.error === "object" && obj.error !== null) {
|
|
53
|
+
const inner = obj.error as Record<string, unknown>;
|
|
54
|
+
if (typeof inner.message === "string") return inner.message.slice(0, maxLen);
|
|
55
|
+
}
|
|
56
|
+
// Last resort: JSON stringify with truncation
|
|
57
|
+
try {
|
|
58
|
+
const json = JSON.stringify(value);
|
|
59
|
+
return json.slice(0, maxLen);
|
|
60
|
+
} catch {
|
|
61
|
+
return "Non-serializable error object";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// number, boolean, symbol, etc.
|
|
65
|
+
return String(value).slice(0, maxLen);
|
|
66
|
+
}
|
|
67
|
+
|
|
38
68
|
export function createHooks(deps: HookDeps) {
|
|
39
69
|
const { showToast, log } = deps;
|
|
40
70
|
|
|
@@ -93,11 +123,7 @@ export function createHooks(deps: HookDeps) {
|
|
|
93
123
|
// --- Session error: classify and guide ---
|
|
94
124
|
if (event.type === "session.error") {
|
|
95
125
|
const props = event.properties as Record<string, unknown> | undefined;
|
|
96
|
-
const errorMsg = props?.error
|
|
97
|
-
? String(props.error).slice(0, 200)
|
|
98
|
-
: props?.message
|
|
99
|
-
? String(props.message).slice(0, 200)
|
|
100
|
-
: "Unknown error";
|
|
126
|
+
const errorMsg = extractErrorMessage(props?.error ?? props?.message ?? "Unknown error");
|
|
101
127
|
|
|
102
128
|
// Log full error for debugging
|
|
103
129
|
await log(`Session error: ${errorMsg}`, "warn");
|