CH·02CLI reference

deeprelay setup deepseek-harness

Point DeepSeek Harness at deeprelay

Point DeepSeek Harness at deeprelay

Synopsis

Points DeepSeek Harness, DeepSeek's open-source agent (the desktop app, dsh web and dsh --profile headless), at deeprelay. After it runs, DeepSeek Harness has a deeprelay model provider that sends its requests to deeprelay's Anthropic-compatible /v1/messages endpoint, and new sessions start on a deeprelay model.

This is DeepSeek Harness (github.com/deepseek-ai/deepseek-harness), not Deep Code. For Deep Code, see deeprelay setup deep-code.

What it writes

DeepSeek Harness keeps one configuration file per profile: cordis.patch.yml in ~/.dsh/profiles//, or under the directory $DSH_HOME names. Setup writes the profiles that exist: desktop (the app), web (dsh web) and headless (dsh --profile headless). DeepSeek Harness creates a profile the first time that surface starts. If none exists yet, setup stops and asks you to open the app (or run dsh web) once.

The file is a list of rows, each keyed by id. Setup adds one provider, deeprelay, to the llm-pi-ai row. This is the same place the app's Settings → Models → Add model provider → Custom model API form saves to. Setup also points the agent-default-model row at it:

- id: llm-pi-ai
  config:
    providers:
      deeprelay:
        displayName: deeprelay
        apiKeyEnv: DEEPRELAY_API_KEY
        api: anthropic-messages
        baseURL: https://api.deeprelay.ai
        reasoning: high
        models:
          - id: deeprelay/deepseek-v4.1-flash
            contextWindow: 1048576
            maxTokens: 393216
            reasoningEfforts:
              off: none
              low: low
              medium: medium
              high: high
- id: agent-default-model
  config:
    provider: deeprelay
    model: deeprelay/deepseek-v4.1-flash

There is one models entry for every model in deeprelay's list of models tested with coding agents. id is the exact deeprelay model ID, which DeepSeek Harness sends unchanged. contextWindow and maxTokens come from the deeprelay catalog, and either is left out when the catalog does not list it.

reasoningEfforts gives the model an Effort menu in the model picker. Without it, DeepSeek Harness never asks a hand-added model to think. reasoning: high is the effort a session uses until you pick one.

Both are written only for models the catalog lists with reasoning efforts.

baseURL is the API base setup runs against (--api-base, or DEEPRELAY_API_BASE) without /v1: DeepSeek Harness appends /v1/messages itself.

The rest of the file is left alone:

  • every other row, including the - insert: rows;
  • the other providers in the llm-pi-ai row;
  • comments, blank lines and !!js expressions.

Setup never changes DeepSeek Harness's built-in DeepSeek provider, so your own DeepSeek key keeps working beside deeprelay.

This shape was checked on 2026-10-08 with DeepSeek Harness 0.2.0-rc.2: coding tasks ran on deeprelay models, with thinking on.

Your key never lands in a file

apiKeyEnv holds the name of an environment variable, DEEPRELAY_API_KEY, not the key. DeepSeek Harness reads the key from that variable on every request.

To set the variable, add this line to your shell rc (~/.zshrc, ~/.bashrc). Setup and --print print it with the absolute path of your deeprelay binary:

export DEEPRELAY_API_KEY="$('/usr/local/bin/deeprelay' auth token)"

The desktop app reads your login shell's environment when it starts, so it sees the variable even when you open it from the Dock. Quit and reopen it after adding the line.

Each new shell runs deeprelay auth token, which reads your key from the deeprelay credentials file (deeprelay login). The key is never stored in your rc file, cordis.patch.yml, the setup record or a backup. If DEEPRELAY_API_KEY is not set when you run setup, setup warns and prints this line.

Modes

  • Default: writes the provider and the default model into every existing profile. Asks before writing.
  • --model : writes only that model instead of the curated list. It must exist on deeprelay and support tool calling.
  • --print: writes nothing. It prints the snippet and the export line, so you can merge them into a profile's cordis.patch.yml yourself.
  • --refresh: rewrites the provider's models and baseURL from the current list. It needs an earlier setup, and it shows a diff and backs up each file like setup does.
  • --remove: undoes a previous setup (see below).
  • --force: with --yes, replaces setup's provider even if you edited it (see below).

Before anything is written

Setup resolves your key the way deeprelay auth token does: from DEEPRELAY_API_KEY if it is set, or else from the credentials file. It reads the model list from GET /v1/models and checks that each model exists and supports tool calling. It makes no billed call.

Setup then shows a diff per file and the undo command, and asks you to confirm. --yes skips the prompt for scripts. If stdin is not a terminal and you did not pass --yes, setup stops without writing. If nothing would change, setup says DeepSeek Harness is already configured.

Setup owns the deeprelay provider. If you edited it after setup (changed baseURL on the Models page, say), a run asks before replacing your edit. --yes alone leaves the edited provider alone and leaves the default model as it is. It writes everything else and exits non-zero. --yes --force replaces it.

Setup warns when ~/.dsh/cordis.patch.yml has an llm-pi-ai or agent-default-model row. That home-level file applies to every profile and wins over the profile files setup writes.

If setup cannot follow a file (a comment it could not keep, or YAML anchors), it stops with an error and writes nothing. It also stops if a value it has not written before holds a !!js expression, such as a default model read from an environment variable. --remove could not put the expression back, so change that row by hand. A !!js expression you put inside setup's own deeprelay provider is an edit like any other: left alone under --yes, replaced under --force.

Backups and undo

Before each write, setup copies the existing file into backups/deepseek-harness/ in the deeprelay config directory (the one holding your credentials file). It also records what it added or changed, and the earlier values, per profile in the setup directory next to it.

deeprelay setup deepseek-harness --remove replays that record for every profile:

  • the provider is deleted if it still holds what setup wrote, and a row left empty goes with it;
  • the default model selection (the agent-default-model row's whole config) goes back to what it was. If you picked a model or an effort in the app since, your selection is left as it is, with a warning. If it names a deeprelay model, pick another model once the provider is gone;
  • a provider you edited after setup is left alone, with a warning.

A profile file left with no rows becomes [], never empty, because DeepSeek Harness will not start on an empty file. Running --remove again, or when setup never ran, reports "nothing to remove" and exits 0.

Default model

The default model is the first one in deeprelay's list of models tested with coding agents. A model covered by your plan comes first. Every other model on the list is in the model picker. Picking one there saves it, with its effort, as the default for new sessions. Setup writes that selection as a whole: a later setup run sets it back to the first model, with no effort saved, and shows that in its diff.

Examples

# Configure DeepSeek Harness (asks before writing)
deeprelay setup deepseek-harness

# No prompt
deeprelay setup deepseek-harness --yes

# Only one model
deeprelay setup deepseek-harness --model deeprelay/deepseek-v4-pro

# Print the snippet and the shell rc line
deeprelay setup deepseek-harness --print

# Undo
deeprelay setup deepseek-harness --remove

# One-shot run on deeprelay, once set up
dsh --profile headless "run the tests and fix what fails"
deeprelay setup deepseek-harness [flags]

Options

      --force          With --yes, replace a setup-owned entry you have edited since the last run
  -h, --help           help for deepseek-harness
      --model string   Use this model instead of the curated list
      --print          Print the config snippet and export line instead of writing any file
      --refresh        Re-sync the configured models from the curated list
      --remove         Undo a previous setup entry by entry
      --yes            Apply without the confirmation prompt (warnings still print)

Options inherited from parent commands

      --api-base string   API base URL (override with DEEPRELAY_API_BASE env) (default "https://api.deeprelay.ai/v1")
      --debug             Enable debug logging to stderr
      --no-preflight      Skip the plan/credit check before inference requests (override with DEEPRELAY_NO_PREFLIGHT env)
  -o, --output string     Output format: table|json (default table on TTY, json otherwise) (default "table")

SEE ALSO

← The gpu CLI