Skip to main content

tai-daf-sdk

Python SDK for DAF — Declarative Agentic Framework. Thin, MCP-native client. Every call goes to the same MCP tool the backend exposes at /mcp — no separate REST surface to keep in sync, no per-resource wrappers to hand-write.

PyPI: https://pypi.org/project/tai-daf-sdk/

Install

Alpha channel while the surface stabilises:

pip install --pre tai-daf-sdk

Python ≥ 3.10.

30-second quickstart

from tai_daf_sdk import DAF

with DAF(
    base_url="https://daf-sdk-backend-dev.azurewebsites.net",
    api_key="daf_...",
) as client:
    # List LLM endpoints on your account
    endpoints = client.llm_endpoints.list()
    ep_id = endpoints["endpoints"][0]["id"]

    # Create an agent bound to that endpoint
    agent = client.agents.create(
        name="my-assistant",
        system_instructions="You answer politely.",
        llm_endpoint_id=ep_id,
        confirm=True,
    )
    print("Created:", agent["created"]["id"])

Async version

Same API, async prefix, always inside async with:

import asyncio
from tai_daf_sdk import AsyncDAF

async def main():
    async with AsyncDAF(base_url="...", api_key="daf_...") as client:
        agents = await client.agents.list()
        for a in agents["agents"]:
            print(a["id"], a["name"])

asyncio.run(main())

How the dispatch works

The SDK is a thin dispatch layer over MCP tools. client.<resource>.<method>(**kwargs) maps to daf_<method>_<resource>:

Python call MCP tool
client.agents.list() daf_list_agents
client.agents.create(...) daf_create_agent (singular fallback)
client.agents.describe(name_or_id=...) daf_describe_agent
client.agents.update(agent_id=..., patch=...) daf_update_agent
client.agents.delete(agent_id=..., confirm=True) daf_delete_agent
client.swarms.list() daf_list_swarms
client.llm_endpoints.list() daf_list_llm_endpoints

Singular fallback. Every collection is plural on the SDK (client.agents, client.swarms) so it reads naturally. When you call .create() the SDK first tries daf_create_agents (plural), and if that's not registered, falls back to daf_create_agent (singular). This matches the backend's real naming — list ops are plural, per-item ops are singular.

Escape hatch for irregular tool names. A handful of tools don't fit daf_<method>_<resource> — like daf_attach_guardrail_to_agent, daf_run_tool, daf_mcp_health_check, daf_export_agent, daf_import_agent, daf_list_node_types. Use client.call(tool_name, args_dict):

result = client.call(
    "daf_attach_guardrail_to_agent",
    {"agent_id": agent_id, "guardrail_id": gid, "confirm": True},
)

Async client has the same escape hatch:

result = await async_client.call("daf_attach_guardrail_to_agent", {...})

Errors

The SDK maps the backend's structured error codes to typed exceptions:

Backend code Exception
VALIDATION_ERROR BadRequestError
ENTITY_NOT_FOUND NotFoundError
FORBIDDEN PermissionError
NAME_TAKEN / DUPLICATE_URL ConflictError
QUOTA_EXCEEDED RateLimitError
Others APIError (base class)
from tai_daf_sdk.exceptions import BadRequestError

try:
    client.agents.create(name="broken", model_provider="azure", confirm=True)
except BadRequestError as exc:
    print(f"Invalid config: {exc}")

ConnectionError is raised for transport failures (backend unreachable, DNS, TLS).

Configuration

Constructor accepts:

  • base_url (str) — DAF backend URL. Local dev = http://localhost:8012, dev cloud = https://daf-sdk-backend-dev.azurewebsites.net.
  • api_key (str) — DAF API key (starts with daf_). Get one from Settings → API keys in the webapp.
  • token (str) — Bearer JWT alternative to API key. Only one of api_key / token at a time.
  • timeout (float, default 60.0) — HTTP timeout in seconds.

Alternatively, set DAF_MCP_STDIO_COMMAND to run the SDK against a local stdio MCP server instead of HTTP.

Streaming

For tools whose backend implementation streams SSE events (daf_start_workflow, daf_subscribe_workflow), use client.stream(tool_name, args):

for event in client.stream("daf_subscribe_workflow", {"run_id": run_id}):
    if event.get("event") == "output_node":
        print(event["data"]["content"], end="", flush=True)

Async equivalent iterates via async for:

async for event in async_client.stream("daf_subscribe_workflow", {"run_id": run_id}):
    ...

Full guide + more examples

  • Guide: docs/GUIDE.md — every capability with working code.
  • Examples: examples/ — runnable scripts:
    • 01_hello_agent.py — create + describe + delete an agent
    • 02_swarm_workflow.py — compose a two-agent swarm via workflow drafts
    • 03_triggers.py — webhook + cron + event triggers
    • 04_memory.py — per-agent memory + shared memory
    • 05_guardrails.py — attach a guardrail to an agent
    • 06_streaming.py — subscribe to workflow SSE events

Each example is self-contained. Pass --url and --api-key (or set DAF_MCP_URL / DAF_API_KEY env vars).

Regenerating from your backend's catalog

When the backend adds tools, the SDK's tool registry catches up automatically:

python -m tai_daf_sdk.codegen \
    --mcp-url https://daf-sdk-backend-dev.azurewebsites.net \
    --api-key daf_... \
    --out tai_daf_sdk/

Regenerates:

  • _tool_registry.py — MCP tool → resource+method map
  • types.py — TypedDict per tool input
  • client.pyi — IDE stubs for autocomplete
  • models.py — Pydantic wrappers where declared

The CI workflow .github/workflows/mcp-catalog-sync.yml runs this on schedule and fails when the shipped registry drifts from the live backend catalog.

End-to-end test scenarios

scripts/sdk_tests/ — 45 scripts (24 customer sandbox stories + 21 read-only sweeps) verify the whole surface against a live backend. Same story IDs as the MCP-side suite in daf-sdk-backend/scripts/mcp_tests so you can cross-check SDK ↔ MCP agree on the customer contract.

python -m scripts.sdk_tests.run_all \
    --url https://daf-sdk-backend-dev.azurewebsites.net \
    --api-key daf_...

Filter with --set 1|2 or --filter us_01 for one scenario at a time.

License

MIT.

Metadata

Release files for tai-daf-sdk 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tai-daf-sdk 2.0.0
File Size Uploaded
tai_daf_sdk-2.0.0.tar.gz 31.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tai-daf-sdk 2.0.0
File Interpreter ABI Platform
tai_daf_sdk-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 61.6 kB

Release files / tai_daf_sdk-2.0.0.tar.gz

Download URL tai_daf_sdk-2.0.0.tar.gz
Size 31.2 kB
Tags Source
SHA-256 checksum
How to use checksums
a984f1f04417b4cb23b00edb27cc1a80739bb934715774abec6fbc5c9b7b4446
BLAKE2b-256 checksum
How to use checksums
06215b8a5d0f0e8a4bb319c1d562eff43d52a3e2c2a3c128a29d696ffd702849
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / tai_daf_sdk-2.0.0-py3-none-any.whl

Download URL tai_daf_sdk-2.0.0-py3-none-any.whl
Size 30.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e6823b426e60e4c5ff45dcf52fb6ee8d46e1b0912c93a2cd28e615541d162e66
BLAKE2b-256 checksum
How to use checksums
d5f8cc2872b3b4145ebbfc253bc46ccc84b4a76231a30bc85dabd5eb0dbadcb0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page