Agent Loop
Execution model
Agent orchestration is iterative, not one-shot.
- Collect messages (
system_prompt,user_prompt, optional memory context) - Collect attached tool metadata from
mcp_toolnodes - Call model with tool definitions
- If model returns tool calls:
- execute tool(s)
- append tool outputs to conversation
- call model again
- Stop on final answer or
maxIterations
Attachment ports
chat_model: attach model node- supported:
openai_chat_model,anthropic_chat_model,ollama_chat_model,openai_compatible_chat_model,ai_gateway_chat_model,azure_openai_chat_model,google_gemini_chat_model,llm_call
- supported:
memory: attachlocal_memorytool: attach one or moremcp_toolworker: attach worker agents (supervisor use cases)
In the visual editor, use the + button below an Agent port to open a filtered drawer for compatible Language Model, Memory, or Tool nodes. Clicking an item creates and attaches it automatically.
Common failure causes
- No model node attached to
chat_model - Tool definitions too large for model context
- Missing credential secret refs
- Max iterations too low for required task depth
Reliability guidance
- Keep tool schema concise
- Restrict tool set to task-relevant tools
- Set explicit max iterations
- Ensure upstream nodes provide stable prompt fields
Session tool cache (multi-turn reuse)
The runtime persists full MCP tool outputs outside prompt context and exposes cache tools back to the model for follow-up turns.
Behavior:
- External MCP tool call completes.
- Runtime stores full args/output by
namespace + session_id. - Runtime gives the model compact in-context tool messages.
- On later turns, model can call:
session_cache_listsession_cache_get
- Model reuses prior fetched data instead of repeating expensive MCP calls.
Notes:
- Cache tools are injected automatically when
session_idis present. - Reuse depends on stable
session_idand memory namespace. - Cached payloads are stored in SQLite table
session_tool_cache.
Mid-turn clarification (agent_clarify)
The runtime exposes a third built-in tool — agent_clarify — that the agent can call whenever it needs information only the user can provide. It's always available, regardless of whether a session_id is set.
How it works
- The agent decides it can't proceed without more info and calls
agent_clarify({ question, reason? }). - The runtime breaks out of the iteration loop before invoking the tool body. The assistant's tool-call message is saved to session memory.
run()returns withstopReason: "clarification_requested"and aclarificationfield containing the question, optional reason, and the tool call id.- The
agent_orchestratornode surfaces the clarification on its output. The workflow's top-level result also carries aclarificationfield so chat UIs and webhook callers don't have to dig intonodeResults.
Resume
On the next run() call with the same sessionId and a non-empty userPrompt:
- The runtime loads session memory, sees the orphaned
agent_clarifytool call. - It injects the new
userPromptas the tool result for that call (not as a fresh user message) — so the LLM sees a clean tool-call → tool-result exchange in the standard tool-calling protocol. - The agent loop continues from there. The next assistant turn is the answer.
For chat triggers this happens automatically — every chat message in the same session reuses the same session_id, so the next user reply resumes naturally.
For non-chat triggers (webhook, schedule), the workflow caller inspects result.clarification and re-invokes the workflow with the reply as user_prompt.
What gets persisted
Tool results are normally filtered from session memory (the in-context tool message has the full output). The agent_clarify tool result is the exception — it's always persisted, so the resume-detection on subsequent runs sees the question as answered and doesn't re-resume.
When to use it
- ✅ The user said "send him an email" without specifying who.
- ✅ The user asked for "the report" without saying which one.
- ❌ Don't use it as a confirmation gate. If the request is clear, just do it.
- ❌ Don't use it to ask the user to fix the user's own typo — make the best reasonable inference.
Chat UI
When the workflow result carries clarification, the chat bubble renders with a "?" badge labeled "Assistant is asking", the question as the body, and the optional reason below it as italic context. The bubble looks different enough from a regular answer that users can tell at a glance "the agent is waiting on me."
Sample workflow: samples/workflows/agent-clarify-flow.json.