GitHub user wzhero1 added a comment to the discussion: [Feature] Cross Language
Actions
Hi @addu390, wenjin272 is on vacation, so I'll take a look.
Overall direction looks good — I think this is ready to start. All three gaps
(decorator parity, SerDe, E2E tests) are correctly identified and the proposed
approach is reasonable. A few details on each gap below.
---
## Gap 1 — Decorator parity details
**Leaning Option A**: it aligns with the existing imperative form
`add_action(func=JavaFunction(...))`, and `parameter_types` stays a structured
field. Option B's string form can't carry `parameter_types`; squeezing them in
would just turn the string into a mini-DSL.
Two follow-ups for landing it:
### 1. Python `@action` backward compat
The snippet `@action(events=["my_event"], target=...)` doesn't actually work
against today's signature `def action(*listen_events: str)` — Python varargs
don't accept `events=` as a keyword, so existing `@action("foo")` usage would
break. Suggest keeping varargs and adding a keyword-only `target` for zero
breakage:
```python
def action(*listen_events: str, *, target: Function | None = None) -> Callable:
...
```
### 2. Stub body convention
The `def handle(): ...` body decorated with `@action(target=...)` never runs —
that's a new wrinkle the decorator form introduces (the imperative `add_action`
doesn't have it since there's no method). Suggest the body be `raise
NotImplementedError("cross-language stub")` so direct calls outside the
framework (unit tests, debugging) fail loud rather than silently passing.
`pass` / `...` as a fallback.
---
## Gap 2 — SerDe inconsistencies details
### Pin down audit scope
The full set of built-in events in the repo is 8: InputEvent / OutputEvent /
ChatRequest / ChatResponse / ToolRequest / ToolResponse /
ContextRetrievalRequest / ContextRetrievalResponse. Suggest classifying each:
- **Must support in 0.3**: at least ChatRequest / ChatResponse (chat model main
path)
- **OK to defer past 0.3**: probably ToolResponseEvent — both an attr-set
divergence and a Map-type divergence (see below); not solvable by simple SerDe
tweaks. Document the gap explicitly and add a boundary test pinning the
"doesn't work cross-language" state to prevent regression
### Wire format spec
The design's 3 categories (snake_case fields, lowercase enum values,
optional/null handling) cover **naming-level** divergences (e.g. `MessageRole`
"USER" vs "user", `ChatMessage.toolCalls` vs `tool_calls`).
Suggest adding two more rules to cover schema-level divergences:
- **Attribute sets aligned on both sides** — e.g. `ToolResponseEvent` Java has
`success` / `error` / `timestamp` (`ToolResponseEvent.java:46-49`) that Python
doesn't (`tool_event.py:96-103`).
- **No `Object` / `Any` fallback; `Map<K, V>` must have matching K and V
types** — e.g. `responses` is `Map<String, ToolResponse>` on Java vs
`Dict[UUID, Any]` on Python; `ChatRequestEvent.outputSchema` Java uses `Object`
(`ChatRequestEvent.java:42`).
---
## Gap 3 — E2E test coverage details
### Test scope = the "must support" list from Gap 2
Test matrix should share the same event list as Gap 2's "must support" tier.
Events Gap 2 defers (e.g. ToolResponseEvent) get a boundary test pinning the
unsupported state instead of e2e.
### Add a user-authored event axis
Built-in events alone aren't enough — user-authored events dominate
cross-language action scenarios. Two cases:
- `Event(type="my_custom", attributes={...primitive...})` — both sides use base
`Event`
- User defines `class MyEvent(Event)` in Python with no Java counterpart — test
Java-side fallback (base `Event` reception) degrades gracefully
### Form: round-trip + JSON snapshot
Beyond round-trip e2e, also add **JSON snapshot tests** — pin a fixed
wire-format JSON string and have both sides deserialize, then assert typed
access. Snapshot turns Gap 2's wire format spec into an **executable
contract**: spec changes → snapshot changes → CI enforces both sides stay in
sync.
GitHub link:
https://github.com/apache/flink-agents/discussions/697#discussioncomment-17050163
----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]