Azure / Azure/azure-functions-agents-runtime

Proposal: make Dynamic Workflow dependencies optional

Open
#188 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
9
Forks
7
Avg merge
1d 21h
Merged PRs (30d)
20

Description

## Summary

Make Dynamic Workflow dependencies optional so applications that do not enable workflows avoid installing and importing the Durable Functions stack.

Proposed installation experience:

```text
# Standard agents
pip install azurefunctions-agents-runtime

# Dynamic Workflows
pip install azurefunctions-agents-runtime[workflows]

# Dynamic Workflows with Azure Monitor
pip install azurefunctions-agents-runtime[workflows,monitor]
```

## Motivation

Dynamic Workflows depend on `azure-functions-durable`. With Durable Functions Python 2.x, this also brings in packages such as `durabletask`, `grpcio`, and `protobuf`.

A local measurement of the relevant installed distributions was approximately:

| Distribution | Installed size |
| --- | ---: |
| `azure-functions-durable` | 0.4 MiB |
| `durabletask` | 1.9 MiB |
| `grpcio` | 12.6 MiB |
| `protobuf` | 2.6 MiB |
| **Total** | **17.5 MiB** |

Today, `app.py` imports `azure.durable_functions` at module load time and imports `workflows.integration`, which imports the Durable engine. As a result, importing `azure_functions_agents` loads the Durable stack even when no agent enables Dynamic Workflows. In one local check, this loaded 85 Durable/grpc-related modules.

This increases deployment size and cold-start work for the default, non-workflow experience.

## Proposed design

### 1. Establish a lazy import boundary

Keep workflow configuration, schema, policy, decorators, discovery, and validation independent of the Durable SDK.

Move or isolate Durable-specific behavior behind a runtime boundary:

- `DFApp` creation;
- orchestrator and Activity registration;
- Durable client bindings and management operations;
- Durable engine implementation.

`create_function_app()` should first resolve agent configuration and build the workflow policy catalog. It should import the Durable runtime only when at least one agent has `workflows.enabled: true`.

```text
create_function_app()
-> load and validate agents
-> no workflow-enabled agents
-> create FunctionApp
-> do not import Durable
-> workflow-enabled agent exists
-> verify workflow dependencies
-> lazily import Durable runtime
-> create DFApp and register workflows
```

### 2. Add a `workflows` optional extra

Move `azure-functions-durable` from the default dependency set to:

```toml
[project.optional-dependencies]
workflows = [
"azure-functions-durable==...",
]
```

Workflow samples and documentation should install `[workflows]`; standard samples should remain on the lightweight default package.

### 3. Provide an actionable startup error

If an agent enables workflows without the extra installed, fail during app composition with a concise error such as:

```text
Dynamic Workflows are enabled, but workflow dependencies are not installed.
Install them with: pip install azurefunctions-agents-runtime[workflows]
```

Applications without workflow-enabled agents should not warn or fail when Durable is absent.

## User experience considerations

- Keep one runtime package and one version number; avoid a separate workflow package unless the extra proves insufficient.
- Use installation as the capability opt-in, following the existing `[monitor]` pattern.
- Do not add another frontmatter switch: `workflows.enabled` remains the feature declaration, while `[workflows]` supplies its runtime dependency.
- Detect a missing extra at startup rather than at the first workflow invocation.
- Update every workflow sample so copying its `requirements.txt` continues to work without additional discovery.
- Clearly document combinations such as `[workflows,monitor]`.

## Compatibility and rollout

This changes installation requirements for existing Dynamic Workflow users. Because the feature is currently experimental, making the split before a stable release minimizes long-term migration cost.

A safe implementation can use two PRs:

1. Refactor import boundaries and prove that non-workflow applications do not import Durable, while retaining the current hard dependency.
2. Move Durable to `[workflows]`, add missing-extra diagnostics, and update workflow samples and documentation.

## Acceptance criteria

- A default installation does not install `azure-functions-durable`, `durabletask`, or their workflow-only transitive dependencies.
- Importing `azure_functions_agents` does not import `azure.durable_functions`, `durabletask`, or `grpc`.
- Creating a non-workflow `FunctionApp` succeeds without Durable installed and does not load Durable modules.
- Enabling workflows without `[workflows]` fails at startup with an actionable installation command.
- Installing `[workflows]` preserves current Dynamic Workflow behavior and passes existing unit and real Functions-host E2E tests.
- Workflow samples install `[workflows]`; non-workflow samples do not.
- Package-size impact is measured and recorded before and after the change.
- Documentation covers default, workflow, monitor, and combined installation commands.

## Alternatives considered

### Lazy imports without changing dependencies

This can reduce import and cold-start work, but it does not reduce deployment size. It is useful as the first implementation step, not the complete solution.

### Separate workflow distribution

A package such as `azurefunctions-agents-runtime-workflows` could isolate dependencies more strongly, but it would add version synchronization, release, API, and support complexity. An optional extra should be preferred unless a technical constraint requires a separate distribution.

Contributor guide

Open the contributing guide

Research direction

Start with app.py and create_function_app(), then trace workflows.integration and the current Durable imports. Inspect pyproject.toml, workflow and standard sample requirements, and related documentation. Done means non-workflow apps run without Durable imports or dependencies, workflow setup gives the specified missing-extra error, and existing workflow tests and samples remain valid.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, python
Domain
backend, cloud
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.