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.

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