{"id":6956,"library":"agent-framework-durabletask","title":"Durable Task for Microsoft Agent Framework","description":"The `agent-framework-durabletask` library provides robust integration for orchestrating long-running agent operations within the Microsoft Agent Framework, leveraging the capabilities of Durable Task (often via Azure Durable Functions). It enables complex, stateful workflows for agent-based systems. The current version is `1.0.0b260409`, indicating a beta phase with potentially frequent updates as it evolves alongside the core `agent-framework` library.","status":"active","version":"1.0.0b260409","language":"en","source_language":"en","source_url":"https://github.com/microsoft/agent-framework/tree/main/python/agent-framework-durabletask","tags":["agent-framework","durabletask","azure","orchestration","microsoft","workflow","stateful"],"install":[{"cmd":"pip install agent-framework-durabletask","lang":"bash","label":"Install latest beta"}],"dependencies":[{"reason":"Core dependency for Microsoft Agent Framework integration.","package":"agent-framework"},{"reason":"Provides the underlying Durable Task framework for Azure-based orchestration.","package":"azure-functions-durable","optional":true},{"reason":"Used for state management and task queuing when interacting with Azure Durable Functions.","package":"azure-storage-queue","optional":true}],"imports":[{"symbol":"DurableTaskOrchestrator","correct":"from agent_framework_durabletask.orchestration import DurableTaskOrchestrator"},{"symbol":"DurableTaskOrchestrationContext","correct":"from agent_framework_durabletask.orchestration import DurableTaskOrchestrationContext"},{"symbol":"DurableTaskClient","correct":"from agent_framework_durabletask.client import DurableTaskClient"},{"note":"Use this specific client for interactions with Azure Durable Functions.","symbol":"AzureDurableTaskClient","correct":"from agent_framework_durabletask.azure import AzureDurableTaskClient"}],"quickstart":{"code":"import os\nfrom agent_framework_durabletask.orchestration import (\n    DurableTaskOrchestrator,\n    DurableTaskOrchestrationContext,\n)\nfrom agent_framework_durabletask.client import DurableTaskClient\nfrom agent_framework_durabletask.azure import AzureDurableTaskClient\n\n# 1. Define a Durable Task Orchestrator\nclass MySimpleOrchestrator(DurableTaskOrchestrator):\n    \"\"\"\n    A simple orchestrator that logs its input and returns a processed string.\n    In a real scenario, this would coordinate calls to 'activities'.\n    \"\"\"\n    async def orchestrate(self, context: DurableTaskOrchestrationContext, input_data: str):\n        print(f\"Orchestrator '{context.instance_id}' received input: '{input_data}'\")\n        # Simulate some async work by returning immediately for this example\n        return f\"Processed '{input_data}' at {context.current_utc_datetime}\"\n\n# 2. Instantiate a Durable Task Client (e.g., for Azure Durable Functions)\n# This client requires connection details to an Azure Storage Account\n# which is used by Azure Durable Functions to manage orchestration state.\nazure_storage_connection_string = os.environ.get(\"AZURE_STORAGE_CONNECTION_STRING\", \"\")\ntask_hub_name = os.environ.get(\"DURABLETASK_HUB_NAME\", \"DefaultTaskHub\")\n\nif azure_storage_connection_string:\n    print(\"Initializing AzureDurableTaskClient...\")\n    try:\n        client = AzureDurableTaskClient(\n            task_hub_name=task_hub_name,\n            azure_storage_connection_string=azure_storage_connection_string\n        )\n        print(f\"AzureDurableTaskClient initialized for task hub '{task_hub_name}'.\")\n        # In a real application, you would then use `client` to start and manage orchestrations:\n        # import asyncio\n        # async def run_orchestration():\n        #     instance_id = await client.start_orchestration(MySimpleOrchestrator, \"Hello DurableTask!\")\n        #     print(f\"Started orchestration with ID: {instance_id}\")\n        #     # You'd typically poll or wait for the orchestration to complete\n        #     # status = await client.get_orchestration_status(instance_id)\n        #     # while status.runtime_status not in [OrchestrationRuntimeStatus.Completed, OrchestrationRuntimeStatus.Failed, OrchestrationRuntimeStatus.Terminated]:\n        #     #     await asyncio.sleep(5)\n        #     #     status = await client.get_orchestration_status(instance_id)\n        #     # print(f\"Orchestration {instance_id} finished with status: {status.runtime_status}\")\n        # asyncio.run(run_orchestration())\n    except Exception as e:\n        print(f\"Failed to initialize AzureDurableTaskClient: {e}\")\n        print(\"Please ensure AZURE_STORAGE_CONNECTION_STRING is valid and points to an Azure Storage Account.\")\nelse:\n    print(\"AZURE_STORAGE_CONNECTION_STRING environment variable not set.\")\n    print(\"Cannot initialize AzureDurableTaskClient without storage connection details.\")\n    print(\"To run this, ensure you have an Azure Storage Account and set its connection string.\")\n\nprint(\"\\n--- Example finished. This code defines an orchestrator and attempts to initialize a client. ---\")\nprint(\"To execute orchestrations, you need a Durable Task backend host (e.g., Azure Functions).\")","lang":"python","description":"This quickstart demonstrates how to define a `DurableTaskOrchestrator` and initialize an `AzureDurableTaskClient`. To make the client fully functional and execute orchestrations, you must set the `AZURE_STORAGE_CONNECTION_STRING` environment variable, pointing to an Azure Storage Account that backs an Azure Functions app running Durable Functions."},"warnings":[{"fix":"Always pin to a specific version (`agent-framework-durabletask==X.Y.Z`) and thoroughly test updates. Monitor the official GitHub repository for release notes.","message":"The library is currently in a beta (`1.0.0b...`) state, which means its API is subject to change without strict backward compatibility guarantees between minor or even patch versions. Expect breaking changes.","severity":"breaking","affected_versions":"<=1.0.0b260409"},{"fix":"Use `DurableTaskOrchestrationContext` methods for all side-effecting operations (e.g., `context.call_activity`, `context.current_utc_datetime`). Avoid any non-deterministic code paths within the orchestrator function itself.","message":"Orchestrator functions must be deterministic. Any non-deterministic operations (e.g., direct I/O, generating random numbers, using `datetime.now()` without `context.current_utc_datetime`) can lead to replay issues, where the orchestration behaves differently on replay, causing runtime errors.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Set up an Azure Storage Account and an Azure Functions app with Durable Functions enabled. Provide the storage account's connection string via the `AZURE_STORAGE_CONNECTION_STRING` environment variable or directly to the client constructor.","message":"Using `AzureDurableTaskClient` (the most common client) requires an Azure Storage Account and an Azure Functions app configured to host Durable Functions. Without this backend, the client cannot communicate with an orchestrator runtime.","severity":"gotcha","affected_versions":"All versions using Azure integration"},{"fix":"Regularly update `agent-framework-durabletask` and its core `azure-*` dependencies. Check PyPI for the latest compatible versions.","message":"While not explicitly deprecated yet, reliance on older versions of `azure-functions-durable` or `azure-storage-queue` can lead to compatibility issues with newer Azure services or Python runtimes. Always ensure these dependencies are up-to-date.","severity":"deprecated","affected_versions":"Implicitly affects older underlying Azure dependencies"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure the library is installed using `pip install agent-framework-durabletask` in the active virtual environment.","cause":"The library is not installed or the Python environment is not configured correctly.","error":"ModuleNotFoundError: No module named 'agent_framework_durabletask'"},{"fix":"Refactor the orchestrator function to ensure all operations are deterministic. Use `DurableTaskOrchestrationContext` for time, random numbers, or external calls. Delegate non-deterministic logic to 'activity' functions.","cause":"The orchestrator code contains operations that are not deterministic across replays, which is forbidden in Durable Task.","error":"Orchestrator function 'MyOrchestrator' failed due to a non-deterministic operation. See the function log for more details."},{"fix":"Verify that the `AZURE_STORAGE_CONNECTION_STRING` environment variable or constructor argument contains a valid connection string for an Azure Storage Account. Ensure the account has permissions for queue and table access.","cause":"The `AZURE_STORAGE_CONNECTION_STRING` provided for `AzureDurableTaskClient` is invalid, expired, or lacks necessary permissions.","error":"azure.core.exceptions.ClientAuthenticationError: Authentication failed."},{"fix":"Ensure the `AZURE_STORAGE_CONNECTION_STRING` environment variable is set or pass the connection string directly to the `AzureDurableTaskClient` constructor.","cause":"The `AzureDurableTaskClient` was instantiated without the required Azure Storage connection string.","error":"ValueError: The 'azure_storage_connection_string' must be provided."}]}