diff --git a/dapr_agents/agents/durable.py b/dapr_agents/agents/durable.py index b0d5251f3..6a738ab80 100644 --- a/dapr_agents/agents/durable.py +++ b/dapr_agents/agents/durable.py @@ -32,8 +32,7 @@ ) from dapr_agents.types.workflow import DaprWorkflowStatus from dapr_agents.tool.utils.serialization import serialize_tool_result -from dapr_agents.workflow.decorators.routers import message_router -from dapr_agents.workflow.runners.agent import workflow_entry +from dapr_agents.workflow.decorators import message_router, workflow_entry from dapr_agents.workflow.utils.grpc import apply_grpc_options from dapr_agents.workflow.utils.pubsub import broadcast_message, send_message_to_agent diff --git a/dapr_agents/agents/orchestrators/llm/orchestrator.py b/dapr_agents/agents/orchestrators/llm/orchestrator.py index ab2a652cd..7e1dfd955 100644 --- a/dapr_agents/agents/orchestrators/llm/orchestrator.py +++ b/dapr_agents/agents/orchestrators/llm/orchestrator.py @@ -16,7 +16,7 @@ TriggerAction, ) from dapr_agents.workflow.decorators.routers import message_router -from dapr_agents.workflow.runners.agent import workflow_entry +from dapr_agents.workflow.decorators import workflow_entry from dapr_agents.agents.orchestrators.llm.prompts import ( NEXT_STEP_PROMPT, PROGRESS_CHECK_PROMPT, diff --git a/dapr_agents/agents/orchestrators/random.py b/dapr_agents/agents/orchestrators/random.py index c8fe08f1f..96607e61b 100644 --- a/dapr_agents/agents/orchestrators/random.py +++ b/dapr_agents/agents/orchestrators/random.py @@ -22,7 +22,7 @@ TriggerAction, ) from dapr_agents.workflow.decorators.routers import message_router -from dapr_agents.workflow.runners.agent import workflow_entry +from dapr_agents.workflow.decorators import workflow_entry from dapr_agents.workflow.utils.pubsub import broadcast_message, send_message_to_agent logger = logging.getLogger(__name__) diff --git a/dapr_agents/agents/orchestrators/roundrobin.py b/dapr_agents/agents/orchestrators/roundrobin.py index 438294aea..3a04bfb1f 100644 --- a/dapr_agents/agents/orchestrators/roundrobin.py +++ b/dapr_agents/agents/orchestrators/roundrobin.py @@ -21,7 +21,7 @@ TriggerAction, ) from dapr_agents.workflow.decorators.routers import message_router -from dapr_agents.workflow.runners.agent import workflow_entry +from dapr_agents.workflow.decorators import workflow_entry from dapr_agents.workflow.utils.pubsub import broadcast_message, send_message_to_agent logger = logging.getLogger(__name__) diff --git a/dapr_agents/workflow/__init__.py b/dapr_agents/workflow/__init__.py index 6652594ab..6362a54ba 100644 --- a/dapr_agents/workflow/__init__.py +++ b/dapr_agents/workflow/__init__.py @@ -1,8 +1,15 @@ -from .decorators import message_router, http_router, llm_activity, agent_activity +from .decorators import ( + message_router, + http_router, + llm_activity, + agent_activity, + workflow_entry, +) __all__ = [ "message_router", "http_router", "llm_activity", "agent_activity", + "workflow_entry", ] diff --git a/dapr_agents/workflow/decorators/__init__.py b/dapr_agents/workflow/decorators/__init__.py index 62bd9942c..8d23a1d85 100644 --- a/dapr_agents/workflow/decorators/__init__.py +++ b/dapr_agents/workflow/decorators/__init__.py @@ -1,9 +1,10 @@ from .routers import message_router, http_router -from .activities import llm_activity, agent_activity +from .activities import llm_activity, agent_activity, workflow_entry __all__ = [ "message_router", "http_router", "llm_activity", "agent_activity", + "workflow_entry", ] diff --git a/dapr_agents/workflow/decorators/activities.py b/dapr_agents/workflow/decorators/activities.py index a40b43384..b3a696d12 100644 --- a/dapr_agents/workflow/decorators/activities.py +++ b/dapr_agents/workflow/decorators/activities.py @@ -4,7 +4,7 @@ import functools import inspect import logging -from typing import Any, Callable, Literal, Optional +from typing import Any, Callable, Literal, Optional, TypeVar from dapr.ext.workflow import WorkflowActivityContext # type: ignore @@ -23,6 +23,29 @@ logger = logging.getLogger(__name__) +R = TypeVar("R") + + +def workflow_entry(func: Callable[..., R]) -> Callable[..., R]: + """ + Mark a method/function as the workflow entrypoint for an Agent. + + This decorator does not wrap the function; it simply annotates the callable + with `_is_workflow_entry = True` so AgentRunner can discover it on the agent + instance via reflection. + + Usage: + class MyAgent: + @workflow_entry + def my_workflow(self, ctx: DaprWorkflowContext, wf_input: dict) -> str: + ... + + Returns: + The same callable (unmodified), with an identifying attribute. + """ + setattr(func, "_is_workflow_entry", True) # type: ignore[attr-defined] + return func + def llm_activity( *, diff --git a/dapr_agents/workflow/runners/agent.py b/dapr_agents/workflow/runners/agent.py index bc570cd95..c5825fc6e 100644 --- a/dapr_agents/workflow/runners/agent.py +++ b/dapr_agents/workflow/runners/agent.py @@ -3,11 +3,13 @@ import asyncio import concurrent.futures import logging -import threading -from typing import Any, Callable, Dict, Literal, Optional, TypeVar, Union +from threading import Lock, Thread +from typing import Any, Callable, Dict, Literal, Optional, TypeVar, Union, List from fastapi import Body, FastAPI, HTTPException +from dapr_agents.agents.components import AgentComponents +from dapr_agents.agents.durable import DurableAgent from dapr_agents.types.workflow import PubSubRouteSpec from dapr_agents.workflow.runners.base import WorkflowRunner from dapr_agents.workflow.utils.core import get_decorated_methods @@ -21,27 +23,6 @@ R = TypeVar("R") -def workflow_entry(func: Callable[..., R]) -> Callable[..., R]: - """ - Mark a method/function as the workflow entrypoint for an Agent. - - This decorator does not wrap the function; it simply annotates the callable - with `_is_workflow_entry = True` so AgentRunner can discover it on the agent - instance via reflection. - - Usage: - class MyAgent: - @workflow_entry - def my_workflow(self, ctx: DaprWorkflowContext, wf_input: dict) -> str: - ... - - Returns: - The same callable (unmodified), with an identifying attribute. - """ - setattr(func, "_is_workflow_entry", True) # type: ignore[attr-defined] - return func - - class AgentRunner(WorkflowRunner): """ Runner specialized for Agent classes. @@ -73,9 +54,15 @@ def __init__( ) self._default_http_paths: set[str] = set() + # In-memory store of managed agents - used for handling shutdown + self._managed_agents: List[ + AgentComponents + ] = [] # AgentComponents is the lowest common denominator between orchestrators and agents. + self._lock: Lock = Lock() + async def run( self, - agent: Any, + agent: AgentComponents, payload: Optional[Union[str, Dict[str, Any]]] = None, *, instance_id: Optional[str] = None, @@ -112,6 +99,14 @@ async def run( wait, timeout_in_seconds, ) + try: + agent.start() + except RuntimeError: + # The agent is already started + pass + with self._lock: + if agent not in self._managed_agents: + self._managed_agents.append(agent) entry = self.discover_entry(agent) logger.debug("[%s] Discovered workflow entry: %s", self._name, entry.__name__) @@ -128,7 +123,7 @@ async def run( def run_sync( self, - agent: Any, + agent: AgentComponents, payload: Optional[Union[str, Dict[str, Any]]] = None, *, instance_id: Optional[str] = None, @@ -223,13 +218,13 @@ def _runner() -> None: finally: loop.close() - t = threading.Thread(target=_runner, daemon=True) + t = Thread(target=_runner, daemon=True) t.start() return fut.result() def register_routes( self, - agent: Any, + agent: AgentComponents, *, fastapi_app: Optional[FastAPI] = None, delivery_mode: Literal["sync", "async"] = "sync", @@ -252,6 +247,16 @@ def register_routes( fetch_payloads: Whether to fetch input/output payloads for awaited workflows. log_outcome: Whether to log the final outcome of awaited workflows. """ + + try: + agent.start() + except RuntimeError: + # The agent is already started + pass + with self._lock: + if agent not in self._managed_agents: + self._managed_agents.append(agent) + self._wire_pubsub_routes( agent=agent, delivery_mode=delivery_mode, @@ -265,7 +270,9 @@ def register_routes( if fastapi_app is not None: self._wire_http_routes(agent=agent, fastapi_app=fastapi_app) - def _build_pubsub_specs(self, agent: Any, config: Any) -> list[PubSubRouteSpec]: + def _build_pubsub_specs( + self, agent: AgentComponents, config: Any + ) -> list[PubSubRouteSpec]: handlers = get_decorated_methods(agent, "_is_message_handler") if not handlers: return [] @@ -300,7 +307,7 @@ def _build_pubsub_specs(self, agent: Any, config: Any) -> list[PubSubRouteSpec]: def _wire_pubsub_routes( self, *, - agent: Any, + agent: AgentComponents, delivery_mode: Literal["sync", "async"], queue_maxsize: int, await_result: bool, @@ -339,7 +346,9 @@ def _wire_pubsub_routes( self._pubsub_closers.extend(closers) self._wired_pubsub = True - def _wire_http_routes(self, *, agent: Any, fastapi_app: Optional[FastAPI]) -> None: + def _wire_http_routes( + self, *, agent: AgentComponents, fastapi_app: Optional[FastAPI] + ) -> None: if fastapi_app is None or self._wired_http: return @@ -352,7 +361,7 @@ def _wire_http_routes(self, *, agent: Any, fastapi_app: Optional[FastAPI]) -> No def subscribe( self, - agent: Any, + agent: AgentComponents, *, delivery_mode: Literal["sync", "async"] = "sync", queue_maxsize: int = 1024, @@ -376,6 +385,17 @@ def subscribe( Returns: The runner (to allow fluent chaining). """ + + try: + agent.start() + except RuntimeError: + # The agent is already started + pass + + with self._lock: + if agent not in self._managed_agents: + self._managed_agents.append(agent) + self._wire_pubsub_routes( agent=agent, delivery_mode=delivery_mode, @@ -389,7 +409,7 @@ def subscribe( def serve( self, - agent: Any, + agent: AgentComponents, *, app: Optional[FastAPI] = None, host: str = "0.0.0.0", @@ -422,8 +442,19 @@ def serve( Returns: The FastAPI application with the workflow routes. """ + fastapi_app = app or FastAPI(title="Dapr Agent Service", version="1.0.0") + try: + agent.start() + except RuntimeError: + # The agent is already started + pass + + with self._lock: + if agent not in self._managed_agents: + self._managed_agents.append(agent) + self.subscribe( agent, delivery_mode=delivery_mode, @@ -476,7 +507,7 @@ def _mount_service_routes( self, *, fastapi_app: FastAPI, - agent: Any, + agent: AgentComponents, entry_path: str, status_path: str, workflow_component: str, @@ -550,3 +581,32 @@ async def _get_status(instance_id: str) -> dict: tags=["workflow"], ) logger.info("Mounted default workflow status endpoint at %s", status_path) + + def shutdown(self, agent: Optional[AgentComponents]) -> None: + """ + Unwire subscriptions and close owned clients. + + Args: + agent: Durable agent instance. + + Returns: + None + """ + + if agent: + # We need to shutdown a single agent + # First verify we're managing it + with self._lock: + if agent in self._managed_agents: + agent.stop() # This is safe as they'll return None if not started + self._managed_agents.remove(agent) + return + try: + self.unwire_pubsub() + finally: + with self._lock: + agents = list(self._managed_agents) + for ag in agents: + ag.stop() + self._close_dapr_client() + self._close_wf_client() diff --git a/quickstarts/01-hello-world/03_durable_agent_run.py b/quickstarts/01-hello-world/03_durable_agent_run.py index d556b3edd..ae913d50e 100644 --- a/quickstarts/01-hello-world/03_durable_agent_run.py +++ b/quickstarts/01-hello-world/03_durable_agent_run.py @@ -76,7 +76,6 @@ async def main() -> None: memory=memory, state=state, ) - travel_planner.start() runner = AgentRunner() prompt = "I want to find flights to Paris" @@ -91,8 +90,7 @@ async def main() -> None: print(f"Error running workflow: {e}") raise finally: - travel_planner.stop() - runner.shutdown() + runner.shutdown(travel_planner) if __name__ == "__main__": diff --git a/quickstarts/01-hello-world/03_durable_agent_serve.py b/quickstarts/01-hello-world/03_durable_agent_serve.py index 26272f3a1..526539fc6 100644 --- a/quickstarts/01-hello-world/03_durable_agent_serve.py +++ b/quickstarts/01-hello-world/03_durable_agent_serve.py @@ -76,14 +76,12 @@ def main() -> None: memory=memory, state=state, ) - agent.start() runner = AgentRunner() try: runner.serve(agent, port=8001) finally: - runner.shutdown() - agent.stop() + runner.shutdown(agent) if __name__ == "__main__": diff --git a/quickstarts/01-hello-world/03_durable_agent_subscribe.py b/quickstarts/01-hello-world/03_durable_agent_subscribe.py index 6281d221d..7b6e087d1 100644 --- a/quickstarts/01-hello-world/03_durable_agent_subscribe.py +++ b/quickstarts/01-hello-world/03_durable_agent_subscribe.py @@ -78,15 +78,12 @@ async def main() -> None: memory=memory, state=state, ) - agent.start() - runner = AgentRunner() try: runner.subscribe(agent) await wait_for_shutdown() finally: - runner.shutdown() - agent.stop() + runner.shutdown(agent) if __name__ == "__main__": diff --git a/quickstarts/03-durable-agent-tool-call/durable_weather_agent_dapr.py b/quickstarts/03-durable-agent-tool-call/durable_weather_agent_dapr.py index 5f71ae8f4..5f34d0135 100644 --- a/quickstarts/03-durable-agent-tool-call/durable_weather_agent_dapr.py +++ b/quickstarts/03-durable-agent-tool-call/durable_weather_agent_dapr.py @@ -25,8 +25,6 @@ async def main(): ], tools=tools, ) - # Start the agent (registers workflows with the runtime) - weather_agent.start() # Create an AgentRunner to execute the workflow runner = AgentRunner() @@ -46,10 +44,8 @@ async def main(): logger.error(f"Error running workflow: {e}", exc_info=True) raise finally: - # Stop agent first (tears down durabletask runtime) - weather_agent.stop() # Then shut down runner (unwire/close clients) - runner.shutdown() + runner.shutdown(weather_agent) if __name__ == "__main__": diff --git a/quickstarts/03-durable-agent-tool-call/durable_weather_agent_hf.py b/quickstarts/03-durable-agent-tool-call/durable_weather_agent_hf.py index 873d967b1..fe545b5a9 100644 --- a/quickstarts/03-durable-agent-tool-call/durable_weather_agent_hf.py +++ b/quickstarts/03-durable-agent-tool-call/durable_weather_agent_hf.py @@ -29,8 +29,6 @@ async def main(): llm=llm, tools=tools, ) - # Start the agent (registers workflows with the runtime) - weather_agent.start() # Create an AgentRunner to execute the workflow runner = AgentRunner() @@ -50,10 +48,8 @@ async def main(): logger.error(f"Error running workflow: {e}", exc_info=True) raise finally: - # Stop agent first (tears down durabletask runtime) - weather_agent.stop() # Then shut down runner (unwire/close clients) - runner.shutdown() + runner.shutdown(weather_agent) if __name__ == "__main__": diff --git a/quickstarts/03-durable-agent-tool-call/durable_weather_agent_nv.py b/quickstarts/03-durable-agent-tool-call/durable_weather_agent_nv.py index 5aa8171ad..924499f9d 100644 --- a/quickstarts/03-durable-agent-tool-call/durable_weather_agent_nv.py +++ b/quickstarts/03-durable-agent-tool-call/durable_weather_agent_nv.py @@ -29,9 +29,6 @@ async def main(): llm=llm, tools=tools, ) - # Start the agent (registers workflows with the runtime) - weather_agent.start() - # Create an AgentRunner to execute the workflow runner = AgentRunner() @@ -50,10 +47,8 @@ async def main(): logger.error(f"Error running workflow: {e}", exc_info=True) raise finally: - # Stop agent first (tears down durabletask runtime) - weather_agent.stop() # Then shut down runner (unwire/close clients) - runner.shutdown() + runner.shutdown(weather_agent) if __name__ == "__main__": diff --git a/quickstarts/03-durable-agent-tool-call/durable_weather_agent_openai.py b/quickstarts/03-durable-agent-tool-call/durable_weather_agent_openai.py index b1bb2eaa6..e96fe2219 100644 --- a/quickstarts/03-durable-agent-tool-call/durable_weather_agent_openai.py +++ b/quickstarts/03-durable-agent-tool-call/durable_weather_agent_openai.py @@ -28,9 +28,6 @@ async def main(): llm=OpenAIChatClient(model="gpt-4o-mini"), tools=tools, ) - # Start the agent (registers workflows with the runtime) - weather_agent.start() - # Create an AgentRunner to execute the workflow runner = AgentRunner() @@ -49,10 +46,8 @@ async def main(): logger.error(f"Error running workflow: {e}", exc_info=True) raise finally: - # Stop agent first (tears down durabletask runtime) - weather_agent.stop() # Then shut down runner (unwire/close clients) - runner.shutdown() + runner.shutdown(weather_agent) if __name__ == "__main__": diff --git a/quickstarts/03-durable-agent-tool-call/durable_weather_agent_tracing.py b/quickstarts/03-durable-agent-tool-call/durable_weather_agent_tracing.py index a7527a97e..a0f90ddce 100644 --- a/quickstarts/03-durable-agent-tool-call/durable_weather_agent_tracing.py +++ b/quickstarts/03-durable-agent-tool-call/durable_weather_agent_tracing.py @@ -39,9 +39,6 @@ async def main(): ], tools=tools, ) - # Start the agent (registers workflows with the runtime) - weather_agent.start() - # Create an AgentRunner to execute the workflow runner = AgentRunner() @@ -63,10 +60,8 @@ async def main(): logger.error(f"Error running workflow: {e}", exc_info=True) raise finally: - # Stop agent first (tears down durabletask runtime) - weather_agent.stop() # Then shut down runner (unwire/close clients) - runner.shutdown() + runner.shutdown(weather_agent) if __name__ == "__main__": diff --git a/quickstarts/05-multi-agent-workflows/services/frodo/app.py b/quickstarts/05-multi-agent-workflows/services/frodo/app.py index 20f260092..169393a21 100644 --- a/quickstarts/05-multi-agent-workflows/services/frodo/app.py +++ b/quickstarts/05-multi-agent-workflows/services/frodo/app.py @@ -95,7 +95,6 @@ async def main() -> None: memory=frodo_memory, llm=llm, ) - frodo.start() # --------------------------- # PubSub routing & shutdown @@ -106,8 +105,7 @@ async def main() -> None: runner.register_routes(frodo) await wait_for_shutdown() finally: - runner.shutdown() - frodo.stop() + runner.shutdown(frodo) if __name__ == "__main__": diff --git a/quickstarts/05-multi-agent-workflows/services/gandalf/app.py b/quickstarts/05-multi-agent-workflows/services/gandalf/app.py index ecb95cb03..90b836775 100644 --- a/quickstarts/05-multi-agent-workflows/services/gandalf/app.py +++ b/quickstarts/05-multi-agent-workflows/services/gandalf/app.py @@ -97,7 +97,6 @@ async def main() -> None: memory=gandalf_memory, llm=llm, ) - gandalf.start() # --------------------------- # PubSub routing & shutdown @@ -107,8 +106,7 @@ async def main() -> None: runner.register_routes(gandalf) await wait_for_shutdown() finally: - runner.shutdown() - gandalf.stop() + runner.shutdown(gandalf) if __name__ == "__main__": diff --git a/quickstarts/05-multi-agent-workflows/services/legolas/app.py b/quickstarts/05-multi-agent-workflows/services/legolas/app.py index d3dcaea24..738ad1c13 100644 --- a/quickstarts/05-multi-agent-workflows/services/legolas/app.py +++ b/quickstarts/05-multi-agent-workflows/services/legolas/app.py @@ -95,7 +95,6 @@ async def main() -> None: memory=legolas_memory, llm=llm, ) - legolas.start() # --------------------------- # PubSub routing & shutdown @@ -105,8 +104,7 @@ async def main() -> None: runner.register_routes(legolas) await wait_for_shutdown() finally: - runner.shutdown() - legolas.stop() + runner.shutdown(legolas) if __name__ == "__main__": diff --git a/quickstarts/05-multi-agent-workflows/services/sam/app.py b/quickstarts/05-multi-agent-workflows/services/sam/app.py index 1b3cd58b3..c4ee948b3 100644 --- a/quickstarts/05-multi-agent-workflows/services/sam/app.py +++ b/quickstarts/05-multi-agent-workflows/services/sam/app.py @@ -98,7 +98,6 @@ async def main() -> None: memory=sam_memory, llm=llm, ) - sam.start() # --------------------------- # PubSub routing & shutdown @@ -109,8 +108,7 @@ async def main() -> None: runner.register_routes(sam) await wait_for_shutdown() finally: - runner.shutdown() - sam.stop() + runner.shutdown(sam) if __name__ == "__main__": diff --git a/quickstarts/05-multi-agent-workflows/services/workflow-llm/app.py b/quickstarts/05-multi-agent-workflows/services/workflow-llm/app.py index 4752dbbdf..05b2644d7 100644 --- a/quickstarts/05-multi-agent-workflows/services/workflow-llm/app.py +++ b/quickstarts/05-multi-agent-workflows/services/workflow-llm/app.py @@ -71,14 +71,12 @@ def on_summary(summary: str): runtime=wf.WorkflowRuntime(), final_summary_callback=on_summary, ) - orchestrator.start() runner = AgentRunner() try: runner.serve(orchestrator, port=8004) finally: - runner.shutdown() - orchestrator.stop() + runner.shutdown(orchestrator) if __name__ == "__main__": diff --git a/quickstarts/05-multi-agent-workflows/services/workflow-random/app.py b/quickstarts/05-multi-agent-workflows/services/workflow-random/app.py index 8b503351a..76b24d0d2 100644 --- a/quickstarts/05-multi-agent-workflows/services/workflow-random/app.py +++ b/quickstarts/05-multi-agent-workflows/services/workflow-random/app.py @@ -52,14 +52,12 @@ def main() -> None: timeout_seconds=int(os.getenv("TIMEOUT_SECONDS", "45")), runtime=wf.WorkflowRuntime(), ) - orchestrator.start() runner = AgentRunner() try: runner.serve(orchestrator, port=8004) finally: - runner.shutdown() - orchestrator.stop() + runner.shutdown(orchestrator) if __name__ == "__main__": diff --git a/quickstarts/05-multi-agent-workflows/services/workflow-roundrobin/app.py b/quickstarts/05-multi-agent-workflows/services/workflow-roundrobin/app.py index 20c452965..9ebfaf47d 100644 --- a/quickstarts/05-multi-agent-workflows/services/workflow-roundrobin/app.py +++ b/quickstarts/05-multi-agent-workflows/services/workflow-roundrobin/app.py @@ -47,14 +47,12 @@ def main() -> None: agent_metadata={"legend": "Sends tasks in a fair rotation."}, runtime=wf.WorkflowRuntime(), ) - orchestrator.start() runner = AgentRunner() try: runner.serve(orchestrator, port=8004) finally: - runner.shutdown() - orchestrator.stop() + runner.shutdown(orchestrator) if __name__ == "__main__": diff --git a/quickstarts/07-agent-mcp-client-sse/README.md b/quickstarts/07-agent-mcp-client-sse/README.md index a3cf584a6..511d8de97 100644 --- a/quickstarts/07-agent-mcp-client-sse/README.md +++ b/quickstarts/07-agent-mcp-client-sse/README.md @@ -114,7 +114,6 @@ agent = DurableAgent( memory=memory_config, state=state_config, ) -agent.start() runner = AgentRunner() runner.serve(agent, port=8001) diff --git a/quickstarts/07-agent-mcp-client-sse/app.py b/quickstarts/07-agent-mcp-client-sse/app.py index 449891d04..5f39f7959 100644 --- a/quickstarts/07-agent-mcp-client-sse/app.py +++ b/quickstarts/07-agent-mcp-client-sse/app.py @@ -72,14 +72,12 @@ def main() -> None: memory=memory, state=state, ) - agent.start() runner = AgentRunner() try: runner.serve(agent, port=8001) finally: - runner.shutdown() - agent.stop() + runner.shutdown(agent) if __name__ == "__main__": diff --git a/quickstarts/07-agent-mcp-client-stdio/agent.py b/quickstarts/07-agent-mcp-client-stdio/agent.py index e9fb7e297..1f4ed6aba 100644 --- a/quickstarts/07-agent-mcp-client-stdio/agent.py +++ b/quickstarts/07-agent-mcp-client-stdio/agent.py @@ -84,14 +84,12 @@ def main() -> None: memory=memory, state=state, ) - agent.start() runner = AgentRunner() try: runner.serve(agent, port=8001) finally: - runner.shutdown() - agent.stop() + runner.shutdown(agent) if __name__ == "__main__": diff --git a/quickstarts/07-agent-mcp-client-streamablehttp/app.py b/quickstarts/07-agent-mcp-client-streamablehttp/app.py index 1e14a5659..3752285a8 100644 --- a/quickstarts/07-agent-mcp-client-streamablehttp/app.py +++ b/quickstarts/07-agent-mcp-client-streamablehttp/app.py @@ -82,14 +82,12 @@ def main() -> None: memory=memory, state=state, ) - agent.start() runner = AgentRunner() try: runner.serve(agent, port=8001) finally: - runner.shutdown() - agent.stop() + runner.shutdown(agent) if __name__ == "__main__": diff --git a/tests/integration/quickstarts/test_04_llm_based_workflows.py b/tests/integration/quickstarts/test_04_llm_based_workflows.py index bdf01d17e..94797f308 100644 --- a/tests/integration/quickstarts/test_04_llm_based_workflows.py +++ b/tests/integration/quickstarts/test_04_llm_based_workflows.py @@ -32,7 +32,7 @@ def test_single_activity_workflow(self, dapr_runtime): # noqa: ARG002 assert "Workflow started:" in result.stdout or "bio" in result.stdout.lower() def test_single_structured_activity_workflow(self, dapr_runtime): # noqa: ARG002 - script = self.quickstart_dir / "01_single_structured_activity_workflow.py" + script = self.quickstart_dir / "02_single_structured_activity_workflow.py" result = run_quickstart_script( script, cwd=self.quickstart_dir,