@@ -52,7 +52,6 @@ public class AppConfig implements Serializable {
5252 private final String listenerIndexer ;
5353 private final String providerConfig ;
5454 private final String providerConfigHash ;
55- private final transient JsonNode providerConfigRoot ;
5655 private final Map <String , Secret > configValues ;
5756
5857 public AppConfig (final String host , final Map <String , Secret > secrets ) {
@@ -68,23 +67,22 @@ public AppConfig(final String host, final Map<String, Secret> secrets) {
6867
6968 if (StringUtils .isNotBlank (providerConfig )) {
7069 providerConfigHash = DigestUtils .sha256Hex (providerConfig );
71- providerConfigRoot = parseProviderConfig (providerConfig );
70+ final JsonNode providerConfigRoot = parseProviderConfig (providerConfig );
7271 model = buildModelFromProviderConfigNode (providerConfigRoot , "chat" , AIModelType .TEXT );
7372 imageModel = buildModelFromProviderConfigNode (providerConfigRoot , "image" , AIModelType .IMAGE );
7473 embeddingsModel = buildModelFromProviderConfigNode (providerConfigRoot , "embeddings" , AIModelType .EMBEDDINGS );
7574 } else {
7675 providerConfigHash = "no-config" ;
77- providerConfigRoot = MAPPER .createObjectNode ();
7876 model = AIModel .NOOP_MODEL ;
7977 imageModel = AIModel .NOOP_MODEL ;
8078 embeddingsModel = AIModel .NOOP_MODEL ;
8179 }
8280
83- rolePrompt = getFromSection ( providerConfigRoot , "chat" , "rolePrompt" , AppKeys .ROLE_PROMPT . defaultValue );
84- textPrompt = getFromSection ( providerConfigRoot , "chat" , "textPrompt" , AppKeys .TEXT_PROMPT . defaultValue );
85- imagePrompt = getFromSection ( providerConfigRoot , "image" , "imagePrompt" , AppKeys .IMAGE_PROMPT . defaultValue );
86- imageSize = getFromSection ( providerConfigRoot , "image" , "size" , AppKeys .IMAGE_SIZE . defaultValue );
87- listenerIndexer = getFromSection ( providerConfigRoot , "embeddings" , "listenerIndexer" , AppKeys .LISTENER_INDEXER . defaultValue );
81+ rolePrompt = aiAppUtil . discoverSecret ( secrets , AppKeys .ROLE_PROMPT );
82+ textPrompt = aiAppUtil . discoverSecret ( secrets , AppKeys .TEXT_PROMPT );
83+ imagePrompt = aiAppUtil . discoverSecret ( secrets , AppKeys .IMAGE_PROMPT );
84+ imageSize = aiAppUtil . discoverSecret ( secrets , AppKeys .IMAGE_SIZE );
85+ listenerIndexer = aiAppUtil . discoverSecret ( secrets , AppKeys .LISTENER_INDEXER );
8886
8987 configValues = secrets .entrySet ().stream ().collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue ));
9088
@@ -329,7 +327,7 @@ public String getProviderConfig() {
329327 }
330328
331329 /**
332- * Returns the SHA-256 hex digest of the {@code providerConfig} JSON, or {@code "no-config" } if not set.
330+ * Returns the SHA-256 hex digest of the {@code providerConfig} JSON, or {@code null } if not set.
333331 * Computed once at construction time — safe to use as a cache key on every request.
334332 */
335333 public String getProviderConfigHash () {
@@ -355,25 +353,6 @@ public boolean isEnabled() {
355353 return true ;
356354 }
357355
358- private static String getFromSection (final JsonNode root , final String section ,
359- final String field , final String defaultValue ) {
360- try {
361- final JsonNode sectionNode = root .get (section );
362- if (sectionNode == null || sectionNode .isNull ()) {
363- return defaultValue ;
364- }
365- final JsonNode fieldNode = sectionNode .get (field );
366- if (fieldNode == null || fieldNode .isNull ()) {
367- return defaultValue ;
368- }
369- // Container nodes (object/array) are serialized back to a JSON string (e.g. listenerIndexer)
370- final String value = fieldNode .isContainerNode () ? fieldNode .toString () : fieldNode .asText ();
371- return StringUtils .isNotBlank (value ) ? value : defaultValue ;
372- } catch (final Exception e ) {
373- return defaultValue ;
374- }
375- }
376-
377356 @ com .google .common .annotations .VisibleForTesting
378357 static JsonNode parseProviderConfig (final String json ) {
379358 try {
0 commit comments