Skip to content

Roles And Routing

PyFlue supports scoped roles and file-based agent routes.

Note

This page covers Markdown roles and the original file based handler model. For the current model, see Agents for persistent create_agent instances and Workflows for finite run(ctx) operations. The file based default(context) handler still works and is treated as workflow like, so it keeps its run lifecycle. Markdown roles remain current and bridge to subagent profiles; see Subagents.

Roles

Roles live in .agents/roles.

.agents/
  roles/
    coder.md
    data_analyst.md

Example role:

---
name: coder
description: Careful coding role
---

You are a careful coding agent. Inspect before editing and verify your work.

Use the role on a prompt, skill, or task:

result = await session.prompt(
    "Review this patch",
    role="coder",
)

File-Based Routes

Python files in agents/ or .agents/ become webhook routes.

agents/
  code.py

The route is:

POST /agents/code/{agent_id}

Agent file:

triggers = {"webhook": True}


async def default(context):
    agent = await context.init()
    session = await agent.session(context.agent_id)
    result = await session.prompt(context.payload["prompt"])
    return {"text": result.text}

Start the development server:

pyflue dev --port 2024

Call the route:

curl http://127.0.0.1:2024/agents/code/default \
  -H "Content-Type: application/json" \
  -d '{"payload": {"prompt": "Review this repository"}}'

HTTP errors use a stable JSON envelope:

{
  "error": {
    "type": "agent_not_found",
    "message": "Agent \"missing\" is not registered.",
    "details": "Verify the agent name is correct."
  }
}

The server validates request method, JSON content type, JSON body shape, registered agent names, and webhook trigger settings.

Secrets are available to host code through context.env, but PyFlue does not inject those values into prompts.

Triggers

Routes are webhook-enabled by default. You can disable the webhook route or add metadata for your own scheduler:

triggers = {
    "webhook": False,
    "schedule": "0 * * * *",
}

The built-in server only exposes webhook routes. Schedule metadata is available through route discovery so applications can wire their own scheduler.