TurfAITurfAI Developers
Concepts

Agents

ReAct workers with a goal, a tool set, and a prompt.

An agent is a first-class, reusable entity (/api/agents): an LLM given a goal, a set of available_tools, and a prompt, run as a ReAct loop. You can embed an agent in a workflow node or call it directly over a public chat endpoint.

The mental model: an augmented LLM

Underneath every agent is one idea: an LLM given augmentations — tools to act with, retrieval to pull in knowledge, and memory to carry state across turns. Hand that augmented model a goal and let it choose when to use each augmentation, and you have an agent.

An LLM enhanced with retrieval, tools, and memory

An agent is an LLM plus retrieval, tools, and memory — and the judgement to pick which to use.

Source: Anthropic

Foundational framing adapted from Anthropic's "Building effective agents". In TurfAI those augmentations are concrete: the built-in tool registry and MCP (tools), the knowledge base (retrieval), and conversational session memory (memory).

Configuration

These fields map 1:1 to the agent content type. Pass them under data on POST /agents (see Build an agent with tools).

FieldTypeDefaultDescription
namestringDisplay name (required)
goaltextObjective the agent works toward; supports {{variables}} (required)
descriptiontextnullHuman-readable summary of what the agent does
slugstringautoUnique URL-safe identifier used in public endpoints
available_toolsjson[]Tool IDs the agent may call. Omit the field entirely to grant all built-ins; [] means no tools (pure text agent)
modelstringvertexLLM model (vertex, openai, anthropic)
max_iterationsinteger10Max ReAct cycles before it must answer. Hard-capped at 20
temperaturefloat0.3LLM temperature
conversationalbooleanfalseMulti-turn mode with session memory + context resolvers
custom_toolsjson[]User-defined tools: { name, description, parameters, endpoint } merged into the tool list at runtime
mcp_serversjson[]External MCP servers (inline configs or registry IDs) added as tool sources
guardrailsjson{}Output guardrails: { block_patterns: [], require_tool_for: [] }
context_resolversjson["conversation", "temporal", "channel"]Which context blocks to inject (conversational mode only)
business_hoursjsonnullOptional schedule used by the temporal context resolver
welcome_messagetextHi! How can I help you?First message shown by an embedded chat widget
brandingjson{ primary_color: "#8b5cf6" }Widget branding for the public chat surface
allowed_originsjson[]CORS origins allowed to call public chat
activebooleantrueWhether the agent can be invoked

Create one with POST /agents; the response includes the generated api_key (an ag_ key for public chat — private, returned only on create, regenerate via POST /agents/:id/regenerate-key).

available_tools is three-state: omit the field → all built-ins; [] → text-only (no tools); a list → only those tools. Saved-agent fields act as defaults that inline node config overrides.

The built-in tool registry

Agents draw from a built-in tool set defined in the processor's tool_registry.py. Give each agent only the tools its job needs:

Tool IDRequired argsWhat it does
classify_documentdocument_idClassify a document's type and category; returns type, confidence, reasoning
extract_from_documentdocument_id or file_url (+mime_type)Extract structured fields from a document as JSON
search_documentsquery (+ top_k)Semantic / RAG search over the knowledge base; returns excerpts + citations
summarizeone of document_id / file_url / textSummarize content (style: brief, detailed, bullet_points)
send_emailto, subject, bodySend an email (HTML supported)
fetch_urlurl (+ method)HTTP GET/POST a URL and return the body
fetch_drive_filefile_idFetch a Google Drive file by ID
generate_textprompt (+ context)Generate text with a prompt — for analysis, writing, formatting

Extend beyond the built-ins with MCP tools — external MCP servers (databases, SaaS, custom) are discovered and merged into the agent's tool list at runtime — or with custom_tools (your own HTTP endpoints).

The execution-time tool list lives in the processor's tool_registry.py; the IDs above are the same ones surfaced by GET /workflows/task-types under the agent task's agent_tools. Don't hardcode a list that contradicts the API.

The ReAct loop

Each iteration the agent reasons, optionally calls one tool, observes the result, and repeats until it produces a plain-text answer or hits max_iterations:

Reading the trace

Every execution records a structured reasoning_trace — your primary debugging tool. Each entry is one step keyed by type:

{
  "answer": "Employees may work remotely up to 3 days per week.",
  "reasoning_trace": [
    { "step": 1, "type": "act", "tool": "search_documents",
      "args": { "query": "remote work policy", "top_k": 5 } },
    { "step": 1, "type": "observe", "status": "success",
      "result": { "data": { "results": ["…top chunks…"] } } },
    { "step": 2, "type": "answer",
      "content": "Employees may work remotely up to 3 days per week." }
  ],
  "tools_used": ["search_documents"],
  "iteration_count": 2
}
  • type: "act" — the agent chose a tool; tool + args show the call.
  • type: "observe" — the tool result; status is success or error.
  • type: "think" — intermediate reasoning text (no tool call).
  • type: "answer" — the final response.

The public chat endpoint returns a flattened trace string plus a deduplicated tools_used array. Read them in this order when debugging: did the agent pick the right tools (tools_used), did each call succeed (observe.status), and did it stop on an answer or run out of iterations.

Multi-turn conversations

Set conversational: true and pass a stable session_id on every public-chat call. The processor loads prior turns from the session, injects the configured context_resolvers, and persists each new turn — so the agent remembers earlier answers without you re-sending them.

# Turn 1 — creates the session
curl -X POST https://apisandbox.turfai.in/api/agents/support-bot/public-chat \
  -H "X-Agent-Key: $AGENT_KEY" -H "Content-Type: application/json" \
  -d '{ "query": "What is your refund policy?", "session_id": "sess-1" }'

# Turn 2 — same session_id; "it" resolves from memory
curl -X POST https://apisandbox.turfai.in/api/agents/support-bot/public-chat \
  -H "X-Agent-Key: $AGENT_KEY" -H "Content-Type: application/json" \
  -d '{ "query": "Does it cover digital goods?", "session_id": "sess-1" }'

Omit session_id (or leave conversational: false) for stateless, single-shot calls.

Calling an agent

In a workflow — an agent_task node references a saved agent by agent_id; any field set inline (e.g. goal) overrides the saved default:

{
  "task_type": "agent_task",
  "config": { "agent_id": 42, "goal": "Override goal if needed" }
}

Over public chatPOST /agents/:slug/public-chat with an X-Agent-Key header:

curl -X POST https://apisandbox.turfai.in/api/agents/support-bot/public-chat \
  -H "X-Agent-Key: $AGENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "query": "What is your refund policy?", "session_id": "sess-1" }'
{
  "answer": "Our refund policy allows returns within 30 days…",
  "trace": "Thought: I should search the knowledge base…",
  "tools_used": ["search_documents"],
  "session_id": "sess-1"
}

Reference

Full schema and endpoints: Agent API. To build one hands-on, see Build an agent with tools.

On this page