Skip to content

manmit-s/flux-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

162 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Flux-CLI

An AI coding agent built from scratch β€” inspired by Claude Code CLI β€” with full multi-tool orchestration, streaming responses, sub-agent delegation, MCP server integration, and an interactive terminal UI.

🎯 Project Aim

This project is a learning initiative designed to understand and implement core concepts behind intelligent coding agents:

  • How AI agents reason about problems and select appropriate tools
  • Multi-tool orchestration β€” deciding which tools to use and in what order
  • Iterative refinement β€” analyzing code, identifying issues, and autonomously refactoring
  • Streaming capabilities β€” real-time response generation and token consumption
  • Error handling & resilience β€” retry logic, exponential backoff, graceful degradation
  • Async patterns β€” non-blocking operations for API calls and task orchestration
  • Context management β€” intelligent conversation history with automatic compression
  • Extensible tool system β€” plugin architecture with built-in, sub-agent, and MCP tools

πŸ“‹ Completed Features

1. LLM Client (AsyncOpenAI Integration)

  • βœ… Async OpenAI client with lazy initialization
  • βœ… Support for streaming and non-streaming responses
  • βœ… Stream event architecture (StreamEvent, TextDelta, TokenUsage)
  • βœ… Tool call streaming β€” incremental TOOL_CALL_START, TOOL_CALL_DELTA, TOOL_CALL_COMPLETE events
  • βœ… Error handling with retry logic:
    • Rate limit handling with exponential backoff
    • Connection error recovery
    • API error catching and reporting
  • βœ… Configurable API key via .env file
  • βœ… Support for different LLM providers (configurable base URL)
  • βœ… Tool schema building from tool definitions

2. Response Event System

  • βœ… Event-based architecture for streaming responses
  • βœ… Event types: TEXT_DELTA, TOOL_CALL_START, TOOL_CALL_DELTA, TOOL_CALL_COMPLETE, MESSAGE_COMPLETE, ERROR
  • βœ… Type-safe response events with usage tracking
  • βœ… Tool call delta tracking for incremental argument streaming
  • βœ… Consistent interface for both streaming and non-streaming modes

3. Async Generator Pattern

  • βœ… Unified caller interface using async for
  • βœ… Generator-based streaming with yield
  • βœ… Single entry point for different response modes

4. Agent Core & Event System

  • βœ… Agent orchestrator with async context manager support
  • βœ… Event-driven architecture with AgentEvent and AgentEventType
  • βœ… Event lifecycle: AGENT_START β†’ TEXT_DELTA Γ— N β†’ TOOL_CALL_START/COMPLETE Γ— N β†’ TEXT_COMPLETE β†’ AGENT_END
  • βœ… Error propagation through event system (AGENT_ERROR)
  • βœ… Full agentic loop with multi-turn tool calling
  • βœ… Message context storage via ContextManager
  • βœ… Tool call event streaming with result tracking
  • βœ… Maximum turns enforcement with graceful error reporting

5. Session Management

  • βœ… Session class orchestrating lifecycle of client, tools, context, and MCP
  • βœ… UUID-based session identification with timestamps
  • βœ… Turn counting and tracking
  • βœ… User memory persistence across sessions (JSON-based)
  • βœ… Initialization lifecycle: MCP β†’ Tool Discovery β†’ Tool Registration β†’ Context Setup

6. Configuration System

  • βœ… Pydantic-based hierarchical configuration (Config, ModelConfig, ShellEnvironmentPolicy, MCPServerConfig)
  • βœ… Multi-level config loading β€” system-level β†’ project-level β†’ CLI overrides
  • βœ… TOML-based configuration files (.flux-cli/config.toml)
  • βœ… Auto-detection of AGENT.md files for developer instructions
  • βœ… Configurable model, temperature, context window, max turns
  • βœ… Shell environment policy β€” secret masking, env variable setting
  • βœ… MCP server configuration with stdio and HTTP/SSE transport
  • βœ… Allowed tools restriction list
  • βœ… --cwd CLI option for working directory
  • βœ… Config validation on startup

7. Context Management

  • βœ… ContextManager with full message history tracking
  • βœ… Token counting per message
  • βœ… System prompt construction with identity, environment, tool guidelines, security
  • βœ… Automatic context compression trigger (80% of context window)
  • βœ… Smart tool output pruning β€” protects recent outputs, prunes older ones
  • βœ… Compression-aware continuation with context restoration
  • βœ… Usage tracking (latest_usage + total_usage)

8. Context Compression

  • βœ… ChatCompactor for summarizing conversation history
  • βœ… Smart history formatting for compression (truncates long tool outputs, assistant responses)
  • βœ… Structured compression output (original goal, completed actions, current state, remaining tasks)
  • βœ… Seamless continuation with "don't repeat completed actions" guard
  • βœ… Compression prompt with detailed template

9. Tool System Architecture

  • βœ… Abstract Tools base class with Pydantic schema validation
  • βœ… ToolKind enum β€” READ, WRITE, SHELL, NETWORK, MEMORY, MCP
  • βœ… ToolRegistry with registration, lookup, MCP tool segregation
  • βœ… ToolInvocation β€” parameter + cwd context for execution
  • βœ… ToolResult β€” standardized result with output, error, metadata, diff, truncation flag
  • βœ… FileDiff β€” unified diff generation for file operations
  • βœ… ToolConfirmation β€” confirmation model for mutating operations
  • βœ… Automatic OpenAI schema generation from Pydantic models (to_openai_schema())
  • βœ… ToolDiscoveryManager β€” auto-discovers custom tools from .ai-agent/tools/ directories
  • βœ… Parameter validation with descriptive error messages

10. Built-in Tools (11 Tools)

Tool Kind Description
read_file READ Read text files with line numbers, offset/limit, binary detection
write_file WRITE Create/overwrite files with automatic parent directory creation
edit WRITE Precise surgical text replacement with uniqueness checks
shell SHELL Command execution with timeout, blocked command safety, environment control
list_dir READ Directory listing with hidden file toggle
grep READ Regex search across files with case-insensitive option
glob READ File pattern matching with recursive ** support
web_search NETWORK DuckDuckGo web search integration
web_fetch NETWORK HTTP fetch with automatic fallback to proxy on 403/5xx
todos MEMORY Session-scoped task tracking (add/complete/list/clear)
memory MEMORY Persistent user memory stored across sessions

11. Sub-Agent System

  • βœ… SubAgentTool β€” spawns child agents for specialized tasks
  • βœ… SubAgentDefinition β€” name, description, goal prompt, allowed tools, timeout
  • βœ… codebase_investigator β€” explores code structure using read/grep/glob/list_dir (read-only)
  • βœ… code_reviewer β€” reviews code changes for bugs, security, improvements
  • βœ… Isolated context execution with turn and timeout limits
  • βœ… Result aggregation β€” tool calls made, final response, termination reason

12. MCP (Model Context Protocol) Integration

  • βœ… MCP server management with connect/disconnect lifecycle
  • βœ… Support for stdio transport (local processes) and SSE transport (remote servers)
  • βœ… Automatic tool registration from MCP server capabilities
  • βœ… Configurable startup timeout and environment variables
  • βœ… Health status tracking (disconnected/connecting/connected/error)
  • βœ… Graceful shutdown with resource cleanup

13. CLI & Terminal UI

  • βœ… Click-based CLI with command-line argument parsing
  • βœ… Rich terminal output with custom theme styling (16+ semantic styles)
  • βœ… Dual mode: single-prompt (python main.py "prompt") and interactive mode
  • βœ… Interactive commands: /exit, /help support
  • βœ… Real-time streaming text display with stream_assistant_delta()
  • βœ… Tool call panels β€” rich panels with tool name, call ID, arguments table, status
  • βœ… Tool result rendering β€” syntax-highlighted code, diffs, shell output, search results
  • βœ… Per-tool-kind border styling (read=cyan, write=yellow, shell=magenta, etc.)
  • βœ… Welcome panel with model info, cwd, and available commands
  • βœ… Error suppression for clean shutdown (unclosed resource warnings)

14. Prompt System

  • βœ… Comprehensive system prompt generation with multiple sections
  • βœ… Identity & role definition
  • βœ… Environment context (date, OS, working directory, shell)
  • βœ… Tool usage guidelines with best practices
  • βœ… AGENTS.md specification integration
  • βœ… Security guidelines (secrets, path validation, prompt injection defense)
  • βœ… Operational guidelines (tone, primary workflows, error recovery)
  • βœ… Developer instructions (from config/AGENT.md)
  • βœ… User instructions support
  • βœ… User memory injection
  • βœ… Tool list auto-generation with descriptions

15. Utility Modules

  • βœ… utils/paths.py β€” path resolution, relative display, parent directory creation, binary file detection
  • βœ… utils/text.py β€” token counting (tiktoken), text truncation by tokens/lines/characters
  • βœ… utils/errors.py β€” AgentError and ConfigError with structured error details

πŸ“ Project Structure

flux/
β”œβ”€β”€ main.py                      # CLI entry point with Click, interactive/single modes
β”œβ”€β”€ agent/
β”‚   β”œβ”€β”€ agent.py                # Agent orchestrator with multi-turn agentic loops
β”‚   β”œβ”€β”€ events.py               # AgentEvent, AgentEventType (lifecycle + tool call events)
β”‚   └── session.py              # Session: client + registry + context + MCP lifecycle
β”œβ”€β”€ client/
β”‚   β”œβ”€β”€ llm_client.py           # AsyncOpenAI wrapper with streaming, retry, tool call support
β”‚   └── response.py             # StreamEvent, TextDelta, TokenUsage, ToolCall types
β”œβ”€β”€ config/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ config.py               # Pydantic Config, ModelConfig, ShellEnvironmentPolicy, MCPServerConfig
β”‚   └── loader.py               # TOML config loading, multi-level merge, AGENT.md detection
β”œβ”€β”€ context/
β”‚   β”œβ”€β”€ compaction.py           # ChatCompactor β€” context summarization when limit is hit
β”‚   └── manager.py              # ContextManager β€” message history, tokens, pruning, compression
β”œβ”€β”€ prompts/
β”‚   └── system.py               # System prompt generation (identity, tools, security, guidelines)
β”œβ”€β”€ tools/
β”‚   β”œβ”€β”€ base.py                 # Tools ABC, ToolInvocation, ToolResult, FileDiff, ToolKind
β”‚   β”œβ”€β”€ registry.py             # ToolRegistry, create_default_registry
β”‚   β”œβ”€β”€ discovery.py            # ToolDiscoveryManager β€” custom tool auto-discovery
β”‚   β”œβ”€β”€ subagent.py             # SubAgentTool, SubAgentDefinition, default definitions
β”‚   β”œβ”€β”€ builtin/
β”‚   β”‚   β”œβ”€β”€ __init__.py         # Tool exports and get_all_builtin_tools()
β”‚   β”‚   β”œβ”€β”€ read_file.py        # File reading with line numbers, offset, binary detection
β”‚   β”‚   β”œβ”€β”€ write_file.py       # File creation/overwrite with diff tracking
β”‚   β”‚   β”œβ”€β”€ edit_file.py        # Surgical text replacement with uniqueness validation
β”‚   β”‚   β”œβ”€β”€ shell.py            # Command execution with timeout, safety blocks
β”‚   β”‚   β”œβ”€β”€ list_dir.py         # Directory listing
β”‚   β”‚   β”œβ”€β”€ grep.py             # Regex file search
β”‚   β”‚   β”œβ”€β”€ glob.py             # Glob pattern file matching
β”‚   β”‚   β”œβ”€β”€ web_search.py       # DuckDuckGo search integration
β”‚   β”‚   β”œβ”€β”€ web_fetch.py        # HTTP fetch with proxy fallback
β”‚   β”‚   β”œβ”€β”€ todo.py             # Session-scoped task tracking
β”‚   β”‚   └── memory.py           # Persistent user memory
β”‚   └── mcp/
β”‚       β”œβ”€β”€ client.py           # MCPClient β€” stdio/SSE transport, tool listing, invocation
β”‚       β”œβ”€β”€ mcp_manager.py      # MCPManager β€” server lifecycle, tool registration
β”‚       └── mcp_tool.py         # MCPTool adapter β€” wraps MCP tools in Tool interface
β”œβ”€β”€ ui/
β”‚   └── tui.py                  # TUI with Rich themes, tool panels, streaming, syntax highlighting
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ errors.py               # AgentError, ConfigError
β”‚   β”œβ”€β”€ paths.py                # Path resolution, binary detection, directory creation
β”‚   └── text.py                 # Token counting, text truncation
β”œβ”€β”€ .env                        # API keys and configuration (git-ignored)
β”œβ”€β”€ .gitignore
└── README.md

πŸ”§ Setup & Usage

Prerequisites

  • Python 3.10+
  • OpenRouter API key (or other OpenAI-compatible API)

Installation

# Clone the repository
git clone https://github.com/yourusername/flux.git
cd flux

# Create virtual environment
python -m venv .venv

# Activate virtual environment
# On Windows:
.venv\Scripts\activate
# On macOS/Linux:
source .venv/bin/activate

# Install dependencies
pip install openai python-dotenv pydantic httpx rich click tiktoken platformdirs tomli duckduckgo-search fastmcp

Configuration

Create a .env file in the project root:

API_KEY=your_api_key_here
BASE_URL=https://openrouter.ai/api/v1  # Optional, default for OpenRouter

Or use a TOML config file at ~/.config/flux-cli/config.toml:

[model]
name = "mistralai/mistral-small-2603"
temperature = 1.0
context_window = 256000

max_turns = 100

[shell_environment]
exclude_patterns = ["*KEY", "*TOKEN", "*SECRET"]

Project-level config goes in .flux-cli/config.toml relative to CWD.

Running

# Single prompt mode
python main.py "Find all Python files and count the lines"

# Interactive mode (REPL)
python main.py

# Specify working directory
python main.py --cwd /path/to/project "Analyze this codebase"

# Interactive commands:
#   /help     - Show help
#   /exit     - Exit the CLI

🎨 Terminal UI Highlights

The TUI (ui/tui.py) provides a rich terminal experience:

  • Welcome Panel: Contextual startup info with model, CWD, and available commands
  • Streaming Text: Real-time assistant response display
  • Tool Call Panels: Each tool invocation gets a styled panel with:
    • Tool name and short call ID
    • Arguments table (ordered by most important params)
    • Running/done status indicators
    • Kind-based border styling (read=cyan, write=yellow, shell=magenta, network=blue, memory=green, mcp=cyan)
  • Result Rendering:
    • read_file β†’ Syntax-highlighted code with line numbers
    • write_file/edit β†’ Unified diff display
    • shell β†’ Command echo + output with exit code
    • grep β†’ Match count summary + results
    • web_search/web_fetch β†’ Summary with status, results count
  • Truncation Warnings: When tool output exceeds token limits

πŸ“š Key Concepts Explored

1. Async Generators

Why use yield in async functions? Creates a consistent interface where callers always use async for, regardless of streaming mode. Both streaming and non-streaming LLM responses yield events through the same channel.

2. Error Resilience

Implemented retry logic with exponential backoff for:

  • Rate limiting (429 errors)
  • Connection issues
  • API errors

3. Type Safety

Using Python type hints and Pydantic throughout to catch issues early:

  • AsyncGenerator[StreamEvent, None]
  • AsyncOpenAI | None
  • Pydantic BaseModel for all tool parameters
  • Strict validation with descriptive error messages

4. Lazy Initialization

API client is only created when first needed, reducing startup overhead.

5. Context Compression

Automatic conversation summarization when approaching context window limits. Uses a child LLM call to create a structured continuation prompt that preserves goal, completed actions, and remaining tasks.

6. Plugin Architecture

Three-tier tool system:

  • Built-in β€” core tools for file operations, code search, web access
  • Sub-agents β€” spawned child agents with isolated context for specialized tasks
  • MCP β€” external tool servers via Model Context Protocol

7. Config Layering

Configuration is merged from multiple sources with increasing priority: System config β†’ Project config β†’ CLI arguments

πŸ“‹ Next Steps

  1. User Approval System: Implement tool call approval workflow for mutating operations
  2. Multi-turn Conversation Persistence: Full conversation history across CLI sessions
  3. Code-aware Editing: AST-based code operations for safer refactoring
  4. Plugin Hot-Reloading: Dynamic tool registration without restart
  5. Performance Optimizations: Token caching, response caching, parallel tool execution
  6. Testing Suite: Comprehensive unit and integration tests
  7. Configuration UI: Interactive config wizard for first-time setup
  8. Documentation Site: Full API docs with examples

πŸ‘¨β€πŸ« Credits

Inspired by and learning from:

🀝 Contributing

This is a personal learning project, but feel free to fork and experiment!


Note: This project is actively being developed as a learning exercise. Expect API changes and refactoring as new features are added.

About

An AI agent framework built from scratch to understand LLM reasoning, multi-tool orchestration, and iterative code refinement. Features async streaming, event-based architecture, and resilient error handling with retry logic.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages