Skip to main content
The Action Runner plugin intercepts special [ACTION:slug:{"params"}] tags emitted by the LLM in chat responses, strips them from the visible message, executes the corresponding flow, and streams status updates back to the user.

Why Action Runner?

Problem: Qwen-2.5 (and many uncensored models) struggle with reliable tool calling in AnythingLLM’s agent mode. Function calls often fail, get malformed, or hallucinate parameters. Solution: Instead of relying on native tool calling, the model emits structured text tags that trigger pre-built flows. The Action Runner plugin intercepts these tags, validates parameters, and executes multi-step workflows using a declarative JSON format.

How It Works

1. Model Emission

The model outputs a special tag in its prose:

2. Interception

The action-runner plugin:
  • Detects the [ACTION:slug:{params}] pattern
  • Strips it from the visible chat response
  • Parses the slug and JSON parameters
  • Looks up the flow definition in action_flows collection

3. Execution

The plugin executes the flow’s steps sequentially:
  • Each step is one of 14 available step types
  • Steps can use variables from previous steps via {{step_name.field}}
  • Execution status is streamed back to the chat UI
  • Results are logged to agent_audits (success/error/miss)

4. Logging

Every ACTION execution is logged to the agent_audits collection:
  • success: Flow completed without errors
  • error: Flow failed (with error message)
  • miss: Slug not found in action_flows

Available Actions


Flow Definition Format

Flows are stored in the action_flows Directus collection with this structure:

Step Types

The Action Runner supports 14 step types:

MCP Tool Steps

Utility Steps


Variable Interpolation

Steps can reference variables from:
  • {{params.fieldName}} — Input parameters from the ACTION tag
  • {{stepName.field}} — Output from previous steps
  • {{env.VARIABLE}} — Environment variables
  • {{user.id}} — Current user context
Example:

System Prompt Integration

The GENIE_SYSTEM_PROMPT includes instructions for emitting ACTION tags:

Error Handling

Flow Not Found

If the slug doesn’t exist in action_flows, the runner logs a miss to agent_audits and returns an error message to the chat.

Step Failure

If a step throws an error:
  • Execution halts immediately
  • Error is logged to agent_audits with full stack trace
  • User sees a friendly error message in chat

Tier Limits

If a step triggers a tier-gated operation (e.g. create-item on media_jobs), the Directus MCP server checks quotas and throws a tier_limit: error that propagates to the user.

Implementation Details

Plugin Location

server/utils/actionRunner/

Key Files

  • index.js — Main plugin entrypoint and tag interceptor
  • executor.js — Flow step executor
  • steps/ — Individual step type implementations

Integration Points

  • Chat stream: Intercepts SSE stream from AnythingLLM
  • Agent audits: Logs every execution to Directus
  • MCP servers: Reuses existing MCP tool connections

Compared to Native Tool Calling

When to use Action Runner: Complex workflows, unreliable tool-calling models, need for audit trails When to use native tools: Simple single-step operations, models with good function calling (GPT-4, Claude)
  • MCP Servers — The 29 tools available in flow steps
  • Ollama Models — Models that emit ACTION tags
  • Collection: action_flows — Flow definitions (slug → steps JSON)
  • Collection: agent_audits — Execution logs (success/error/miss)