This is an automated email from the ASF dual-hosted git repository.
wenjin272 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/flink-agents.git
The following commit(s) were added to refs/heads/main by this push:
new 0c8da869 [fix] Make agents block optional so infra-only YAML files
load (#775) (#809)
0c8da869 is described below
commit 0c8da869605112de7549393d5ebeb1393e0bbe1f
Author: Wenjin Xie <[email protected]>
AuthorDate: Mon Jun 8 17:12:11 2026 +0800
[fix] Make agents block optional so infra-only YAML files load (#775) (#809)
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
---
.../apache/flink/agents/api/yaml/spec/YamlAgentsDocument.java | 4 ++--
.../flink/agents/api/yaml/spec/YamlAgentsDocumentTest.java | 10 ++++++++++
docs/content/docs/development/yaml.md | 2 +-
docs/yaml-schema.json | 5 +----
python/flink_agents/api/yaml/specs.py | 9 ++++++---
python/flink_agents/api/yaml/tests/test_specs.py | 9 ++++++---
6 files changed, 26 insertions(+), 13 deletions(-)
diff --git
a/api/src/main/java/org/apache/flink/agents/api/yaml/spec/YamlAgentsDocument.java
b/api/src/main/java/org/apache/flink/agents/api/yaml/spec/YamlAgentsDocument.java
index cc0874d0..1b0fbfa9 100644
---
a/api/src/main/java/org/apache/flink/agents/api/yaml/spec/YamlAgentsDocument.java
+++
b/api/src/main/java/org/apache/flink/agents/api/yaml/spec/YamlAgentsDocument.java
@@ -42,7 +42,7 @@ public final class YamlAgentsDocument {
@JsonCreator
public YamlAgentsDocument(
- @JsonProperty(value = "agents", required = true) List<AgentSpec>
agents,
+ @JsonProperty("agents") List<AgentSpec> agents,
@JsonProperty("prompts") List<PromptSpec> prompts,
@JsonProperty("tools") List<ToolSpec> tools,
@JsonProperty("skills") List<SkillsSpec> skills,
@@ -54,7 +54,7 @@ public final class YamlAgentsDocument {
@JsonProperty("embedding_model_setups") List<DescriptorSpec>
embeddingModelSetups,
@JsonProperty("vector_stores") List<DescriptorSpec> vectorStores,
@JsonProperty("mcp_servers") List<DescriptorSpec> mcpServers) {
- this.agents = agents;
+ this.agents = orEmpty(agents);
this.prompts = orEmpty(prompts);
this.tools = orEmpty(tools);
this.skills = orEmpty(skills);
diff --git
a/api/src/test/java/org/apache/flink/agents/api/yaml/spec/YamlAgentsDocumentTest.java
b/api/src/test/java/org/apache/flink/agents/api/yaml/spec/YamlAgentsDocumentTest.java
index e5326826..d7e7604e 100644
---
a/api/src/test/java/org/apache/flink/agents/api/yaml/spec/YamlAgentsDocumentTest.java
+++
b/api/src/test/java/org/apache/flink/agents/api/yaml/spec/YamlAgentsDocumentTest.java
@@ -46,4 +46,14 @@ class YamlAgentsDocumentTest {
assertThat(doc.getActions()).hasSize(1);
assertThat(doc.getActions().get(0).getName()).isEqualTo("shared_a");
}
+
+ @Test
+ void infraOnlyFile() throws Exception {
+ YamlAgentsDocument doc =
+ M.readValue(
+ "chat_model_connections:\n - name: x\n clazz:
ollama\n",
+ YamlAgentsDocument.class);
+ assertThat(doc.getAgents()).isEmpty();
+ assertThat(doc.getChatModelConnections()).hasSize(1);
+ }
}
diff --git a/docs/content/docs/development/yaml.md
b/docs/content/docs/development/yaml.md
index 30760d80..a6054fa3 100644
--- a/docs/content/docs/development/yaml.md
+++ b/docs/content/docs/development/yaml.md
@@ -382,7 +382,7 @@ agentsEnv.loadYaml(Paths.get("./shared.yaml"));
{{< /tabs >}}
-A common pattern is to split a topology file (the agents themselves) from an
infrastructure file (chat-model connections, vector stores, ...). The
infrastructure file can be swapped per environment (dev / staging / prod)
without touching the agent definitions.
+A common pattern is to split a topology file (the agents themselves) from an
infrastructure file (chat-model connections, vector stores, ...). The
infrastructure file can be swapped per environment (dev / staging / prod)
without touching the agent definitions. The `agents:` block is optional, so an
infrastructure-only file (no `agents:` block) is loaded as shared resources.
For an end-to-end runnable walkthrough that loads a YAML-declared agent and
runs it on Flink, see [YAML Agent Quickstart]({{< ref
"docs/get-started/quickstart/yaml_agent" >}}).
diff --git a/docs/yaml-schema.json b/docs/yaml-schema.json
index 015fdebd..2b21d71d 100644
--- a/docs/yaml-schema.json
+++ b/docs/yaml-schema.json
@@ -400,7 +400,7 @@
}
},
"additionalProperties": false,
- "description": "Top-level YAML document.\n\nAlways wraps one or more agents
under ``agents:``. Resources and\nactions declared at the same level as
``agents:`` are shared:\nresources are registered on the environment; actions
can be\nreferenced from any agent by name string.",
+ "description": "Top-level YAML document.\n\nAgents are declared under
``agents:``. The block is optional, so a\nfile may carry only shared
infrastructure (chat-model connections,\nvector stores, ...) \u2014 useful for
splitting a topology file from an\ninfrastructure file that can be swapped per
environment. Resources\nand actions declared at the same level as ``agents:``
are shared:\nresources are registered on the environment; actions can
be\nreferenced from any agent by name string.",
"properties": {
"actions": {
"items": {
@@ -480,9 +480,6 @@
"type": "array"
}
},
- "required": [
- "agents"
- ],
"title": "YamlAgentsDocument",
"type": "object"
}
diff --git a/python/flink_agents/api/yaml/specs.py
b/python/flink_agents/api/yaml/specs.py
index b7b7cf71..cf99c66b 100644
--- a/python/flink_agents/api/yaml/specs.py
+++ b/python/flink_agents/api/yaml/specs.py
@@ -220,15 +220,18 @@ class AgentSpec(BaseModel):
class YamlAgentsDocument(BaseModel):
"""Top-level YAML document.
- Always wraps one or more agents under ``agents:``. Resources and
- actions declared at the same level as ``agents:`` are shared:
+ Agents are declared under ``agents:``. The block is optional, so a
+ file may carry only shared infrastructure (chat-model connections,
+ vector stores, ...) — useful for splitting a topology file from an
+ infrastructure file that can be swapped per environment. Resources
+ and actions declared at the same level as ``agents:`` are shared:
resources are registered on the environment; actions can be
referenced from any agent by name string.
"""
model_config = ConfigDict(extra="forbid")
- agents: List[AgentSpec]
+ agents: List[AgentSpec] = Field(default_factory=list)
prompts: List[PromptSpec] = Field(default_factory=list)
tools: List[ToolSpec] = Field(default_factory=list)
diff --git a/python/flink_agents/api/yaml/tests/test_specs.py
b/python/flink_agents/api/yaml/tests/test_specs.py
index e7028588..1c849f0f 100644
--- a/python/flink_agents/api/yaml/tests/test_specs.py
+++ b/python/flink_agents/api/yaml/tests/test_specs.py
@@ -224,9 +224,12 @@ def test_agent_spec_action_can_be_string_reference() ->
None:
assert isinstance(spec.actions[1], ActionSpec)
-def test_yaml_document_requires_agents() -> None:
- with pytest.raises(ValidationError):
- YamlAgentsDocument.model_validate({})
+def test_yaml_document_allows_infra_only_file() -> None:
+ doc = YamlAgentsDocument.model_validate(
+ {"chat_model_connections": [{"name": "x", "clazz": "ollama"}]}
+ )
+ assert doc.agents == []
+ assert doc.chat_model_connections[0].name == "x"
def test_yaml_document_minimal() -> None: