Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/python-code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ env:
UV_CACHE_DIR: /tmp/.uv-cache

jobs:
pre-commit:
prek:
name: Checks
if: "!cancelled()"
strategy:
Expand Down Expand Up @@ -41,12 +41,12 @@ jobs:
UV_CACHE_DIR: /tmp/.uv-cache
- uses: actions/cache@v5
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ matrix.python-version }}|${{ hashFiles('python/.pre-commit-config.yaml') }}
- uses: pre-commit/action@v3.0.1
name: Run Pre-Commit Hooks
path: ~/.cache/prek
key: prek|${{ matrix.python-version }}|${{ hashFiles('python/.pre-commit-config.yaml') }}
- uses: j178/prek-action@v1
name: Run Prek Hooks
with:
extra_args: --config python/.pre-commit-config.yaml --all-files
extra-args: --cd python --all-files
- name: Run Mypy
env:
GITHUB_BASE_REF: ${{ github.event.pull_request.base.ref || github.base_ref || 'main' }}
Expand Down
43 changes: 26 additions & 17 deletions python/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,59 +1,68 @@
files: ^python/
fail_fast: true
exclude: ^scripts/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
- repo: builtin
hooks:
- id: check-toml
name: Check TOML files
files: \.toml$
exclude: ^python/packages/lab/cookiecutter-agent-framework-lab/
exclude: ^packages/lab/cookiecutter-agent-framework-lab/
- id: check-yaml
name: Check YAML files
files: \.yaml$
- id: check-json
name: Check JSON files
files: \.json$
exclude: ^.*\.vscode\/.*|^python/demos/samples/chatkit-integration/frontend/(tsconfig.*\.json|package-lock\.json)$
exclude: ^.*\.vscode\/.*|^demos/samples/chatkit-integration/frontend/(tsconfig.*\.json|package-lock\.json)$
- id: end-of-file-fixer
name: Fix End of File
files: \.py$
exclude: ^python/packages/lab/cookiecutter-agent-framework-lab/
exclude: ^packages/lab/cookiecutter-agent-framework-lab/
- id: mixed-line-ending
name: Check Mixed Line Endings
files: \.py$
exclude: ^python/packages/lab/cookiecutter-agent-framework-lab/
exclude: ^packages/lab/cookiecutter-agent-framework-lab/
- id: trailing-whitespace
name: Trim Trailing Whitespace
exclude: ^packages/lab/cookiecutter-agent-framework-lab/
- id: check-merge-conflict
name: Check Merge Conflicts
- id: detect-private-key
name: Detect Private Keys
- id: check-added-large-files
name: Check Added Large Files
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-ast
name: Check Valid Python Samples
types: ["python"]
exclude: ^python/packages/lab/cookiecutter-agent-framework-lab/
exclude: ^packages/lab/cookiecutter-agent-framework-lab/
- repo: https://github.com/asottile/pyupgrade
rev: v3.20.0
rev: v3.21.2
hooks:
- id: pyupgrade
name: Upgrade Python syntax
args: [--py310-plus]
exclude: ^python/packages/lab/cookiecutter-agent-framework-lab/
exclude: ^packages/lab/cookiecutter-agent-framework-lab/
- repo: local
hooks:
- id: poe-check
name: Run checks through Poe
entry: uv --directory ./python run poe pre-commit-check
entry: uv run poe prek-check
language: system
files: ^python/
- repo: https://github.com/PyCQA/bandit
rev: 1.8.5
rev: 1.9.3
hooks:
- id: bandit
name: Bandit Security Checks
args: ["-c", "python/pyproject.toml"]
args: ["-c", "pyproject.toml"]
additional_dependencies: ["bandit[toml]"]
- repo: https://github.com/astral-sh/uv-pre-commit
# uv version.
rev: 0.7.18
rev: 0.10.0
hooks:
# Update the uv lockfile
- id: uv-lock
name: Update uv lockfile
files: python/pyproject.toml
args: [--project, python]
files: pyproject.toml
2 changes: 1 addition & 1 deletion python/.vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"command": "uv",
"args": [
"run",
"pre-commit",
"prek",
"run",
"-a"
],
Expand Down
17 changes: 2 additions & 15 deletions python/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,9 @@ from agent_framework.azure import AzureOpenAIChatClient, AzureAIAgentClient
- **Comments**: Avoid excessive comments; prefer clear code
- **Formatting**: Format only files you changed, not the entire codebase

## Sample Structure
## Samples

1. Copyright header: `# Copyright (c) Microsoft. All rights reserved.`
2. Required imports
3. Module docstring: `"""This sample demonstrates..."""`
4. Helper functions
5. Main function(s) demonstrating functionality
6. Entry point: `if __name__ == "__main__": asyncio.run(main())`

When modifying samples, update associated README files in the same or parent folders.

### Samples 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.
See [samples/SAMPLE_GUIDELINES.md](samples/SAMPLE_GUIDELINES.md) for sample structure, external dependency handling (PEP 723), and syntax checking instructions.

## Package Documentation

Expand Down
7 changes: 7 additions & 0 deletions python/CODING_STANDARD.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,13 @@ After the package has been released and gained a measure of confidence:
2. Add the package to the `[all]` extra in `packages/core/pyproject.toml`
3. Create a provider folder in `agent_framework/` with lazy loading `__init__.py`

### Versioning and Core Dependency

All non-core packages declare a lower bound on `agent-framework-core` (e.g., `"agent-framework-core>=1.0.0b260130"`). Follow these rules when bumping versions:

- **Core version changes**: When `agent-framework-core` is updated with breaking or significant changes and its version is bumped, update the `agent-framework-core>=...` lower bound in every other package's `pyproject.toml` to match the new core version.
- **Non-core version changes**: Non-core packages (connectors, extensions) can have their own versions incremented independently while keeping the existing core lower bound pinned. Only raise the core lower bound if the non-core package actually depends on new core APIs.

### Installation Options

Connectors are distributed as separate packages and are not imported by default in the core package. Users install the specific connectors they need:
Expand Down
24 changes: 12 additions & 12 deletions python/DEV_SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ uv venv --python $PYTHON_VERSION
uv sync --dev
# Install all the tools and dependencies
uv run poe install
# Install pre-commit hooks
uv run poe pre-commit-install
# Install prek hooks
uv run poe prek-install
```

Alternatively, you can reinstall the venv, pacakges, dependencies and pre-commit hooks with a single command (but this requires poe in the current env), this is especially useful if you want to switch python versions:
Alternatively, you can reinstall the venv, pacakges, dependencies and prek hooks with a single command (but this requires poe in the current env), this is especially useful if you want to switch python versions:

```bash
uv run poe setup -p 3.13
Expand Down Expand Up @@ -144,7 +144,7 @@ To run the same checks that run during a commit and the GitHub Action `Python Co
uv run poe check
```

Ideally you should run these checks before committing any changes, when you install using the instructions above the pre-commit hooks should be installed already.
Ideally you should run these checks before committing any changes, when you install using the instructions above the prek hooks should be installed already.

## Code Coverage

Expand Down Expand Up @@ -196,10 +196,10 @@ and then you can run the following tasks:
uv sync --all-extras --dev
```

After this initial setup, you can use the following tasks to manage your development environment. It is advised to use the following setup command since that also installs the pre-commit hooks.
After this initial setup, you can use the following tasks to manage your development environment. It is advised to use the following setup command since that also installs the prek hooks.

#### `setup`
Set up the development environment with a virtual environment, install dependencies and pre-commit hooks:
Set up the development environment with a virtual environment, install dependencies and prek hooks:
```bash
uv run poe setup
# or with specific Python version
Expand All @@ -220,10 +220,10 @@ uv run poe venv
uv run poe venv --python 3.12
```

#### `pre-commit-install`
Install pre-commit hooks:
#### `prek-install`
Install prek hooks:
```bash
uv run poe pre-commit-install
uv run poe prek-install
```

### Code Quality and Formatting
Expand Down Expand Up @@ -325,10 +325,10 @@ Publish packages to PyPI:
uv run poe publish
```

## Pre-commit Hooks
## Prek Hooks

Pre-commit hooks run automatically on commit and execute a subset of the checks on changed files only. You can also run all checks using pre-commit directly:
Prek hooks run automatically on commit and execute a subset of the checks on changed files only. You can also run all checks using prek directly:

```bash
uv run pre-commit run -a
uv run prek run -a
```
4 changes: 2 additions & 2 deletions python/devsetup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ uv venv --python $PYTHON_VERSION
uv sync --dev
# Install all the tools and dependencies
uv run poe install
# Install pre-commit hooks
uv run poe pre-commit-install
# Install prek hooks
uv run poe prek-install
2 changes: 1 addition & 1 deletion python/packages/a2a/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ classifiers = [
"Typing :: Typed",
]
dependencies = [
"agent-framework-core",
"agent-framework-core>=1.0.0b260130",
"a2a-sdk>=0.3.5",
]

Expand Down
3 changes: 1 addition & 2 deletions python/packages/ag-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,14 @@ 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():
async with AGUIChatClient(endpoint="http://localhost:8000/") as client:
# 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()

Expand Down
3 changes: 1 addition & 2 deletions python/packages/ag-ui/getting_started/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion python/packages/ag-ui/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion python/packages/anthropic/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ classifiers = [
"Typing :: Typed",
]
dependencies = [
"agent-framework-core",
"agent-framework-core>=1.0.0b260130",
"anthropic>=0.70.0,<1",
]

Expand Down
2 changes: 1 addition & 1 deletion python/packages/azure-ai-search/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ classifiers = [
"Typing :: Typed",
]
dependencies = [
"agent-framework-core",
"agent-framework-core>=1.0.0b260130",
"azure-search-documents==11.7.0b2",
]

Expand Down
2 changes: 1 addition & 1 deletion python/packages/azure-ai/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion python/packages/azurefunctions/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion python/packages/bedrock/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]
Expand Down
2 changes: 1 addition & 1 deletion python/packages/chatkit/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]

Expand Down
2 changes: 1 addition & 1 deletion python/packages/claude/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ classifiers = [
"Typing :: Typed",
]
dependencies = [
"agent-framework-core",
"agent-framework-core>=1.0.0b260130",
"claude-agent-sdk>=0.1.25",
]

Expand Down
2 changes: 1 addition & 1 deletion python/packages/copilotstudio/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ classifiers = [
"Typing :: Typed",
]
dependencies = [
"agent-framework-core",
"agent-framework-core>=1.0.0b260130",
"microsoft-agents-copilotstudio-client>=0.3.1",
]

Expand Down
2 changes: 1 addition & 1 deletion python/packages/declarative/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading
Loading