Skip to content

Commit 2c24b98

Browse files
wenjin272claude
andcommitted
[api] Rename action 'on:' to 'listen_to:' in YAML
Per PR #670 review comment by xintongsong: the previous keyword collided with YAML 1.1's boolean resolver (which coerces unquoted 'on' / 'off' / 'yes' / 'no'), forcing a custom SafeLoader subclass to patch the bool resolver. The new keyword 'listen_to:' aligns with the Java @action(listenEventTypes = {...}) annotation and lets us drop the loader workaround so the YAML stays portable to any standard YAML 1.1 / 1.2 consumer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1c67e3f commit 2c24b98

14 files changed

Lines changed: 58 additions & 88 deletions

docs/yaml-schema.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,18 @@
2929
"default": null,
3030
"title": "Function"
3131
},
32-
"name": {
33-
"title": "Name",
34-
"type": "string"
35-
},
36-
"on": {
32+
"listen_to": {
3733
"items": {
3834
"type": "string"
3935
},
4036
"minItems": 1,
41-
"title": "On",
37+
"title": "Listen To",
4238
"type": "array"
4339
},
40+
"name": {
41+
"title": "Name",
42+
"type": "string"
43+
},
4444
"type": {
4545
"anyOf": [
4646
{
@@ -60,7 +60,7 @@
6060
},
6161
"required": [
6262
"name",
63-
"on"
63+
"listen_to"
6464
],
6565
"title": "ActionSpec",
6666
"type": "object"

python/flink_agents/api/yaml/loader.py

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
environment.
2020
"""
2121

22-
import re
2322
from pathlib import Path
2423
from typing import TYPE_CHECKING, Any, Dict, List, Tuple
2524

@@ -51,27 +50,6 @@
5150
YamlAgentsDocument,
5251
)
5352

54-
55-
class _FlinkAgentsYamlLoader(yaml.SafeLoader):
56-
"""SafeLoader that recognizes only ``true``/``false`` as booleans.
57-
58-
PyYAML follows YAML 1.1 by default, where ``on``/``off``/``yes``/``no``
59-
also coerce to booleans. ``on:`` is the natural way to declare an
60-
action's event listeners in this API, so we strip those legacy
61-
keywords from the bool resolver.
62-
"""
63-
64-
65-
_FlinkAgentsYamlLoader.yaml_implicit_resolvers = {
66-
key: [(tag, regexp) for tag, regexp in resolvers if tag != "tag:yaml.org,2002:bool"]
67-
for key, resolvers in yaml.SafeLoader.yaml_implicit_resolvers.items()
68-
}
69-
_FlinkAgentsYamlLoader.add_implicit_resolver(
70-
"tag:yaml.org,2002:bool",
71-
re.compile(r"^(?:true|True|TRUE|false|False|FALSE)$"),
72-
list("tTfF"),
73-
)
74-
7553
# Default Java parameter types for an action. Action methods in
7654
# flink-agents always have signature (Event, RunnerContext).
7755
_JAVA_ACTION_PARAMETER_TYPES: list[str] = [
@@ -145,7 +123,7 @@ def resolve_function(
145123

146124
def _load_document(path: Path | str) -> YamlAgentsDocument:
147125
text = Path(path).read_text()
148-
raw = yaml.load(text, Loader=_FlinkAgentsYamlLoader)
126+
raw = yaml.load(text, Loader=yaml.SafeLoader)
149127
if raw is None:
150128
msg = f"YAML file {path} is empty"
151129
raise ValueError(msg)
@@ -192,7 +170,7 @@ def _resolve_action_function(action: ActionSpec) -> Function:
192170

193171
def _add_action_to_agent(agent: Agent, action: ActionSpec) -> None:
194172
func = _resolve_action_function(action)
195-
events = [resolve_event_type(e) for e in action.on]
173+
events = [resolve_event_type(e) for e in action.listen_to]
196174
config = action.config or {}
197175
agent.add_action(action.name, events, func, **config)
198176

python/flink_agents/api/yaml/specs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class ActionSpec(BaseModel):
150150

151151
name: str
152152
function: str | None = None
153-
on: List[str] = Field(..., min_length=1)
153+
listen_to: List[str] = Field(..., min_length=1)
154154
config: Dict[str, Any] | None = None
155155
type: Language | None = None
156156

python/flink_agents/api/yaml/tests/fixtures/multi_agent.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ agents:
33
actions:
44
- name: increment
55
function: flink_agents.api.yaml.tests.fixtures.loader_targets:increment
6-
on: [input]
6+
listen_to: [input]
77
- name: a2
88
actions:
99
- name: decrement
1010
function: flink_agents.api.yaml.tests.fixtures.loader_targets:decrement
11-
on: [input]
11+
listen_to: [input]

python/flink_agents/api/yaml/tests/fixtures/multi_file_a.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ agents:
33
actions:
44
- name: increment
55
function: flink_agents.api.yaml.tests.fixtures.loader_targets:increment
6-
on: [input]
7-
6+
listen_to: [input]
87
chat_model_connections:
98
- name: conn_from_a
109
clazz: ollama

python/flink_agents/api/yaml/tests/fixtures/multi_file_b.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ agents:
33
actions:
44
- name: decrement
55
function: flink_agents.api.yaml.tests.fixtures.loader_targets:decrement
6-
on: [input]
7-
6+
listen_to: [input]
87
chat_model_connections:
98
- name: conn_from_b
109
clazz: ollama

python/flink_agents/api/yaml/tests/fixtures/single_agent.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ agents:
33
actions:
44
- name: increment
55
function: flink_agents.api.yaml.tests.fixtures.loader_targets:increment
6-
on: [input]
6+
listen_to: [input]

python/flink_agents/api/yaml/tests/fixtures/with_descriptors.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ agents:
33
actions:
44
- name: increment
55
function: flink_agents.api.yaml.tests.fixtures.loader_targets:increment
6-
on: [input]
6+
listen_to: [input]
77
- name: decrement
88
function: flink_agents.api.yaml.tests.fixtures.loader_targets:decrement
9-
on: [chat_response]
9+
listen_to: [chat_response]
1010
chat_model_connections:
1111
- name: ollama_conn
1212
clazz: ollama

python/flink_agents/api/yaml/tests/fixtures/with_shared.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ agents:
44
- shared_inc
55
- name: own_dec
66
function: flink_agents.api.yaml.tests.fixtures.loader_targets:decrement
7-
on: [chat_response]
7+
listen_to: [chat_response]
88
- name: a2
99
actions:
1010
- shared_inc
@@ -17,4 +17,4 @@ chat_model_connections:
1717
actions:
1818
- name: shared_inc
1919
function: flink_agents.api.yaml.tests.fixtures.loader_targets:increment
20-
on: [input]
20+
listen_to: [input]

python/flink_agents/api/yaml/tests/test_loader.py

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -99,35 +99,19 @@ def test_resolve_function_missing_target_raises_importerror() -> None:
9999
func.as_callable()
100100

101101

102-
def test_build_agents_treats_unquoted_on_as_string_not_bool(tmp_path: Path) -> None:
103-
yaml_text = (
104-
"agents:\n"
105-
" - name: a\n"
106-
" actions:\n"
107-
" - name: increment\n"
108-
f" function: {_TARGETS_MODULE}:increment\n"
109-
" on: [input]\n"
110-
)
111-
p = tmp_path / "on_keyword.yaml"
112-
p.write_text(yaml_text)
113-
agents, _, _ = build_agents(p)
114-
assert "a" in agents
115-
assert "increment" in agents["a"].actions
116-
117-
118102
def test_build_agents_rejects_duplicate_agent_within_file(tmp_path: Path) -> None:
119103
yaml_text = (
120104
"agents:\n"
121105
" - name: dup\n"
122106
" actions:\n"
123107
" - name: increment\n"
124108
f" function: {_TARGETS_MODULE}:increment\n"
125-
" on: [input]\n"
109+
" listen_to: [input]\n"
126110
" - name: dup\n"
127111
" actions:\n"
128112
" - name: decrement\n"
129113
f" function: {_TARGETS_MODULE}:decrement\n"
130-
" on: [input]\n"
114+
" listen_to: [input]\n"
131115
)
132116
p = tmp_path / "dup.yaml"
133117
p.write_text(yaml_text)
@@ -305,9 +289,9 @@ def test_load_yaml_duplicate_shared_action_within_file_errors(tmp_path) -> None:
305289
" - name: a\n"
306290
"actions:\n"
307291
" - name: shared\n"
308-
" on: [input]\n"
292+
" listen_to: [input]\n"
309293
" - name: shared\n"
310-
" on: [input]\n"
294+
" listen_to: [input]\n"
311295
)
312296
env = AgentsExecutionEnvironment.get_execution_environment()
313297
with pytest.raises(ValueError, match="Duplicate shared action name 'shared'"):
@@ -506,7 +490,7 @@ def test_build_agents_builds_java_action(tmp_path: Path) -> None:
506490
" - name: a1\n"
507491
" type: java\n"
508492
" function: com.example.MyAgent:handle\n"
509-
" on: [input]\n"
493+
" listen_to: [input]\n"
510494
)
511495
p = tmp_path / "java_action.yaml"
512496
p.write_text(yaml_text)
@@ -535,7 +519,7 @@ def test_build_agents_rejects_java_tool_missing_parameter_types(
535519
" actions:\n"
536520
" - name: noop\n"
537521
f" function: {_TARGETS_MODULE}:increment\n"
538-
" on: [input]\n"
522+
" listen_to: [input]\n"
539523
)
540524
p = tmp_path / "java_tool_no_params.yaml"
541525
p.write_text(yaml_text)
@@ -562,7 +546,7 @@ def test_build_agents_builds_java_tool_descriptor(tmp_path: Path) -> None:
562546
" actions:\n"
563547
" - name: noop\n"
564548
f" function: {_TARGETS_MODULE}:increment\n"
565-
" on: [input]\n"
549+
" listen_to: [input]\n"
566550
)
567551
p = tmp_path / "java_tool.yaml"
568552
p.write_text(yaml_text)

0 commit comments

Comments
 (0)