mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: replace pre-commit with prek, add PEP 723 script deps, clean up dev dependencies (#3748)
* python: replace pre-commit with prek, add PEP 723 script deps, clean up dev dependencies - Replace pre-commit with prek (Rust-native, faster pre-commit alternative) - Move supported hooks to repo: builtin for zero-clone speed - Add new builtin hooks: trailing-whitespace, check-merge-conflict, detect-private-key, check-added-large-files - Update all hook versions to latest (pre-commit-hooks v6, pyupgrade v3.21.2, bandit 1.9.3, uv-pre-commit 0.10.0) - Add PEP 723 inline script metadata to 34 samples with external deps - Remove autogen-agentchat/autogen-ext from dev deps (now declared per-sample) - Remove unused dev deps: pytest-env, tomli-w - Add agent-framework-core>=1.0.0b260130 lower bound to all 21 packages - Update CI workflow to use j178/prek-action - Update docs: DEV_SETUP.md, AGENTS.md, CODING_STANDARD.md, SAMPLE_GUIDELINES.md * updated lock * python: fix prek config paths for local execution and CI workflow Remove global 'files: ^python/' filter and strip python/ prefix from all path patterns in .pre-commit-config.yaml so prek finds files when run from the python/ directory. Update CI workflow to use --cd python instead of --config path. Include trailing whitespace fixes and dev dependency cleanup. * python: move helper scripts to scripts/ folder and exclude from checks * python: exclude AGENTS.md from prek markdown code lint * python: exclude AGENTS.md and azure_ai_search sample from markdown lint * fix m365 sample * python: ignore CPY rule for samples with PEP 723 headers * fix in dev_setup * python: replace aiofiles with regular open in samples * python: suppress reportUnusedImport in markdown code block checker * python: use samples pyright config for markdown code block checker Write a temp pyrightconfig.json matching pyrightconfig.samples.json rules (typeCheckingMode=off, only reportMissingImports and reportAttributeAccessIssue). Filter output to only fail on these rules since syntax-level errors (top-level await, undefined vars) are expected in README documentation snippets. * python: use markdown-code-lint with fixed globs instead of prek file list The prek-markdown-code-lint task received all changed files including non-README markdown and files with pre-existing broken imports. Replace with the standard markdown-code-lint task which uses the correct glob patterns (README.md, packages/**/README.md, samples/**/*.md). * python: exclude READMEs with pre-existing broken imports from markdown lint * python: fix broken README code snippets instead of excluding them - ag-ui: replace TextContent (removed) with content.type == 'text' - durabletask: fix import path to durabletask.worker.TaskHubGrpcWorker - orchestrations: use constructor params instead of .participants() method - observability: mark deprecated code blocks as plain text, filter reportMissingImports to agent_framework modules only - remove README excludes from markdown-code-lint task * add revision to gaia download * feat(python): parallelize checks across packages Run (package × task) cross-product in parallel using ThreadPoolExecutor and subprocesses. Key changes: - Add scripts/task_runner.py with shared parallel execution engine - Update run_tasks_in_packages_if_exists.py to accept multiple tasks - Update run_tasks_in_changed_packages.py with --files flag and parallel support - Add check-packages poe task (fmt+lint+pyright+mypy in parallel) - Add prek-markdown-code-lint and prek-samples-check with change detection - Split CI code quality workflow into parallel prek and mypy jobs - Update DEV_SETUP.md to document new parallel behavior Core package changes still trigger checks on all packages. * feat(ci): split code quality into 4 parallel jobs Split the single prek job into parallel jobs: - pre-commit-hooks: lightweight hooks (SKIP=poe-check) - package-checks: fmt/lint/pyright/mypy via check-packages - samples-markdown: samples-lint, samples-syntax, markdown-code-lint - mypy: change-detected mypy checks All 4 jobs run concurrently (×2 Python versions = 8 runners). * feat(ci): use only Python 3.10 for code quality checks * refactor(python): add future annotations and remove quoted types Add `from __future__ import annotations` to 93 package files that used quoted string annotations, then run pyupgrade --py310-plus to remove the now-unnecessary quotes. Fixes https://github.com/microsoft/agent-framework/issues/3578
This commit is contained in:
committed by
GitHub
Unverified
parent
ad0dac3c86
commit
977c3adfb2
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import json
|
||||
import re
|
||||
@@ -169,7 +171,7 @@ class A2AAgent(AgentTelemetryLayer, BaseAgent):
|
||||
msg = f"Invalid timeout type: {type(timeout)}. Expected float, httpx.Timeout, or None."
|
||||
raise TypeError(msg)
|
||||
|
||||
async def __aenter__(self) -> "A2AAgent":
|
||||
async def __aenter__(self) -> A2AAgent:
|
||||
"""Async context manager entry."""
|
||||
return self
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"a2a-sdk>=0.3.5",
|
||||
]
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ add_agent_framework_fastapi_endpoint(app, agent, "/")
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from agent_framework import TextContent
|
||||
from agent_framework.ag_ui import AGUIChatClient
|
||||
|
||||
async def main():
|
||||
@@ -48,7 +47,7 @@ async def main():
|
||||
# Stream responses
|
||||
async for update in client.get_response("Hello!", stream=True):
|
||||
for content in update.contents:
|
||||
if isinstance(content, TextContent):
|
||||
if content.type == "text" and content.text:
|
||||
print(content.text, end="", flush=True)
|
||||
print()
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""AG-UI Chat Client implementation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
@@ -216,7 +218,7 @@ class AGUIChatClient(
|
||||
http_client: httpx.AsyncClient | None = None,
|
||||
timeout: float = 60.0,
|
||||
additional_properties: dict[str, Any] | None = None,
|
||||
middleware: Sequence["ChatAndFunctionMiddlewareTypes"] | None = None,
|
||||
middleware: Sequence[ChatAndFunctionMiddlewareTypes] | None = None,
|
||||
function_invocation_configuration: FunctionInvocationConfiguration | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""FastAPI endpoint creation for AG-UI agents."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import logging
|
||||
from collections.abc import AsyncGenerator, Sequence
|
||||
@@ -77,7 +79,7 @@ def add_agent_framework_fastapi_endpoint(
|
||||
)
|
||||
logger.info(f"Received request at {path}: {input_data.get('run_id', 'no-run-id')}")
|
||||
|
||||
async def event_generator() -> AsyncGenerator[str, None]:
|
||||
async def event_generator() -> AsyncGenerator[str]:
|
||||
encoder = EventEncoder()
|
||||
event_count = 0
|
||||
async for event in wrapped_agent.run_agent(input_data):
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Event converter for AG-UI protocol events to Agent Framework types."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import (
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""HTTP service for AG-UI protocol communication."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from collections.abc import AsyncIterable
|
||||
@@ -148,7 +150,7 @@ class AGUIHttpService:
|
||||
if self._owns_client and self.http_client:
|
||||
await self.http_client.aclose()
|
||||
|
||||
async def __aenter__(self) -> "AGUIHttpService":
|
||||
async def __aenter__(self) -> AGUIHttpService:
|
||||
"""Enter async context manager."""
|
||||
return self
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Message format conversion between AG-UI and Agent Framework."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import Any, cast
|
||||
|
||||
@@ -6,6 +6,8 @@ Most orchestration helpers have been moved inline to _run.py.
|
||||
This module retains utilities that may be useful for testing or extensions.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Predictive state handling utilities."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Tool handling helpers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
@@ -29,7 +31,7 @@ def _collect_mcp_tool_functions(mcp_tools: list[Any]) -> list[Any]:
|
||||
return functions
|
||||
|
||||
|
||||
def collect_server_tools(agent: "SupportsAgentRun") -> list[Any]:
|
||||
def collect_server_tools(agent: SupportsAgentRun) -> list[Any]:
|
||||
"""Collect server tools from an agent.
|
||||
|
||||
This includes both regular tools from default_options and MCP tools.
|
||||
@@ -64,7 +66,7 @@ def collect_server_tools(agent: "SupportsAgentRun") -> list[Any]:
|
||||
return server_tools
|
||||
|
||||
|
||||
def register_additional_client_tools(agent: "SupportsAgentRun", client_tools: list[Any] | None) -> None:
|
||||
def register_additional_client_tools(agent: SupportsAgentRun, client_tools: list[Any] | None) -> None:
|
||||
"""Register client tools as additional declaration-only tools to avoid server execution.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Simplified AG-UI orchestration - single linear flow."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import uuid
|
||||
@@ -742,8 +744,8 @@ def _build_messages_snapshot(
|
||||
async def run_agent_stream(
|
||||
input_data: dict[str, Any],
|
||||
agent: SupportsAgentRun,
|
||||
config: "AgentConfig",
|
||||
) -> "AsyncGenerator[BaseEvent, None]":
|
||||
config: AgentConfig,
|
||||
) -> AsyncGenerator[BaseEvent]:
|
||||
"""Run agent and yield AG-UI events.
|
||||
|
||||
This is the single entry point for all AG-UI agent runs. It follows a simple
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Utility functions for AG-UI integration."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
import uuid
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Example agent demonstrating predictive state updates with document writing."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from agent_framework import ChatAgent, ChatClientProtocol, tool
|
||||
from agent_framework.ag_ui import AgentFrameworkAgent
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Recipe agent example demonstrating shared state management (Feature 3)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Task steps agent demonstrating agentic generative UI (Feature 6)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import AsyncGenerator
|
||||
from enum import Enum
|
||||
@@ -128,7 +130,7 @@ class TaskStepsAgentWithExecution:
|
||||
"""Delegate all other attribute access to base agent."""
|
||||
return getattr(self._base_agent, name)
|
||||
|
||||
async def run_agent(self, input_data: dict[str, Any]) -> AsyncGenerator[Any, None]:
|
||||
async def run_agent(self, input_data: dict[str, Any]) -> AsyncGenerator[Any]:
|
||||
"""Run the agent and then simulate step execution."""
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Example agent demonstrating Tool-based Generative UI (Feature 5)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from typing import TYPE_CHECKING, Any, TypedDict
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Weather agent example demonstrating backend tool rendering."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import ChatAgent, ChatClientProtocol, tool
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Example FastAPI server with AG-UI endpoints."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import cast
|
||||
|
||||
@@ -292,7 +292,6 @@ Create a file named `client.py`:
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import TextContent
|
||||
from agent_framework.ag_ui import AGUIChatClient
|
||||
|
||||
|
||||
@@ -333,7 +332,7 @@ async def main():
|
||||
|
||||
# Stream text content as it arrives
|
||||
for content in update.contents:
|
||||
if isinstance(content, TextContent) and content.text:
|
||||
if content.type == "text" and content.text:
|
||||
print(content.text, end="", flush=True)
|
||||
|
||||
print() # New line after response
|
||||
|
||||
@@ -9,6 +9,8 @@ This example demonstrates advanced AGUIChatClient features including:
|
||||
- Error handling
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
from typing import cast
|
||||
|
||||
@@ -18,6 +18,8 @@ This demonstrates the HYBRID pattern matching .NET AGUIClient implementation:
|
||||
This matches .NET pattern: thread maintains state, tools execute on appropriate side.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""AG-UI server example with server-side tools."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"ag-ui-protocol>=0.1.9",
|
||||
"fastapi>=0.115.0",
|
||||
"uvicorn>=0.30.0"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import AsyncIterable, Awaitable, Mapping, MutableMapping, Sequence
|
||||
from typing import Any, ClassVar, Final, Generic, Literal, TypedDict
|
||||
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"anthropic>=0.70.0,<1",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import Awaitable, Callable, MutableSequence
|
||||
from typing import TYPE_CHECKING, Any, ClassVar, Literal
|
||||
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"azure-search-documents==11.7.0b2",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import Callable, MutableMapping, Sequence
|
||||
from typing import TYPE_CHECKING, Any, Generic, cast
|
||||
@@ -141,7 +143,7 @@ class AzureAIAgentsProvider(Generic[TOptions_co]):
|
||||
)
|
||||
self._should_close_client = True
|
||||
|
||||
async def __aenter__(self) -> "Self":
|
||||
async def __aenter__(self) -> Self:
|
||||
"""Async context manager entry."""
|
||||
return self
|
||||
|
||||
@@ -177,7 +179,7 @@ class AzureAIAgentsProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Create a new agent on the Azure AI service and return a ChatAgent.
|
||||
|
||||
This method creates a persistent agent on the Azure AI service with the specified
|
||||
@@ -274,7 +276,7 @@ class AzureAIAgentsProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Retrieve an existing agent from the service and return a ChatAgent.
|
||||
|
||||
This method fetches an agent by ID from the Azure AI service
|
||||
@@ -330,7 +332,7 @@ class AzureAIAgentsProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Wrap an existing Agent SDK object as a ChatAgent without making HTTP calls.
|
||||
|
||||
Use this method when you already have an Agent object from a previous
|
||||
@@ -383,7 +385,7 @@ class AzureAIAgentsProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Create a ChatAgent from an Agent SDK object.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
import json
|
||||
import os
|
||||
@@ -346,7 +348,7 @@ class AzureAIAgentClient(
|
||||
self._should_close_client = should_close_client # Track whether we should close client connection
|
||||
self._agent_definition: Agent | None = None # Cached definition for existing agent
|
||||
|
||||
async def __aenter__(self) -> "Self":
|
||||
async def __aenter__(self) -> Self:
|
||||
"""Async context manager entry."""
|
||||
return self
|
||||
|
||||
@@ -1047,9 +1049,7 @@ class AzureAIAgentClient(
|
||||
|
||||
return tool_definitions
|
||||
|
||||
def _prepare_mcp_resources(
|
||||
self, tools: Sequence["ToolProtocol | MutableMapping[str, Any]"]
|
||||
) -> list[dict[str, Any]]:
|
||||
def _prepare_mcp_resources(self, tools: Sequence[ToolProtocol | MutableMapping[str, Any]]) -> list[dict[str, Any]]:
|
||||
"""Prepare MCP tool resources for approval mode configuration."""
|
||||
mcp_tools = [tool for tool in tools if isinstance(tool, HostedMCPTool)]
|
||||
if not mcp_tools:
|
||||
@@ -1142,7 +1142,7 @@ class AzureAIAgentClient(
|
||||
return additional_messages, instructions, required_action_results
|
||||
|
||||
async def _prepare_tools_for_azure_ai(
|
||||
self, tools: Sequence["ToolProtocol | MutableMapping[str, Any]"], run_options: dict[str, Any] | None = None
|
||||
self, tools: Sequence[ToolProtocol | MutableMapping[str, Any]], run_options: dict[str, Any] | None = None
|
||||
) -> list[ToolDefinition | dict[str, Any]]:
|
||||
"""Prepare tool definitions for the Azure AI Agents API."""
|
||||
tool_definitions: list[ToolDefinition | dict[str, Any]] = []
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import Callable, Mapping, MutableMapping, Sequence
|
||||
from typing import Any, ClassVar, Generic, TypedDict, TypeVar, cast
|
||||
@@ -295,7 +297,7 @@ class RawAzureAIClient(RawOpenAIResponsesClient[TAzureAIClientOptions], Generic[
|
||||
# Complete setup with core observability
|
||||
enable_instrumentation(enable_sensitive_data=enable_sensitive_data)
|
||||
|
||||
async def __aenter__(self) -> "Self":
|
||||
async def __aenter__(self) -> Self:
|
||||
"""Async context manager entry."""
|
||||
return self
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import Callable, MutableMapping, Sequence
|
||||
from typing import Any, Generic
|
||||
@@ -168,7 +170,7 @@ class AzureAIProjectAgentProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Create a new agent on the Azure AI service and return a local ChatAgent wrapper.
|
||||
|
||||
Args:
|
||||
@@ -270,7 +272,7 @@ class AzureAIProjectAgentProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Retrieve an existing agent from the Azure AI service and return a local ChatAgent wrapper.
|
||||
|
||||
You must provide either name or reference. Use `as_agent()` if you already have
|
||||
@@ -330,7 +332,7 @@ class AzureAIProjectAgentProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Wrap an SDK agent version object into a ChatAgent without making HTTP calls.
|
||||
|
||||
Use this when you already have an AgentVersionDetails from a previous API call.
|
||||
@@ -370,7 +372,7 @@ class AzureAIProjectAgentProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Create a ChatAgent from an AgentVersionDetails.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from collections.abc import Mapping, MutableMapping, Sequence
|
||||
from typing import Any, ClassVar, Literal, cast
|
||||
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"azure-ai-projects >= 2.0.0b3",
|
||||
"azure-ai-agents == 1.2.0b5",
|
||||
"aiohttp",
|
||||
|
||||
@@ -6,6 +6,8 @@ This module provides the AgentFunctionApp class that integrates Microsoft Agent
|
||||
with Azure Durable Entities, enabling stateful and durable AI agent execution.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import uuid
|
||||
|
||||
@@ -7,6 +7,8 @@ Using entities instead of orchestrations provides better state management and
|
||||
allows for long-running agent conversations.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Callable
|
||||
from typing import Any, cast
|
||||
|
||||
@@ -22,7 +22,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"agent-framework-durabletask",
|
||||
"azure-functions",
|
||||
"azure-functions-durable",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import sys
|
||||
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"boto3>=1.35.0,<2.0.0",
|
||||
"botocore>=1.35.0,<2.0.0",
|
||||
]
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Converter utilities for converting ChatKit thread items to Agent Framework messages."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from collections.abc import Awaitable, Callable, Sequence
|
||||
|
||||
@@ -22,7 +22,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"openai-chatkit>=1.4.0,<2.0.0",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import sys
|
||||
from collections.abc import AsyncIterable, Awaitable, Callable, MutableMapping, Sequence
|
||||
@@ -100,13 +102,13 @@ class ClaudeAgentOptions(TypedDict, total=False):
|
||||
disallowed_tools: list[str]
|
||||
"""Blocklist of tools. Claude cannot use these tools."""
|
||||
|
||||
mcp_servers: dict[str, "McpServerConfig"]
|
||||
mcp_servers: dict[str, McpServerConfig]
|
||||
"""MCP server configurations for external tools."""
|
||||
|
||||
permission_mode: "PermissionMode"
|
||||
permission_mode: PermissionMode
|
||||
"""Permission handling mode ("default", "acceptEdits", "plan", "bypassPermissions")."""
|
||||
|
||||
can_use_tool: "CanUseTool"
|
||||
can_use_tool: CanUseTool
|
||||
"""Permission callback for tool use."""
|
||||
|
||||
max_turns: int
|
||||
@@ -115,16 +117,16 @@ class ClaudeAgentOptions(TypedDict, total=False):
|
||||
max_budget_usd: float
|
||||
"""Budget limit in USD."""
|
||||
|
||||
hooks: dict[str, list["HookMatcher"]]
|
||||
hooks: dict[str, list[HookMatcher]]
|
||||
"""Pre/post tool hooks."""
|
||||
|
||||
add_dirs: list[str | Path]
|
||||
"""Additional directories to add to context."""
|
||||
|
||||
sandbox: "SandboxSettings"
|
||||
sandbox: SandboxSettings
|
||||
"""Sandbox configuration for bash isolation."""
|
||||
|
||||
agents: dict[str, "AgentDefinition"]
|
||||
agents: dict[str, AgentDefinition]
|
||||
"""Custom agent definitions."""
|
||||
|
||||
output_format: dict[str, Any]
|
||||
@@ -133,7 +135,7 @@ class ClaudeAgentOptions(TypedDict, total=False):
|
||||
enable_file_checkpointing: bool
|
||||
"""Enable file checkpointing for rewind."""
|
||||
|
||||
betas: list["SdkBeta"]
|
||||
betas: list[SdkBeta]
|
||||
"""Beta features to enable."""
|
||||
|
||||
|
||||
@@ -328,7 +330,7 @@ class ClaudeAgent(BaseAgent, Generic[TOptions]):
|
||||
normalized = normalize_tools(tool)
|
||||
self._custom_tools.extend(normalized)
|
||||
|
||||
async def __aenter__(self) -> "ClaudeAgent[TOptions]":
|
||||
async def __aenter__(self) -> ClaudeAgent[TOptions]:
|
||||
"""Start the agent when entering async context."""
|
||||
await self.start()
|
||||
return self
|
||||
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"claude-agent-sdk>=0.1.25",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncIterable, Awaitable, Sequence
|
||||
from typing import Any, ClassVar, Literal, overload
|
||||
|
||||
@@ -213,7 +215,7 @@ class CopilotStudioAgent(BaseAgent):
|
||||
stream: Literal[False] = False,
|
||||
thread: AgentThread | None = None,
|
||||
**kwargs: Any,
|
||||
) -> "Awaitable[AgentResponse]": ...
|
||||
) -> Awaitable[AgentResponse]: ...
|
||||
|
||||
@overload
|
||||
def run(
|
||||
@@ -232,7 +234,7 @@ class CopilotStudioAgent(BaseAgent):
|
||||
stream: bool = False,
|
||||
thread: AgentThread | None = None,
|
||||
**kwargs: Any,
|
||||
) -> "Awaitable[AgentResponse] | ResponseStream[AgentResponseUpdate, AgentResponse]":
|
||||
) -> Awaitable[AgentResponse] | ResponseStream[AgentResponseUpdate, AgentResponse]:
|
||||
"""Get a response from the agent.
|
||||
|
||||
This method returns the final result of the agent's execution
|
||||
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"microsoft-agents-copilotstudio-client>=0.3.1",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
import re
|
||||
import sys
|
||||
@@ -729,7 +731,7 @@ class RawChatAgent(BaseAgent, Generic[TOptions_co]): # type: ignore[misc]
|
||||
self._async_exit_stack = AsyncExitStack()
|
||||
self._update_agent_name_and_description()
|
||||
|
||||
async def __aenter__(self) -> "Self":
|
||||
async def __aenter__(self) -> Self:
|
||||
"""Enter the async context manager.
|
||||
|
||||
If any of the chat_client or local_mcp_tools are context managers,
|
||||
@@ -787,7 +789,7 @@ class RawChatAgent(BaseAgent, Generic[TOptions_co]): # type: ignore[misc]
|
||||
| MutableMapping[str, Any]
|
||||
| list[ToolProtocol | Callable[..., Any] | MutableMapping[str, Any]]
|
||||
| None = None,
|
||||
options: "ChatOptions[TResponseModelT]",
|
||||
options: ChatOptions[TResponseModelT],
|
||||
**kwargs: Any,
|
||||
) -> Awaitable[AgentResponse[TResponseModelT]]: ...
|
||||
|
||||
@@ -803,7 +805,7 @@ class RawChatAgent(BaseAgent, Generic[TOptions_co]): # type: ignore[misc]
|
||||
| MutableMapping[str, Any]
|
||||
| list[ToolProtocol | Callable[..., Any] | MutableMapping[str, Any]]
|
||||
| None = None,
|
||||
options: "TOptions_co | ChatOptions[None] | None" = None,
|
||||
options: TOptions_co | ChatOptions[None] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> Awaitable[AgentResponse[Any]]: ...
|
||||
|
||||
@@ -819,7 +821,7 @@ class RawChatAgent(BaseAgent, Generic[TOptions_co]): # type: ignore[misc]
|
||||
| MutableMapping[str, Any]
|
||||
| list[ToolProtocol | Callable[..., Any] | MutableMapping[str, Any]]
|
||||
| None = None,
|
||||
options: "TOptions_co | ChatOptions[Any] | None" = None,
|
||||
options: TOptions_co | ChatOptions[Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> ResponseStream[AgentResponseUpdate, AgentResponse[Any]]: ...
|
||||
|
||||
@@ -834,7 +836,7 @@ class RawChatAgent(BaseAgent, Generic[TOptions_co]): # type: ignore[misc]
|
||||
| MutableMapping[str, Any]
|
||||
| list[ToolProtocol | Callable[..., Any] | MutableMapping[str, Any]]
|
||||
| None = None,
|
||||
options: "TOptions_co | ChatOptions[Any] | None" = None,
|
||||
options: TOptions_co | ChatOptions[Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> Awaitable[AgentResponse[Any]] | ResponseStream[AgentResponseUpdate, AgentResponse[Any]]:
|
||||
"""Run the agent with the given messages and options.
|
||||
@@ -1149,9 +1151,9 @@ class RawChatAgent(BaseAgent, Generic[TOptions_co]): # type: ignore[misc]
|
||||
server_name: str = "Agent",
|
||||
version: str | None = None,
|
||||
instructions: str | None = None,
|
||||
lifespan: Callable[["Server[Any]"], AbstractAsyncContextManager[Any]] | None = None,
|
||||
lifespan: Callable[[Server[Any]], AbstractAsyncContextManager[Any]] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> "Server[Any]":
|
||||
) -> Server[Any]:
|
||||
"""Create an MCP server from an agent instance.
|
||||
|
||||
This function automatically creates a MCP server from an agent instance, it uses the provided arguments to
|
||||
@@ -1177,7 +1179,7 @@ class RawChatAgent(BaseAgent, Generic[TOptions_co]): # type: ignore[misc]
|
||||
if kwargs:
|
||||
server_args.update(kwargs)
|
||||
|
||||
server: "Server[Any]" = Server(**server_args) # type: ignore[call-arg]
|
||||
server: Server[Any] = Server(**server_args) # type: ignore[call-arg]
|
||||
|
||||
agent_tool = self.as_tool(name=self._get_agent_name())
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import (
|
||||
@@ -137,7 +139,7 @@ class ChatClientProtocol(Protocol[TOptions_contra]):
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage],
|
||||
*,
|
||||
stream: Literal[False] = ...,
|
||||
options: "ChatOptions[TResponseModelT]",
|
||||
options: ChatOptions[TResponseModelT],
|
||||
**kwargs: Any,
|
||||
) -> Awaitable[ChatResponse[TResponseModelT]]: ...
|
||||
|
||||
@@ -147,7 +149,7 @@ class ChatClientProtocol(Protocol[TOptions_contra]):
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage],
|
||||
*,
|
||||
stream: Literal[False] = ...,
|
||||
options: "TOptions_contra | ChatOptions[None] | None" = None,
|
||||
options: TOptions_contra | ChatOptions[None] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> Awaitable[ChatResponse[Any]]: ...
|
||||
|
||||
@@ -157,7 +159,7 @@ class ChatClientProtocol(Protocol[TOptions_contra]):
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage],
|
||||
*,
|
||||
stream: Literal[True],
|
||||
options: "TOptions_contra | ChatOptions[Any] | None" = None,
|
||||
options: TOptions_contra | ChatOptions[Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> ResponseStream[ChatResponseUpdate, ChatResponse[Any]]: ...
|
||||
|
||||
@@ -166,7 +168,7 @@ class ChatClientProtocol(Protocol[TOptions_contra]):
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage],
|
||||
*,
|
||||
stream: bool = False,
|
||||
options: "TOptions_contra | ChatOptions[Any] | None" = None,
|
||||
options: TOptions_contra | ChatOptions[Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> Awaitable[ChatResponse[Any]] | ResponseStream[ChatResponseUpdate, ChatResponse[Any]]:
|
||||
"""Send input and return the response.
|
||||
@@ -366,7 +368,7 @@ class BaseChatClient(SerializationMixin, ABC, Generic[TOptions_co]):
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage],
|
||||
*,
|
||||
stream: Literal[False] = ...,
|
||||
options: "ChatOptions[TResponseModelT]",
|
||||
options: ChatOptions[TResponseModelT],
|
||||
**kwargs: Any,
|
||||
) -> Awaitable[ChatResponse[TResponseModelT]]: ...
|
||||
|
||||
@@ -376,7 +378,7 @@ class BaseChatClient(SerializationMixin, ABC, Generic[TOptions_co]):
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage],
|
||||
*,
|
||||
stream: Literal[False] = ...,
|
||||
options: "TOptions_co | ChatOptions[None] | None" = None,
|
||||
options: TOptions_co | ChatOptions[None] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> Awaitable[ChatResponse[Any]]: ...
|
||||
|
||||
@@ -386,7 +388,7 @@ class BaseChatClient(SerializationMixin, ABC, Generic[TOptions_co]):
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage],
|
||||
*,
|
||||
stream: Literal[True],
|
||||
options: "TOptions_co | ChatOptions[Any] | None" = None,
|
||||
options: TOptions_co | ChatOptions[Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> ResponseStream[ChatResponseUpdate, ChatResponse[Any]]: ...
|
||||
|
||||
@@ -395,7 +397,7 @@ class BaseChatClient(SerializationMixin, ABC, Generic[TOptions_co]):
|
||||
messages: str | ChatMessage | Sequence[str | ChatMessage],
|
||||
*,
|
||||
stream: bool = False,
|
||||
options: "TOptions_co | ChatOptions[Any] | None" = None,
|
||||
options: TOptions_co | ChatOptions[Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> Awaitable[ChatResponse[Any]] | ResponseStream[ChatResponseUpdate, ChatResponse[Any]]:
|
||||
"""Get a response from a chat client.
|
||||
@@ -443,10 +445,10 @@ class BaseChatClient(SerializationMixin, ABC, Generic[TOptions_co]):
|
||||
default_options: TOptions_co | Mapping[str, Any] | None = None,
|
||||
chat_message_store_factory: Callable[[], ChatMessageStoreProtocol] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
middleware: Sequence["MiddlewareTypes"] | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
function_invocation_configuration: FunctionInvocationConfiguration | None = None,
|
||||
**kwargs: Any,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Create a ChatAgent with this client.
|
||||
|
||||
This is a convenience method that creates a ChatAgent instance with this
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import base64
|
||||
import logging
|
||||
@@ -333,7 +335,7 @@ class MCPTool:
|
||||
parse_prompt_results: Literal[True] | Callable[[types.GetPromptResult], Any] | None = True,
|
||||
session: ClientSession | None = None,
|
||||
request_timeout: int | None = None,
|
||||
chat_client: "ChatClientProtocol | None" = None,
|
||||
chat_client: ChatClientProtocol | None = None,
|
||||
additional_properties: dict[str, Any] | None = None,
|
||||
) -> None:
|
||||
"""Initialize the MCP Tool base.
|
||||
@@ -940,7 +942,7 @@ class MCPStdioTool(MCPTool):
|
||||
args: list[str] | None = None,
|
||||
env: dict[str, str] | None = None,
|
||||
encoding: str | None = None,
|
||||
chat_client: "ChatClientProtocol | None" = None,
|
||||
chat_client: ChatClientProtocol | None = None,
|
||||
additional_properties: dict[str, Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
@@ -1059,7 +1061,7 @@ class MCPStreamableHTTPTool(MCPTool):
|
||||
approval_mode: (Literal["always_require", "never_require"] | HostedMCPSpecificApproval | None) = None,
|
||||
allowed_tools: Collection[str] | None = None,
|
||||
terminate_on_close: bool | None = None,
|
||||
chat_client: "ChatClientProtocol | None" = None,
|
||||
chat_client: ChatClientProtocol | None = None,
|
||||
additional_properties: dict[str, Any] | None = None,
|
||||
http_client: httpx.AsyncClient | None = None,
|
||||
**kwargs: Any,
|
||||
@@ -1173,7 +1175,7 @@ class MCPWebsocketTool(MCPTool):
|
||||
description: str | None = None,
|
||||
approval_mode: (Literal["always_require", "never_require"] | HostedMCPSpecificApproval | None) = None,
|
||||
allowed_tools: Collection[str] | None = None,
|
||||
chat_client: "ChatClientProtocol | None" = None,
|
||||
chat_client: ChatClientProtocol | None = None,
|
||||
additional_properties: dict[str, Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import MutableSequence, Sequence
|
||||
@@ -50,7 +52,7 @@ class Context:
|
||||
self,
|
||||
instructions: str | None = None,
|
||||
messages: Sequence[ChatMessage] | None = None,
|
||||
tools: Sequence["ToolProtocol"] | None = None,
|
||||
tools: Sequence[ToolProtocol] | None = None,
|
||||
):
|
||||
"""Create a new Context object.
|
||||
|
||||
@@ -61,7 +63,7 @@ class Context:
|
||||
"""
|
||||
self.instructions = instructions
|
||||
self.messages: Sequence[ChatMessage] = messages or []
|
||||
self.tools: Sequence["ToolProtocol"] = tools or []
|
||||
self.tools: Sequence[ToolProtocol] = tools or []
|
||||
|
||||
|
||||
# region ContextProvider
|
||||
@@ -151,7 +153,7 @@ class ContextProvider(ABC):
|
||||
"""
|
||||
pass
|
||||
|
||||
async def __aenter__(self) -> "Self":
|
||||
async def __aenter__(self) -> Self:
|
||||
"""Enter the async context manager.
|
||||
|
||||
Override this method to perform any setup operations when the context provider is entered.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Annotated, Any, ClassVar, TypeVar
|
||||
|
||||
from pydantic import Field, UrlConstraints
|
||||
@@ -48,7 +50,7 @@ class AFBaseSettings(BaseSettings):
|
||||
kwargs = {k: v for k, v in kwargs.items() if v is not None}
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def __new__(cls: type["TSettings"], *args: Any, **kwargs: Any) -> "TSettings":
|
||||
def __new__(cls: type[TSettings], *args: Any, **kwargs: Any) -> TSettings:
|
||||
"""Override the __new__ method to set the env_prefix."""
|
||||
# for both, if supplied but None, set to default
|
||||
if "env_file_encoding" in kwargs and kwargs["env_file_encoding"] is not None:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
from collections.abc import Mapping, MutableMapping
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from typing import Any, Final
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import MutableMapping, Sequence
|
||||
from typing import Any, Protocol, TypeVar
|
||||
|
||||
@@ -74,7 +76,7 @@ class ChatMessageStoreProtocol(Protocol):
|
||||
@classmethod
|
||||
async def deserialize(
|
||||
cls, serialized_store_state: MutableMapping[str, Any], **kwargs: Any
|
||||
) -> "ChatMessageStoreProtocol":
|
||||
) -> ChatMessageStoreProtocol:
|
||||
"""Creates a new instance of the store from previously serialized state.
|
||||
|
||||
This method, together with ``serialize()`` can be used to save and load messages from a persistent store
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import importlib
|
||||
import logging
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import Mapping
|
||||
from typing import TYPE_CHECKING, Any, ClassVar, Generic
|
||||
@@ -63,7 +65,7 @@ class AzureOpenAIAssistantsClient(
|
||||
ad_token: str | None = None,
|
||||
ad_token_provider: AsyncAzureADTokenProvider | None = None,
|
||||
token_endpoint: str | None = None,
|
||||
credential: "TokenCredential | None" = None,
|
||||
credential: TokenCredential | None = None,
|
||||
default_headers: Mapping[str, str] | None = None,
|
||||
async_client: AsyncAzureOpenAI | None = None,
|
||||
env_file_path: str | None = None,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
@@ -175,7 +177,7 @@ class AzureOpenAIChatClient( # type: ignore[misc]
|
||||
env_file_path: str | None = None,
|
||||
env_file_encoding: str | None = None,
|
||||
instruction_role: str | None = None,
|
||||
middleware: Sequence["MiddlewareTypes"] | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
function_invocation_configuration: FunctionInvocationConfiguration | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
@@ -15,7 +17,7 @@ logger: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_entra_auth_token(
|
||||
credential: "TokenCredential",
|
||||
credential: TokenCredential,
|
||||
token_endpoint: str,
|
||||
**kwargs: Any,
|
||||
) -> str | None:
|
||||
@@ -49,7 +51,7 @@ def get_entra_auth_token(
|
||||
|
||||
|
||||
async def get_entra_auth_token_async(
|
||||
credential: "AsyncTokenCredential", token_endpoint: str, **kwargs: Any
|
||||
credential: AsyncTokenCredential, token_endpoint: str, **kwargs: Any
|
||||
) -> str | None:
|
||||
"""Retrieve a async Microsoft Entra Auth Token for a given token endpoint.
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import Mapping, Sequence
|
||||
from typing import TYPE_CHECKING, Any, Generic
|
||||
@@ -74,7 +76,7 @@ class AzureOpenAIResponsesClient( # type: ignore[misc]
|
||||
env_file_path: str | None = None,
|
||||
env_file_encoding: str | None = None,
|
||||
instruction_role: str | None = None,
|
||||
middleware: Sequence["MiddlewareTypes"] | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
function_invocation_configuration: FunctionInvocationConfiguration | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from collections.abc import Awaitable, Callable, Mapping
|
||||
@@ -110,7 +112,7 @@ class AzureOpenAISettings(AFBaseSettings):
|
||||
default_token_endpoint: str = DEFAULT_AZURE_TOKEN_ENDPOINT
|
||||
|
||||
def get_azure_auth_token(
|
||||
self, credential: "TokenCredential", token_endpoint: str | None = None, **kwargs: Any
|
||||
self, credential: TokenCredential, token_endpoint: str | None = None, **kwargs: Any
|
||||
) -> str | None:
|
||||
"""Retrieve a Microsoft Entra Auth Token for a given token endpoint for the use with Azure OpenAI.
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import Awaitable, Callable, MutableMapping, Sequence
|
||||
from typing import TYPE_CHECKING, Any, Generic, cast
|
||||
@@ -177,7 +179,7 @@ class OpenAIAssistantProvider(Generic[TOptions_co]):
|
||||
|
||||
self._client = AsyncOpenAI(**client_args)
|
||||
|
||||
async def __aenter__(self) -> "Self":
|
||||
async def __aenter__(self) -> Self:
|
||||
"""Async context manager entry."""
|
||||
return self
|
||||
|
||||
@@ -206,7 +208,7 @@ class OpenAIAssistantProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Create a new assistant on OpenAI and return a ChatAgent.
|
||||
|
||||
This method creates a new assistant on the OpenAI service and wraps it
|
||||
@@ -314,7 +316,7 @@ class OpenAIAssistantProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Retrieve an existing assistant by ID and return a ChatAgent.
|
||||
|
||||
This method fetches an existing assistant from OpenAI by its ID
|
||||
@@ -380,7 +382,7 @@ class OpenAIAssistantProvider(Generic[TOptions_co]):
|
||||
default_options: TOptions_co | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
context_provider: ContextProvider | None = None,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Wrap an existing SDK Assistant object as a ChatAgent.
|
||||
|
||||
This method does NOT make any HTTP calls. It simply wraps an already-
|
||||
@@ -524,7 +526,7 @@ class OpenAIAssistantProvider(Generic[TOptions_co]):
|
||||
context_provider: ContextProvider | None,
|
||||
default_options: TOptions_co | None = None,
|
||||
**kwargs: Any,
|
||||
) -> "ChatAgent[TOptions_co]":
|
||||
) -> ChatAgent[TOptions_co]:
|
||||
"""Create a ChatAgent from an Assistant.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from collections.abc import (
|
||||
@@ -227,7 +229,7 @@ class OpenAIAssistantsClient( # type: ignore[misc]
|
||||
async_client: AsyncOpenAI | None = None,
|
||||
env_file_path: str | None = None,
|
||||
env_file_encoding: str | None = None,
|
||||
middleware: Sequence["MiddlewareTypes"] | None = None,
|
||||
middleware: Sequence[MiddlewareTypes] | None = None,
|
||||
function_invocation_configuration: FunctionInvocationConfiguration | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
@@ -325,7 +327,7 @@ class OpenAIAssistantsClient( # type: ignore[misc]
|
||||
self.thread_id: str | None = thread_id
|
||||
self._should_delete_assistant: bool = False
|
||||
|
||||
async def __aenter__(self) -> "Self":
|
||||
async def __aenter__(self) -> Self:
|
||||
"""Async context manager entry."""
|
||||
return self
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from collections.abc import AsyncIterable, Awaitable, Callable, Mapping, MutableMapping, Sequence
|
||||
@@ -305,7 +307,7 @@ class RawOpenAIChatClient( # type: ignore[misc]
|
||||
run_options["response_format"] = type_to_response_format_param(response_format)
|
||||
return run_options
|
||||
|
||||
def _parse_response_from_openai(self, response: ChatCompletion, options: Mapping[str, Any]) -> "ChatResponse":
|
||||
def _parse_response_from_openai(self, response: ChatCompletion, options: Mapping[str, Any]) -> ChatResponse:
|
||||
"""Parse a response from OpenAI into a ChatResponse."""
|
||||
response_metadata = self._get_metadata_from_chat_response(response)
|
||||
messages: list[ChatMessage] = []
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
@@ -29,7 +31,7 @@ class ContentFilterResult:
|
||||
severity: ContentFilterResultSeverity = ContentFilterResultSeverity.SAFE
|
||||
|
||||
@classmethod
|
||||
def from_inner_error_result(cls, inner_error_results: dict[str, Any]) -> "ContentFilterResult":
|
||||
def from_inner_error_result(cls, inner_error_results: dict[str, Any]) -> ContentFilterResult:
|
||||
"""Creates a ContentFilterResult from the inner error results.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import (
|
||||
AsyncIterable,
|
||||
@@ -815,7 +817,7 @@ class RawOpenAIResponsesClient( # type: ignore[misc]
|
||||
self,
|
||||
response: OpenAIResponse | ParsedResponse[BaseModel],
|
||||
options: dict[str, Any],
|
||||
) -> "ChatResponse":
|
||||
) -> ChatResponse:
|
||||
"""Parse an OpenAI Responses API response into a ChatResponse."""
|
||||
structured_response: BaseModel | None = response.output_parsed if isinstance(response, ParsedResponse) else None # type: ignore[reportUnknownMemberType]
|
||||
|
||||
@@ -945,7 +947,7 @@ class RawOpenAIResponsesClient( # type: ignore[misc]
|
||||
)
|
||||
case "code_interpreter_call": # ResponseOutputCodeInterpreterCall
|
||||
call_id = getattr(item, "call_id", None) or getattr(item, "id", None)
|
||||
outputs: list["Content"] = []
|
||||
outputs: list[Content] = []
|
||||
if item_outputs := getattr(item, "outputs", None):
|
||||
for code_output in item_outputs:
|
||||
if getattr(code_output, "type", None) == "logs":
|
||||
@@ -1456,7 +1458,7 @@ class OpenAIResponsesClient( # type: ignore[misc]
|
||||
env_file_path: str | None = None,
|
||||
env_file_encoding: str | None = None,
|
||||
middleware: (
|
||||
Sequence["ChatMiddleware | ChatMiddlewareCallable | FunctionMiddleware | FunctionMiddlewareCallable"] | None
|
||||
Sequence[ChatMiddleware | ChatMiddlewareCallable | FunctionMiddleware | FunctionMiddlewareCallable] | None
|
||||
) = None,
|
||||
function_invocation_configuration: FunctionInvocationConfiguration | None = None,
|
||||
**kwargs: Any,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from collections.abc import Awaitable, Callable, Mapping, MutableMapping, Sequence
|
||||
from copy import copy
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from collections.abc import Callable, Mapping
|
||||
from pathlib import Path
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from collections.abc import MutableMapping
|
||||
from contextvars import ContextVar
|
||||
@@ -101,7 +103,7 @@ class Property(SerializationMixin):
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls, value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
||||
) -> "Property":
|
||||
) -> Property:
|
||||
"""Create a Property instance from a dictionary, dispatching to the appropriate subclass."""
|
||||
# Only dispatch if we're being called on the base Property class
|
||||
if cls is not Property:
|
||||
@@ -211,7 +213,7 @@ class PropertySchema(SerializationMixin):
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls, value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
||||
) -> "PropertySchema":
|
||||
) -> PropertySchema:
|
||||
"""Create a PropertySchema instance from a dictionary, filtering out 'kind' field."""
|
||||
# Filter out 'kind', 'type', 'name', and 'description' fields that may appear in YAML
|
||||
# but aren't PropertySchema params
|
||||
@@ -491,7 +493,7 @@ class AgentDefinition(SerializationMixin):
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls, value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
||||
) -> "AgentDefinition":
|
||||
) -> AgentDefinition:
|
||||
"""Create an AgentDefinition instance from a dictionary, dispatching to the appropriate subclass."""
|
||||
# Only dispatch if we're being called on the base AgentDefinition class
|
||||
if cls is not AgentDefinition:
|
||||
@@ -537,7 +539,7 @@ class Tool(SerializationMixin):
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls: type[TTool], value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
||||
) -> "TTool":
|
||||
) -> TTool:
|
||||
"""Create a Tool instance from a dictionary, dispatching to the appropriate subclass."""
|
||||
# Only dispatch if we're being called on the base Tool class
|
||||
if cls is not Tool:
|
||||
@@ -867,7 +869,7 @@ class Resource(SerializationMixin):
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls, value: MutableMapping[str, Any], /, *, dependencies: MutableMapping[str, Any] | None = None
|
||||
) -> "Resource":
|
||||
) -> Resource:
|
||||
"""Create a Resource instance from a dictionary, dispatching to the appropriate subclass."""
|
||||
# Only dispatch if we're being called on the base Resource class
|
||||
if cls is not Resource:
|
||||
|
||||
+4
-2
@@ -7,6 +7,8 @@ This module implements handlers for:
|
||||
- InvokePromptAgent: Invoke a local prompt-based agent
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from collections.abc import AsyncGenerator
|
||||
from typing import Any, cast
|
||||
@@ -185,7 +187,7 @@ def _build_messages_from_state(ctx: ActionContext) -> list[ChatMessage]:
|
||||
|
||||
|
||||
@action_handler("InvokeAzureAgent")
|
||||
async def handle_invoke_azure_agent(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]:
|
||||
async def handle_invoke_azure_agent(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]:
|
||||
"""Invoke a hosted Azure AI agent.
|
||||
|
||||
Supports both Python-style and .NET-style YAML schemas:
|
||||
@@ -523,7 +525,7 @@ def _normalize_variable_path(variable: str) -> str:
|
||||
|
||||
|
||||
@action_handler("InvokePromptAgent")
|
||||
async def handle_invoke_prompt_agent(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]:
|
||||
async def handle_invoke_prompt_agent(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]:
|
||||
"""Invoke a local prompt-based agent (similar to InvokeAzureAgent but for local agents).
|
||||
|
||||
Action schema:
|
||||
|
||||
+17
-15
@@ -16,6 +16,8 @@ network calls. The `return; yield` pattern makes a function an async generator w
|
||||
actually yielding any events.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
@@ -37,7 +39,7 @@ logger = get_logger("agent_framework.declarative.workflows.actions")
|
||||
|
||||
|
||||
@action_handler("SetValue")
|
||||
async def handle_set_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_set_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Set a value in the workflow state.
|
||||
|
||||
Action schema:
|
||||
@@ -63,7 +65,7 @@ async def handle_set_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent,
|
||||
|
||||
|
||||
@action_handler("SetVariable")
|
||||
async def handle_set_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_set_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Set a variable in the workflow state (.NET workflow format).
|
||||
|
||||
This is an alias for SetValue with 'variable' instead of 'path'.
|
||||
@@ -113,7 +115,7 @@ def _normalize_variable_path(variable: str) -> str:
|
||||
|
||||
|
||||
@action_handler("AppendValue")
|
||||
async def handle_append_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_append_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Append a value to a list in the workflow state.
|
||||
|
||||
Action schema:
|
||||
@@ -139,7 +141,7 @@ async def handle_append_value(ctx: ActionContext) -> AsyncGenerator[WorkflowEven
|
||||
|
||||
|
||||
@action_handler("SendActivity")
|
||||
async def handle_send_activity(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_send_activity(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Send text or attachments to the user.
|
||||
|
||||
Action schema (object form):
|
||||
@@ -189,7 +191,7 @@ async def handle_send_activity(ctx: ActionContext) -> AsyncGenerator[WorkflowEve
|
||||
|
||||
|
||||
@action_handler("EmitEvent")
|
||||
async def handle_emit_event(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_emit_event(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Emit a custom workflow event.
|
||||
|
||||
Action schema:
|
||||
@@ -213,7 +215,7 @@ async def handle_emit_event(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent,
|
||||
yield CustomEvent(name=name, data=evaluated_data)
|
||||
|
||||
|
||||
def _evaluate_dict_values(d: dict[str, Any], state: "WorkflowState") -> dict[str, Any]:
|
||||
def _evaluate_dict_values(d: dict[str, Any], state: WorkflowState) -> dict[str, Any]:
|
||||
"""Recursively evaluate PowerFx expressions in a dictionary.
|
||||
|
||||
Args:
|
||||
@@ -245,7 +247,7 @@ def _evaluate_dict_values(d: dict[str, Any], state: "WorkflowState") -> dict[str
|
||||
|
||||
|
||||
@action_handler("SetTextVariable")
|
||||
async def handle_set_text_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_set_text_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Set a text variable with string interpolation support.
|
||||
|
||||
This is similar to SetVariable but supports multi-line text with
|
||||
@@ -281,7 +283,7 @@ async def handle_set_text_variable(ctx: ActionContext) -> AsyncGenerator[Workflo
|
||||
|
||||
|
||||
@action_handler("SetMultipleVariables")
|
||||
async def handle_set_multiple_variables(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_set_multiple_variables(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Set multiple variables at once.
|
||||
|
||||
Action schema:
|
||||
@@ -313,7 +315,7 @@ async def handle_set_multiple_variables(ctx: ActionContext) -> AsyncGenerator[Wo
|
||||
|
||||
|
||||
@action_handler("ResetVariable")
|
||||
async def handle_reset_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_reset_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Reset a variable to its default/blank state.
|
||||
|
||||
Action schema:
|
||||
@@ -336,7 +338,7 @@ async def handle_reset_variable(ctx: ActionContext) -> AsyncGenerator[WorkflowEv
|
||||
|
||||
|
||||
@action_handler("ClearAllVariables")
|
||||
async def handle_clear_all_variables(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_clear_all_variables(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Clear all turn-scoped variables.
|
||||
|
||||
Action schema:
|
||||
@@ -350,7 +352,7 @@ async def handle_clear_all_variables(ctx: ActionContext) -> AsyncGenerator[Workf
|
||||
|
||||
|
||||
@action_handler("CreateConversation")
|
||||
async def handle_create_conversation(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_create_conversation(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Create a new conversation context.
|
||||
|
||||
Action schema (.NET style):
|
||||
@@ -399,7 +401,7 @@ async def handle_create_conversation(ctx: ActionContext) -> AsyncGenerator[Workf
|
||||
|
||||
|
||||
@action_handler("AddConversationMessage")
|
||||
async def handle_add_conversation_message(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_add_conversation_message(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Add a message to a conversation.
|
||||
|
||||
Action schema:
|
||||
@@ -451,7 +453,7 @@ async def handle_add_conversation_message(ctx: ActionContext) -> AsyncGenerator[
|
||||
|
||||
|
||||
@action_handler("CopyConversationMessages")
|
||||
async def handle_copy_conversation_messages(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_copy_conversation_messages(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Copy messages from one conversation to another.
|
||||
|
||||
Action schema:
|
||||
@@ -506,7 +508,7 @@ async def handle_copy_conversation_messages(ctx: ActionContext) -> AsyncGenerato
|
||||
|
||||
|
||||
@action_handler("RetrieveConversationMessages")
|
||||
async def handle_retrieve_conversation_messages(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_retrieve_conversation_messages(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Retrieve messages from a conversation and store in a variable.
|
||||
|
||||
Action schema:
|
||||
@@ -547,7 +549,7 @@ async def handle_retrieve_conversation_messages(ctx: ActionContext) -> AsyncGene
|
||||
yield # Make it a generator
|
||||
|
||||
|
||||
def _interpolate_string(text: str, state: "WorkflowState") -> str:
|
||||
def _interpolate_string(text: str, state: WorkflowState) -> str:
|
||||
"""Interpolate {Variable.Path} references in a string.
|
||||
|
||||
Args:
|
||||
|
||||
+4
-2
@@ -7,6 +7,8 @@ This module implements handlers for:
|
||||
- TryCatch: Try-catch-finally error handling
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
from dataclasses import dataclass
|
||||
|
||||
@@ -44,7 +46,7 @@ class ErrorEvent(WorkflowEvent):
|
||||
|
||||
|
||||
@action_handler("ThrowException")
|
||||
async def handle_throw_exception(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_throw_exception(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Raise an exception that can be caught by TryCatch.
|
||||
|
||||
Action schema:
|
||||
@@ -67,7 +69,7 @@ async def handle_throw_exception(ctx: ActionContext) -> AsyncGenerator[WorkflowE
|
||||
|
||||
|
||||
@action_handler("TryCatch")
|
||||
async def handle_try_catch(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]:
|
||||
async def handle_try_catch(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]:
|
||||
"""Try-catch-finally error handling.
|
||||
|
||||
Action schema:
|
||||
|
||||
+4
-2
@@ -23,6 +23,8 @@ the full RecalcEngine API. We work around this by:
|
||||
See: dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PowerFx/
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from collections.abc import Mapping
|
||||
@@ -148,7 +150,7 @@ class DeclarativeWorkflowState:
|
||||
"""
|
||||
self._state = state
|
||||
|
||||
def initialize(self, inputs: "Mapping[str, Any] | None" = None) -> None:
|
||||
def initialize(self, inputs: Mapping[str, Any] | None = None) -> None:
|
||||
"""Initialize the declarative state with inputs.
|
||||
|
||||
Args:
|
||||
@@ -814,7 +816,7 @@ class DeclarativeActionExecutor(Executor):
|
||||
|
||||
async def _ensure_state_initialized(
|
||||
self,
|
||||
ctx: "WorkflowContext[Any, Any]",
|
||||
ctx: WorkflowContext[Any, Any],
|
||||
trigger: Any,
|
||||
) -> DeclarativeWorkflowState:
|
||||
"""Ensure declarative state is initialized.
|
||||
|
||||
+2
@@ -11,6 +11,8 @@ action definitions and creates a proper workflow graph with:
|
||||
- Loop edges for foreach
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from agent_framework._workflows import (
|
||||
|
||||
@@ -10,6 +10,8 @@ Each YAML action becomes a real Executor node in the workflow graph,
|
||||
enabling checkpointing, visualization, and pause/resume capabilities.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from pathlib import Path
|
||||
from typing import Any, cast
|
||||
@@ -506,7 +508,7 @@ class WorkflowFactory:
|
||||
f"Invalid agent definition. Expected 'file', 'kind', or 'connection': {agent_def}"
|
||||
)
|
||||
|
||||
def register_agent(self, name: str, agent: SupportsAgentRun | AgentExecutor) -> "WorkflowFactory":
|
||||
def register_agent(self, name: str, agent: SupportsAgentRun | AgentExecutor) -> WorkflowFactory:
|
||||
"""Register an agent instance with the factory for use in workflows.
|
||||
|
||||
Registered agents are available to InvokeAzureAgent actions by name.
|
||||
@@ -552,7 +554,7 @@ class WorkflowFactory:
|
||||
self._agents[name] = agent
|
||||
return self
|
||||
|
||||
def register_binding(self, name: str, func: Any) -> "WorkflowFactory":
|
||||
def register_binding(self, name: str, func: Any) -> WorkflowFactory:
|
||||
"""Register a function binding with the factory for use in workflow actions.
|
||||
|
||||
Bindings allow workflow actions to invoke Python functions by name.
|
||||
|
||||
@@ -7,6 +7,8 @@ workflow actions defined in YAML. Each action type (InvokeAzureAgent, Foreach, e
|
||||
has a corresponding handler registered via the @action_handler decorator.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncGenerator, Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
|
||||
@@ -27,13 +29,13 @@ class ActionContext:
|
||||
for executing nested actions (for control flow constructs like Foreach).
|
||||
"""
|
||||
|
||||
state: "WorkflowState"
|
||||
state: WorkflowState
|
||||
"""The current workflow state with variables and agent results."""
|
||||
|
||||
action: dict[str, Any]
|
||||
"""The action definition from the YAML."""
|
||||
|
||||
execute_actions: "ExecuteActionsFn"
|
||||
execute_actions: ExecuteActionsFn
|
||||
"""Function to execute a list of nested actions (for Foreach, If, etc.)."""
|
||||
|
||||
agents: dict[str, Any]
|
||||
@@ -150,7 +152,7 @@ class ActionHandler(Protocol):
|
||||
def __call__(
|
||||
self,
|
||||
ctx: ActionContext,
|
||||
) -> AsyncGenerator[WorkflowEvent, None]:
|
||||
) -> AsyncGenerator[WorkflowEvent]:
|
||||
"""Execute the action and yield events.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -8,6 +8,8 @@ This module implements handlers for human input patterns:
|
||||
- ExternalLoop processing: Loop while waiting for external input
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
@@ -75,7 +77,7 @@ class ExternalLoopEvent(WorkflowEvent):
|
||||
|
||||
|
||||
@action_handler("Question")
|
||||
async def handle_question(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_question(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Handle Question action - request human input with optional validation.
|
||||
|
||||
Action schema:
|
||||
@@ -140,7 +142,7 @@ async def handle_question(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, N
|
||||
|
||||
|
||||
@action_handler("RequestExternalInput")
|
||||
async def handle_request_external_input(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_request_external_input(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Handle RequestExternalInput action - request input from external system.
|
||||
|
||||
Action schema:
|
||||
@@ -197,7 +199,7 @@ async def handle_request_external_input(ctx: ActionContext) -> AsyncGenerator[Wo
|
||||
|
||||
|
||||
@action_handler("WaitForInput")
|
||||
async def handle_wait_for_input(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent, None]: # noqa: RUF029
|
||||
async def handle_wait_for_input(ctx: ActionContext) -> AsyncGenerator[WorkflowEvent]: # noqa: RUF029
|
||||
"""Handle WaitForInput action - pause and wait for external input.
|
||||
|
||||
Action schema:
|
||||
@@ -231,7 +233,7 @@ async def handle_wait_for_input(ctx: ActionContext) -> AsyncGenerator[WorkflowEv
|
||||
|
||||
def process_external_loop(
|
||||
input_config: dict[str, Any],
|
||||
state: "WorkflowState",
|
||||
state: WorkflowState,
|
||||
) -> tuple[bool, str | None]:
|
||||
"""Process the externalLoop.when pattern from action input.
|
||||
|
||||
|
||||
+2
@@ -10,6 +10,8 @@ These functions can be used as fallbacks when PowerFx is not available,
|
||||
or registered with the PowerFx engine when it is available.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, cast
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ This module provides state management for declarative workflows, handling:
|
||||
- Agent results and context
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any, cast
|
||||
|
||||
@@ -624,7 +626,7 @@ class WorkflowState:
|
||||
"""Reset the agent result for a new agent invocation."""
|
||||
self._agent.clear()
|
||||
|
||||
def clone(self) -> "WorkflowState":
|
||||
def clone(self) -> WorkflowState:
|
||||
"""Create a shallow copy of the state.
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -22,7 +22,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"powerfx>=0.0.31; python_version < '3.14'",
|
||||
"pyyaml>=6.0,<7.0",
|
||||
]
|
||||
|
||||
@@ -6,6 +6,8 @@ This module provides a clean abstraction layer for managing conversations
|
||||
while wrapping AgentFramework's AgentThread underneath.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
import uuid
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Agent Framework entity discovery implementation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
import importlib
|
||||
import importlib.util
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Agent Framework executor implementation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from collections.abc import AsyncGenerator
|
||||
@@ -184,7 +186,7 @@ class AgentFrameworkExecutor:
|
||||
raise EntityNotFoundError(f"Entity '{entity_id}' not found")
|
||||
return entity_info
|
||||
|
||||
async def execute_streaming(self, request: AgentFrameworkRequest) -> AsyncGenerator[Any, None]:
|
||||
async def execute_streaming(self, request: AgentFrameworkRequest) -> AsyncGenerator[Any]:
|
||||
"""Execute request and stream results in OpenAI format.
|
||||
|
||||
Args:
|
||||
@@ -229,7 +231,7 @@ class AgentFrameworkExecutor:
|
||||
# Aggregate into final response
|
||||
return await self.message_mapper.aggregate_to_response(events, request)
|
||||
|
||||
async def execute_entity(self, entity_id: str, request: AgentFrameworkRequest) -> AsyncGenerator[Any, None]:
|
||||
async def execute_entity(self, entity_id: str, request: AgentFrameworkRequest) -> AsyncGenerator[Any]:
|
||||
"""Execute the entity and yield raw Agent Framework events plus trace events.
|
||||
|
||||
Args:
|
||||
@@ -286,7 +288,7 @@ class AgentFrameworkExecutor:
|
||||
|
||||
async def _execute_agent(
|
||||
self, agent: SupportsAgentRun, request: AgentFrameworkRequest, trace_collector: Any
|
||||
) -> AsyncGenerator[Any, None]:
|
||||
) -> AsyncGenerator[Any]:
|
||||
"""Execute Agent Framework agent with trace collection and optional thread support.
|
||||
|
||||
Args:
|
||||
@@ -361,7 +363,7 @@ class AgentFrameworkExecutor:
|
||||
|
||||
async def _execute_workflow(
|
||||
self, workflow: Workflow, request: AgentFrameworkRequest, trace_collector: Any
|
||||
) -> AsyncGenerator[Any, None]:
|
||||
) -> AsyncGenerator[Any]:
|
||||
"""Execute Agent Framework workflow with checkpoint support via conversation items.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Agent Framework message mapper implementation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
|
||||
@@ -6,6 +6,8 @@ This executor mirrors the AgentFrameworkExecutor interface but routes
|
||||
requests to OpenAI's API instead of executing local entities.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
from collections.abc import AsyncGenerator
|
||||
@@ -76,7 +78,7 @@ class OpenAIExecutor:
|
||||
|
||||
return self._client
|
||||
|
||||
async def execute_streaming(self, request: AgentFrameworkRequest) -> AsyncGenerator[Any, None]:
|
||||
async def execute_streaming(self, request: AgentFrameworkRequest) -> AsyncGenerator[Any]:
|
||||
"""Execute request via OpenAI and stream results in OpenAI format.
|
||||
|
||||
This mirrors AgentFrameworkExecutor.execute_streaming() interface.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""FastAPI server implementation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import importlib.metadata
|
||||
import inspect
|
||||
@@ -287,7 +289,7 @@ class DevServer:
|
||||
"""Create the FastAPI application."""
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
|
||||
async def lifespan(app: FastAPI) -> AsyncGenerator[None]:
|
||||
# Startup
|
||||
logger.info("Starting Agent Framework Server")
|
||||
await self._ensure_executor()
|
||||
@@ -623,7 +625,7 @@ class DevServer:
|
||||
entity_path = Path(entity_path_str)
|
||||
|
||||
# Stream deployment events
|
||||
async def event_generator() -> AsyncGenerator[str, None]:
|
||||
async def event_generator() -> AsyncGenerator[str]:
|
||||
async for event in self.deployment_manager.deploy(config, entity_path):
|
||||
# Format as SSE
|
||||
import json
|
||||
@@ -1085,7 +1087,7 @@ class DevServer:
|
||||
|
||||
async def _stream_execution(
|
||||
self, executor: AgentFrameworkExecutor, request: AgentFrameworkRequest
|
||||
) -> AsyncGenerator[str, None]:
|
||||
) -> AsyncGenerator[str]:
|
||||
"""Stream execution directly through executor."""
|
||||
try:
|
||||
# Collect events for final response.completed event
|
||||
@@ -1155,7 +1157,7 @@ class DevServer:
|
||||
|
||||
async def _stream_openai_execution(
|
||||
self, executor: OpenAIExecutor, request: AgentFrameworkRequest
|
||||
) -> AsyncGenerator[str, None]:
|
||||
) -> AsyncGenerator[str]:
|
||||
"""Stream execution through OpenAI executor.
|
||||
|
||||
OpenAI events are already in final format - no conversion or aggregation needed.
|
||||
@@ -1212,7 +1214,7 @@ class DevServer:
|
||||
|
||||
async def _stream_with_cancellation(
|
||||
self, executor: AgentFrameworkExecutor, request: AgentFrameworkRequest, response_id: str
|
||||
) -> AsyncGenerator[str, None]:
|
||||
) -> AsyncGenerator[str]:
|
||||
"""Stream execution with automatic cancellation on client disconnect.
|
||||
|
||||
This wrapper adds cancellation support to the execution stream:
|
||||
@@ -1231,7 +1233,7 @@ class DevServer:
|
||||
"""
|
||||
task = None
|
||||
|
||||
async def execution_wrapper() -> AsyncGenerator[str, None]:
|
||||
async def execution_wrapper() -> AsyncGenerator[str]:
|
||||
"""Inner wrapper to handle the actual execution."""
|
||||
try:
|
||||
logger.debug(f"[CANCELLATION] Starting execution for {response_id}")
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
"""Simplified tracing integration for Agent Framework Server."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from collections.abc import Generator, Sequence
|
||||
from contextlib import contextmanager
|
||||
@@ -120,9 +122,7 @@ class SimpleTraceCollector(SpanExporter):
|
||||
|
||||
|
||||
@contextmanager
|
||||
def capture_traces(
|
||||
response_id: str | None = None, entity_id: str | None = None
|
||||
) -> Generator[SimpleTraceCollector, None, None]:
|
||||
def capture_traces(response_id: str | None = None, entity_id: str | None = None) -> Generator[SimpleTraceCollector]:
|
||||
"""Context manager to capture traces during execution.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -559,7 +559,7 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) {
|
||||
|
||||
// Backend successfully returned conversations list
|
||||
setAvailableConversations(conversations);
|
||||
|
||||
|
||||
if (conversations.length > 0) {
|
||||
// Found conversations on backend - use most recent
|
||||
const mostRecent = conversations[0];
|
||||
@@ -614,7 +614,7 @@ export function AgentView({ selectedAgent, onDebugEvent }: AgentViewProps) {
|
||||
|
||||
// Check for incomplete stream and resume if needed
|
||||
const state = loadStreamingState(mostRecent.id);
|
||||
|
||||
|
||||
if (state && !state.completed) {
|
||||
accumulatedTextRef.current = state.accumulatedText || "";
|
||||
// Add assistant message with resumed text
|
||||
|
||||
@@ -565,7 +565,7 @@ export const WorkflowFlow = memo(function WorkflowFlow({
|
||||
0% { stroke-dashoffset: 0; }
|
||||
100% { stroke-dashoffset: -10; }
|
||||
}
|
||||
|
||||
|
||||
/* Dark theme styles for React Flow controls */
|
||||
.dark .react-flow__controls {
|
||||
background-color: rgba(31, 41, 55, 0.9) !important;
|
||||
|
||||
@@ -13,7 +13,7 @@ export function LoadingSpinner({ size = "md", className }: LoadingSpinnerProps)
|
||||
"animate-spin",
|
||||
{
|
||||
"h-4 w-4": size === "sm",
|
||||
"h-6 w-6": size === "md",
|
||||
"h-6 w-6": size === "md",
|
||||
"h-8 w-8": size === "lg",
|
||||
},
|
||||
className
|
||||
|
||||
@@ -9,8 +9,8 @@ interface LoadingStateProps {
|
||||
fullPage?: boolean
|
||||
}
|
||||
|
||||
export function LoadingState({
|
||||
message = "Loading...",
|
||||
export function LoadingState({
|
||||
message = "Loading...",
|
||||
description,
|
||||
size = "md",
|
||||
className,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Streaming State Persistence
|
||||
*
|
||||
*
|
||||
* Manages browser storage of streaming response state to enable:
|
||||
* - Resume interrupted streams after page refresh
|
||||
* - Replay cached events before fetching new ones
|
||||
@@ -73,7 +73,7 @@ export function loadStreamingState(conversationId: string): StreamingState | nul
|
||||
try {
|
||||
const key = getStorageKey(conversationId);
|
||||
const data = localStorage.getItem(key);
|
||||
|
||||
|
||||
if (!data) {
|
||||
return null;
|
||||
}
|
||||
@@ -111,9 +111,9 @@ export function updateStreamingState(
|
||||
try {
|
||||
const existing = loadStreamingState(conversationId);
|
||||
const sequenceNumber = "sequence_number" in event ? event.sequence_number : undefined;
|
||||
|
||||
|
||||
const newEvents = existing ? [...existing.events, event] : [event];
|
||||
|
||||
|
||||
const state: StreamingState = {
|
||||
conversationId,
|
||||
responseId,
|
||||
@@ -174,7 +174,7 @@ export function clearExpiredStreamingStates(): void {
|
||||
if (data) {
|
||||
const state: StreamingState = JSON.parse(data);
|
||||
const age = now - state.timestamp;
|
||||
|
||||
|
||||
if (age > STATE_EXPIRY_MS || state.completed) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"fastapi>=0.104.0",
|
||||
"uvicorn[standard]>=0.24.0",
|
||||
"python-dotenv>=1.0.0",
|
||||
|
||||
@@ -15,15 +15,15 @@ The durable task integration lets you host Microsoft Agent Framework agents usin
|
||||
### Basic Usage Example
|
||||
|
||||
```python
|
||||
from durabletask import TaskHubGrpcWorker
|
||||
from durabletask.worker import TaskHubGrpcWorker
|
||||
from agent_framework.azure import DurableAIAgentWorker
|
||||
|
||||
# Create the worker
|
||||
with TaskHubGrpcWorker(...) as worker:
|
||||
|
||||
|
||||
# Register the agent worker wrapper
|
||||
agent_worker = DurableAIAgentWorker(worker)
|
||||
|
||||
|
||||
# Register the agent
|
||||
agent_worker.add_agent(my_agent)
|
||||
```
|
||||
|
||||
@@ -22,7 +22,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"durabletask>=1.3.0",
|
||||
"durabletask-azuremanaged>=1.3.0",
|
||||
"python-dateutil>=2.8.0",
|
||||
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"foundry-local-sdk>=0.5.1,<1",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
# ruff: noqa
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from random import randint
|
||||
from typing import TYPE_CHECKING, Annotated
|
||||
@@ -31,7 +33,7 @@ def get_weather(
|
||||
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
|
||||
|
||||
|
||||
async def non_streaming_example(agent: "ChatAgent") -> None:
|
||||
async def non_streaming_example(agent: ChatAgent) -> None:
|
||||
"""Example of non-streaming response (get the complete result at once)."""
|
||||
print("=== Non-streaming Response Example ===")
|
||||
|
||||
@@ -41,7 +43,7 @@ async def non_streaming_example(agent: "ChatAgent") -> None:
|
||||
print(f"Agent: {result}\n")
|
||||
|
||||
|
||||
async def streaming_example(agent: "ChatAgent") -> None:
|
||||
async def streaming_example(agent: ChatAgent) -> None:
|
||||
"""Example of streaming response (get results as they are generated)."""
|
||||
print("=== Streaming Response Example ===")
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import logging
|
||||
@@ -223,7 +225,7 @@ class GitHubCopilotAgent(BaseAgent, Generic[TOptions]):
|
||||
self._default_options = opts
|
||||
self._started = False
|
||||
|
||||
async def __aenter__(self) -> "GitHubCopilotAgent[TOptions]":
|
||||
async def __aenter__(self) -> GitHubCopilotAgent[TOptions]:
|
||||
"""Start the agent when entering async context."""
|
||||
await self.start()
|
||||
return self
|
||||
|
||||
@@ -23,7 +23,7 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
]
|
||||
dependencies = [
|
||||
"agent-framework-core",
|
||||
"agent-framework-core>=1.0.0b260130",
|
||||
"github-copilot-sdk>=0.1.0",
|
||||
]
|
||||
|
||||
|
||||
@@ -371,6 +371,7 @@ class GAIA:
|
||||
local_dir = snapshot_download( # type: ignore
|
||||
repo_id="gaia-benchmark/GAIA",
|
||||
repo_type="dataset",
|
||||
revision="682dd723ee1e1697e00360edccf2366dc8418dd9",
|
||||
token=token,
|
||||
local_dir=str(self.data_dir),
|
||||
force_download=False,
|
||||
|
||||
@@ -8,6 +8,8 @@ using an MCP calculator tool.
|
||||
One GPU with 40GB of memory is sufficient for this sample.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
@@ -12,6 +12,8 @@ Builds on concepts from train_math_agent.py with additional complexity.
|
||||
Requires one GPU of at least 80GB of memory.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user