@@ -17,6 +17,7 @@ import play.api.libs.json.{Format, JsObject, JsValue, Json}
1717
1818import scala .concurrent .{ExecutionContext , Future }
1919import com .fasterxml .jackson .core .JsonProcessingException
20+ import com .typesafe .config .Config
2021import io .cequence .openaiscala .OpenAIScalaClientException
2122import io .cequence .openaiscala .domain .JsonSchema .JsonSchemaOrMap
2223import io .cequence .wsclient .JsonUtil
@@ -127,7 +128,8 @@ object OpenAIChatCompletionExtra extends OpenAIServiceConsts {
127128 maxRetries : Option [Int ] = Some (defaultMaxRetries),
128129 retryOnAnyError : Boolean = false ,
129130 taskNameForLogging : Option [String ] = None ,
130- jsonSchemaModels : Seq [String ] = defaultModelsSupportingJsonSchema,
131+ jsonSchemaModels : Seq [String ] = Nil ,
132+ config : Option [Config ] = None ,
131133 enforceJsonSchemaMode : Boolean = false ,
132134 parseJson : String => JsValue = defaultParseJsonOrRepair
133135 )(
@@ -144,6 +146,7 @@ object OpenAIChatCompletionExtra extends OpenAIServiceConsts {
144146 settings,
145147 taskNameForLoggingFinal,
146148 jsonSchemaModels,
149+ config,
147150 enforceJsonSchemaMode
148151 )
149152 } else {
@@ -203,19 +206,42 @@ object OpenAIChatCompletionExtra extends OpenAIServiceConsts {
203206 }
204207 }
205208
206- val defaultModelsSupportingJsonSchema = {
207- val config = loadDefaultConfig()
209+ private lazy val defaultConfig = loadDefaultConfig()
210+
211+ private def getJsonSchemaModels (
212+ jsonSchemaModels : Seq [String ],
213+ config : Option [Config ]
214+ ): Seq [String ] = {
208215 import scala .collection .JavaConverters ._
209- config.getStringList(s " $configPrefix.models-supporting-json-schema " ).asScala.toSeq
216+ val cfg = config.getOrElse(defaultConfig)
217+ val configPath = s " $configPrefix.models-supporting-json-schema "
218+ val configModels = if (cfg.hasPath(configPath)) {
219+ cfg.getStringList(configPath).asScala.toSeq
220+ } else {
221+ Nil
222+ }
223+
224+ if (jsonSchemaModels.isEmpty) {
225+ configModels
226+ } else if (config.isDefined) {
227+ // Both explicit models and custom config provided - merge and deduplicate
228+ (jsonSchemaModels ++ configModels).distinct
229+ } else {
230+ // Only explicit models provided
231+ jsonSchemaModels
232+ }
210233 }
211234
212235 def handleOutputJsonSchema (
213236 messages : Seq [BaseMessage ],
214237 settings : CreateChatCompletionSettings ,
215238 taskNameForLogging : String ,
216- jsonSchemaModels : Seq [String ] = defaultModelsSupportingJsonSchema,
239+ jsonSchemaModels : Seq [String ] = Nil ,
240+ config : Option [Config ] = None ,
217241 enforceJsonSchemaMode : Boolean = false
218242 ): (Seq [BaseMessage ], CreateChatCompletionSettings ) = {
243+ val jsonSchemaModelsFinal = getJsonSchemaModels(jsonSchemaModels, config)
244+
219245 val jsonSchemaDef = settings.jsonSchema.getOrElse(
220246 throw new IllegalArgumentException (" JSON schema is not defined but expected." )
221247 )
@@ -226,7 +252,7 @@ object OpenAIChatCompletionExtra extends OpenAIServiceConsts {
226252 // to be more robust we also match models with a suffix
227253 if (
228254 enforceJsonSchemaMode ||
229- jsonSchemaModels .exists(model =>
255+ jsonSchemaModelsFinal .exists(model =>
230256 settings.model.equals(model) || settings.model.endsWith(" -" + model)
231257 )
232258 ) {
0 commit comments