Expected Behavior

The project should be fully configurable using both Spring Boot configuration file formats: properties and yaml. There should not be the keys that serve as both scalar and a container for more keys/objects at the same time.

Current Behavior

Currently there are some keys that serve as both scalar and a container for more keys/objects at the same time.

E.g., if I have both spring-ai-starter-model-ollama and spring-ai-starter-model-vertex-ai-embedding, then I'm forced to use these properties together to disable one of the auto-configurations.

spring.ai.model.embedding=none # Disable Ollama embeddings
spring.ai.model.embedding.text=vertexai # Enable Vertex AI embeddings

Otherwise the DI container will have 2 beans of EmbeddingModel type that I don't want:

Parameter 0 of constructor in me.venn.ai.EmbeddingController required a single bean, but 2 were found:
    - ollamaEmbeddingModel: defined by method 'ollamaEmbeddingModel' in class path resource [org/springframework/ai/model/ollama/autoconfigure/OllamaEmbeddingAutoConfiguration.class]
    - textEmbedding: defined by method 'textEmbedding' in class path resource [org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiTextEmbeddingAutoConfiguration.class]

But if I use application.yaml instead of application.properties I can't use these properties like this:

spring:
  ai:
    model:
      embedding: none
        text: vertexai  #  invalid!

It is invalid because embedding can't be both a value (none) and a container for further nesting.

The workaround is to flatten some keys like this:

spring:
  ai:
    model:
      embedding: none
      embedding.text: vertexai

This works because Spring Boot's Binder flattens the properties before binding them to the @ConfigurationProperties classes.

But it doesn't look like it is intended usage. I never seen similar clashes in any autoconfiguration of any Spring Boot related project.

I think, Spring AI should take it into account and never create configuration properties which have a value, but at the same time are objects themselves with sub-keys.

In this particular case the spring.ai.model.embedding could be renamed to spring.ai.model.embedding.model-name for example. Or spring.ai.model.embedding.text could be renamed to spring.ai.model.embedding-text (probaby will affect less projects, maybe only Vertex AI if only it uses these keys, I'm not sure).

But I seen other examples of such collisions in other parts of the docs (can't remember which exactly, unfortunately).

I suggest going through every property and collect if it clashes with any other property, and then take a decision. Renaming the properties will be backward incompatible in some cases, but it is better to do this sooner than later.