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
@@ -2,6 +2,45 @@
|
||||
|
||||
Samples are extremely important for developers to get started with Agent Framework. We strive to provide a wide range of samples that demonstrate the capabilities of Agent Framework with consistency and quality. This document outlines the guidelines for creating samples.
|
||||
|
||||
## File Structure
|
||||
|
||||
Every sample file should follow this order:
|
||||
|
||||
1. PEP 723 inline script metadata (if external dependencies are needed)
|
||||
2. Copyright header: `# Copyright (c) Microsoft. All rights reserved.`
|
||||
3. Required imports
|
||||
4. Module docstring: `"""This sample demonstrates..."""`
|
||||
5. Helper functions
|
||||
6. Main function(s) demonstrating functionality
|
||||
7. Entry point: `if __name__ == "__main__": asyncio.run(main())`
|
||||
|
||||
When modifying samples, update associated README files in the same or parent folders.
|
||||
|
||||
## External Dependencies
|
||||
|
||||
When samples depend on external packages not included in the dev environment (e.g., `semantic-kernel`, `autogen-agentchat`, `pandas`), declare them using [PEP 723](https://peps.python.org/pep-0723/) inline script metadata at the top of the file, before the copyright header:
|
||||
|
||||
```python
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "some-external-package",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/path/to/script.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
```
|
||||
|
||||
This makes samples self-contained and runnable without installing extra packages into the dev environment. Do not add sample-only dependencies to the root `pyproject.toml` dev group.
|
||||
|
||||
## Syntax Checking
|
||||
|
||||
Run `uv run poe samples-syntax` to check samples for syntax errors and missing imports from `agent_framework`. This uses a relaxed pyright configuration that validates imports without strict type checking.
|
||||
|
||||
Some samples depend on external packages (e.g., `azure.ai.agentserver.agentframework`, `microsoft_agents`) that are not installed in the dev environment. These are excluded in `pyrightconfig.samples.json`. When adding or modifying these excluded samples, add them to the exclude list and manually verify they have no import errors from `agent_framework` packages by temporarily removing them from the exclude list and running the check.
|
||||
|
||||
## General Guidelines
|
||||
|
||||
- **Clear and Concise**: Samples should be clear and concise. They should demonstrate a specific set of features or capabilities of Agent Framework. The less concepts a sample demonstrates, the better.
|
||||
@@ -49,7 +88,7 @@ For the getting started samples and the concept samples, we should have the foll
|
||||
```python
|
||||
# 1. Create the instance of the Kernel to register the plugin and service.
|
||||
...
|
||||
|
||||
|
||||
# 2. Create the agent with the kernel instance.
|
||||
...
|
||||
```
|
||||
@@ -64,7 +103,7 @@ For the getting started samples and the concept samples, we should have the foll
|
||||
User:> Why is the sky blue in one sentence?
|
||||
Mosscap:> The sky is blue due to the scattering of sunlight by the molecules in the Earth's atmosphere,
|
||||
a phenomenon known as Rayleigh scattering, which causes shorter blue wavelengths to become more
|
||||
prominent in our visual perception.
|
||||
prominent in our visual perception.
|
||||
'''
|
||||
```
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "autogen-agentchat",
|
||||
# "autogen-ext[openai]",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/autogen-migration/orchestrations/01_round_robin_group_chat.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""AutoGen RoundRobinGroupChat vs Agent Framework GroupChatBuilder/SequentialBuilder.
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "autogen-agentchat",
|
||||
# "autogen-ext[openai]",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/autogen-migration/orchestrations/02_selector_group_chat.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""AutoGen SelectorGroupChat vs Agent Framework GroupChatBuilder.
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "autogen-agentchat",
|
||||
# "autogen-ext[openai]",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/autogen-migration/orchestrations/03_swarm.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""AutoGen Swarm pattern vs Agent Framework HandoffBuilder.
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "autogen-agentchat",
|
||||
# "autogen-ext[openai]",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/autogen-migration/orchestrations/04_magentic_one.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""AutoGen MagenticOneGroupChat vs Agent Framework MagenticBuilder.
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "autogen-agentchat",
|
||||
# "autogen-ext[openai]",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/autogen-migration/single_agent/01_basic_assistant_agent.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Basic AutoGen AssistantAgent vs Agent Framework ChatAgent.
|
||||
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "autogen-agentchat",
|
||||
# "autogen-core",
|
||||
# "autogen-ext[openai]",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/autogen-migration/single_agent/02_assistant_agent_with_tool.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""AutoGen AssistantAgent vs Agent Framework ChatAgent with function tools.
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "autogen-agentchat",
|
||||
# "autogen-ext[openai]",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/autogen-migration/single_agent/03_assistant_agent_thread_and_stream.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""AutoGen vs Agent Framework: Thread management and streaming responses.
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "autogen-agentchat",
|
||||
# "autogen-ext[openai]",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/autogen-migration/single_agent/04_agent_as_tool.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""AutoGen vs Agent Framework: Agent-as-a-Tool pattern.
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "fastapi",
|
||||
# "uvicorn",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/demos/chatkit-integration/app.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
# /// script
|
||||
# requires-python = ">=3.11"
|
||||
# dependencies = [
|
||||
@@ -10,6 +9,9 @@
|
||||
# "aiohttp"
|
||||
# ]
|
||||
# ///
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/demos/m365-agent/m365_agent_demo/app.py
|
||||
|
||||
import os
|
||||
from dataclasses import dataclass
|
||||
|
||||
@@ -5,7 +5,6 @@ import tempfile
|
||||
from pathlib import Path
|
||||
from urllib import request as urllib_request
|
||||
|
||||
import aiofiles
|
||||
from agent_framework import HostedImageGenerationTool
|
||||
from agent_framework.azure import AzureAIProjectAgentProvider
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
@@ -89,8 +88,8 @@ async def main() -> None:
|
||||
if data_bytes is None:
|
||||
raise RuntimeError("Image output present but could not retrieve bytes.")
|
||||
|
||||
async with aiofiles.open(file_path, "wb") as f:
|
||||
await f.write(data_bytes)
|
||||
with open(file_path, "wb") as f:
|
||||
f.write(data_bytes)
|
||||
|
||||
print(f"Image downloaded and saved to: {file_path}")
|
||||
else:
|
||||
|
||||
@@ -3,7 +3,6 @@ import asyncio
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import aiofiles
|
||||
from agent_framework.azure import AzureAIProjectAgentProvider
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
@@ -23,9 +22,8 @@ async def main() -> None:
|
||||
# Load the OpenAPI specification
|
||||
resources_path = Path(__file__).parent.parent / "resources" / "countries.json"
|
||||
|
||||
async with aiofiles.open(resources_path, "r") as f:
|
||||
content = await f.read()
|
||||
openapi_countries = json.loads(content)
|
||||
with open(resources_path) as f:
|
||||
openapi_countries = json.load(f)
|
||||
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "microsoft-agents",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/getting_started/agents/copilotstudio/copilotstudio_with_explicit_settings.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
|
||||
@@ -8,7 +8,7 @@ All of these samples are set up to run in Azure Functions. Azure Functions has a
|
||||
### 1. Install dependencies and create appropriate services
|
||||
|
||||
- Install [Azure Functions Core Tools 4.x](https://learn.microsoft.com/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cv2&pivots=programming-language-python#install-the-azure-functions-core-tools)
|
||||
|
||||
|
||||
- Install [Azurite storage emulator](https://learn.microsoft.com/en-us/azure/storage/common/storage-install-azurite?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json&tabs=visual-studio%2Cblob-storage)
|
||||
|
||||
- Create an [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-foundry/models/openai) resource. Note the Azure OpenAI endpoint, deployment name, and the key (or ensure you can authenticate with `AzureCliCredential`).
|
||||
@@ -29,17 +29,17 @@ python -m venv .venv
|
||||
```bash
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
```
|
||||
```
|
||||
|
||||
### 3. Running the samples
|
||||
### 3. Running the samples
|
||||
|
||||
- [Start the Azurite emulator](https://learn.microsoft.com/en-us/azure/storage/common/storage-install-azurite?tabs=npm%2Cblob-storage#run-azurite)
|
||||
|
||||
- Inside each sample:
|
||||
- Inside each sample:
|
||||
|
||||
- Install Python dependencies – from the sample directory, run `pip install -r requirements.txt` (or the equivalent in your active virtual environment).
|
||||
|
||||
- Copy `local.settings.json.template` to `local.settings.json`, then update `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME` for Azure OpenAI authentication. The samples use `AzureCliCredential` by default, so ensure you're logged in via `az login`.
|
||||
|
||||
- Copy `local.settings.json.template` to `local.settings.json`, then update `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME` for Azure OpenAI authentication. The samples use `AzureCliCredential` by default, so ensure you're logged in via `az login`.
|
||||
- Alternatively, you can use API key authentication by setting `AZURE_OPENAI_API_KEY` and updating the code to use `AzureOpenAIChatClient()` without the credential parameter.
|
||||
- Keep `TASKHUB_NAME` set to `default` unless you plan to change the durable task hub name.
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ A focused sample demonstrating Azure AI's RedTeam functionality to assess the sa
|
||||
|
||||
### Python Environment
|
||||
```bash
|
||||
pip install agent-framework azure-ai-evaluation pyrit duckdb azure-identity aiofiles
|
||||
pip install agent-framework azure-ai-evaluation pyrit duckdb azure-identity
|
||||
```
|
||||
|
||||
Note: The sample uses `python-dotenv` to load environment variables from a `.env` file.
|
||||
|
||||
@@ -23,7 +23,7 @@ Prerequisites:
|
||||
- Environment variables set in .env file or environment
|
||||
|
||||
Installation:
|
||||
pip install agent-framework azure-ai-evaluation pyrit duckdb azure-identity aiofiles
|
||||
pip install agent-framework azure-ai-evaluation pyrit duckdb azure-identity
|
||||
|
||||
Reference:
|
||||
Azure AI Red Teaming: https://github.com/Azure-Samples/azureai-samples/blob/main/scenarios/evaluate/AI_RedTeaming/AI_RedTeaming.ipynb
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "pandas",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/getting_started/evaluation/self_reflection/self_reflection.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
# type: ignore
|
||||
import argparse
|
||||
|
||||
@@ -273,7 +273,7 @@ If you're updating from a previous version of the Agent Framework, here are the
|
||||
### OTLP Configuration
|
||||
|
||||
**Before (Deprecated):**
|
||||
```python
|
||||
```
|
||||
from agent_framework.observability import setup_observability
|
||||
# Via parameter
|
||||
setup_observability(otlp_endpoint="http://localhost:4317")
|
||||
@@ -305,7 +305,7 @@ configure_otel_providers(exporters=[
|
||||
### Azure Monitor Configuration
|
||||
|
||||
**Before (Deprecated):**
|
||||
```python
|
||||
```
|
||||
from agent_framework.observability import setup_observability
|
||||
|
||||
setup_observability(
|
||||
@@ -341,7 +341,7 @@ enable_instrumentation()
|
||||
### Console Output
|
||||
|
||||
**Before (Deprecated):**
|
||||
```python
|
||||
```
|
||||
from agent_framework.observability import setup_observability
|
||||
|
||||
# Console was used as automatic fallback
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "azure-monitor-opentelemetry",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/getting_started/observability/agent_with_foundry_tracing.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
|
||||
@@ -40,7 +40,7 @@ actions:
|
||||
- kind: SetValue
|
||||
path: turn.greeting
|
||||
value: Hello, World!
|
||||
|
||||
|
||||
- kind: SendActivity
|
||||
activity:
|
||||
text: =turn.greeting
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# This workflow demonstrates using multiple agents to provide automated
|
||||
# troubleshooting steps to resolve common issues with escalation options.
|
||||
#
|
||||
# Example input:
|
||||
# Example input:
|
||||
# My PC keeps rebooting and I can't use it.
|
||||
#
|
||||
kind: Workflow
|
||||
@@ -12,7 +12,7 @@ trigger:
|
||||
id: workflow_demo
|
||||
actions:
|
||||
|
||||
# Interact with user until the issue has been resolved or
|
||||
# Interact with user until the issue has been resolved or
|
||||
# a determination is made that a ticket is required.
|
||||
- kind: InvokeAzureAgent
|
||||
id: service_agent
|
||||
@@ -23,7 +23,7 @@ trigger:
|
||||
externalLoop:
|
||||
when: |-
|
||||
=Not(Local.ServiceParameters.IsResolved)
|
||||
And
|
||||
And
|
||||
Not(Local.ServiceParameters.NeedsTicket)
|
||||
output:
|
||||
responseObject: Local.ServiceParameters
|
||||
@@ -32,14 +32,14 @@ trigger:
|
||||
- kind: ConditionGroup
|
||||
id: check_if_resolved
|
||||
conditions:
|
||||
|
||||
|
||||
- condition: =Local.ServiceParameters.IsResolved
|
||||
id: test_if_resolved
|
||||
actions:
|
||||
- kind: GotoAction
|
||||
id: end_when_resolved
|
||||
actionId: all_done
|
||||
|
||||
|
||||
# Create the ticket.
|
||||
- kind: InvokeAzureAgent
|
||||
id: ticket_agent
|
||||
@@ -103,7 +103,7 @@ trigger:
|
||||
externalLoop:
|
||||
when: |-
|
||||
=Not(Local.SupportParameters.IsResolved)
|
||||
And
|
||||
And
|
||||
Not(Local.SupportParameters.NeedsEscalation)
|
||||
output:
|
||||
autoSend: true
|
||||
@@ -124,7 +124,7 @@ trigger:
|
||||
- condition: =Local.SupportParameters.IsResolved
|
||||
id: handle_if_resolved
|
||||
actions:
|
||||
|
||||
|
||||
- kind: InvokeAzureAgent
|
||||
id: resolution_agent
|
||||
agent:
|
||||
|
||||
+13
-15
@@ -6,7 +6,6 @@ import os
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
|
||||
import aiofiles
|
||||
from agent_framework import (
|
||||
Executor, # Base class for custom workflow steps
|
||||
WorkflowBuilder, # Fluent builder for executors and edges
|
||||
@@ -33,13 +32,12 @@ Show how to:
|
||||
|
||||
Prerequisites:
|
||||
- Familiarity with WorkflowBuilder, executors, fan out and fan in edges, events, and streaming runs.
|
||||
- aiofiles installed for async file I/O.
|
||||
- Write access to a tmp directory next to this script.
|
||||
- A source text at resources/long_text.txt.
|
||||
- Optional for SVG export: install graphviz.
|
||||
|
||||
Installation:
|
||||
pip install agent-framework aiofiles graphviz
|
||||
pip install agent-framework graphviz
|
||||
"""
|
||||
|
||||
# Define the temporary directory for storing intermediate results
|
||||
@@ -128,8 +126,8 @@ class Map(Executor):
|
||||
|
||||
# Write this mapper's results as simple text lines for easy debugging.
|
||||
file_path = os.path.join(TEMP_DIR, f"map_results_{self.id}.txt")
|
||||
async with aiofiles.open(file_path, "w") as f:
|
||||
await f.writelines([f"{item}: {count}\n" for item, count in results])
|
||||
with open(file_path, "w") as f:
|
||||
f.writelines([f"{item}: {count}\n" for item, count in results])
|
||||
|
||||
await ctx.send_message(MapCompleted(file_path))
|
||||
|
||||
@@ -163,8 +161,8 @@ class Shuffle(Executor):
|
||||
async def _process_chunk(chunk: list[tuple[str, list[int]]], index: int) -> None:
|
||||
"""Write one grouped partition for reducer index and notify that reducer."""
|
||||
file_path = os.path.join(TEMP_DIR, f"shuffle_results_{index}.txt")
|
||||
async with aiofiles.open(file_path, "w") as f:
|
||||
await f.writelines([f"{key}: {value}\n" for key, value in chunk])
|
||||
with open(file_path, "w") as f:
|
||||
f.writelines([f"{key}: {value}\n" for key, value in chunk])
|
||||
await ctx.send_message(ShuffleCompleted(file_path, self._reducer_ids[index]))
|
||||
|
||||
tasks = [asyncio.create_task(_process_chunk(chunk, i)) for i, chunk in enumerate(chunks)]
|
||||
@@ -179,9 +177,9 @@ class Shuffle(Executor):
|
||||
# Load all intermediate pairs.
|
||||
map_results: list[tuple[str, int]] = []
|
||||
for result in data:
|
||||
async with aiofiles.open(result.file_path, "r") as f:
|
||||
with open(result.file_path) as f:
|
||||
map_results.extend([
|
||||
(line.strip().split(": ")[0], int(line.strip().split(": ")[1])) for line in await f.readlines()
|
||||
(line.strip().split(": ")[0], int(line.strip().split(": ")[1])) for line in f.readlines()
|
||||
])
|
||||
|
||||
# Group values by token.
|
||||
@@ -230,8 +228,8 @@ class Reduce(Executor):
|
||||
return
|
||||
|
||||
# Read grouped values from the shuffle output.
|
||||
async with aiofiles.open(data.file_path, "r") as f:
|
||||
lines = await f.readlines()
|
||||
with open(data.file_path) as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# Sum values per key. Values are serialized Python lists like [1, 1, ...].
|
||||
reduced_results: dict[str, int] = defaultdict(int)
|
||||
@@ -241,8 +239,8 @@ class Reduce(Executor):
|
||||
|
||||
# Persist our partition totals.
|
||||
file_path = os.path.join(TEMP_DIR, f"reduced_results_{self.id}.txt")
|
||||
async with aiofiles.open(file_path, "w") as f:
|
||||
await f.writelines([f"{key}: {value}\n" for key, value in reduced_results.items()])
|
||||
with open(file_path, "w") as f:
|
||||
f.writelines([f"{key}: {value}\n" for key, value in reduced_results.items()])
|
||||
|
||||
await ctx.send_message(ReduceCompleted(file_path))
|
||||
|
||||
@@ -324,8 +322,8 @@ async def main():
|
||||
print("Tip: Install 'viz' extra to export workflow visualization: pip install agent-framework[viz] --pre")
|
||||
|
||||
# Step 3: Open the text file and read its content.
|
||||
async with aiofiles.open(os.path.join(DIR, "../resources", "long_text.txt"), "r") as f:
|
||||
raw_text = await f.read()
|
||||
with open(os.path.join(DIR, "../resources", "long_text.txt")) as f:
|
||||
raw_text = f.read()
|
||||
|
||||
# Step 4: Run the workflow with the raw text as input.
|
||||
async for event in workflow.run(raw_text, stream=True):
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/azure_ai_agent/01_basic_azure_ai_agent.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Create an Azure AI agent using both Semantic Kernel and Agent Framework.
|
||||
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/azure_ai_agent/02_azure_ai_agent_with_code_interpreter.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Enable the hosted code interpreter for Azure AI agents in SK and AF.
|
||||
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/azure_ai_agent/03_azure_ai_agent_threads_and_followups.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Maintain Azure AI agent conversation state across turns in SK and AF."""
|
||||
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/chat_completion/01_basic_chat_completion.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Basic SK ChatCompletionAgent vs Agent Framework ChatAgent.
|
||||
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/chat_completion/02_chat_completion_with_tool.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Demonstrate SK plugins vs Agent Framework tools with a chat agent.
|
||||
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/chat_completion/03_chat_completion_thread_and_stream.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Compare conversation threading and streaming responses for chat agents.
|
||||
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/copilot_studio/01_basic_copilot_studio_agent.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Call a Copilot Studio agent with SK and Agent Framework."""
|
||||
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/copilot_studio/02_copilot_studio_streaming.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Stream responses from Copilot Studio agents in SK and AF."""
|
||||
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/openai_assistant/01_basic_openai_assistant.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Create an OpenAI Assistant using SK and Agent Framework."""
|
||||
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/openai_assistant/02_openai_assistant_with_code_interpreter.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Enable the code interpreter tool for OpenAI Assistants in SK and AF."""
|
||||
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/openai_assistant/03_openai_assistant_function_tool.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Implement a function tool for OpenAI Assistants in SK and AF."""
|
||||
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/openai_responses/01_basic_responses_agent.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Issue a basic Responses API call using SK and Agent Framework."""
|
||||
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/openai_responses/02_responses_agent_with_tool.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Attach a lightweight function tool to the Responses API in SK and AF."""
|
||||
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/openai_responses/03_responses_agent_structured_output.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Request structured JSON output from the Responses API in SK and AF."""
|
||||
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/orchestrations/concurrent_basic.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Side-by-side concurrent orchestrations for Agent Framework and Semantic Kernel."""
|
||||
@@ -6,7 +15,7 @@ import asyncio
|
||||
from collections.abc import Sequence
|
||||
from typing import cast
|
||||
|
||||
from agent_framework import ChatMessage, ConcurrentBuilderWorkflowEvent
|
||||
from agent_framework import ChatMessage
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from semantic_kernel.agents import Agent, ChatCompletionAgent, ConcurrentOrchestration
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/orchestrations/group_chat.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Side-by-side group chat orchestrations for Agent Framework and Semantic Kernel."""
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/orchestrations/handoff.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Side-by-side handoff orchestrations for Semantic Kernel and Agent Framework."""
|
||||
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/orchestrations/magentic.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Side-by-side Magentic orchestrations for Agent Framework and Semantic Kernel."""
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/orchestrations/sequential.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Side-by-side sequential orchestrations for Agent Framework and Semantic Kernel."""
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/processes/fan_out_fan_in_process.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Side-by-side sample comparing Semantic Kernel Process Framework and Agent Framework workflows."""
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "semantic-kernel",
|
||||
# ]
|
||||
# ///
|
||||
# Run with any PEP 723 compatible runner, e.g.:
|
||||
# uv run samples/semantic-kernel-migration/processes/nested_process.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Nested process comparison between Semantic Kernel Process Framework and Agent Framework sub-workflows."""
|
||||
@@ -17,7 +26,7 @@ from agent_framework import (
|
||||
WorkflowBuilder,
|
||||
WorkflowContext,
|
||||
WorkflowExecutor,
|
||||
|
||||
|
||||
handler,
|
||||
)
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
Reference in New Issue
Block a user