Skip to content

fuseraft/fuseraft-cli

Repository files navigation

Fuseraft CLI

Production-grade multi-agent orchestration powered by Microsoft Semantic Kernel and xAI's Grok models.

Define a team of AI agents in a simple JSON config, give them a task, and watch them collaborate intelligently — with every turn automatically checkpointed to disk so you can resume exactly where you left off, even after killing the process.


Features

  • Fully configurable agents — names, instructions, models, and plugins defined in JSON; mix reasoning and non-reasoning models per agent
  • Pluggable selection strategies — sequential, round-robin, or LLM-driven selection
  • Flexible termination strategies — regex (e.g. APPROVED), max iterations, or composite
  • 9 built-in plugins — FileSystem, Shell, Git, Http, Json, Search, Probe, Plan, and CodeExecution (sandboxed REPL)
  • MCP server support — connect any Model Context Protocol server as a plugin; tools appear alongside built-in plugins and agents consume them transparently
  • Live cost tracking — per-turn and session totals with real estimated USD cost
  • Token budget cap — set MaxCostUsd in config to stop the session before it overspends
  • Human-in-the-loop (--hitl) — pause after any turn to inject context, redirect, or approve
  • Resumable sessions — full conversation history saved to ~/.fuseraft/sessions/ (owner-only permissions)
  • Built-in resilience — transient API errors (429, 502, 503, 504) are retried automatically with exponential back-off
  • API key validation — keys are verified against the provider before the session starts, not mid-run
  • Rich CLI experience — colour-coded panels, live spinner, markdown transcript export with costs
  • Cake-powered buildbuild.sh / build.ps1 with single-file publish support

Prerequisites

  • .NET 9 SDK
  • xAI API key (set as XAI_API_KEY environment variable)
export XAI_API_KEY=your_key_here

Tip: Use grok-4-1-fast-non-reasoning for action-heavy agents (those calling tools) and grok-4-1-fast-reasoning for judgment/approval roles. Reasoning models reject the Temperature parameter — omit it from the config when using them.


Quick start

# Restore tools and build
./build.sh

# Run the default software-development team
./bin/fuseraft run "Build a REST API in Go with JWT authentication"

CLI reference

fuseraft [command] [options]
Command Description
run [task] Start a new orchestration session (default)
sessions List, inspect, or delete checkpoints
plugins List available plugins and their functions
config [path] Display config as rich tables
validate [path] Validate a config file

fuseraft run examples

fuseraft run "Your task here"
fuseraft run --config config/examples/devops-team.json "Set up CI/CD for a Node.js app"
fuseraft run --resume                    # resume most recent incomplete session
fuseraft run --resume a1b2c3d4           # resume specific session
fuseraft run --hitl "Refactor the auth module"   # enable human-in-the-loop
fuseraft run --output transcript.md      # export full transcript with costs
fuseraft run --verbose --no-banner

fuseraft sessions

fuseraft sessions                          # list incomplete sessions
fuseraft sessions --all                    # include completed sessions
fuseraft sessions --delete a1b2c3d4        # delete a specific session
fuseraft sessions --delete all             # purge all completed sessions

fuseraft plugins

fuseraft plugins                           # list all plugins and their functions
fuseraft plugins --plugin Git              # filter to a specific plugin

fuseraft config / fuseraft validate

fuseraft config                            # show default config
fuseraft config config/examples/devops-team.json
fuseraft config --list                     # enumerate all configs under config/
fuseraft validate config/my-team.json
fuseraft validate config/my-team.json --strict   # also check plugin names

Configuration

Configs live under config/. The default is config/orchestration.json.

{
  "Orchestration": {
    "Name": "SoftwareDevelopmentTeam",
    "Description": "Developer writes code, Tester verifies, Reviewer approves.",

    "Agents": [
      {
        "Name": "Developer",
        "Description": "Senior software engineer.",
        "Instructions": "You are an expert software developer...",
        "Model": {
          "ModelId": "grok-4-1-fast-non-reasoning",
          "Endpoint": "https://api.x.ai/v1",
          "ApiKeyEnvVar": "XAI_API_KEY",
          "MaxTokens": 16384
        },
        "Plugins": ["FileSystem", "Shell", "Git", "Search"]
      },
      {
        "Name": "Reviewer",
        "Description": "Tech lead who approves changes.",
        "Instructions": "You are a senior tech lead...",
        "Model": {
          "ModelId": "grok-4-1-fast-reasoning",
          "Endpoint": "https://api.x.ai/v1",
          "ApiKeyEnvVar": "XAI_API_KEY",
          "MaxTokens": 8192
        },
        "Plugins": ["FileSystem", "Search"]
      }
    ],

    "Selection": {
      "Type": "sequential"
    },

    "Termination": {
      "Type": "composite",
      "MaxIterations": 30,
      "Strategies": [
        {
          "Type": "regex",
          "Pattern": "\\bAPPROVED\\b",
          "AgentNames": ["Reviewer"]
        }
      ]
    },

    "Compaction": {
      "TriggerTurnCount": 30,
      "KeepRecentTurns": 8
    },

    "MaxCostUsd": 3.00
  }
}

Token budget (MaxCostUsd)

Set MaxCostUsd to cap the total estimated spend for a session. After the turn that pushes cumulative cost over the limit, the session stops and the checkpoint is saved so it can be resumed later. Omit the field (or set it to null) for no limit.

Conversation compaction

Long sessions accumulate history that consumes tokens on every subsequent turn. Set Compaction to automatically summarise old turns with an LLM call when the history grows past a threshold, replacing the oldest turns with a single compact summary while retaining the most recent turns verbatim.

"Compaction": {
  "TriggerTurnCount": 30,
  "KeepRecentTurns": 8
}

TriggerTurnCount is the history length that triggers compaction. KeepRecentTurns is how many of the most recent turns to preserve unchanged. The cost of compacted turns is carried forward in the session total. Omit the section entirely to disable compaction.

Model selection: reasoning vs non-reasoning

xAI (and similar providers) offer two model variants per tier:

Variant Best for
grok-4-1-fast-non-reasoning Action agents that call tools repeatedly — Developer, Engineer, Tester, Researcher
grok-4-1-fast-reasoning Judgment agents that analyse and decide — Reviewer, Architect, Analyst

Reasoning models reject the Temperature parameter. Omit Temperature from the config (it defaults to null, which sends no value to the API) unless you are using a standard non-reasoning model that accepts it.

Security constraints

{
  "Orchestration": {
    "Security": {
      "FileSystemSandboxPath": "/path/to/project",
      "HttpAllowedHosts": ["api.github.com", "registry.npmjs.org"]
    }
  }
}

Both the FileSystem and Shell plugins enforce FileSystemSandboxPath — any path or working directory outside the tree is rejected. Http enforces HttpAllowedHosts and always blocks private/loopback addresses regardless of the allowlist.

Selection strategies

Type Description
sequential Agents take turns in the order they are defined
llm An LLM call picks the next agent each turn. Requires Prompt and Model

Termination strategies

Type Description
regex Stops when a message matches Pattern. Optionally scoped to AgentNames
maxiterations Stops after MaxIterations turns regardless of content
composite Stops when any child strategy in Strategies fires

Built-in plugins

Plugin Functions
FileSystem read_file, write_file, list_files, delete_file
Shell shell_run, shell_run_script, shell_get_env, shell_which, shell_pwd
Git git_status, git_diff, git_log, git_show, git_branch_list, git_add, git_commit, git_checkout, git_create_branch, git_init
Http http_get, http_post, http_put, http_delete, http_head
Json json_format, json_minify, json_get, json_keys, json_search, json_merge, json_to_text, json_validate
Search search_files, search_content, search_symbol
Probe probe_code, assert_output, compare_outputs, run_hypothesis
Plan plan_create, plan_get, plan_update_step, plan_add_step, plan_summary
CodeExecution check_docker, sandbox_run, repl_start, repl_exec, repl_reset, repl_stop

Add any plugin to an agent by listing its name in the Plugins array in the config.


MCP server support

Add any Model Context Protocol server as a plugin source. Servers are connected at session startup; their tools are registered as a KernelPlugin and agents reference them by name exactly like built-in plugins.

{
  "Orchestration": {
    "McpServers": [
      {
        "Name": "Filesystem",
        "Transport": "stdio",
        "Command": "npx",
        "Args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp/workspace"]
      },
      {
        "Name": "MyApi",
        "Transport": "http",
        "Url": "http://localhost:3000/sse"
      }
    ],
    "Agents": [
      {
        "Name": "Developer",
        "Plugins": ["Filesystem", "MyApi", "Git"]
      }
    ]
  }
}

MCP server config fields

Field Transport Description
Name both Plugin name used in agent Plugins lists
Transport both "stdio" (default) or "http"
Command stdio Executable to launch (e.g. "npx", "python")
Args stdio Arguments passed to the command
Env stdio Extra environment variables for the child process
WorkingDirectory stdio Working directory for the child process
Url http SSE endpoint URL (e.g. "http://localhost:3000/sse")

Stdio servers spawn a child process that is terminated when the session ends. HTTP servers connect to an already-running endpoint.


Example configs

Two ready-to-use configs are included under config/examples/:

File Team
devops-team.json Architect + Engineer (Shell/Git/FileSystem/Http) + Reviewer
research-team.json Researcher (Http/Json/FileSystem) + Analyst (FileSystem/Json)
fuseraft run --config config/examples/devops-team.json "Set up a CI/CD pipeline for a Node.js app"
fuseraft run --config config/examples/research-team.json "Summarize the latest .NET 9 release notes"

Session resumption

Every agent turn is checkpointed to ~/.fuseraft/sessions/<sessionId>.json immediately after it completes. Session files are written with owner-only permissions (0600 on Unix). If the process is killed mid-session the full conversation history is preserved on disk, and the team picks up from the exact turn it was interrupted on.

# Resume the most recent incomplete session interactively
fuseraft run --resume

# Resume a specific session by ID
fuseraft run --resume a1b2c3d4

# See what sessions are available
fuseraft sessions
fuseraft sessions --all

Token tracking and cost estimation

Input and output tokens as well as estimated cost are captured from the API response after every agent turn and shown inline in each message panel:

╭─ Developer  turn 3  2.1s  in:1,842 out:634  ~$0.0155 ─╮

The session summary table shows per-agent and total figures:

 Agent      Turns   Input tokens   Output tokens   Est. cost
 Developer    3        5,521           1,902         $0.0461
 Tester       2        4,108           1,245         $0.0309
 Reviewer     1        6,034             287         $0.0225
 Total        6       15,663           3,434         $0.0995

The pricing table is loaded at startup from ~/.fuseraft/pricing.json when that file exists, so you can update prices without recompiling. Copy config/pricing.json from the repo as a starting point — the format is a JSON object mapping model IDs to [inputPricePerMillion, outputPricePerMillion]. If the file is absent the built-in table is used. If a model is not listed, token counts are still shown but the cost column shows .

Token counts and cost are also written into markdown transcripts when --output is used.


Human-in-the-loop (HITL)

Run with --hitl to pause after every agent turn:

fuseraft run --hitl "Redesign the database schema"

After each turn a prompt appears:

  ↩ Enter to continue  ·  type a message to redirect  ·  q to stop:
Input Effect
Enter Continue — the next agent takes its turn as normal
Any text Inject — your message is added to the conversation as a Human turn; agents see it and respond to the redirect on the next round
q / quit Stop — the session is checkpointed and can be resumed later

Human injections are saved to the session checkpoint and replayed correctly if the session is resumed later.


Building

Linux / macOS

# full pipeline (clean, restore, build, test, publish)
./build.sh

# compile only
./build.sh --target=Build

# self-contained single-file archive
./build.sh --target=Pack --runtime=linux-x64

Windows

.\build.ps1
.\build.ps1 -Target Build
.\build.ps1 -Target Pack -Runtime win-x64

Direct Cake invocation

dotnet cake build.cake --target=Lint
dotnet cake build.cake --configuration=Debug

License

MIT

About

Multi-agent AI orchestration powered by Semantic Kernel and xAI Grok.

Resources

License

Stars

Watchers

Forks

Contributors

Languages