Skip to content

AI Agents Event Driven Communication as Virtual Actors using Actor Model with OpenAI Agents SDK as agentic engine and Dapr Virtual Actors for distributed runtime

Notifications You must be signed in to change notification settings

mjunaidca/vagent_comm

Repository files navigation

VAgentComm: Agents SDK with Dapr Virtual Actor Agent Communication

This project, VAgentComm, is an implementation of a multi-agent system using Dapr Virtual Actors. It focuses on demonstrating core cloud-native agentic patterns such as actor-to-actor communication, event-driven state management, and dynamic actor creation. It is built based on the principles and architecture laid out in Step 3 of the Dapr Agentic Cloud Ascent (DACA) learning path.

VAgentComm provides a solid architectural foundation showcasing how decoupled, stateful actors can collaborate to handle complex workflows, such as managing conversations and contextual memory.

Project Overview

VAgentComm models a conversational processing pipeline involving three key types of Dapr Virtual Actors:

  1. ChatAgent: Acts as the entry point and orchestrator. It receives user input, maintains the conversation history for a specific user (actor_id), delegates the task of generating a response to the ResponseAgent, and publishes an event upon completing a conversation turn.
  2. ResponseAgent: A specialized actor dynamically created by the ChatAgent. Its primary role is to construct a response based on the user's input and contextual information retrieved from the MemoryAgentActor. It also maintains a simple count of the messages it has processed.
  3. MemoryAgentActor: An event-driven actor that manages a simple memory store for each user (actor_id). It subscribes to ConversationUpdated events published by the ChatAgent and updates its internal state (memory) based on the event data. Other actors, like the ResponseAgent, can query it for this stored memory.

The system leverages Dapr's State Management for actor state persistence, Actor Proxies for asynchronous invocation between actors, and Pub/Sub for a decoupled, event-driven approach to memory updates.

Purpose and Goals

  • Demonstrate Actor Communication: Implement and showcase asynchronous invocation patterns between different Dapr Virtual Actor instances using Actor Proxies.
  • Dynamic Actor Creation: Illustrate how external interactions or parent actors can dynamically create child actors (ResponseAgent, MemoryAgentActor) tailored to specific users or tasks.
  • Event-Driven State Management: Show how Dapr Pub/Sub can be used in conjunction with actors to implement event-driven updates to actor state (specifically, updating memory).
  • Fault Isolation: Highlight the resilience provided by the actor model, where independent state and execution prevent failures in one actor instance from cascading to others.
  • Context Awareness Foundation: Establish the architectural pattern for providing context (via the MemoryAgentActor) that can be utilized by processing actors (ResponseAgent) to influence behavior.
  • Build a Robust Architecture: Provide a practical, runnable example of a multi-actor system that serves as a robust base for building more sophisticated agentic applications.

Key Features

  • Three interconnected Dapr Virtual Actor types: ChatAgent, ResponseAgent, and MemoryAgentActor. Guardrails to user and agent context related to topic.
  • Dynamic, per-user/session instantiation of ResponseAgent and MemoryAgentActor driven by interactions.
  • Asynchronous method invocation between actors (ChatAgent -> ResponseAgent, ResponseAgent -> MemoryAgentActor, Pub/Sub Subscriber -> MemoryAgentActor) using Dapr Actor Proxies.
  • Event publication (ConversationUpdated) from the ChatAgent to a Dapr Pub/Sub topic (user-chat).
  • Event subscription handled by the application's /subscribe endpoint, which in turn triggers the relevant MemoryAgentActor instance.
  • State persistence for ChatAgent history, ResponseAgent count, and MemoryAgentActor memory using a configured Dapr State Store.
  • Fault isolation and single-threaded execution guarantee provided by the Dapr Actor runtime.
  • FastAPI web server providing REST endpoints for:
    • Initiating a conversation turn and triggering the agent workflow (POST /chat/{actor_id}).
    • Retrieving the conversation history for a user (GET /chat/{actor_id}/history).
    • Checking the message count for a ResponseAgent instance (GET /response/{actor_id}/count).
    • Retrieving the current memory state for a MemoryAgentActor instance (GET /memory/{actor_id}).
    • Receiving Dapr Pub/Sub events (POST /subscribe).

Technology Stack

  • Python: The main programming language.
  • FastAPI: Used for building the web server and handling Dapr callbacks and endpoints.
  • Dapr: The core framework providing Virtual Actors, State Management, and Pub/Sub building blocks.
    • Dapr Python SDK (dapr, dapr-ext-fastapi)
  • Redis: Used as the backing store for Dapr State Store and Pub/Sub components (requires a running Redis instance accessible to Dapr).
  • Tilt (Optional but Recommended): For streamlined local development setup, including starting Dapr, Redis, and the application.
  • uv (Optional): A fast Python package installer.

Prerequisites

Before setting up and running VAgentComm, ensure you have the following installed:

  • Docker/Rancher (for running kubernetes cluster, Redis and Dapr components)
  • Python 3.8+
  • A Python package manager (uv, pip, poetry, etc.)
  • Tilt (Optional - if you want to use the provided Tiltfile)
  • Basic understanding of Dapr concepts (State Management, Pub/Sub, Actors) is helpful.

Setup and Installation

  1. Clone the Repository:

    git clone ...
    cd vagent_comm
  2. Add Env Vars: Create a .env file and add GEMINI_API_KEY - feel free to use kubernetes secret for it. For simplicity here we are using .env.

How to Run

The easiest way to run VAgentComm locally is using Tilt, which orchestrates the Dapr sidecar, Redis, and the application based on a Tiltfile.

  1. Using Tilt (Recommended): Open docjer desktop/rancher desktop. If you are not using nerdctl runtime (we get this in rancher as well) then just comment this line from Tiltfile: load('ext://nerdctl', 'nerdctl_build')

    Tile works with both docker and containerd runtimes. Ensure you have a Tiltfile configured for your project. From the project root:

    tilt up

    Tilt will start the necessary infrastructure and your application, providing a dashboard for monitoring. The application will typically be accessible on http://localhost:8000.

Interacting with VAgentComm

Once the application and Dapr sidecar are running, you can interact with the system using the FastAPI endpoints. Open your browser to the interactive API documentation:

http://localhost:8000/docs

Use the endpoints in the default group to test the multi-agent flow:

  1. Send a message:

    • POST /chat/{actor_id} (e.g., /chat/user1)
    • Request Body: {"role": "user", "content": "Tell me something."}
    • This initiates the workflow: ChatAgent receives input, delegates to ResponseAgent (creating it if it doesn't exist), ResponseAgent queries MemoryAgentActor (creating it if it doesn't exist), generates a response, ChatAgent updates history, and ChatAgent publishes an event.
  2. Check History:

    • GET /chat/{actor_id}/history (e.g., /chat/user1/history)
    • Retrieve the conversation history managed by the ChatAgent.
  3. Check Response Count:

    • GET /response/{actor_id}/count (e.g., /response/user1/count)
    • See how many messages the specific ResponseAgent instance has processed.
  4. Check Memory:

    • GET /memory/{actor_id} (e.g., /memory/user1)
    • Retrieve the memory state stored and updated by the MemoryAgentActor for this user.

The /subscribe endpoint is automatically invoked by Dapr's Pub/Sub component whenever a message arrives on the configured topic (user-chat). It processes the event payload to trigger the MemoryAgentActor.UpdateMemory method.

Monitoring

  • Dapr Logs: View the logs of your application and the Dapr sidecar using the Dapr CLI.

    dapr logs -a vagentcomm-app

    (Replace vagentcomm-app with your application's Dapr app-id)

  • Dapr Dashboard: Access the dashboard to monitor running actor instances, component status, and more.

    Navigate to the Actors tab to see the active instances of ChatAgent, ResponseAgent, and MemoryAgentActor for each user ID you interact with.

Future Enhancements

This project provides a strong foundation. Here are some potential next steps and areas for expansion:

  • AI Agent SDK Integration Enhancement: Explore and manage more complex agent behaviors within the ResponseAgent or by introducing new agent types.
  • Advanced Memory Management: Implement more sophisticated memory handling in MemoryAgentActor, such as summarization, sliding window context, or different types of memory stores (e.g., vector databases).
  • Add More Agents: Introduce new actor types for specific tasks, such as a SentimentAgent, TranslationAgent, ToolCallingAgent, etc., demonstrating more complex multi-agent choreography.
  • Error Handling & Resilience: Enhance error handling and explore Dapr resilience features for retries and circuit breakers.
  • Observability: Add detailed tracing and metrics using Dapr's observability building block.
  • Deployment: Deploy the application and Dapr components to a cloud environment (Kubernetes, GKE, etc.).
  • Add Conversational UI Interface like chainlit.

About

AI Agents Event Driven Communication as Virtual Actors using Actor Model with OpenAI Agents SDK as agentic engine and Dapr Virtual Actors for distributed runtime

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published