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

commit 27cf3bd86ecfa43f028faa3631690fee23996776
Author: WenjinXie <[email protected]>
AuthorDate: Fri Oct 16 11:51:25 2026 +0800

    [api][java][python] Honor empty text when loading YAML prompts
    
    Use message templates when text is empty, matching PromptSpec validation. 
Cover omitted, null and empty text with message role, order and formatting 
assertions.
    
    Generated-by: Codex CLI 0.153.4 (GPT-6)
    
    Co-authored-by: Codex <[email protected]>
---
 .../apache/flink/agents/api/yaml/YamlLoader.java   |  2 +-
 .../agents/api/yaml/YamlLoaderBuildersTest.java    | 29 +++++++++++++++++-----
 python/flink_agents/api/yaml/loader.py             |  2 +-
 python/flink_agents/api/yaml/tests/test_loader.py  | 27 ++++++++++++++++++++
 4 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/api/src/main/java/org/apache/flink/agents/api/yaml/YamlLoader.java 
b/api/src/main/java/org/apache/flink/agents/api/yaml/YamlLoader.java
index a9958f7c..bbb1242e 100644
--- a/api/src/main/java/org/apache/flink/agents/api/yaml/YamlLoader.java
+++ b/api/src/main/java/org/apache/flink/agents/api/yaml/YamlLoader.java
@@ -159,7 +159,7 @@ public final class YamlLoader {
 
     /** Build a {@link Prompt} from a parsed {@link PromptSpec}. */
     public static Prompt buildPrompt(PromptSpec spec) {
-        if (spec.getText() != null) {
+        if (spec.getText() != null && !spec.getText().isEmpty()) {
             return Prompt.fromText(spec.getText());
         }
         List<ChatMessage> messages =
diff --git 
a/api/src/test/java/org/apache/flink/agents/api/yaml/YamlLoaderBuildersTest.java
 
b/api/src/test/java/org/apache/flink/agents/api/yaml/YamlLoaderBuildersTest.java
index 709cd1d0..860727be 100644
--- 
a/api/src/test/java/org/apache/flink/agents/api/yaml/YamlLoaderBuildersTest.java
+++ 
b/api/src/test/java/org/apache/flink/agents/api/yaml/YamlLoaderBuildersTest.java
@@ -20,6 +20,8 @@ package org.apache.flink.agents.api.yaml;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import org.apache.flink.agents.api.chat.messages.ChatMessage;
+import org.apache.flink.agents.api.chat.messages.MessageRole;
 import org.apache.flink.agents.api.function.JavaFunction;
 import org.apache.flink.agents.api.function.PythonFunction;
 import org.apache.flink.agents.api.prompt.Prompt;
@@ -35,7 +37,10 @@ import org.apache.flink.agents.api.yaml.spec.PromptSpec;
 import org.apache.flink.agents.api.yaml.spec.SkillsSpec;
 import org.apache.flink.agents.api.yaml.spec.ToolSpec;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
+import java.util.List;
 import java.util.Map;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -178,15 +183,27 @@ class YamlLoaderBuildersTest {
         assertThat(prompt.formatString(Map.of())).isEqualTo("hi");
     }
 
-    @Test
-    void buildPromptMessages() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {"", "text: null\n", "text: \"\"\n"})
+    void buildPromptMessagesWithUnsetText(String textField) throws Exception {
         PromptSpec spec =
                 M.readValue(
-                        "name: p\nmessages:\n  - {role: system, content: 
hi}\n", PromptSpec.class);
+                        "name: p\n"
+                                + textField
+                                + "messages:\n"
+                                + "  - {role: system, content: 'Hello 
{name}'}\n"
+                                + "  - {role: user, content: '{question}'}\n",
+                        PromptSpec.class);
         Prompt prompt = YamlLoader.buildPrompt(spec);
-        // Both message-templated and text-templated prompts produce 
LocalPrompt instances;
-        // confirm the constructed prompt formats without error.
-        assertThat(prompt).isNotNull();
+        List<ChatMessage> messages =
+                prompt.formatMessages(
+                        MessageRole.SYSTEM, Map.of("name", "Alice", 
"question", "How are you?"));
+        assertThat(messages)
+                .extracting(ChatMessage::getRole)
+                .containsExactly(MessageRole.SYSTEM, MessageRole.USER);
+        assertThat(messages)
+                .extracting(ChatMessage::getText)
+                .containsExactly("Hello Alice", "How are you?");
     }
 
     @Test
diff --git a/python/flink_agents/api/yaml/loader.py 
b/python/flink_agents/api/yaml/loader.py
index dec3c526..77ba5711 100644
--- a/python/flink_agents/api/yaml/loader.py
+++ b/python/flink_agents/api/yaml/loader.py
@@ -196,7 +196,7 @@ def _build_tool(spec: ToolSpec) -> FunctionTool:
 
 
 def _build_prompt(spec: PromptSpec) -> Prompt:
-    if spec.text is not None:
+    if spec.text:
         return Prompt.from_text(spec.text)
     messages = [
         ChatMessage.of(MessageRole(m.role.value), m.content)
diff --git a/python/flink_agents/api/yaml/tests/test_loader.py 
b/python/flink_agents/api/yaml/tests/test_loader.py
index 6abb8564..21ee9cef 100644
--- a/python/flink_agents/api/yaml/tests/test_loader.py
+++ b/python/flink_agents/api/yaml/tests/test_loader.py
@@ -222,6 +222,33 @@ def test_build_agents_loads_tools_and_prompts() -> None:
     assert msg_prompt.template[1].text == "{q}"
 
 
[email protected](
+    "text_field", ["", "        text: null\n", '        text: ""\n']
+)
+def test_build_agents_preserves_prompt_messages_with_unset_text(
+    tmp_path: Path, text_field: str
+) -> None:
+    path = tmp_path / "prompt.yaml"
+    path.write_text(
+        "agents:\n"
+        "  - name: chat_agent\n"
+        "    prompts:\n"
+        "      - name: greeting\n"
+        f"{text_field}"
+        "        messages:\n"
+        "          - {role: system, content: 'Hello {name}'}\n"
+        "          - {role: user, content: '{question}'}\n"
+    )
+    agents, _, _ = build_agents(path)
+    prompt = agents["chat_agent"].resources[ResourceType.PROMPT]["greeting"]
+    messages = prompt.format_messages(name="Alice", question="How are you?")
+    assert [message.role for message in messages] == [
+        MessageRole.SYSTEM,
+        MessageRole.USER,
+    ]
+    assert [message.text for message in messages] == ["Hello Alice", "How are 
you?"]
+
+
 def test_build_agents_handles_shared_resources_and_actions() -> None:
     agents, shared_resources, shared_actions = build_agents(
         _FIXTURES / "with_shared.yaml"

Reply via email to