@@ -804,4 +804,249 @@ describe('buildAppConfig', () => {
804804 expect ( result . model ?. provider ) . toBe ( 'openai' ) ;
805805 } ) ;
806806 } ) ;
807+
808+ describe ( 'unknown options passthrough' , ( ) => {
809+ it ( 'should preserve unknown CLI options in the final config' , ( ) => {
810+ const cliArgs : AgentCLIArguments = {
811+ model : {
812+ provider : 'openai' ,
813+ id : 'gpt-4' ,
814+ } ,
815+ // Unknown options that should be preserved
816+ aioSandbox : 'test-sandbox-value' ,
817+ customOption : 'custom-value' ,
818+ nestedUnknown : {
819+ nested : 'value' ,
820+ } ,
821+ } ;
822+
823+ const result = buildAppConfig ( cliArgs , { } ) ;
824+
825+ // Known options should work as expected
826+ expect ( result . model ) . toEqual ( {
827+ provider : 'openai' ,
828+ id : 'gpt-4' ,
829+ } ) ;
830+
831+ // Unknown options should be preserved
832+ expect ( result ) . toHaveProperty ( 'aioSandbox' , 'test-sandbox-value' ) ;
833+ expect ( result ) . toHaveProperty ( 'customOption' , 'custom-value' ) ;
834+ expect ( result ) . toHaveProperty ( 'nestedUnknown' , {
835+ nested : 'value' ,
836+ } ) ;
837+ } ) ;
838+
839+ it ( 'should preserve unknown options while filtering out known CLI-only options' , ( ) => {
840+ const cliArgs : AgentCLIArguments = {
841+ // Known CLI-only options that should be filtered out
842+ agent : 'agent-tars' ,
843+ workspace : '/workspace' ,
844+ debug : true ,
845+ quiet : false ,
846+ headless : true ,
847+ input : 'test input' ,
848+ format : 'json' ,
849+ includeLogs : true ,
850+ useCache : false ,
851+ open : true ,
852+
853+ // Known options that should be preserved
854+ model : {
855+ provider : 'openai' ,
856+ } ,
857+
858+ // Unknown options that should be preserved
859+ aioSandbox : 'sandbox-value' ,
860+ customAgentOption : 'agent-specific-value' ,
861+ } ;
862+
863+ const result = buildAppConfig ( cliArgs , { } ) ;
864+
865+ // Known CLI-only options should not appear in result
866+ expect ( result ) . not . toHaveProperty ( 'agent' ) ;
867+ expect ( result ) . not . toHaveProperty ( 'workspace' ) ;
868+ expect ( result ) . not . toHaveProperty ( 'debug' ) ;
869+ expect ( result ) . not . toHaveProperty ( 'quiet' ) ;
870+ expect ( result ) . not . toHaveProperty ( 'headless' ) ;
871+ expect ( result ) . not . toHaveProperty ( 'input' ) ;
872+ expect ( result ) . not . toHaveProperty ( 'format' ) ;
873+ expect ( result ) . not . toHaveProperty ( 'includeLogs' ) ;
874+ expect ( result ) . not . toHaveProperty ( 'useCache' ) ;
875+ expect ( result ) . not . toHaveProperty ( 'open' ) ;
876+
877+ // Known options should be preserved
878+ expect ( result . model ) . toEqual ( {
879+ provider : 'openai' ,
880+ } ) ;
881+
882+ // Unknown options should be preserved
883+ expect ( result ) . toHaveProperty ( 'aioSandbox' , 'sandbox-value' ) ;
884+ expect ( result ) . toHaveProperty ( 'customAgentOption' , 'agent-specific-value' ) ;
885+ } ) ;
886+
887+ it ( 'should preserve unknown options alongside deprecated options' , ( ) => {
888+ const cliArgs : AgentCLIArguments = {
889+ // Deprecated options
890+ provider : 'openai' ,
891+ apiKey : 'deprecated-key' , // secretlint-disable-line
892+
893+ // Unknown options
894+ aioSandbox : 'test-value' ,
895+ customFeature : true ,
896+ } ;
897+
898+ const result = buildAppConfig ( cliArgs , { } ) ;
899+
900+ // Deprecated options should be handled normally
901+ expect ( result . model ) . toEqual ( {
902+ provider : 'openai' ,
903+ apiKey : 'deprecated-key' , // secretlint-disable-line
904+ } ) ;
905+
906+ // Unknown options should be preserved
907+ expect ( result ) . toHaveProperty ( 'aioSandbox' , 'test-value' ) ;
908+ expect ( result ) . toHaveProperty ( 'customFeature' , true ) ;
909+ } ) ;
910+
911+ it ( 'should handle unknown options with complex data types' , ( ) => {
912+ const complexObject = {
913+ nested : {
914+ array : [ 1 , 2 , 3 ] ,
915+ boolean : true ,
916+ string : 'test' ,
917+ } ,
918+ } ;
919+
920+ const cliArgs : AgentCLIArguments = {
921+ model : {
922+ provider : 'openai' ,
923+ } ,
924+ complexUnknownOption : complexObject ,
925+ arrayOption : [ 'item1' , 'item2' ] ,
926+ numberOption : 42 ,
927+ booleanOption : false ,
928+ } ;
929+
930+ const result = buildAppConfig ( cliArgs , { } ) ;
931+
932+ expect ( result ) . toHaveProperty ( 'complexUnknownOption' , complexObject ) ;
933+ expect ( result ) . toHaveProperty ( 'arrayOption' , [ 'item1' , 'item2' ] ) ;
934+ expect ( result ) . toHaveProperty ( 'numberOption' , 42 ) ;
935+ expect ( result ) . toHaveProperty ( 'booleanOption' , false ) ;
936+ } ) ;
937+
938+ it ( 'should preserve unknown options when merging with user config' , ( ) => {
939+ const cliArgs : AgentCLIArguments = {
940+ model : {
941+ provider : 'openai' ,
942+ } ,
943+ aioSandbox : 'cli-value' ,
944+ cliOnlyOption : 'cli-only' ,
945+ } ;
946+
947+ const userConfig : AgentAppConfig = {
948+ model : {
949+ id : 'user-model' ,
950+ } ,
951+ instructions : 'User instructions' ,
952+ // User config might also have unknown properties
953+ userSpecificOption : 'user-value' ,
954+ } as any ;
955+
956+ const result = buildAppConfig ( cliArgs , userConfig ) ;
957+
958+ // Known options should merge correctly
959+ expect ( result . model ) . toEqual ( {
960+ provider : 'openai' , // From CLI
961+ id : 'user-model' , // From user config
962+ } ) ;
963+ expect ( result . instructions ) . toBe ( 'User instructions' ) ;
964+
965+ // Unknown options from both sources should be preserved
966+ expect ( result ) . toHaveProperty ( 'aioSandbox' , 'cli-value' ) ; // CLI overrides
967+ expect ( result ) . toHaveProperty ( 'cliOnlyOption' , 'cli-only' ) ;
968+ expect ( result ) . toHaveProperty ( 'userSpecificOption' , 'user-value' ) ;
969+ } ) ;
970+
971+ it ( 'should handle unknown options with CLI enhancer' , ( ) => {
972+ const cliArgs : AgentCLIArguments = {
973+ model : {
974+ provider : 'openai' ,
975+ } ,
976+ aioSandbox : 'test-value' ,
977+ customOption : 'original-value' ,
978+ } ;
979+
980+ const userConfig : AgentAppConfig = { } ;
981+
982+ const enhancer : any = ( cliArguments : any , appConfig : any ) => {
983+ // Enhancer might modify unknown options
984+ if ( cliArguments . customOption ) {
985+ appConfig . enhancedCustomOption = `enhanced-${ cliArguments . customOption } ` ;
986+ }
987+ } ;
988+
989+ const result = buildAppConfig ( cliArgs , userConfig , undefined , enhancer ) ;
990+
991+ // Original unknown options should be preserved
992+ expect ( result ) . toHaveProperty ( 'aioSandbox' , 'test-value' ) ;
993+ expect ( result ) . toHaveProperty ( 'customOption' , 'original-value' ) ;
994+
995+ // Enhancer modifications should also be present
996+ expect ( result ) . toHaveProperty ( 'enhancedCustomOption' , 'enhanced-original-value' ) ;
997+ } ) ;
998+
999+ it ( 'should not include known options in unknown options preservation' , ( ) => {
1000+ const cliArgs : AgentCLIArguments = {
1001+ // All known options
1002+ model : { provider : 'openai' } ,
1003+ thinking : { type : 'enabled' } ,
1004+ toolCallEngine : 'native' ,
1005+ share : { provider : 'test' } ,
1006+ snapshot : { enable : true } ,
1007+ logLevel : 'info' as any ,
1008+ server : { exclusive : true } ,
1009+ port : 3000 ,
1010+ provider : 'deprecated-provider' ,
1011+ apiKey : 'deprecated-key' , // secretlint-disable-line
1012+ baseURL : 'deprecated-url' ,
1013+ shareProvider : 'deprecated-share' ,
1014+ config : [ 'config.json' ] ,
1015+ debug : true ,
1016+ quiet : false ,
1017+ stream : true ,
1018+ open : true ,
1019+ agent : 'test-agent' ,
1020+ headless : true ,
1021+ input : 'test' ,
1022+ format : 'json' ,
1023+ includeLogs : true ,
1024+ useCache : true ,
1025+ workspace : '/workspace' ,
1026+
1027+ // Unknown option
1028+ unknownOption : 'should-be-preserved' ,
1029+ } ;
1030+
1031+ const result = buildAppConfig ( cliArgs , { } ) ;
1032+
1033+ // All the known options should be properly processed, not duplicated as unknown
1034+ expect ( result . model ?. provider ) . toBe ( 'openai' ) ;
1035+ expect ( result . thinking ?. type ) . toBe ( 'enabled' ) ;
1036+ expect ( result . toolCallEngine ) . toBe ( 'native' ) ;
1037+ expect ( result . share ?. provider ) . toBe ( 'test' ) ;
1038+ expect ( result . snapshot ?. enable ) . toBe ( true ) ;
1039+ expect ( result . server ?. exclusive ) . toBe ( true ) ;
1040+ expect ( result . server ?. port ) . toBe ( 3000 ) ;
1041+
1042+ // Unknown option should be preserved
1043+ expect ( result ) . toHaveProperty ( 'unknownOption' , 'should-be-preserved' ) ;
1044+
1045+ // Known CLI-only options should not appear
1046+ expect ( result ) . not . toHaveProperty ( 'agent' ) ;
1047+ expect ( result ) . not . toHaveProperty ( 'workspace' ) ;
1048+ expect ( result ) . not . toHaveProperty ( 'debug' ) ;
1049+ expect ( result ) . not . toHaveProperty ( 'config' ) ;
1050+ } ) ;
1051+ } ) ;
8071052} ) ;
0 commit comments