From 8cad9e77d70c3bf6605364c4e3324a58546c7687 Mon Sep 17 00:00:00 2001 From: Filinto Duran <1373693+filintod@users.noreply.github.com> Date: Thu, 25 Sep 2025 14:28:26 -0500 Subject: [PATCH 1/8] make devex a bit better when there is only one conversation component Signed-off-by: Filinto Duran <1373693+filintod@users.noreply.github.com> --- dapr_agents/agents/durableagent/agent.py | 3 - dapr_agents/llm/dapr/chat.py | 56 +++++++++---- dapr_agents/workflow/base.py | 4 + .../01-hello-world/03_durable_agent.py | 22 ++++-- quickstarts/01-hello-world/README.md | 53 ++++++++++++- .../03-durable-agent-multitool-dapr/README.md | 78 +++++++++++++++++-- .../components/openai.yaml | 2 +- 7 files changed, 188 insertions(+), 30 deletions(-) diff --git a/dapr_agents/agents/durableagent/agent.py b/dapr_agents/agents/durableagent/agent.py index bd05316d..c9d47a47 100644 --- a/dapr_agents/agents/durableagent/agent.py +++ b/dapr_agents/agents/durableagent/agent.py @@ -120,9 +120,6 @@ def model_post_init(self, __context: Any) -> None: self.register_agentic_system() - # Start the runtime if it's not already running - logger.info("Starting workflow runtime...") - self.start_runtime() async def run(self, input_data: Union[str, Dict[str, Any]]) -> Any: """ diff --git a/dapr_agents/llm/dapr/chat.py b/dapr_agents/llm/dapr/chat.py index c43bc4b4..d4009540 100644 --- a/dapr_agents/llm/dapr/chat.py +++ b/dapr_agents/llm/dapr/chat.py @@ -15,7 +15,7 @@ ) from pydantic import BaseModel, Field - +from dapr.clients.grpc.client import GetMetadataResponse from dapr_agents.llm.chat import ChatClientBase from dapr_agents.llm.dapr.client import DaprInferenceClientBase from dapr_agents.llm.utils import RequestHandler, ResponseHandler @@ -23,11 +23,13 @@ from dapr_agents.prompt.prompty import Prompty from dapr_agents.tool import AgentTool from dapr_agents.types.exceptions import DaprRuntimeVersionNotSupportedError +from dapr_agents.types.exceptions import DaprRuntimeVersionNotSupportedError from dapr_agents.types.message import ( BaseMessage, LLMChatResponse, ) from dapr_agents.utils import is_version_supported +from dapr_agents.utils import is_version_supported # Lazy import to avoid import issues during test collection @@ -80,6 +82,8 @@ class DaprChatClient(DaprInferenceClientBase, ChatClientBase): component_name: Optional[str] = None + component_name: Optional[str] = None + # Only function_call–style structured output is supported SUPPORTED_STRUCTURED_MODES: ClassVar[set[str]] = {"function_call"} @@ -92,8 +96,8 @@ def model_post_init(self, __context: Any) -> None: if not self._llm_component: self._llm_component = os.environ.get("DAPR_LLM_COMPONENT_DEFAULT") if not self._llm_component: - raise ValueError( - "You must provide a component_name or set DAPR_LLM_COMPONENT_DEFAULT in the environment." + logger.debug( + "No LLM component provided and no default component found in the environment. Will try to get it from the metadata at runtime." ) super().model_post_init(__context) @@ -327,16 +331,11 @@ def generate( ) # get metadata information from the dapr client metadata = self.client.dapr_client.get_metadata() - extended_metadata = metadata.extended_metadata - dapr_runtime_version = extended_metadata.get("daprRuntimeVersion", None) - if dapr_runtime_version is not None: - # Allow only versions >=1.16.0 and <2.0.0 for Alpha2 Chat Client - if not is_version_supported( - str(dapr_runtime_version), ">=1.16.0, edge, <2.0.0" - ): - raise DaprRuntimeVersionNotSupportedError( - f"!!!!! Dapr Runtime Version {dapr_runtime_version} is not supported with Alpha2 Dapr Chat Client. Only Dapr runtime versions >=1.16.0, edge,and <2.0.0 are supported." - ) + _check_dapr_runtime_support(metadata) + + llm_component = llm_component or self._llm_component + if not llm_component: + llm_component = _get_llm_component(metadata) raw = self.client.chat_completion_alpha2( llm=llm_component or self._llm_component, @@ -365,3 +364,34 @@ def generate( structured_mode=structured_mode, stream=False, ) + + +def _check_dapr_runtime_support(metadata: GetMetadataResponse): + """Check if the Dapr runtime version is supported for Alpha2 Chat Client.""" + extended_metadata = metadata.extended_metadata + dapr_runtime_version = extended_metadata.get("daprRuntimeVersion", None) + if dapr_runtime_version is not None: + # Allow only versions >=1.16.0 and <2.0.0 for Alpha2 Chat Client + if not is_version_supported(str(dapr_runtime_version), ">=1.16.0, <2.0.0"): + raise DaprRuntimeVersionNotSupportedError( + f"!!!!! Dapr Runtime Version {dapr_runtime_version} is not supported with Alpha2 Dapr Chat Client. Only Dapr runtim versions >=1.16.0 and <2.0.0 are supported." + ) + + +def _get_llm_component(metadata: GetMetadataResponse) -> str: + """Get the LLM component from the metadata.""" + conversation_components = [ + component + for component in metadata.registered_components + if component.type.startswith("conversation.") + ] + if len(conversation_components) == 1: + return conversation_components[0].name + elif len(conversation_components) > 1: + raise ValueError( + "Multiple LLM components found in the metadata. Please provide the component name explicitly (e.g. llm = DaprChatClient(component_name='openai')) or environment variable DAPR_LLM_COMPONENT_DEFAULT." + ) + else: + raise ValueError( + "No LLM component provided and no default component found in the metadata." + ) diff --git a/dapr_agents/workflow/base.py b/dapr_agents/workflow/base.py index dd24d8b4..e17b63bd 100644 --- a/dapr_agents/workflow/base.py +++ b/dapr_agents/workflow/base.py @@ -3,6 +3,7 @@ import inspect import json import logging +import time import sys import uuid from datetime import datetime, timezone @@ -516,6 +517,9 @@ def start_runtime(self): self.wf_runtime.start() self.wf_runtime_is_running = True + logger.info("Sleeping for 5 seconds to ensure runtime is started.") + time.sleep(5) + # Sync database state with Dapr workflow status after runtime starts # This ensures our database reflects the actual state of resumed workflows self._sync_workflow_state_after_startup() diff --git a/quickstarts/01-hello-world/03_durable_agent.py b/quickstarts/01-hello-world/03_durable_agent.py index 4c43501e..e9d3de8d 100644 --- a/quickstarts/01-hello-world/03_durable_agent.py +++ b/quickstarts/01-hello-world/03_durable_agent.py @@ -9,9 +9,10 @@ import asyncio import logging + from typing import List from pydantic import BaseModel, Field -from dapr_agents import tool, DurableAgent, DaprChatClient +from dapr_agents import tool, DurableAgent from dapr_agents.memory import ConversationDaprStateMemory from dotenv import load_dotenv @@ -38,11 +39,20 @@ def search_flights(destination: str) -> List[FlightOption]: ] -# one can use the environment variable to set the default component name +# There are three ways to set the LLM component with DaprChatClient: +# +# 1. Directly pass the component name +# 2. Use the environment variable DAPR_LLM_COMPONENT_DEFAULT +# 3. If there is only one conversation component in the metadata, it will be used by default +# +# Option 1: Directly pass the component name +# llm = DaprChatClient(component_name="openai") +# +# Option 2: Use the environment variable to set the default component name # os.environ.setdefault("DAPR_LLM_COMPONENT_DEFAULT", "openai") - -# or directly pass the component name -llm = DaprChatClient(component_name="openai") +# +# Option 3: If there is only one conversation component in the metadata, it will be used by default +# async def main(): @@ -66,7 +76,7 @@ async def main(): memory=ConversationDaprStateMemory( store_name="conversationstore", session_id="my-unique-id" ), - llm=llm, + # llm=llm, # if you don't set the llm attribute, it will be by default set to DaprChatClient() ) await travel_planner.run("I want to find flights to Paris") diff --git a/quickstarts/01-hello-world/README.md b/quickstarts/01-hello-world/README.md index 3c442c3d..816cc1ae 100644 --- a/quickstarts/01-hello-world/README.md +++ b/quickstarts/01-hello-world/README.md @@ -4,8 +4,8 @@ This quickstart provides a hands-on introduction to Dapr Agents through simple e ## Prerequisites -- Python 3.10 (recommended) -- pip package manager +- Python 3.10+ (recommended) +- [uv package manager](https://docs.astral.sh/uv/getting-started/installation/) - OpenAI API key (you can put in an .env file or directly in the `openai.yaml` file, but we recommend the .env file that is gitignored) ## Environment Setup @@ -24,6 +24,22 @@ uv pip install -r requirements.txt +
+Option 2: Using pip +
+Option 1: Using uv (Recommended) + +```bash +# Create and activate virtual environment +uv venv .venv +source .venv/bin/activate + +# Install core dependencies +uv pip install -r requirements.txt +``` + +
+
Option 2: Using pip @@ -44,12 +60,18 @@ pip install -r requirements.txt
+
+ ## Configuration > **Warning** > The examples will not work if you do not have a OpenAI API key exported in the environment. +Create a `.env` file in the project root and add your OpenAI API key: +> **Warning** +> The examples will not work if you do not have a OpenAI API key exported in the environment. + Create a `.env` file in the project root and add your OpenAI API key: ```env @@ -63,6 +85,11 @@ Export the environment variables from the .env file to your shell: export $(grep -v '^#' .env | xargs) # or if .env is in the root directory, you can just run `export $(grep -v '^#' ../../.env | xargs)` ``` +Export the environment variables from the .env file to your shell: +```bash +export $(grep -v '^#' .env | xargs) # or if .env is in the root directory, you can just run `export $(grep -v '^#' ../../.env | xargs)` +``` + ## Examples ### 1. Basic LLM Usage @@ -167,6 +194,9 @@ A stateful agent that uses Dapr Workflows to ensure durability and persistence o We are using the Dapr ChatClient to interact with the OpenAI API. In the components folder, we have a `openai.yaml` file that contains the configuration for the OpenAI API. You need to replace the `{YOUR_OPENAI_API_KEY}` with your actual OpenAI API key. +We are using the Dapr ChatClient to interact with the OpenAI API. In the components folder, we have a `openai.yaml` file that contains the configuration for the OpenAI API. +You need to replace the `{YOUR_OPENAI_API_KEY}` with your actual OpenAI API key. + Make sure Dapr is initialized on your system: ```bash @@ -185,15 +215,31 @@ output_match_mode: substring --> +We are using the `resolve_env_templates.py` script to resolve the environment variables in the components folder and substitute them with the actual values in your .env file, like the OpenAI API key. + + + + We are using the `resolve_env_templates.py` script to resolve the environment variables in the components folder and substitute them with the actual values in your .env file, like the OpenAI API key. ```bash dapr run --app-id stateful-llm --dapr-http-port 3500 --resources-path $(../resolve_env_templates.py ./components) -- python 03_durable_agent.py +dapr run --app-id stateful-llm --dapr-http-port 3500 --resources-path $(../resolve_env_templates.py ./components) -- python 03_durable_agent.py ``` + + + This example demonstrates a stateful travel planning assistant that: 1. Remembers user context persistently (across restarts) 2. Uses a tool to search for flight options @@ -322,6 +368,7 @@ output_match_mode: substring --> ```bash dapr run --app-id dapr-agent-wf --resources-path $(../resolve_env_templates.py ./components) -- python 04_chain_tasks.py +dapr run --app-id dapr-agent-wf --resources-path $(../resolve_env_templates.py ./components) -- python 04_chain_tasks.py ``` @@ -392,6 +439,8 @@ Run the vector store agent example to see how to create an agent that can search + + ```bash +# Create and activate virtual environment uv venv .venv source .venv/bin/activate + +# Install core dependencies uv pip install -r requirements.txt ``` + + +
+Option 2: Using pip + +```text +# Create a virtual environment +python3.10 -m venv .venv + +# Activate the virtual environment +# On Windows: +.venv\Scripts\activate +# On macOS/Linux: +source .venv/bin/activate + +# Install dependencies +pip install -r requirements.txt + +``` + +
+ ## Component Configuration + We provide a `components` folder with the Dapr components for the LLM and state/pubsub. The Conversation component example uses [OpenAI](https://docs.dapr.io/reference/components-reference/supported-conversation/openai/) component. + Many other LLM providers are compatible with OpenAI to certain extent (DeepSeek, Google AI, etc) so you can use them with the OpenAI component by configuring it with the appropriate parameters. But Dapr also has [native support](https://docs.dapr.io/reference/components-reference/supported-conversation/) for other providers like Google AI, Anthropic, Mistral, DeepSeek, etc. -One thing you will need to update is the `key` in the [component configuration file](components/openai.yaml): +One thing you will need to update is the `key` in the [component configuration file](components/openai.yaml). You can do it directly in the file: ```yaml metadata: @@ -32,12 +83,31 @@ metadata: Replace `YOUR_OPENAI_API_KEY` with your actual OpenAI API (or other provider's API) key. ## Run -```bash +```text dapr run --app-id durablemultitoolapp \ --resources-path ./components \ -- python multi_tool_agent_dapr.py ``` +Another safer option is to use the environment variable `OPENAI_API_KEY` and use the helper (quickstarts/resolve_env_templates.py) to render a temporary resources folder and pass it to Dapr: +```bash +# Get the environment variables from the .env file in the root directory: +export $(grep -v '^#' ../../.env | xargs) + +# create the temporary resources folder +temp_resources_folder=$(../resolve_env_templates.py ./components) + +# run the application +dapr run --resources-path $temp_resources_folder -- python multi_tool_agent_dapr.py + +# delete the temporary resources folder +rm -rf $temp_resources_folder +``` + + + +The temporary resources folder will be deleted after the Dapr sidecar is stopped or when the computer is restarted. + ## Files - `multi_tool_agent_dapr.py`: Durable agent using `llm_provider="dapr"` - `multi_tools.py`: sample tools @@ -45,5 +115,3 @@ dapr run --app-id durablemultitoolapp \ Notes: - Alpha2 currently does not support streaming; this example is non-streaming. - - diff --git a/quickstarts/03-durable-agent-multitool-dapr/components/openai.yaml b/quickstarts/03-durable-agent-multitool-dapr/components/openai.yaml index e1c03b1d..be2f95b1 100644 --- a/quickstarts/03-durable-agent-multitool-dapr/components/openai.yaml +++ b/quickstarts/03-durable-agent-multitool-dapr/components/openai.yaml @@ -7,7 +7,7 @@ spec: version: v1 metadata: - name: key - value: "YOUR_OPENAI_API_KEY" + value: "{{OPENAI_API_KEY}}" - name: model value: gpt-5-2025-08-07 - name: temperature From 4c36598ce01b3ce1663238f837f967e496184991 Mon Sep 17 00:00:00 2001 From: Filinto Duran <1373693+filintod@users.noreply.github.com> Date: Thu, 25 Sep 2025 14:32:41 -0500 Subject: [PATCH 2/8] lint Signed-off-by: Filinto Duran <1373693+filintod@users.noreply.github.com> --- dapr_agents/agents/durableagent/agent.py | 1 - dapr_agents/workflow/base.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dapr_agents/agents/durableagent/agent.py b/dapr_agents/agents/durableagent/agent.py index c9d47a47..d2d35f24 100644 --- a/dapr_agents/agents/durableagent/agent.py +++ b/dapr_agents/agents/durableagent/agent.py @@ -120,7 +120,6 @@ def model_post_init(self, __context: Any) -> None: self.register_agentic_system() - async def run(self, input_data: Union[str, Dict[str, Any]]) -> Any: """ Fire up the workflow, wait for it to complete, then return the final serialized_output. diff --git a/dapr_agents/workflow/base.py b/dapr_agents/workflow/base.py index e17b63bd..b25e1278 100644 --- a/dapr_agents/workflow/base.py +++ b/dapr_agents/workflow/base.py @@ -517,7 +517,7 @@ def start_runtime(self): self.wf_runtime.start() self.wf_runtime_is_running = True - logger.info("Sleeping for 5 seconds to ensure runtime is started.") + logger.info("Sleeping for 5 seconds to ensure runtime is started.") time.sleep(5) # Sync database state with Dapr workflow status after runtime starts From 094509330f614f5dd7ddfa06de2f325d0f4a9e32 Mon Sep 17 00:00:00 2001 From: Filinto Duran <1373693+filintod@users.noreply.github.com> Date: Thu, 25 Sep 2025 23:07:28 -0500 Subject: [PATCH 3/8] lint Signed-off-by: Filinto Duran <1373693+filintod@users.noreply.github.com> --- dapr_agents/llm/dapr/chat.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/dapr_agents/llm/dapr/chat.py b/dapr_agents/llm/dapr/chat.py index d4009540..09e72df0 100644 --- a/dapr_agents/llm/dapr/chat.py +++ b/dapr_agents/llm/dapr/chat.py @@ -23,13 +23,11 @@ from dapr_agents.prompt.prompty import Prompty from dapr_agents.tool import AgentTool from dapr_agents.types.exceptions import DaprRuntimeVersionNotSupportedError -from dapr_agents.types.exceptions import DaprRuntimeVersionNotSupportedError from dapr_agents.types.message import ( BaseMessage, LLMChatResponse, ) from dapr_agents.utils import is_version_supported -from dapr_agents.utils import is_version_supported # Lazy import to avoid import issues during test collection From 5b4877a7a0f4d3673c9e9364033b7348197bbe22 Mon Sep 17 00:00:00 2001 From: Filinto Duran <1373693+filintod@users.noreply.github.com> Date: Fri, 26 Sep 2025 00:20:31 -0500 Subject: [PATCH 4/8] move import to lazy eval to avoid issues on test Signed-off-by: Filinto Duran <1373693+filintod@users.noreply.github.com> --- dapr_agents/llm/dapr/chat.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dapr_agents/llm/dapr/chat.py b/dapr_agents/llm/dapr/chat.py index 09e72df0..3c2c9eb8 100644 --- a/dapr_agents/llm/dapr/chat.py +++ b/dapr_agents/llm/dapr/chat.py @@ -15,7 +15,6 @@ ) from pydantic import BaseModel, Field -from dapr.clients.grpc.client import GetMetadataResponse from dapr_agents.llm.chat import ChatClientBase from dapr_agents.llm.dapr.client import DaprInferenceClientBase from dapr_agents.llm.utils import RequestHandler, ResponseHandler @@ -43,6 +42,7 @@ def _import_conversation_types(): create_system_message, create_assistant_message, create_tool_message, + GetMetadataResponse, ) return ( @@ -56,6 +56,7 @@ def _import_conversation_types(): create_system_message, create_assistant_message, create_tool_message, + GetMetadataResponse, ) From 1fcca382fc7de25c60e8d495806133e7ed50daae Mon Sep 17 00:00:00 2001 From: Filinto Duran <1373693+filintod@users.noreply.github.com> Date: Fri, 26 Sep 2025 00:30:28 -0500 Subject: [PATCH 5/8] lint Signed-off-by: Filinto Duran <1373693+filintod@users.noreply.github.com> --- dapr_agents/llm/dapr/chat.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dapr_agents/llm/dapr/chat.py b/dapr_agents/llm/dapr/chat.py index 3c2c9eb8..d867a2ae 100644 --- a/dapr_agents/llm/dapr/chat.py +++ b/dapr_agents/llm/dapr/chat.py @@ -42,7 +42,6 @@ def _import_conversation_types(): create_system_message, create_assistant_message, create_tool_message, - GetMetadataResponse, ) return ( @@ -56,7 +55,6 @@ def _import_conversation_types(): create_system_message, create_assistant_message, create_tool_message, - GetMetadataResponse, ) @@ -365,7 +363,7 @@ def generate( ) -def _check_dapr_runtime_support(metadata: GetMetadataResponse): +def _check_dapr_runtime_support(metadata: 'GetMetadataResponse'): # noqa: F821 """Check if the Dapr runtime version is supported for Alpha2 Chat Client.""" extended_metadata = metadata.extended_metadata dapr_runtime_version = extended_metadata.get("daprRuntimeVersion", None) @@ -377,7 +375,7 @@ def _check_dapr_runtime_support(metadata: GetMetadataResponse): ) -def _get_llm_component(metadata: GetMetadataResponse) -> str: +def _get_llm_component(metadata: 'GetMetadataResponse') -> str: # noqa: F821 """Get the LLM component from the metadata.""" conversation_components = [ component From 75982e6e406b340b9a60f94c994ca25e4af50462 Mon Sep 17 00:00:00 2001 From: Filinto Duran <1373693+filintod@users.noreply.github.com> Date: Fri, 26 Sep 2025 07:19:04 -0500 Subject: [PATCH 6/8] lint Signed-off-by: Filinto Duran <1373693+filintod@users.noreply.github.com> --- dapr_agents/llm/dapr/chat.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dapr_agents/llm/dapr/chat.py b/dapr_agents/llm/dapr/chat.py index d867a2ae..821912c1 100644 --- a/dapr_agents/llm/dapr/chat.py +++ b/dapr_agents/llm/dapr/chat.py @@ -363,7 +363,7 @@ def generate( ) -def _check_dapr_runtime_support(metadata: 'GetMetadataResponse'): # noqa: F821 +def _check_dapr_runtime_support(metadata: "GetMetadataResponse"): # noqa: F821 """Check if the Dapr runtime version is supported for Alpha2 Chat Client.""" extended_metadata = metadata.extended_metadata dapr_runtime_version = extended_metadata.get("daprRuntimeVersion", None) @@ -375,7 +375,7 @@ def _check_dapr_runtime_support(metadata: 'GetMetadataResponse'): # noqa: F821 ) -def _get_llm_component(metadata: 'GetMetadataResponse') -> str: # noqa: F821 +def _get_llm_component(metadata: "GetMetadataResponse") -> str: # noqa: F821 """Get the LLM component from the metadata.""" conversation_components = [ component From 8b1cd65715ab2b2df55130b4a2ebada76e81fd94 Mon Sep 17 00:00:00 2001 From: Filinto Duran <1373693+filintod@users.noreply.github.com> Date: Fri, 26 Sep 2025 08:31:22 -0500 Subject: [PATCH 7/8] cleanup/refactor README.md for quickstart 01 Signed-off-by: Filinto Duran <1373693+filintod@users.noreply.github.com> --- .../01-hello-world/03_durable_agent.py | 13 +-- quickstarts/01-hello-world/README.md | 92 ++++++++----------- 2 files changed, 42 insertions(+), 63 deletions(-) diff --git a/quickstarts/01-hello-world/03_durable_agent.py b/quickstarts/01-hello-world/03_durable_agent.py index e9d3de8d..63e5083a 100644 --- a/quickstarts/01-hello-world/03_durable_agent.py +++ b/quickstarts/01-hello-world/03_durable_agent.py @@ -39,20 +39,17 @@ def search_flights(destination: str) -> List[FlightOption]: ] +# ---------------------------------------------------------------------------------------------------------------------- # There are three ways to set the LLM component with DaprChatClient: # -# 1. Directly pass the component name -# 2. Use the environment variable DAPR_LLM_COMPONENT_DEFAULT -# 3. If there is only one conversation component in the metadata, it will be used by default -# -# Option 1: Directly pass the component name +# 1. Explicitly instantiate the DaprChatClient with the component name # llm = DaprChatClient(component_name="openai") # -# Option 2: Use the environment variable to set the default component name +# 2. Use the environment variable DAPR_LLM_COMPONENT_DEFAULT # os.environ.setdefault("DAPR_LLM_COMPONENT_DEFAULT", "openai") # -# Option 3: If there is only one conversation component in the metadata, it will be used by default -# +# 3. If there is only one conversation component in the resources folder, it will be used by default +# ---------------------------------------------------------------------------------------------------------------------- async def main(): diff --git a/quickstarts/01-hello-world/README.md b/quickstarts/01-hello-world/README.md index 816cc1ae..3b4667ab 100644 --- a/quickstarts/01-hello-world/README.md +++ b/quickstarts/01-hello-world/README.md @@ -13,21 +13,15 @@ This quickstart provides a hands-on introduction to Dapr Agents through simple e
Option 1: Using uv (Recommended) -```bash -# Create and activate virtual environment -uv venv .venv -source .venv/bin/activate - -# Install core dependencies -uv pip install -r requirements.txt -``` - -
+ -
-Option 2: Using pip -
-Option 1: Using uv (Recommended) + ```bash # Create and activate virtual environment @@ -43,7 +37,7 @@ uv pip install -r requirements.txt
Option 2: Using pip -```bash +```a shell [not setting type to avoid mechanical markdown execution] # Create a virtual environment python3.10 -m venv .venv @@ -55,22 +49,18 @@ source .venv/bin/activate # Install dependencies pip install -r requirements.txt - ```
-
- -## Configuration +## OpenAI API Key > **Warning** > The examples will not work if you do not have a OpenAI API key exported in the environment. -Create a `.env` file in the project root and add your OpenAI API key: -> **Warning** -> The examples will not work if you do not have a OpenAI API key exported in the environment. +
+Option 1: Using .env file Create a `.env` file in the project root and add your OpenAI API key: @@ -81,28 +71,32 @@ OPENAI_API_KEY=your_api_key_here Replace `your_api_key_here` with your actual OpenAI API key. Export the environment variables from the .env file to your shell: -```bash -export $(grep -v '^#' .env | xargs) # or if .env is in the root directory, you can just run `export $(grep -v '^#' ../../.env | xargs)` +```a shell [not setting type to avoid mechanical markdown execution] +export $(grep -v '^#' .env | xargs) + +# or if .env is in the root directory of the repository, +# export $(grep -v '^#' ../../.env | xargs) ``` -Export the environment variables from the .env file to your shell: -```bash -export $(grep -v '^#' .env | xargs) # or if .env is in the root directory, you can just run `export $(grep -v '^#' ../../.env | xargs)` +
+ +
+Option 2: Exporting the OpenAI API Key directly to the shell + +```a shell [not setting type to avoid mechanical markdown execution] +export OPENAI_API_KEY=your_api_key_here ``` +Replace `your_api_key_here` with your actual OpenAI API key. + +
+ ## Examples ### 1. Basic LLM Usage Run the basic LLM example to see how to interact with OpenAI's language models: - ```bash python 01_ask_llm.py ``` @@ -210,36 +204,22 @@ name: Run basic LLM example expected_stdout_lines: - "I want to find flights to Paris" - "TravelBuddy" -timeout_seconds: 30 -output_match_mode: substring ---> - - -We are using the `resolve_env_templates.py` script to resolve the environment variables in the components folder and substitute them with the actual values in your .env file, like the OpenAI API key. - - -We are using the `resolve_env_templates.py` script to resolve the environment variables in the components folder and substitute them with the actual values in your .env file, like the OpenAI API key. +We are using the `resolve_env_templates.py` script to resolve the environment variables in the components folder and substitute them with the actual values in your environment, like the OpenAI API key. ```bash -dapr run --app-id stateful-llm --dapr-http-port 3500 --resources-path $(../resolve_env_templates.py ./components) -- python 03_durable_agent.py +source .venv/bin/activate + dapr run --app-id stateful-llm --dapr-http-port 3500 --resources-path $(../resolve_env_templates.py ./components) -- python 03_durable_agent.py ``` - - - This example demonstrates a stateful travel planning assistant that: 1. Remembers user context persistently (across restarts) 2. Uses a tool to search for flight options @@ -367,7 +347,8 @@ expected_stdout_lines: output_match_mode: substring --> ```bash -dapr run --app-id dapr-agent-wf --resources-path $(../resolve_env_templates.py ./components) -- python 04_chain_tasks.py +source .venv/bin/activate + dapr run --app-id dapr-agent-wf --resources-path $(../resolve_env_templates.py ./components) -- python 04_chain_tasks.py ``` @@ -439,8 +420,6 @@ Run the vector store agent example to see how to create an agent that can search ```bash +source .venv/bin/activate + python 05_agent_with_vectorstore.py ``` @@ -590,6 +571,7 @@ if __name__ == "__main__": ## Key Concepts +- **DaprChatClient**: The interface for interacting with Dapr's LLMs - **OpenAIChatClient**: The interface for interacting with OpenAI's LLMs - **Agent**: A class that combines an LLM with tools and instructions - **@tool decorator**: A way to create tools that agents can use From 237d5e7bed18be97548f449855ff21ed31ff5849 Mon Sep 17 00:00:00 2001 From: Filinto Duran <1373693+filintod@users.noreply.github.com> Date: Tue, 30 Sep 2025 13:43:35 -0500 Subject: [PATCH 8/8] use edge in our check function Signed-off-by: Filinto Duran <1373693+filintod@users.noreply.github.com> --- dapr_agents/llm/dapr/chat.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dapr_agents/llm/dapr/chat.py b/dapr_agents/llm/dapr/chat.py index 821912c1..ba3d06b5 100644 --- a/dapr_agents/llm/dapr/chat.py +++ b/dapr_agents/llm/dapr/chat.py @@ -368,10 +368,12 @@ def _check_dapr_runtime_support(metadata: "GetMetadataResponse"): # noqa: F821 extended_metadata = metadata.extended_metadata dapr_runtime_version = extended_metadata.get("daprRuntimeVersion", None) if dapr_runtime_version is not None: - # Allow only versions >=1.16.0 and <2.0.0 for Alpha2 Chat Client - if not is_version_supported(str(dapr_runtime_version), ">=1.16.0, <2.0.0"): + # Allow only versions >=1.16.0, edge, and <2.0.0 for Alpha2 Chat Client + if not is_version_supported( + str(dapr_runtime_version), ">=1.16.0, edge, <2.0.0" + ): raise DaprRuntimeVersionNotSupportedError( - f"!!!!! Dapr Runtime Version {dapr_runtime_version} is not supported with Alpha2 Dapr Chat Client. Only Dapr runtim versions >=1.16.0 and <2.0.0 are supported." + f"!!!!! Dapr Runtime Version {dapr_runtime_version} is not supported with Alpha2 Dapr Chat Client. Only Dapr runtime versions >=1.16.0, edge, and <2.0.0 are supported." )