Metadata-Version: 2.4
Name: agent-framework-appkit
Version: 0.1.0
Summary: Utility helpers for Microsoft Agent Framework applications.
Author: Microsoft
License-Expression: MIT
Project-URL: Homepage, https://github.com/Dongbumlee/agent-framework-appkit
Project-URL: Repository, https://github.com/Dongbumlee/agent-framework-appkit
Project-URL: Issues, https://github.com/Dongbumlee/agent-framework-appkit/issues
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: agent-framework<2,>=1.2.2
Provides-Extra: dev
Requires-Dist: pytest>=9.0.3; extra == "dev"
Requires-Dist: pytest-asyncio>=1.3.0; extra == "dev"
Requires-Dist: ruff>=0.9.0; extra == "dev"
Requires-Dist: build>=1.2.0; extra == "dev"
Dynamic: license-file

# Agent Framework AppKit

[![CI/CD](https://github.com/Dongbumlee/agent-framework-appkit/actions/workflows/ci.yml/badge.svg)](https://github.com/Dongbumlee/agent-framework-appkit/actions/workflows/ci.yml)

Utility app kit for Microsoft Agent Framework: configuration, DI, agent/client factories, resilience, and Skills helpers without adding a second framework.

## Why this package exists

Microsoft Agent Framework already provides the core agent runtime. This package stays intentionally small and provides reusable app-level helpers around native MAF extension points:

| Namespace | Use case |
|---|---|
| `agent_framework_appkit.config` | Discover OpenAI-compatible and Foundry service settings from environment variables. |
| `agent_framework_appkit.di` | Register and resolve app-local services with singleton, transient, scoped, and async lifetimes. |
| `agent_framework_appkit.agents` | Build native MAF `Agent` objects and chat clients with less repeated setup code. |
| `agent_framework_appkit.resilience` | Add HTTP 429 retry middleware and env-driven native compaction settings. |
| `agent_framework_appkit.skills` | Build native `SkillsProvider` objects and run file-based skill scripts safely. |

## Install

```bash
pip install agent-framework-appkit
```

For local development:

```bash
git clone https://github.com/Dongbumlee/agent-framework-appkit.git
cd agent-framework-appkit
uv sync --locked --dev
uv run pytest -q
uv run ruff check .
uv run python -m build
```

## Quick start

```python
from agent_framework_appkit.agents import AgentClientRegistry, build_agent
from agent_framework_appkit.config import AgentFrameworkSettings

settings = AgentFrameworkSettings(
    env={
        "AZURE_OPENAI_ENDPOINT": "https://example.openai.azure.com/",
        "AZURE_OPENAI_MODEL": "gpt-4o",
    }
)

registry = AgentClientRegistry(credential_factory=lambda service: get_token_provider())
registry.initialize(settings)

client = registry.get_client("default")
agent = build_agent(
    client=client,
    name="Assistant",
    instructions="You are a helpful assistant.",
    temperature=0.2,
)
```

`get_token_provider()` is intentionally not provided by this package. Bring your own credential factory from Azure Identity, your host app, or your platform.

## Common use cases

### 1. Discover model endpoints from environment variables

```python
from agent_framework_appkit.config import AgentFrameworkSettings

settings = AgentFrameworkSettings(
    custom_service_prefixes={
        "east": "AZURE_OPENAI_EASTUS",
        "west": "AZURE_OPENAI_WESTUS",
    }
)

for service_id in settings.get_available_services():
    service = settings.get_service_config(service_id)
    print(service_id, service.chat_deployment_name)
```

Supported model aliases include:

- `{PREFIX}_CHAT_DEPLOYMENT_NAME`
- `{PREFIX}_CHAT_MODEL`
- `{PREFIX}_CHAT_COMPLETION_MODEL`
- `{PREFIX}_MODEL`

Supported endpoint aliases include:

- `{PREFIX}_ENDPOINT`
- `{PREFIX}_BASE_URL`
- `{PREFIX}_BASEURL`

### 2. Use lightweight dependency injection

```python
from agent_framework_appkit.di import AppContext

class Repository:
    def list_items(self) -> list[str]:
        return ["alpha", "beta"]

class Service:
    def __init__(self, repo: Repository) -> None:
        self.repo = repo

ctx = AppContext()
ctx.add_singleton(Repository)
ctx.add_transient(Service, lambda c: Service(c.get_service(Repository)))

service = ctx.get_service(Service)
print(service.repo.list_items())
```

### 3. Build agents with native MAF options

```python
from agent_framework_appkit.agents import build_agent

agent = build_agent(
    client=chat_client,
    name="ResearchAssistant",
    instructions="Answer with citations when possible.",
    tools=[search_docs],
    temperature=0.1,
    max_tokens=1200,
)
```

`build_agent` returns a native `agent_framework.Agent`.

### 4. Add retry and compaction helpers

```python
from agent_framework_appkit.agents import ClientType, create_client
from agent_framework_appkit.resilience import RateLimitRetryConfig

client = create_client(
    ClientType.OpenAIChatClient,
    azure_endpoint="https://example.openai.azure.com/",
    model="gpt-4o",
    credential=token_provider,
    api_version="2024-10-01-preview",
    enable_rate_limit_retry=True,
    retry_config=RateLimitRetryConfig(max_retries=3),
)
```

Compaction can be controlled with environment variables:

```bash
MAF_COMPACTION_ENABLED=true
MAF_COMPACTION_MAX_MESSAGES=80
MAF_COMPACTION_COMPACT_TO=40
```

### 5. Attach file-based Skills

```python
from agent_framework_appkit.agents import build_agent

agent = build_agent(
    client=chat_client,
    instructions="Use available skills when helpful.",
    skill_paths=["./skills"],
    require_script_approval=True,
)
```

You can also configure skills through environment variables:

```bash
MAF_SKILL_PATHS=./skills,./more-skills
MAF_SKILL_REQUIRE_APPROVAL=true
MAF_SKILL_SCRIPT_EXTENSIONS=.py,.ps1
```

## Examples

See the `examples/` directory:

| Example | Shows |
|---|---|
| `examples/config_and_clients.py` | service discovery and client registry setup |
| `examples/dependency_injection.py` | singleton/transient/scoped DI usage |
| `examples/agent_with_skills.py` | building a native MAF agent with skills and retry |

## Design guardrails

- This is **not** a second agent framework.
- No custom dotenv loading; load `.env` before constructing settings if needed.
- No template-specific credential utilities; pass credentials or credential factories explicitly.
- No declarative agent/orchestration layer; use native MAF APIs for those surfaces.
- Keep helpers thin, typed, and easy to remove if MAF adds native equivalents.

## Development

```bash
uv sync --locked --dev
uv run pytest -q
uv run ruff check .
uv run python -m build
```

CI runs the same commands on pull requests and pushes to `main`.

## Publishing to PyPI

Publishing uses PyPI trusted publishing through GitHub Actions. No PyPI API token is stored in GitHub secrets.

GitHub Actions workflow:

- Workflow file: `.github/workflows/ci.yml`
- Publish trigger: GitHub release `published`
- GitHub environment: `pypi`
- PyPI project: `agent-framework-appkit`

Configure the trusted publisher in PyPI with these values:

| PyPI trusted publisher field | Value |
|---|---|
| Owner | `Dongbumlee` |
| Repository name | `agent-framework-appkit` |
| Workflow name | `ci.yml` |
| Environment name | `pypi` |

Release flow:

1. Update `version` in `pyproject.toml`.
2. Run local validation:

   ```bash
   uv sync --locked --dev
   uv run pytest -q
   uv run ruff check .
   uv run python -m build
   ```

3. Commit and push the version change.
4. Create and publish a GitHub release, for example:

   ```bash
   gh release create v0.1.0 --title "v0.1.0" --notes "Initial release"
   ```

5. The `publish` job builds the distributions and publishes them to PyPI using the GitHub OIDC identity.

## License

MIT
