English · 简体中文
Open-source Thin Harness Engine — decouple Shell, Engine, Brain, and plugins with clear contracts.
Swap your Feishu bot without touching Brain. Swap your LLM without touching plugins.
Decisions live in Brain. Execution lives in plugins. Evidence lives in V. Routing lives in Engine.
In any AI application: who is allowed to decide? Who is allowed to execute? Where is the evidence chain when something fails?
Most projects slowly become monoliths — swap a channel and you rewrite Brain; swap a model and you touch plugins; when things break, no one can tell which layer failed. DeskHarness answers these questions as an Integration Harness — not an Agent framework, but an integration contract layer that does not build the "engine"; it defines standard interfaces and wiring between Shell, Brain, and plugins.
| LangChain / CrewAI, etc. | DeskHarness | |
|---|---|---|
| Core question | How should the LLM think and use tools? | How do we cleanly assemble thinking, tools, and channels? |
| Role | Provides engines and sensors | Defines the bus, interfaces, and wiring between them |
| Swappability | Swapping models/tools often means changing framework code | Swap models via brain.yaml; swap channels via Shell plugins |
Complementary, not competitive: run LangChain (or any stack) as your Brain service, then plug it into DeskHarness for orchestration and contracts — keep your reasoning layer, lose the framework lock-in.
Status: Phase 1 MVP and Phase 2 plugin system are done — plugin loader, webhook-generic Shell, docker compose minimal stack, and deskharness plugin new. Next: Phase 3 production hardening — see Roadmap.
OpenHarness and routes.yaml enforce a hard split between Brain (decide), plugins (execute), and Shell (present):
| Rule | Meaning |
|---|---|
| Brain does T+P only | Outputs target and plan; never touches the database |
| Plugins do A+V only | Change world state and return evidence; never pick the next hop |
| Engine does R only | Routes from verification evidence; no business branching |
| Shell converts only | Collects intent, renders replies; never calls Brain or plugins directly |
In multi-channel, multi-plugin setups, these guardrails keep the system from turning into spaghetti. Full anti-pattern list and review 5 questions live in doc/architecture/architecture.md.
Target · Plan · Action · Verify · Route is not just the shell around a Turn — it is a fractal structure from a plugin handler's internals, through a single command, up to a full conversation. Debug at any zoom level and you see the same skeleton. That consistency cuts cognitive load in large AI systems. See architecture §8 TPAVR.
Requires Python 3.11+.
git clone https://github.com/SynSwarm/DeskHarness.git
cd DeskHarness
pip install -e ".[dev]"
# Start Engine (falls back to configs/config.template.yaml if config.yaml is absent)
deskharness serveIn another terminal:
# Health check
curl -s http://127.0.0.1:8080/openharness/health
# Minimal invoke (golden fixture)
curl -s -X POST http://127.0.0.1:8080/openharness/invoke \
-H 'Content-Type: application/json' \
-d @schemas/openharness/fixtures/minimal-request.json
# Full turn: mock Brain → noop plugin (trigger word: trigger-noop)
curl -s -X POST http://127.0.0.1:8080/openharness/invoke \
-H 'Content-Type: application/json' \
-d '{"protocol_version":"1.0.0","request_id":"req_noop","request":{"context":{"session_id":"sess_noop","user_intent":"please trigger-noop"}}}'
# Webhook Shell (Phase 2)
curl -s -X POST http://127.0.0.1:8080/shells/webhook-generic/inbound \
-H 'Content-Type: application/json' \
-d '{"text":"Hello from webhook","session_id":"sess_demo"}'Run contract tests:
pytest tests/ -qDocker one-liner (from repo root):
docker compose -f examples/minimal/docker-compose.yml up --buildScaffold a plugin:
deskharness plugin new my-bot --type plugin
deskharness plugin new my-shell --type shellOptional: copy configs/config.template.yaml → configs/config.yaml for local overrides (gitignored). For rule-based Brain without an LLM, set brain.adapter: prompt-template and brain.template_file: ./configs/brain.prompt-template.yaml — see examples/minimal/.
Four layers, strict boundaries — no cross-layer shortcuts.
flowchart LR
subgraph Channels
IM[Feishu / Telegram / Webhook]
end
subgraph L1["Layer 1 · Shell"]
Shell[Shell plugin]
end
subgraph L2["Layer 2 · Engine"]
Engine[DeskHarness Engine<br/>Session · Routes · Dispatch]
end
subgraph L3["Layer 3 · Brain"]
Brain[Brain service<br/>T+P · stateless]
end
subgraph L4["Layer 4 · Plugin"]
Plugin[Business plugins<br/>A+V · CRUD / APIs]
end
subgraph Systems
ERP[ERP / DB / APIs]
end
IM --> Shell
Shell -->|OpenHarness| Engine
Engine -->|BrainRequest| Brain
Brain -->|BrainResponse| Engine
Engine -->|PluginCommand| Plugin
Plugin -->|PluginResult| Engine
Engine -->|OpenHarness| Shell
Plugin --> ERP
| Layer | Role | Examples |
|---|---|---|
| Shell | Collect intent, render replies; channel adapters | feishu-bot, webhook-generic |
| Engine | OpenHarness endpoint, session, routing, plugin gateway | app/ + core/ |
| Brain | LLM / RAG reasoning; outputs Target + Plan (T+P) | External HTTP service (LangChain works here) |
| Plugin | Mechanical execution; Action + Verify (A+V) | order-lookup, noop |
Rule of thumb: Brain thinks, plugins act, Engine orchestrates. Shell only talks to Engine via OpenHarness.
| Who | What you get |
|---|---|
| Enterprise architects / tech leads | A unified, governable AI integration base; anti-patterns and review 5 questions to prevent architectural rot |
| Senior backend engineers | Tired of wrestling inside frameworks? A thin core with clear boundaries and contract tests |
| Open-source contributors | Thin core, explicit extension points — low cost to ship a new Shell (Discord, Slack, Feishu) or Brain adapter |
| ✅ Good fit | ❌ Not a fit |
|---|---|
| Multi-channel bots (Feishu, Telegram, webhooks) sharing one Brain | Drag-and-drop Agent builder (try Dify, Coze) |
| Teams that want to swap LLM providers without rewriting plugins | All-in-one RAG + UI platform |
| SME deployments: single process, SQLite, no K8s required | Complex multi-agent reasoning graphs |
| Headless integration into existing backends | Replacing LangChain inside your Brain layer |
DeskHarness complements Agent frameworks — it sits at the integration and contract layer.
| DeskHarness | LangChain / CrewAI | Dify / FastGPT | n8n | |
|---|---|---|---|---|
| Core question | Who does what, with what contract? | How does the LLM think and call tools? | How do users build Agents in a UI? | How do I wire automations? |
| Analogy | Integration bus / contract layer | Engine and sensors | Full assembly line | Workflow orchestration |
| Brain / LLM | External HTTP service | Built-in chains & agents | Built-in model routing | Not the focus |
| Channels | Pluggable Shell plugins | Bring your own | Built-in apps | Connectors |
| Business logic | Plugin layer (A+V) | Tools / custom code | Workflow nodes | Workflow nodes |
| Session truth | Engine owns session_id |
Varies by framework | Platform-managed | Per-workflow |
| Deployment | Single process + KV | Library / varied | Managed or self-host | Self-host SaaS |
| UI | Headless (no UI) | None / optional | Full console | Visual editor |
Agent frameworks answer "how should the LLM reason?"
DeskHarness answers "who owns state, how do layers talk, where is the failure evidence, and how do we degrade gracefully?"
- Shell — disposable channel clients (Feishu, Telegram, webhooks)
- Engine — OpenHarness endpoint, session, routing (
app/+core/) - Brain — stateless cognition; structured T+P output
- Plugin — CRUD, APIs, automation hooks (A+V)
Engine does not think or act — it routes and holds session truth.
| Phase | Focus | Status |
|---|---|---|
| Phase 0 | Architecture, protocols, repo layout | ✅ Done |
| Phase 1 | Engine MVP — invoke → Brain → plugin loop | ✅ Done |
| Phase 2 | Plugin loader, Shell API, docker compose, scaffold CLI |
✅ Done |
| Phase 3 | Production — Redis KV, Docker image, acceptance agent, metrics | 🚧 Next |
| Phase 4 | Ecosystem — docs site, plugin SDK, more Shells | Planned |
Details: doc/roadmap/phase-plan.md · Progress: PROGRESS.md
| Topic | Link |
|---|---|
| Architecture (canonical) | doc/architecture/architecture.md |
| OpenHarness protocol | doc/specs/openharness-protocol.md · OpenHarness repo |
| Plugin TPAVR guide | doc/extension/plugin-tpavr-guide.md |
| Repo layout | STRUCTURE.md |
| Doc index | doc/README.md |
| Examples | examples/minimal/ · examples/feishu-order/ |
Issues and PRs welcome. Good starting points:
- Run
pytest tests/ -qbefore submitting - Read
STRUCTURE.mdfor layer boundaries (Engine must not contain business logic) - Plugin code should only depend on
pkg/ - New plugins/routes: pass the review 5 questions before merge
Apache License 2.0. See LICENSE.