Metadata-Version: 2.4
Name: agentfield
Version: 0.1.70rc1
Summary: Python SDK for the AgentField control plane
Author: AgentField Maintainers
License: Apache-2.0
Project-URL: Homepage, https://github.com/Agent-Field/agentfield
Project-URL: Documentation, https://github.com/Agent-Field/agentfield/tree/main/docs
Project-URL: Issues, https://github.com/Agent-Field/agentfield/issues
Keywords: agentfield,sdk,agents
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: <3.14,>=3.10
Description-Content-Type: text/markdown
Requires-Dist: fastapi
Requires-Dist: uvicorn
Requires-Dist: requests>=2.28
Requires-Dist: pydantic>=2.0
Requires-Dist: litellm
Requires-Dist: psutil
Requires-Dist: PyYAML>=6.0
Requires-Dist: aiohttp>=3.8
Requires-Dist: websockets
Requires-Dist: fal-client>=0.5.0
Requires-Dist: cryptography>=41.0
Provides-Extra: harness-claude
Requires-Dist: claude-agent-sdk>=0.1; extra == "harness-claude"
Provides-Extra: harness
Requires-Dist: claude-agent-sdk>=0.1; extra == "harness"
Provides-Extra: dev
Requires-Dist: pytest<10,>=9.0.3; extra == "dev"
Requires-Dist: pytest-asyncio<2,>=1.3; extra == "dev"
Requires-Dist: pytest-cov<5,>=4.1; extra == "dev"
Requires-Dist: pytest-httpx<1,>=0.30; extra == "dev"
Requires-Dist: responses<0.26,>=0.23; extra == "dev"
Requires-Dist: respx<0.22,>=0.20; extra == "dev"
Requires-Dist: freezegun<2,>=1.2; extra == "dev"
Requires-Dist: syrupy<6,>=5; extra == "dev"
Requires-Dist: hypothesis<7,>=6.88; extra == "dev"
Requires-Dist: pytest-socket<0.8,>=0.6; extra == "dev"

# AgentField Python SDK

The AgentField SDK provides a production-ready Python interface for registering agents, executing workflows, and integrating with the AgentField control plane.

## Installation

```bash
pip install agentfield
```

To work on the SDK locally:

```bash
git clone https://github.com/Agent-Field/agentfield.git
cd agentfield/sdk/python
python -m pip install -e .[dev]
```

## Quick Start

```python
from agentfield import Agent

agent = Agent(
    node_id="example-agent",
    agentfield_server="http://localhost:8080",
    dev_mode=True,
)

@agent.reasoner()
async def summarize(text: str) -> dict:
    result = await agent.ai(
        prompt=f"Summarize: {text}",
        response_model={"summary": "string", "tone": "string"},
    )
    return result

if __name__ == "__main__":
    agent.serve(port=8001)
```

## AI Tool Calling

Let LLMs automatically discover and invoke agent capabilities across your system:

```python
from agentfield import Agent, AIConfig, ToolCallConfig

app = Agent(
    node_id="orchestrator",
    agentfield_server="http://localhost:8080",
    ai_config=AIConfig(model="openai/gpt-4o-mini"),
)

@app.reasoner()
async def ask_with_tools(question: str) -> dict:
    # Auto-discover all tools and let the LLM use them
    result = await app.ai(
        system="You are a helpful assistant.",
        user=question,
        tools="discover",
    )
    return {"answer": str(result), "trace": result.trace}

# Filter by tags, limit turns, use lazy hydration
result = await app.ai(
    user="Get weather for Tokyo",
    tools=ToolCallConfig(
        tags=["weather"],
        schema_hydration="lazy",  # Reduces token usage for large catalogs
        max_turns=5,
        max_tool_calls=10,
    ),
)
```

**Key features:**
- `tools="discover"` — Auto-discover all capabilities from the control plane
- `ToolCallConfig` — Filter by tags, agent IDs, health status
- **Lazy hydration** — Send only tool names/descriptions first, hydrate schemas on demand
- **Guardrails** — `max_turns` and `max_tool_calls` prevent runaway loops
- **Observability** — `result.trace` tracks every tool call with latency

See `examples/python_agent_nodes/tool_calling/` for a complete orchestrator + worker example.

## Human-in-the-Loop Approvals

The Python SDK provides a first-class waiting state for pausing agent execution mid-reasoner and waiting for human approval:

```python
from agentfield import Agent, ApprovalResult

app = Agent(node_id="reviewer", agentfield_server="http://localhost:8080")

@app.reasoner()
async def deploy(environment: str) -> dict:
    plan = await app.ai(f"Create deployment plan for {environment}")

    # Pause execution and wait for human approval
    result: ApprovalResult = await app.pause(
        approval_request_id="req-abc123",
        expires_in_hours=24,
        timeout=3600,
    )

    if result.approved:
        return {"status": "deploying", "plan": str(plan)}
    elif result.changes_requested:
        return {"status": "revising", "feedback": result.feedback}
    else:
        return {"status": result.decision}
```

**Two API levels:**

- **High-level:** `app.pause()` blocks the reasoner until approval resolves, with automatic webhook registration
- **Low-level:** `client.request_approval()`, `client.get_approval_status()`, `client.wait_for_approval()` for fine-grained control

See `examples/python_agent_nodes/waiting_state/` for a complete working example.

See `docs/DEVELOPMENT.md` for instructions on wiring agents to the control plane.

## Testing

```bash
./scripts/run_pytest.sh
```

To run coverage locally:

```bash
./scripts/run_pytest.sh --cov=agentfield --cov-report=term-missing
```

The wrapper sets a private `PYTEST_DEBUG_TEMPROOT` automatically so local runs
and CI do not rely on pytest's predictable default temp directory layout.

## License

Distributed under the Apache 2.0 License. See the project root `LICENSE` for details.
