xintongsong commented on code in PR #233: URL: https://github.com/apache/flink-agents/pull/233#discussion_r2385710435
########## docs/content/docs/development/workflow_agent.md: ########## @@ -119,20 +117,78 @@ class ReviewAnalysisAgent(Agent): ## Action -{{< hint warning >}} -**TODO**: How to define an action. -{{< /hint >}} +An action is a piece of code that can be executed. Each action listens to at least one type of event. When an event of the listening type occurs, the action will be triggered. An action can also generate new events, to trigger other actions. + + +To declare an action in Agent, user can use `@action` to decorate a function of Agent class, and declare the listened event types as decorator parameters. + +The decorated function signature should be `(Event, RunnerContext) -> None` +```python +class ReviewAnalysisAgent(Agent): + @action(InputEvent) + @staticmethod + def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # the action logic +``` +In the function, user can also send new events, to trigger other actions, or output the data. +```python +@action(InputEvent) +@staticmethod +def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # send ChatRequestEvent + ctx.send_event(ChatRequestEvent(model=xxx, messages=xxx)) + # output data to downstream + ctx.send_event(OutputEvent(output=xxx)) +``` ## Event +Events are messages passed between actions. Events may carry payloads. A single event may trigger multiple actions if they are all listening to its type. + +There are 2 special types of event. +* `InputEvent`: Generated by the framework, carrying an input data record that arrives at the agent. Actions listening to the `InputEvent` will be the entry points of agent. +* `OutputEvent`: The framework will listen to `OutputEvent`, and convert its payload into outputs of the agent. By generating `OutputEvent`, actions can emit output data. + +User can define owner event by extends `Event`. +```python +class MyEvent(Event): + value: Any +``` +Then, user can define action listen or send `MyEvent` Review Comment: ```suggestion Then, user can define action listen to or send `MyEvent` ``` ########## docs/content/docs/development/workflow_agent.md: ########## @@ -119,20 +117,78 @@ class ReviewAnalysisAgent(Agent): ## Action -{{< hint warning >}} -**TODO**: How to define an action. -{{< /hint >}} +An action is a piece of code that can be executed. Each action listens to at least one type of event. When an event of the listening type occurs, the action will be triggered. An action can also generate new events, to trigger other actions. + + +To declare an action in Agent, user can use `@action` to decorate a function of Agent class, and declare the listened event types as decorator parameters. + +The decorated function signature should be `(Event, RunnerContext) -> None` +```python +class ReviewAnalysisAgent(Agent): + @action(InputEvent) + @staticmethod + def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # the action logic +``` +In the function, user can also send new events, to trigger other actions, or output the data. +```python +@action(InputEvent) +@staticmethod +def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # send ChatRequestEvent + ctx.send_event(ChatRequestEvent(model=xxx, messages=xxx)) + # output data to downstream + ctx.send_event(OutputEvent(output=xxx)) +``` ## Event +Events are messages passed between actions. Events may carry payloads. A single event may trigger multiple actions if they are all listening to its type. + +There are 2 special types of event. +* `InputEvent`: Generated by the framework, carrying an input data record that arrives at the agent. Actions listening to the `InputEvent` will be the entry points of agent. +* `OutputEvent`: The framework will listen to `OutputEvent`, and convert its payload into outputs of the agent. By generating `OutputEvent`, actions can emit output data. Review Comment: I think we need to explicitly mention the field names to be used. ########## docs/content/docs/development/workflow_agent.md: ########## @@ -119,20 +117,78 @@ class ReviewAnalysisAgent(Agent): ## Action -{{< hint warning >}} -**TODO**: How to define an action. -{{< /hint >}} +An action is a piece of code that can be executed. Each action listens to at least one type of event. When an event of the listening type occurs, the action will be triggered. An action can also generate new events, to trigger other actions. + + +To declare an action in Agent, user can use `@action` to decorate a function of Agent class, and declare the listened event types as decorator parameters. + +The decorated function signature should be `(Event, RunnerContext) -> None` +```python +class ReviewAnalysisAgent(Agent): + @action(InputEvent) + @staticmethod + def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # the action logic +``` +In the function, user can also send new events, to trigger other actions, or output the data. +```python +@action(InputEvent) +@staticmethod +def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # send ChatRequestEvent + ctx.send_event(ChatRequestEvent(model=xxx, messages=xxx)) + # output data to downstream + ctx.send_event(OutputEvent(output=xxx)) +``` ## Event +Events are messages passed between actions. Events may carry payloads. A single event may trigger multiple actions if they are all listening to its type. + +There are 2 special types of event. +* `InputEvent`: Generated by the framework, carrying an input data record that arrives at the agent. Actions listening to the `InputEvent` will be the entry points of agent. +* `OutputEvent`: The framework will listen to `OutputEvent`, and convert its payload into outputs of the agent. By generating `OutputEvent`, actions can emit output data. + +User can define owner event by extends `Event`. +```python +class MyEvent(Event): + value: Any +``` +Then, user can define action listen or send `MyEvent` +> **Note**: To support the Event Log of Flink-Agents, the payload of `Event` should be `BaseModel` serializable. +## Built-in Events and Actions -{{< hint warning >}} -**TODO**: How to define, send and handle an event, including InputEvent, OutputEvent, and event between actions. +There are several built-in `Event` in Flink-Agents: +* `ChatRequestEvent`: Event carries the chat messages to be sent to llm. +* `ChatResponseEvent`: Event carries the llm response. +* `ToolRequestEvent`: Event carries the tool call extracted from llm response. +* `ToolResponseEvent`: Event carries the tool execution result. -{{< /hint >}} +Flink-Agents provide two built-in actions to process `ChatRequestEvent`, `ToolRequestEvent` and `ToolResponseEvent`, user only need define actions to send `ChatRequestEvent` and process `ChatResponseEvent`. ## Memory -{{< hint warning >}} -**TODO**: How to use short-term memory and long-term memory. -{{< /hint >}} +Memory is data that will be remembered across actions and agent runs. + +### Short-Term Memory + +Short-Term Memory is shared across all actions within an agent run, and multiple agent runs with the same input key. This corresponds to Flink's Keyed State, which is visible to processing of multiple records with in the same keyed partition, and is transparent to processing of data in other keyed partitions. Review Comment: Explain agent run. ```suggestion Short-Term Memory is shared across all actions within an agent run, and multiple agent runs with the same input key. Here a *agent run* refers to ... This corresponds to Flink's Keyed State, which is visible to processing of multiple records with in the same keyed partition, and is transparent to processing of data in other keyed partitions. ``` ########## docs/content/docs/development/workflow_agent.md: ########## @@ -119,20 +117,78 @@ class ReviewAnalysisAgent(Agent): ## Action -{{< hint warning >}} -**TODO**: How to define an action. -{{< /hint >}} +An action is a piece of code that can be executed. Each action listens to at least one type of event. When an event of the listening type occurs, the action will be triggered. An action can also generate new events, to trigger other actions. + + +To declare an action in Agent, user can use `@action` to decorate a function of Agent class, and declare the listened event types as decorator parameters. + +The decorated function signature should be `(Event, RunnerContext) -> None` +```python +class ReviewAnalysisAgent(Agent): + @action(InputEvent) + @staticmethod + def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # the action logic +``` +In the function, user can also send new events, to trigger other actions, or output the data. +```python +@action(InputEvent) +@staticmethod +def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # send ChatRequestEvent + ctx.send_event(ChatRequestEvent(model=xxx, messages=xxx)) + # output data to downstream + ctx.send_event(OutputEvent(output=xxx)) +``` ## Event +Events are messages passed between actions. Events may carry payloads. A single event may trigger multiple actions if they are all listening to its type. + +There are 2 special types of event. +* `InputEvent`: Generated by the framework, carrying an input data record that arrives at the agent. Actions listening to the `InputEvent` will be the entry points of agent. +* `OutputEvent`: The framework will listen to `OutputEvent`, and convert its payload into outputs of the agent. By generating `OutputEvent`, actions can emit output data. + +User can define owner event by extends `Event`. +```python +class MyEvent(Event): + value: Any +``` +Then, user can define action listen or send `MyEvent` +> **Note**: To support the Event Log of Flink-Agents, the payload of `Event` should be `BaseModel` serializable. +## Built-in Events and Actions -{{< hint warning >}} -**TODO**: How to define, send and handle an event, including InputEvent, OutputEvent, and event between actions. +There are several built-in `Event` in Flink-Agents: +* `ChatRequestEvent`: Event carries the chat messages to be sent to llm. +* `ChatResponseEvent`: Event carries the llm response. +* `ToolRequestEvent`: Event carries the tool call extracted from llm response. +* `ToolResponseEvent`: Event carries the tool execution result. Review Comment: If we are not introducing how to use these built-in events here, we don't need to describe each of them. Instead, we should point to the other documents where they will be explained. Like: * See *link* for how to chat with a LLM leveraging built-in action and events. * See *link* for how to programmatically use a tool leveraging built-in action and events. ########## docs/content/docs/development/workflow_agent.md: ########## @@ -119,20 +117,78 @@ class ReviewAnalysisAgent(Agent): ## Action -{{< hint warning >}} -**TODO**: How to define an action. -{{< /hint >}} +An action is a piece of code that can be executed. Each action listens to at least one type of event. When an event of the listening type occurs, the action will be triggered. An action can also generate new events, to trigger other actions. + + +To declare an action in Agent, user can use `@action` to decorate a function of Agent class, and declare the listened event types as decorator parameters. + +The decorated function signature should be `(Event, RunnerContext) -> None` +```python +class ReviewAnalysisAgent(Agent): + @action(InputEvent) + @staticmethod + def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # the action logic +``` +In the function, user can also send new events, to trigger other actions, or output the data. +```python +@action(InputEvent) +@staticmethod +def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # send ChatRequestEvent + ctx.send_event(ChatRequestEvent(model=xxx, messages=xxx)) + # output data to downstream + ctx.send_event(OutputEvent(output=xxx)) +``` ## Event +Events are messages passed between actions. Events may carry payloads. A single event may trigger multiple actions if they are all listening to its type. + +There are 2 special types of event. +* `InputEvent`: Generated by the framework, carrying an input data record that arrives at the agent. Actions listening to the `InputEvent` will be the entry points of agent. +* `OutputEvent`: The framework will listen to `OutputEvent`, and convert its payload into outputs of the agent. By generating `OutputEvent`, actions can emit output data. + +User can define owner event by extends `Event`. +```python +class MyEvent(Event): + value: Any +``` +Then, user can define action listen or send `MyEvent` +> **Note**: To support the Event Log of Flink-Agents, the payload of `Event` should be `BaseModel` serializable. Review Comment: This is not only for supporting Event Log, it's also needed for persisting events in Flink's state and the WAL for per-action consistency, and cross-language transmission in future if we support hybrid agent with both java and python codes. ########## docs/content/docs/development/workflow_agent.md: ########## @@ -119,20 +117,78 @@ class ReviewAnalysisAgent(Agent): ## Action -{{< hint warning >}} -**TODO**: How to define an action. -{{< /hint >}} +An action is a piece of code that can be executed. Each action listens to at least one type of event. When an event of the listening type occurs, the action will be triggered. An action can also generate new events, to trigger other actions. + + +To declare an action in Agent, user can use `@action` to decorate a function of Agent class, and declare the listened event types as decorator parameters. + +The decorated function signature should be `(Event, RunnerContext) -> None` +```python +class ReviewAnalysisAgent(Agent): + @action(InputEvent) + @staticmethod + def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # the action logic +``` +In the function, user can also send new events, to trigger other actions, or output the data. +```python +@action(InputEvent) +@staticmethod +def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # send ChatRequestEvent + ctx.send_event(ChatRequestEvent(model=xxx, messages=xxx)) + # output data to downstream + ctx.send_event(OutputEvent(output=xxx)) +``` ## Event +Events are messages passed between actions. Events may carry payloads. A single event may trigger multiple actions if they are all listening to its type. + +There are 2 special types of event. +* `InputEvent`: Generated by the framework, carrying an input data record that arrives at the agent. Actions listening to the `InputEvent` will be the entry points of agent. +* `OutputEvent`: The framework will listen to `OutputEvent`, and convert its payload into outputs of the agent. By generating `OutputEvent`, actions can emit output data. + +User can define owner event by extends `Event`. +```python +class MyEvent(Event): + value: Any +``` +Then, user can define action listen or send `MyEvent` +> **Note**: To support the Event Log of Flink-Agents, the payload of `Event` should be `BaseModel` serializable. +## Built-in Events and Actions -{{< hint warning >}} -**TODO**: How to define, send and handle an event, including InputEvent, OutputEvent, and event between actions. +There are several built-in `Event` in Flink-Agents: +* `ChatRequestEvent`: Event carries the chat messages to be sent to llm. +* `ChatResponseEvent`: Event carries the llm response. +* `ToolRequestEvent`: Event carries the tool call extracted from llm response. +* `ToolResponseEvent`: Event carries the tool execution result. -{{< /hint >}} +Flink-Agents provide two built-in actions to process `ChatRequestEvent`, `ToolRequestEvent` and `ToolResponseEvent`, user only need define actions to send `ChatRequestEvent` and process `ChatResponseEvent`. ## Memory -{{< hint warning >}} -**TODO**: How to use short-term memory and long-term memory. -{{< /hint >}} +Memory is data that will be remembered across actions and agent runs. + +### Short-Term Memory + +Short-Term Memory is shared across all actions within an agent run, and multiple agent runs with the same input key. This corresponds to Flink's Keyed State, which is visible to processing of multiple records with in the same keyed partition, and is transparent to processing of data in other keyed partitions. +User can set and get short-term memory in actions. +```python +@action(InputEvent) +@staticmethod +def process_input(event: InputEvent, ctx: RunnerContext) -> None: + """Process input event and send chat request for review analysis.""" + ... + ctx.short_term_memory.set("id", input.id) + ... + +@action(ChatResponseEvent) +@staticmethod +def process_chat_response(event: ChatResponseEvent, ctx: RunnerContext) -> None: + """Process chat response event and send output event.""" + ... + id=ctx.short_term_memory.get("id"), + ... + +``` Review Comment: For Short-Term Memory, I think we should also mention that: 1. It's not just a k-v map. You can store nested objects. Detailed APIs ... 2. You can pass reference of memory object, instead of the actual object. When and how to use this. ########## docs/content/docs/development/workflow_agent.md: ########## @@ -119,20 +117,78 @@ class ReviewAnalysisAgent(Agent): ## Action -{{< hint warning >}} -**TODO**: How to define an action. -{{< /hint >}} +An action is a piece of code that can be executed. Each action listens to at least one type of event. When an event of the listening type occurs, the action will be triggered. An action can also generate new events, to trigger other actions. + + +To declare an action in Agent, user can use `@action` to decorate a function of Agent class, and declare the listened event types as decorator parameters. + +The decorated function signature should be `(Event, RunnerContext) -> None` +```python +class ReviewAnalysisAgent(Agent): + @action(InputEvent) + @staticmethod + def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # the action logic +``` +In the function, user can also send new events, to trigger other actions, or output the data. +```python +@action(InputEvent) +@staticmethod +def process_input(event: InputEvent, ctx: RunnerContext) -> None: + # send ChatRequestEvent + ctx.send_event(ChatRequestEvent(model=xxx, messages=xxx)) + # output data to downstream + ctx.send_event(OutputEvent(output=xxx)) +``` ## Event +Events are messages passed between actions. Events may carry payloads. A single event may trigger multiple actions if they are all listening to its type. + +There are 2 special types of event. +* `InputEvent`: Generated by the framework, carrying an input data record that arrives at the agent. Actions listening to the `InputEvent` will be the entry points of agent. +* `OutputEvent`: The framework will listen to `OutputEvent`, and convert its payload into outputs of the agent. By generating `OutputEvent`, actions can emit output data. + +User can define owner event by extends `Event`. +```python +class MyEvent(Event): + value: Any +``` +Then, user can define action listen or send `MyEvent` +> **Note**: To support the Event Log of Flink-Agents, the payload of `Event` should be `BaseModel` serializable. Review Comment: Just simply say: ```suggestion > **Note**: The payload of `Event` should be `BaseModel` serializable. ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@flink.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org