DeepSeek Harness Plugin

omdsh-dev/dsh-auto-chess

Stars ★ 3 Category Just for Fun Added 2026-08-13

Auto chess: human vs AI, or AI vs AI.

Install

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:omdsh-dev/dsh-auto-chess

GitHub-sourced plugins run build scripts on your machine at install time. Only install sources you trust, and pin a commit (github:owner/repo#sha).

README

English · 中文

dsh-auto-chess

Tucked into the DSH tab bar is a tiny auto-chess table: take the blue side yourself and play a match against the AI, or lean back in the audience seat and watch two AIs, each on a model of its own choosing, slug it out on the board. No move here is free: every round's decision is a real model request. Crank the thinking level up to High or Max, open the reasoning log, and watch the AI work through who to buy, who to sell, which traits to chase, and whether that gold belongs in a level-up or a reroll. The result lands on the board; the reasoning stays in the log.

Game state lives in a module-level store in the browser: switching tabs or sessions never resets the match or interrupts an in-flight AI decision.

Key features

  • Human vs AI, or AI vs AI: play against the AI yourself (you take blue), or spectate two AIs dueling each other.
  • Independent model selection: blue and red each pick their AI from the model catalog (built-in adapters plus your configured providers/models); each side is configured separately, with blue's AI settings and reasoning log on the left of the UI and red's on the right.
  • Adjustable thinking levels: Off / High / Max, set per side, controlling how much each AI thinks before a decision; a level the model does not support falls back to its default automatically.
  • Fixed timeout and token cap: the per-decision deadline (default 300000 ms) and the output-token cap (default 32000) are deployment policy; the UI no longer exposes them, and the client sends the fixed values with every request.
  • Per-side editable prompts: the default system prompt ships with the full rules, a strict return format and one correct example; blue and red can edit their own prompt in their settings area and restore the default in one click.
  • Reasoning display: after every AI decision, the full reasoning text is available in the side's reasoning log (blue left, red right); entries start collapsed and expand on click.
  • Retry on failure: an illegal action batch is rejected with the reason and a retry button; transient streaming failures retry automatically within the attempt budget, so one hiccup never sinks the whole game.
  • Tab switches don't pause the match: the game and its battle animation are driven by the in-page module-level store; switching sessions or closing the tab won't interrupt AI thinking or the battle. The state lives only in page memory though: refreshing or closing the browser page resets the match.

Game rules (Minimal Auto Chess)

  • Board: each side has a 4×7 deployment grid, coordinates [row, col] (row 0-3, col 0-6), mirrored into a 4×14 battlefield for combat.
  • Unit pool: a shared pool of 24 units across 1/2/3 cost, each with HP, attack, attack speed, attack range, race, class and a skill.
  • Cost & star levels: three copies of the same unit at the same star level merge into the next star (1★→2★→3★; 2★≈1.8× stats, 3★≈3.24×). The merged unit keeps the id of the last unit consumed, so the AI can chain actions on it.
  • Traits: 11 races/classes, each triggering a bonus when a fielded-count threshold is met (e.g., 2/4 冰裔, 2/3 星灵, 2/4 法师); only deployed units count.
  • Round structure: prep phase (buy, merge, deploy, level up, reroll) → auto battle (a low-fidelity simulation at 0.5 s per tick) → settlement (damage, income, win/loss streaks).
  • Economy: base income 5 + interest min(gold÷10, 5) + streak bonus (2-win streak +1, 4-win +2, 6-win +3) + win +1; leveling costs 4 gold for 4 exp (exp needed = level + 2, level cap 8).
  • Winning & losing: both sides start at 100 HP; the loser takes damage equal to the enemy's surviving units ×2, and hitting zero loses the game.
  • Simplifications: no item system; combat is a low-fidelity simulation so LLMs can follow it and computation stays bounded.

Quick install

DSH's standard plugin mechanism is bundle → profile: the package declares dsh.bundle in package.json and ships a patch file (cordis.patch.yml); use dsh plugin to install it into any profile:

# Install from a local checkout (run inside the plugin directory; build lib/ first)
pnpm run build
dsh plugin --profile web add /Users/yejiming/Desktop/OpenSource/dsh-auto-chess

After installing, verify the config layer, then start (or restart) the Web UI:

dsh --profile web --dump-config   # the output should contain the auto-chess layer
dsh web                            # the 自走棋 tab appears in the session tab bar after the restart

The plugin is installed into the local web profile (~/.dsh/profiles/web, with @deepseek-ai/dsh-auto-chess in the bundle list as a link dependency). The Web process must restart to scan new client bundles and inject the client tab.

Remove: dsh plugin --profile web remove @deepseek-ai/dsh-auto-chess removes both the dependency and its layer.

Architecture

The game itself (state, economy, traits, battle simulation) lives in the browser UI; the server only arbitrates the AI's prep-phase decisions, so illegal replies are rejected server-side and can never corrupt the browser's game. The game engine (src/game/engine.ts) is pure TypeScript, dependency-free and deterministically shared: the server clones the full board state from each AI request, validates and applies the model's action batch with the exact same engine the browser uses, and returns the all-valid action list plus the reasoning text; the browser then applies the accepted actions to its own authoritative state with the same engine. The two sides can never drift.

Model calls

Auto-chess decision request (auxiliary)

What the model sees

Every AI decision is a standalone auxiliary request to the selected provider/model route. The system prompt is either the user-edited text or the package default (full rules, a strict JSON-array return format, a correct example, common mistakes, and basic strategy); the single user message carries the side's complete board state (HP, gold, exp/level, board cap, bench JSON, board layout JSON, active traits, shop JSON, last round's battle result, and the known enemy composition: fielded count, star distribution, race/class counts and rough power), plus, on retry, the previous illegal reply and its rejection reason. A decision request can also carry a thinking level (off/high/max): the server forwards it as the request's reasoning effort only when the selected model advertises support; unsupported levels fall back to the model's own default. Optional per-request actionTimeoutMs and maxActionOutputTokens overrides replace the config defaults for that request only. The reply's reasoning block is returned to the browser as the reasoning field alongside the action results.

The model returns a JSON array (at most 4 actions): {"action":"buy","name":"..."}, {"action":"sell","chess_id":N}, {"action":"move","chess_id":N,"pos":[r,c]}, {"action":"upgrade"}, {"action":"refresh"}, {"action":"end_prep"}. The server validates the whole batch (gold, bench cap, board cap, coordinates in range, occupied cells, id existence, etc.); any illegal action rejects the entire batch and retries with corrective feedback (default max 3 attempts); the final failure returns error with lastText/lastReason, and the browser shows the error plus a retry button.

Token effect

The auxiliary request spends tokens on constructing the state (roughly 1-2 KB of board text + system prompt + maxActionOutputTokens, default 32000). Thinking levels above off add reasoning tokens that count against the same output budget: reasoning models may spend most of the budget thinking, so a truncated reply still parses as long as the JSON array is complete; only lost JSON triggers a retry. The request is fully independent of any agent conversation and is never written to the session log.

KV cache effect

Auxiliary requests are standalone model requests; their prompts change with every board position, so there is no stable shared prefix with agent traffic. Editing the system prompt replaces the text wholesale, defeating provider-side cross-game prefix reuse; the default prompt stays stable only while unedited.

Configuration

All fields have loader defaults; there are no library-level defaults.

Key Description
actionTimeoutMs End-to-end deadline for one AI decision attempt (default 300000 ms, i.e. 5 minutes); the UI no longer offers an edit entry.
maxActionOutputTokens Output-token cap for one AI decision reply. Default 32000 (generous, because reasoning models count thinking against the output budget); truncated replies still parse while the JSON is complete, and only lost JSON triggers a retry. No longer editable in the UI.
maxActionAttempts Total AI attempts per decision request; the last attempt carries corrective feedback (default 3).

Development

pnpm run build          # tsdown builds the node half + the browser bundle and emits type declarations
pnpm run typecheck      # tsc --noEmit
pnpm test               # vitest: engine (economy/merge/battle/settlement), reply parsing, request validation, prompt assembly
node tests/e2e/gui-round.spec.mjs   # end-to-end: run one full round against a separate dsh web test instance (--port 3095; the plugin must be installed with a working model configured)

Local dependencies point at the Harness SDK checkout through symlinks (packages/* and vendor/* under ~/.dsh/source/current), the same approach as dsh-gomoku.

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →