HarnessClaw Engine

August 11, 2026 · View on GitHub

License

English | 中文

An LLM programming assistant engine built with Go. It provides capabilities via the WebSocket protocol, supporting multi-turn dialogues, tool calling, permission control, and skill extension.

Architecture Overview

┌───────────-──┐   ┌─────────────┐   ┌─────────────┐
│  WebSocket   │   │    HTTP     │   │   Feishu    │
│  Channel     │   │   Channel   │   │  Channel    │
└──────┬───────┘   └──────┬──────┘   └──────┬──────┘
       │                  │                  │
       └──────────────────┼──────────────────┘

                ┌──────────────────┐
                │Router + Middleware│  Auth / RateLimit / Logging
                └────────┬─────────┘

                ┌──────────────────┐
                │   Query Engine   │  5-Phase Loop
                │  (queryloop.go)  │  Preprocessing → LLM Streaming → Error Recovery
                └───┬──────────┬───┘  → Tool Execution → Continuation Check
                    │          │
              ┌─────▼──-─┐  ┌──▼──────────┐
              │ Provider │  │ Tool System │
              │ (LLM)    │  │ 7 Built-in  │
              └───────-──┘  └─────────────┘

Dependency Direction: Channel → Router → Engine → Provider / Tool (Unidirectional, no circular dependencies)

Core Features

  • 5-Phase Query Loop — Preprocessing (Auto-compaction) → LLM Streaming Call → Error Recovery (Exponential Backoff) → Tool Execution (Parallel/Serial) → Continuation Check
  • WebSocket Protocol v2.2 (Card Model) — UI-first streaming: 8 actions (card.add/set/append/tick/close + prompt.user/reply + session.event) × 13 card kinds; server-side & client-side tool execution, permission / question / plan-review prompts, and crash-recovery of unanswered prompts
  • 7 Built-in Tools — Bash, FileRead, FileEdit, FileWrite, Grep, Glob, WebFetch
  • 6-Step Permission Pipeline — DenyRule → ToolCheckPerm → BypassMode → AlwaysAllowRule → ReadOnlyAutoAllow → ModeDefault, supporting 6 permission modes
  • Skill System — Loads skills from SKILL.md files, supporting YAML frontmatter, parameter substitution, and priority override
  • Multi-Provider Support — Direct Anthropic SSE client + Bifrost Multi-Provider adapter (Anthropic/OpenAI/Bedrock/Vertex)
  • Context Compaction — LLM-based conversation summarization + Circuit breaker pattern, automatically triggered when token usage reaches the threshold
  • Session Management — Thread-safe session state, multi-connection fan-out, idle timeout reclamation

Project Structure

go_rebuild/
├── cmd/server/           # Entry point & Integration tests
│   ├── main.go           # 11-step startup process
│   └── main_test.go      # E2E tests (build tag: integration)
├── configs/
│   └── config.yaml       # Default configuration
├── internal/
│   ├── channel/           # Multi-protocol access layer (WebSocket / HTTP / Feishu)
│   ├── command/           # Command registration & Priority system
│   ├── config/            # Viper configuration management (50+ defaults)
│   ├── engine/            # Core query engine
│   │   ├── queryloop.go   # QueryEngine main loop (831 lines)
│   │   ├── executor.go    # Parallel/Serial tool executor
│   │   ├── compact/       # LLM context compaction
│   │   ├── context/       # System prompt assembly
│   │   └── session/       # Session state & Lifecycle
│   ├── event/             # In-process pub/sub event bus
│   ├── permission/        # 6-step permission pipeline (6 modes)
│   ├── provider/          # LLM Provider abstraction
│   │   ├── anthropic/     # Direct Anthropic SSE client
│   │   ├── bifrost/       # Multi-Provider adapter
│   │   └── retry/         # Exponential backoff + 529 overload switching
│   ├── router/            # Message routing + Middleware chain
│   ├── skill/             # SKILL.md loading & Parameter substitution
│   ├── storage/           # Storage interfaces (Memory implementation)
│   └── tool/              # Tool system
│       ├── tool.go        # Tool interface + 10 extension interfaces
│       ├── registry.go    # Thread-safe tool registry
│       ├── pool.go        # Immutable per-query tool pool
│       └── bash/fileread/fileedit/filewrite/grep/glob/webfetch/skilltool/
├── pkg/
│   ├── types/             # Shared types (Message, Event, ToolCall, Context)
│   └── errors/            # Domain errors (16 error codes)
├── docs/
│   ├── protocols/         # WebSocket protocol specification (v2.2)
├── Makefile               # Build/Run/Test/Lint
└── go.mod                 # Go 1.26.1

Quick Start

Prerequisites

  • Go 1.26+
  • (Optional) golangci-lint — For code linting
  • (Optional) ripgrep — Runtime dependency for the Grep tool

Build & Run

# Build
make build              # Outputs to ./dist/harnessclaw-engine

# Run (using default configuration)
make run                # go run ./cmd/server -config ./configs/config.yaml

# Run directly with a specific configuration file
./dist/harnessclaw-engine -config ./configs/config.yaml

Testing

# Unit tests
make test               # go test ./... -v -race -count=1

# Coverage report
make test-cover         # Generates coverage.html

# Integration tests (requires real LLM API)
go test -tags=integration ./cmd/server/ -v
go test -tags=integration ./internal/provider/bifrost/ -v

Other Commands

make fmt                # Format code
make tidy               # Tidy go.mod
make lint               # Run linters
make vuln               # Scan for vulnerabilities
make clean              # Clean build artifacts

Configuration

The configuration file is located at configs/config.yaml. Main configuration items:

Configuration ItemDescriptionDefault Value
server.portHTTP server port8080
channels.websocket.portWebSocket port8081
channels.websocket.pathWebSocket path/v1/ws
llm.default_providerLLM Provideranthropic
llm.providers.anthropic.modelModel nameastron-code-latest
engine.max_turnsMax tool calls per turn50
engine.auto_compact_thresholdToken ratio threshold for auto-compaction0.8
session.idle_timeoutSession idle timeout30m
permission.modePermission modedefault
tools.*Individual tool togglesAll true

WebSocket Protocol

Connection Address: ws://host:8081/v1/ws

The protocol is a UI-first card model: the engine streams cards (a turn, a message, a tool call, a sub-agent, …) that are opened, appended to, and closed, rather than a flat event log.

Session Lifecycle

Client                                    Server
  │                                         │
  │── WebSocket upgrade ────────────────────>│
  │<──────────────── 101 Switching ─────────│
  │<──── session.event (kind=opened) ───────│  handshake + capabilities
  │                                         │
  │── user.message ─────────────────────────>│
  │<──────────────── card.add ──────────────│  open a card (turn / message / tool / …)
  │<──────────────── card.append ───────────│  stream content (channel: text / tool_input)
  │<──── prompt.user (permission / … ) ─────│  engine asks; blocks until answered
  │── prompt.user_response ─────────────────>│
  │<──────────────── card.close ────────────│  card done (+ metrics: tokens, cost)
  │<──────────── card.close (kind=turn) ────│  turn finished
  │                                         │
  │── session.interrupt (trace_id) ─────────>│  interrupt an in-flight turn
  │── session.resume  (last_seq) ───────────>│  reconnect & replay missed events

For a copy-paste client, see the Usage Examples; for the full wire contract, see docs/protocols/websocket.md.

Documentation

📞 Support

License

Apache-2.0 License. See LICENSE for details.