@@ -1011,6 +1011,16 @@ func (s *AccountService) ImportOwnedWithResult(ctx context.Context, ownerUserID
10111011 return nil , err
10121012 }
10131013 if ! IsOpenAIAgentIdentityCredentials (req .Credentials ) {
1014+ // 凭证文件导入没有单独的模型选择步骤。新建账号时若调用方未携带
1015+ // model_mapping,使用同一份活跃渠道定价并集生成 identity 白名单;
1016+ // 这不是平台默认模型兜底,且不会覆盖已有账号的白名单。
1017+ if ! IsOpenAIPersonalAccessTokenCredentials (req .Credentials ) {
1018+ credentials , err := s .ensureOwnedImportModelMapping (ctx , req .Platform , req .Credentials )
1019+ if err != nil {
1020+ return nil , err
1021+ }
1022+ req .Credentials = credentials
1023+ }
10141024 account , err := s .createOwned (ctx , ownerUserID , req , false )
10151025 if err != nil {
10161026 return nil , err
@@ -1040,6 +1050,9 @@ func (s *AccountService) ImportOwnedWithResult(ctx context.Context, ownerUserID
10401050 return & OwnedAccountImportResult {Account : account , Updated : true }, nil
10411051 }
10421052
1053+ if req .Credentials , err = s .ensureOwnedImportModelMapping (ctx , req .Platform , req .Credentials ); err != nil {
1054+ return nil , err
1055+ }
10431056 account , err := s .createOwned (ctx , ownerUserID , req , false )
10441057 if err == nil {
10451058 return & OwnedAccountImportResult {Account : account }, nil
@@ -1103,6 +1116,9 @@ func (s *AccountService) ImportOwnedValidatedPersonalAccessTokenWithResult(
11031116 return & OwnedAccountImportResult {Account : account , Updated : true }, nil
11041117 }
11051118
1119+ if req .Credentials , err = s .ensureOwnedImportModelMapping (ctx , req .Platform , req .Credentials ); err != nil {
1120+ return nil , err
1121+ }
11061122 account , err := s .createOwned (ctx , ownerUserID , req , true )
11071123 if err == nil {
11081124 return & OwnedAccountImportResult {Account : account }, nil
@@ -1358,7 +1374,6 @@ func (s *AccountService) createOwned(ctx context.Context, ownerUserID int64, req
13581374 if isAgentIdentity {
13591375 req .Credentials = normalizeOwnedAgentIdentityCredentials (req .Credentials )
13601376 }
1361- _ , modelMappingProvided := req .Credentials ["model_mapping" ]
13621377 targetLevel := NormalizeAccountLevel (req .AccountLevel )
13631378 levelConfigs , err := s .openAIAccountLevelConfigs (ctx )
13641379 if err != nil {
@@ -1369,11 +1384,6 @@ func (s *AccountService) createOwned(ctx context.Context, ownerUserID int64, req
13691384 if err := applyOwnedPersonalAccountTemplateToCreate (& req ); err != nil {
13701385 return nil , err
13711386 }
1372- if modelMappingProvided {
1373- if err := s .validateOwnedPersonalModelMapping (ctx , req .Platform , req .Credentials ); err != nil {
1374- return nil , err
1375- }
1376- }
13771387 if err := validateOwnedAccountSourceForPlatform (req .Platform , req .Type , req .Credentials , req .Extra ); err != nil {
13781388 return nil , err
13791389 }
@@ -1438,6 +1448,12 @@ func (s *AccountService) createOwned(ctx context.Context, ownerUserID int64, req
14381448 if err != nil {
14391449 return nil , err
14401450 }
1451+ // 个人账号只能使用非空、精确的服务端定价白名单。放在所有业务字段
1452+ // 校验之后、任何重复/容量检查和写入之前,既保持错误优先级,也确保
1453+ // 无效模型不会触发后续副作用。
1454+ if err := s .validateOwnedPersonalModelMapping (ctx , req .Platform , req .Credentials ); err != nil {
1455+ return nil , err
1456+ }
14411457
14421458 account := & Account {
14431459 Name : req .Name ,
@@ -1899,6 +1915,40 @@ func (s *AccountService) listOwnedSelectableModelIDs(ctx context.Context, platfo
18991915 return result , nil
19001916}
19011917
1918+ // ensureOwnedImportModelMapping supplies the compatibility mapping for a
1919+ // credential-file import that does not have a UI model-selection step. The
1920+ // generated mapping is always an identity whitelist from the current active
1921+ // channel pricing union; platform DefaultModels are intentionally never used.
1922+ func (s * AccountService ) ensureOwnedImportModelMapping (
1923+ ctx context.Context ,
1924+ platform string ,
1925+ credentials map [string ]any ,
1926+ ) (map [string ]any , error ) {
1927+ next := mergeAccountMap (credentials , nil )
1928+ if next == nil {
1929+ next = make (map [string ]any )
1930+ }
1931+ if _ , exists := next ["model_mapping" ]; exists {
1932+ return next , nil
1933+ }
1934+ models , err := s .listOwnedSelectableModelIDs (ctx , platform )
1935+ if err != nil {
1936+ return nil , err
1937+ }
1938+ if len (models ) == 0 {
1939+ return nil , ErrOwnedAccountModelMappingInvalid .WithMetadata (map [string ]string {
1940+ "field" : "model_mapping" ,
1941+ "platform" : strings .ToLower (strings .TrimSpace (platform )),
1942+ })
1943+ }
1944+ mapping := make (map [string ]any , len (models ))
1945+ for _ , model := range models {
1946+ mapping [model ] = model
1947+ }
1948+ next ["model_mapping" ] = mapping
1949+ return next , nil
1950+ }
1951+
19021952// ListOwnedSelectableModelIDs 返回号主可用于个人账号白名单的精确模型集合。
19031953// 它只暴露模型 ID,不泄露渠道、价格或分组配置。
19041954func (s * AccountService ) ListOwnedSelectableModelIDs (ctx context.Context , platform string ) ([]string , error ) {
0 commit comments