[api][test] Simplify cross-language Java action declaration and add e2e coverage#827
Conversation
…ions Action signatures are fixed (Event, RunnerContext), but the Python API forced callers to spell out parameter_types when declaring a Java action, while the YAML API auto-fills them. Add JavaFunction.for_action() to fill the fixed signature, share the ACTION_PARAMETER_TYPES constant with the YAML loader, and simplify the cross-language example. Tools keep explicit parameter_types since their signatures vary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The cross-language YAML e2e only covered Java resources/tools. Cover the action path: a basic YAML-declared Java action (multiplyByTwo, no parameter_types written — guards the loader auto-fill), plus orchestration actions in the other language bridged by the host-native built-in chat loop with a cross-language tool — Python host + Java actions and Java host + Python actions. Reuses existing handlers; only YAML + tests are new. Ollama/test-jar skips as before. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
wzhero1
left a comment
There was a problem hiding this comment.
Looks good overall — clean refactor + solid e2e coverage. One minor nit.
|
|
||
| #: Java parameter types of an action method. Action signatures are fixed | ||
| #: ``(Event, RunnerContext)``, so callers never have to spell them out. | ||
| ACTION_PARAMETER_TYPES: List[str] = [ |
There was a problem hiding this comment.
Nit: this constant is never meant to be mutated — a tuple makes the contract enforceable at the language level:
ACTION_PARAMETER_TYPES: Tuple[str, ...] = (
"org.apache.flink.agents.api.Event",
"org.apache.flink.agents.api.context.RunnerContext",
)for_action() already defensively copies with list(...), and pydantic v2 coerces sequences into List[str] on model creation, so all existing call sites (including the YAML loader at _resolve_action_function) would work unchanged. The only difference is that a stray .append() or [0] = ... would raise TypeError instead of silently corrupting every downstream caller in the process.
A tuple enforces the no-mutation contract at the language level; for_action already copies into a list and pydantic coerces sequences to List[str], so all call sites (incl. the YAML loader) are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
weiqingy
left a comment
There was a problem hiding this comment.
Thanks for taking this on — lifting the fixed action signature into one shared immutable ACTION_PARAMETER_TYPES tuple, consumed by both for_action and the YAML loader, is a clean single-source-of-truth move that also closes the shared-default-mutation footgun before it can exist. Reads as ready to me.
Purpose of change
Tests
API
Documentation
doc-neededdoc-not-neededdoc-included