Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sword Agent

An AI-powered coding assistant built with the Eino framework and a TUI interface.

This project extracts and ports the core concepts from Zed Editor's native agent system:

  • Native Agent: AI coding assistant with ReAct loop (via Eino ADK)
  • Model Configuration: Multiple LLM provider support (OpenAI, Anthropic, Ollama)
  • ACP Protocol: Agent Communication Protocol for session management
  • Coding Tools: File operations, terminal commands, search, and more
  • TUI Interface: Interactive terminal user interface with a fixed bottom input line and scrollable conversation area

Architecture

sword-agent/
├── cmd/sword-agent/        # CLI entry point
│   └── main.go
├── internal/
│   ├── acp/                # ACP Protocol (Agent Communication Protocol)
│   │   ├── types.go        # Core types (Message, Session, Stream)
│   │   └── server.go       # ACP server and connection management
│   ├── agent/              # Core agent (Eino-based)
│   │   ├── agent.go        # CodingAgent - main agent with ReAct loop
│   │   └── models.go       # LLM provider integration
│   ├── config/             # Configuration management
│   │   └── config.go       # ConfigManager, profiles, models
│   ├── tools/              # Coding tools
│   │   ├── impl.go         # Tool implementations
│   │   └── eino_tools.go   # Eino tool wrappers
│   └── tui/                # Terminal user interface
│       └── tui.go          # REPL TUI
├── Makefile
├── go.mod
└── go.sum

Prerequisites

  • Go 1.26+ (required by dependencies)
  • API keys for your chosen LLM provider

Quick Start

1. Build

make build

2. Install to user PATH

make install

This overwrites ~/.local/bin/sword-agent and installs ~/.local/bin/sword-agent-mcp on every install, then updates your shell startup file with a managed PATH block. You can override the install directory or rc file:

make install INSTALL_DIR="$HOME/bin"
CODING_AGENT_SHELL_RC="$HOME/.zshrc" make install

Restart your shell after installing, or source the rc file printed by the installer.

3. Set API Keys

export OPENAI_API_KEY="sk-..."      # For OpenAI models
export ANTHROPIC_API_KEY="sk-..."   # For Anthropic/Claude models

4. Run

# Interactive TUI mode
./sword-agent

# Installed command
sword-agent

# Single query mode
./sword-agent -q "read the main.go file"

# Serve ACP JSON-RPC over stdio
./sword-agent -acp-stdio

# Serve a Codex-compatible MCP bridge for sword-agent ACP
./sword-agent-mcp --agent sword-agent

# Specify a model
./sword-agent -model "gpt-4o"

# List available models
./sword-agent -list-models

Features

Coding Tools

Tool Description
read_file Read file contents
write_file Write content to a new file
edit_file Edit files via precise text replacement
run_terminal Execute terminal commands
bash Execute bash commands
grep Search files with regex patterns
list_directory Explore directory structure
glob Find files by glob pattern
find_path Find files by name pattern
fetch Make HTTP requests to URLs; responses over 16KiB are previewed inline and saved under tool-cache/fetch
move_path Move or rename files/directories
delete_path Delete files/directories
create_directory Create new directories
copy_path Copy files or directories
diagnostics Read language-server diagnostics
find_references Find symbol references via LSP
go_to_definition Resolve symbol definitions via LSP
rename_symbol Rename symbols via LSP
create_thread Create an isolated child session
spawn_agent Run a sub-task in a child session and return the result
skill Load reusable instructions from SKILL.md files in the Agent Skills catalog

Supported LLM Providers

Provider Config Key Env Var
OpenAI openai OPENAI_API_KEY
Anthropic (Claude) anthropic ANTHROPIC_API_KEY
Google (Gemini) google GEMINI_API_KEY
DeepSeek deepseek DEEPSEEK_API_KEY
DeepSeek WebSearch deepseek_search DEEPSEEK_SEARCH_API_KEY
Mistral mistral MISTRAL_API_KEY
Amazon Bedrock amazon-bedrock AWS credentials
xAI (Grok) x_ai XAI_API_KEY
OpenRouter openrouter OPENROUTER_API_KEY
Vercel AI Gateway vercel_ai_gateway VERCEL_AI_GATEWAY_API_KEY
Ollama (local) ollama -
LM Studio (local) lmstudio -
OpenAI Compatible openai_compatible OPENAI_COMPATIBLE_API_KEY
Anthropic Compatible anthropic_compatible ANTHROPIC_COMPATIBLE_API_KEY

Configuration

Configuration is stored at ~/.config/sword-agent/sword-agent.json. You can manage:

  • Models: Add/remove LLM providers
  • Profiles: Named configurations with different model/tool combinations
  • Tool Permissions: Control which tools are enabled per profile

Internal debug logging is disabled by default. To capture provider / stream diagnostics, start the CLI with CODING_AGENT_DEBUG_LOG=/path/to/debug.log. Use CODING_AGENT_DEBUG_LOG=stderr to print internal logs to stderr.

DeepSeek WebSearch

web_search can use DeepSeek's hosted Anthropic-compatible WebSearch backend. This uses an independent search key so the search tool does not automatically inherit your normal DeepSeek model API key.

Set it in the TUI:

/key deepseek_search <your DeepSeek Search API key>

Or use an environment variable:

export DEEPSEEK_SEARCH_API_KEY="<your DeepSeek Search API key>"

The configuration file field is:

{
  "providers": {
    "deepseek": {
      "search_api_key": "<your DeepSeek Search API key>"
    }
  }
}

Optional environment variables:

export DEEPSEEK_SEARCH_BASE_URL="https://api.deepseek.com/anthropic"
export DEEPSEEK_SEARCH_MODEL="deepseek-v4-flash"

You can verify the hosted WebSearch endpoint directly with curl:

curl -sS https://api.deepseek.com/anthropic/v1/messages \
  -H "Authorization: Bearer ${DEEPSEEK_SEARCH_API_KEY}" \
  -H "Content-Type: application/json" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "deepseek-v4-flash",
    "max_tokens": 1200,
    "messages": [
      {
        "role": "user",
        "content": "Search the web for best Rust tutorials. Return titles and URLs."
      }
    ],
    "tools": [
      {
        "type": "web_search_20250305",
        "name": "web_search",
        "max_uses": 3
      }
    ],
    "tool_choice": {
      "type": "tool",
      "name": "web_search"
    }
  }' | jq '.content'

When configured, web_search uses DeepSeek hosted WebSearch. If no DeepSeek search key is configured, it falls back to the built-in DuckDuckGo lite search. If a search key is configured but the DeepSeek request fails, web_search returns that DeepSeek error instead of silently falling back.

DeepSeek/Anthropic search results may include an encrypted_content field for server-tool continuation. sword-agent treats WebSearch as a client-side tool, so it intentionally discards that encrypted field and only returns readable titles, URLs, and summaries to avoid polluting the conversation context.

Codex MCP Bridge

sword-agent-mcp exposes a typed MCP server that starts sword-agent -acp-stdio lazily and forwards tool calls through ACP:

[mcp_servers.sword_agent_acp]
command = "/home/projectdata/other/einoresearch/sword-agent/sword-agent-mcp"
args = ["--agent", "sword-agent"]
startup_timeout_sec = 20
tool_timeout_sec = 600
enabled = true

The MCP server intentionally does not fix a global working directory. Codex passes work_dir in each tool call, for example:

{
  "work_dir": "/home/projectdata/other/einoresearch/sword-agent",
  "prompt": "读取 README 并总结可用命令"
}

Available MCP tools:

  • sword_agent_new_session
  • sword_agent_prompt
  • sword_agent_list_sessions
  • sword_agent_load_session
  • sword_agent_compact_session
  • sword_agent_close_session

By default the bridge rejects ACP session/request_permission prompts to avoid unexpected file writes. For a trusted call, pass "permission_policy": "allow" to sword_agent_prompt, or start the server with --permission-policy allow.

Commands

While in the TUI:

  • /help - Show available commands
  • /clear - Clear the terminal only; keep the current conversation context
  • /new - Start a new conversation with an empty session context
  • /resume [session-id] - Open a conversation picker (↑/↓ + Enter), or switch directly
  • /undo - Open a user-message picker and remove the selected input plus everything after it
  • /compact - Summarize older conversation context into a compact handoff
  • /rewind - Restore the latest file checkpoint for the current conversation
  • /close [session-id] - Close a conversation; when omitted, close current
  • /delete <session-id> - Alias for closing a saved conversation
  • /model [name] - Switch model
  • /provider [name] - List models for a provider
  • /profile [name] - Switch profile
  • /key <provider> <key> - Set API key for a provider
  • /key deepseek_search <key> - Set the independent DeepSeek WebSearch key
  • /exit - Exit
  • Ctrl+C - Cancel the running turn first; press again while idle to exit

The REPL keeps one active session at a time. Messages, assistant tool calls, tool results, and final answers are recorded in that session and sent back on the next turn, while /new creates a separate empty session. This mirrors the basic Zed Agent thread model: context is continuous inside one thread and isolated between threads. Sessions are persisted under sessions/ next to the main config file: sessions/index.json tracks project/session metadata, and each conversation is stored as its own JSON file under the project bucket. The old top-level sessions.json is migrated on first load and then left in place as a legacy backup. /resume only shows conversations for the current project directory. Use /close [session-id] to remove a conversation from the active session index. File-modifying tools record in-memory checkpoints before they write. /rewind restores the latest checkpoint for the active conversation and truncates the conversation messages after that checkpoint. Use /undo when you sent the wrong prompt and want to return to an earlier user input before rewriting it. ACP/JSON-RPC clients can also call session/truncate with a message_id (or user_message_id) to remove that user message and all later messages without restoring files. Use session/rewind when file checkpoint restoration is required, and session/retry to continue the latest interrupted context. Long conversations are compacted automatically before they approach the model context window, using the same handoff-summary strategy as Zed Agent. You can also type /compact to compact manually. Configure the threshold in sword-agent.json:

{
  "auto_compact": {
    "enabled": true,
    "threshold": "90%"
  }
}

threshold accepts a percentage ("90%"), used tokens ("100000"), or remaining tokens ("-20000").

Sessions and Repository Instructions

  • Session IDs are generated from a monotonic counter, so closing one session will not cause the next session to overwrite another live session.
  • Sessions are saved to a local JSON store using atomic file replacement, so process restarts do not erase conversation context.
  • Stored messages carry stable message IDs, which lets ACP clients truncate a conversation at an exact user-message boundary.
  • Turns inside the same session are queued. Concurrent sends cannot build a prompt from stale history.
  • Closing a session cancels the active turn before removing it from the session map.
  • Canceling a turn keeps the session and its previous history intact. This is what the REPL does when Ctrl+C is pressed during streaming output.
  • The active work directory is injected per turn, so tools and prompt context stay aligned even when different sessions use different directories.
  • AGENTS.md or Agents.md in the work directory is injected transiently into the model input. It is not persisted into conversation history.
  • Agent Skills are discovered each turn from built-ins, ~/.agents/skills, and <work_dir>/.agents/skills. The model sees a compact catalog and uses the skill tool to load full SKILL.md instructions on demand.
  • create_thread creates a real isolated session. spawn_agent creates a child session, runs the task, and returns the child result to the parent turn.
  • run_terminal supports terminal lifecycle actions. The default action runs a command and waits for completion; action=start returns a terminal_id for a long-running process, and action=read, action=wait, action=kill, and action=release manage that terminal. Terminals created during a turn are recorded in checkpoints so /rewind can release terminals from reverted work.

Porting from Zed Agent

This project extracts and ports the following from Zed's agent system:

  1. NativeAgent → CodingAgent: The core agent orchestrator
  2. AgentConnection → ACP types: Protocol layer for agent communication
  3. AgentSettings → ConfigManager: Model and profile configuration
  4. Tools: File operations, terminal, search tools
  5. Agent Panel → TUI: Terminal-based user interface

Key differences from Zed's implementation:

  • Uses Eino framework (Go) instead of Rust
  • Uses REPL TUI instead of GPUI
  • Includes an in-process ACP API and a newline-delimited stdio JSON-RPC transport via -acp-stdio; advanced Zed ACP capabilities such as auth, session modes, and config options are still simplified
  • Modular architecture with clear separation of concerns

About

sword-agent

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages