Skip to content

feat: Add agent binding interface - #366

Closed
hallvictoria wants to merge 15 commits into
devfrom
hallvictoria/pluggable-agent-extensions
Closed

feat: Add agent binding interface#366
hallvictoria wants to merge 15 commits into
devfrom
hallvictoria/pluggable-agent-extensions

Conversation

@hallvictoria

@hallvictoria hallvictoria commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds lightweight, provider-neutral Agent APIs to azure-functions:

  • Adds FunctionApp.markdown_agent() for decorator-based Agent injection.
    • provider argument is required in V1.
    • Enums for provider are exposed in the respective extension packages - alternatively, customers can write out the string value
  • Adds and exports AgentFunctionApp and AgentDFApp.
  • Loads Agent extensions lazily, keeping provider frameworks and Durable Functions out of core imports.
  • Reports actionable installation guidance when a provider or Durable extra is missing.
  • Delegates Agent construction, markdown resolution, execution, and lifecycle management to extension packages.

These APIs add no host binding metadata and allow future Agent providers through the shared extension contract.

Customer Experience

Non-durable app:

import azure.functions as func
from agent_framework import Agent
from azurefunctions.agents.extensions.agent_framework import (
    AGENT_FRAMEWORK_PROVIDER_ID,
)

app = func.FunctionApp()


@app.route(route="orders", methods=["POST"])
@app.markdown_agent(
    provider=AGENT_FRAMEWORK_PROVIDER_ID,
    arg_name="agent",
    agent_name="orders",
    client_factory=create_chat_client,
)
async def process_order(req: func.HttpRequest, agent: Agent):
    ...

Durable app:

import azure.functions as func
from azurefunctions.agents.extensions.agent_framework import (
    AGENT_FRAMEWORK_PROVIDER_ID,
)

app = func.AgentDFApp(provider=AGENT_FRAMEWORK_PROVIDER_ID,  client_factory=create_chat_client,)

# Orchestration trigger with `call_agent` - built-in activity trigger with agent binding
@app.orchestration_trigger(context_name="context")
def order_orchestrator(context: Any):
    assessment = yield context.call_agent(...)

# Activity trigger with explicit, customer-added agent binding
@app.activity_trigger(input_name="payload")
@app.markdown_agent(arg_name="agent", agent_name="order-fulfillment")
async def process_order(payload: dict, agent: Agent[Any]) -> dict:
    ...

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There is a confirmed provider-selection logic bug in AiApp.markdown_agent, and the new public markdown_agent API lacks consistent type annotations.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds provider-neutral “agent binding” entry points to the Azure Functions Python programming model, enabling extension packages to supply agent behavior (and optional Durable support) without the core SDK depending on a specific provider implementation.

Changes:

  • Introduces FunctionApp.markdown_agent(...) plus AiApp/DurableAiApp convenience wrappers that delegate to a provider extension module.
  • Exports AiApp and DurableAiApp via azure.functions.decorators and azure.functions.
  • Documents the new APIs in README.md and docs/ProgModelSpec.pyi, and adds unit tests validating delegation/error behavior.
File summaries
File Description
tests/decorators/test_agents.py Adds unit tests for agent app delegation, configuration, exports, and import error messaging.
README.md Documents provider-neutral agent APIs and durable extra installation guidance.
docs/ProgModelSpec.pyi Updates public API spec with markdown_agent, AiApp, and DurableAiApp signatures.
azure/functions/decorators/function_app.py Implements provider-loading, markdown_agent, and new AiApp/DurableAiApp classes.
azure/functions/decorators/init.py Re-exports AiApp/DurableAiApp from decorators package.
azure/functions/init.py Re-exports AiApp/DurableAiApp at top-level azure.functions.
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread azure/functions/decorators/function_app.py Outdated
Comment thread azure/functions/decorators/function_app.py Outdated
hallvictoria and others added 3 commits September 2, 2026 14:38
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment thread azure/functions/decorators/__init__.py Outdated
Comment thread azure/functions/decorators/__init__.py Outdated
Comment thread azure/functions/decorators/_agents.py
Comment thread azure/functions/decorators/function_app.py Outdated
Comment thread azure/functions/decorators/function_app.py
Comment thread azure/functions/decorators/__init__.py Outdated
Comment thread docs/ProgModelSpec.pyi Outdated

class DurableAiApp(AiApp):
"""AiApp with optional replay-safe Durable Agent orchestration."""
class DurableAIApp(AIApp):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this extend DFApp?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in the core SDK. DFApp is defined in azure-functions-durable - azure-functions-durable depends on azure-functions (this package), so making DurableAIApp extend DFApp would create a circular dependency.

The main issue with extending DFApp in general now is that doing so requires azure-functions-durable at import time, which doesn't fit in the current model of making AFD an optional dependency.

From my analysis so far, DFApp doesn't give us much benefit for the current proposed behavior of overriding the orchestration_trigger decorator and adding call_agent. FunctionApp already exposes the main durable decorators lazily, which is the main functionality we need atm

Comment thread tests/decorators/test_agents.py Outdated
from azure.functions.decorators.function_app import (
AiApp,
DurableAiApp,
AIApp,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conside - AIFunctionApp and AIDFApp to extend on the original names

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated all to AgentFunctionApp and AgentDFApp

@larohra

Copy link
Copy Markdown

From your customer experience sample, shouldn't the path be
from azurefunctions.agents.extensions.**agent_framework** import (AGENT_FRAMEWORK_PROVIDER_ID) instead of from azurefunctions.agents.extensions.**agent.framework** import (AGENT_FRAMEWORK_PROVIDER_ID)

@hallvictoria

Copy link
Copy Markdown
Contributor Author

Closing this PR for now - V1 does not support FunctionApp or azure-functions. Users are required to import the agent extension package and use AgentFunctionApp - eg:

from azurefunctions.agents.extensions.agent_framework import AgentFunctionApp

app = AgentFunctionApp(...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants