GitHub user GreatEugenius created a discussion: Resource Cross-Language Support 
 for Flink Agents

## Current Situation Analysis

Currently, in Flink Agents execution, PythonEvent can trigger PythonAction and 
call Python Resource; JavaEvent can trigger JavaAction and call Java Resource. 
However, Events from Python and Java APIs cannot trigger Actions from the other 
language, and Actions from Python and Java APIs cannot use Resources from the 
other language.

Overall, Flink Agents cross-language work can be roughly divided into three 
major categories:

*   Cross-language triggering between Event and Action: 
PythonEvent can trigger JavaAction; JavaEvent can trigger PythonAction.

*   Action cross-language Resource calls: Python Action supports calling Java 
Resource; Java Action supports calling Python Resource.

*   Resource cross-language Resource calls: Within Resources, we provide the 
getResource method. This means that a Resource's internal implementation may 
require other Resources, thus creating a need for cross-language calls.

From the user's perspective, cross-language requirements can be divided into 
two phases:

1.  Users build Agents using a single language: To avoid duplicate 
implementations in ecosystem integration, cross-language calls between Action 
and Resource need to be implemented, as well as cross-language calls within 
Resources.

2.  Users can mix multiple languages to build Agents: Cross-language triggering 
between Event and Action needs to be implemented.

Resource implementations often depend on external SDKs, and many times external 
SDKs only provide implementations in either Java or Python. It can be expected 
that Resource cross-language call scenarios will gradually increase as Flink 
Agents users grow and different application scenarios emerge. Therefore, we 
prioritize the scenario where users build Agents using a single language, 
implementing cross-language calls between Action and Resource, and 
cross-language calls within Resources.

Whether in Java or Python, the cross-language support approach for Resources is 
similar. Next, we will discuss how to implement Resource cross-language support 
from the unified perspective of users programming in Java.

## Example: Java Calling PythonChatModel

### Create PythonChatModel

Users can register PythonChatModel by declaring ResourceDescriptor. The 
acquisition and invocation of PythonChatModel is no different from other 
ChatModels.

```java
@ChatModelConnection
public static ResourceDescriptor reviewAnalysisModelConnection() {
    return 
ResourceDescriptor.Builder.newBuilder(PythonChatModelConnection.class.getName())
            .addInitialArgument("module", 
"flink_agents.integrations.chat_models.tongyi_chat_model")
            .addInitialArgument("clazz", "TongyiChatModelConnection")
            .build();
}

@ChatModelSetup
public static ResourceDescriptor reviewAnalysisModel() {
    return 
ResourceDescriptor.Builder.newBuilder(PythonChatModelSetup.class.getName())
            .addInitialArgument("connection", "tongyiChatModelConnection")
            .addInitialArgument("module", 
"flink_agents.integrations.chat_models.tongyi_chat_model")
            .addInitialArgument("clazz", "TongyiChatModelSetup")
            .addInitialArgument("model", "qwen-plus")
            .addInitialArgument("prompt", "reviewAnalysisPrompt")
            .addInitialArgument("tools", 
Collections.singletonList("notifyShippingManager"))
            .addInitialArgument("extract_reasoning", "true")
            .build();
}

```

### GetResource

Users can obtain `PythonChatModel` through the `getResource` method:

```java
public class ChatModelAction {
    public static void chat(UUID initialRequestId, String model, 
List<ChatMessage> messages, RunnerContext ctx) throws Exception {
        BaseChatModelSetup chatModel = (BaseChatModelSetup) 
ctx.getResource(model, ResourceType.CHAT_MODEL);
    }
}

```

## Implementation

### PythonResourceWrapper

To enable seamless Resource cross-language support for users, we need to 
implement Wrapper classes for each ResourceType.

In Java, to implement PythonChatModelConnection and PythonChatModelSetup, we 
abstracted a unified PythonResourceWrapper interface to handle these Wrapper 
classes:

```java
/**
 * Interface for wrapping and providing access to a Python resource.
 *
 * <p>This interface serves as a common abstraction for accessing Python 
resources from Java,
 * enabling seamless cross-language interaction and unified resource 
management.</p>
 *
 * <p>Implementations of this interface should encapsulate the underlying 
Python object or
 * reference, and provide it through the {@link #getPythonResource()} 
method.</p>
 */
public interface PythonResourceWrapper {
    /**
     * Retrieves the underlying Python resource object.
     *
     * @return the native Python resource wrapped by this instance
     */
    Object getPythonResource();
}

```

In Python, we need to implement Wrapper classes for JavaResource:

```python
class JavaResourceWrapper(ABC):
    """Abstract base class that provides access to a Java resource.

    This class defines a common interface for wrapping and accessing Java 
resources,
    enabling cross-language interaction in a unified manner.
    """

    @abstractmethod
    def get_java_resource(self) -> Any:
        """Retrieve the underlying Java resource object.

        Returns:
            Any: A reference to the native Java resource managed by this 
wrapper.
        """

```

To ensure API consistency between Java and Python, we will add end-to-end (e2e) 
tests with each code change to promptly detect API modifications and make 
adaptations.

### Resource Acquisition Situation Analysis

Without considering cross-language scenarios, Resources can be directly 
obtained in Action/Resource by calling the getResource method. When supporting 
Resource cross-language calls, we hope that whether obtaining Resources in 
Action or in Resource, Action and Resource require no changes.

More directly, the implementation form of the Resource obtained by getResource 
is only related to the implementation of the current getResource method caller. 
In different languages, the situations for obtaining Resources implemented in 
different languages are as follows:

![Resource Acquisition Situation 
Analysis](https://github.com/user-attachments/assets/88e18a83-eeb7-49ff-ade7-5fbac8f3907a)

## Work Schedule

1.  ChatModel cross-language calls

    1.  Support Java using PythonChatModel

        1.  ChatMessage: Implement mutual conversion between Java ChatMessage 
and Python ChatMessage.

        2.  Tool: Implement PythonChatModel calling JavaTool (Metadata, Tool 
Call)

        3.  Prompt: PythonChatModel calling JavaPrompt

    2.  Support Python using JavaChatModel (mainly to verify feasibility)

2.  Java using other Python resources

    1.  Support Java using PythonEmbeddingModels

    2.  Support Java using PythonVectorStore

    3.  Support Java using PythonMCP

3.  Python using other Java resources

    1.  Support Python using JavaEmbeddingModels

    2.  Support Python using JavaVectorStore

    3.  Support Python using JavaMCP

GitHub link: https://github.com/apache/flink-agents/discussions/338

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]

Reply via email to