Skip to content
dsh.fish
Bundle

@dsh-polyglot/bundle

dsh-polyglot — the model switch for DSH: one generic OpenAI-compatible ctx.llm adapter, curated free/cheap DeepSeek provider presets, and automatic provider fallback when a free tier rate-limits you

Source
Jesse-njx
stars
4 stars
License
MIT
Updated
Updated 8 days ago

Readme

# dsh-polyglot

**The model switch for DSH.** Point DeepSeek Harness at any OpenAI-compatible
endpoint — with curated presets for free and cheap DeepSeek providers and
automatic fallback when a free tier rate-limits you.

What claude-code-router is to Claude Code, dsh-polyglot is to DSH — except
DSH's `ctx.llm` is a sanctioned extension seam, so there is no request
interception: the generic adapter and the router are both real `LlmAdapter`
registrations.

- **One generic adapter.** A single OpenAI-compatible `ctx.llm` adapter
  parameterized by `{baseUrl, apiKey, model, headers?, quirks?}`. Streaming,
  tool calls, and usage extraction are all handled; per-provider deviations
  (reasoning field names, strict tool schemas, cache-folded usage) are small
  declarative `quirks` flags, never per-provider code.
- **A router with fallback.** On 429 / quota-exceeded / 5xx (or a missing
  key), the failing provider is marked cooling-down (exponential backoff,
  honoring `Retry-After`) and the request is retried on the next provider in
  the chain. Free tiers rate-limit constantly — automatic failover is the
  whole product.
- **Provider presets as data.** `presets/*.json` — community PRs add providers
  without touching the adapter. Each preset carries `verifiedAt` and free-tier
  notes so rot is visible.
- **Usage you can see.** Every attempt lands in the append-only session log as
  `polyglot/served`; `/polyglot usage` tallies per provider with token counts
  and estimated cost from preset pricing.

## Quick start

Install the bundle into a profile (a DSH profile is an ordered stack of
plugin-bundle patch layers):

```bash
dsh plugin --profile web add @dsh-polyglot/bundle
```

The bundle's patch registers the `polyglot` plugin with the recommended
default chain — *"code all day for free until something rate-limits, then
degrade gracefully to cheapest-paid"*:

```
nous-portal → opencode-zen → deepseek-official (5M grant) → kilo
```

Configure keys through the credentials seam (the web Models page writes them),
or export the env names each preset declares:

```bash
export NOUS_PORTAL_TOKEN=...      # nous-portal (bearer, manual token for v0.1)
export OPENCODE_API_KEY=...       # opencode-zen
export DEEPSEEK_API_KEY=...       # deepseek-official (new accounts: 5M free tokens, 30 days, no card)
export KILO_API_KEY=...           # kilo (paid fallback rung)
```

Pick the virtual provider `polyglot` in the model selector. A provider without
a configured key is skipped automatically — the chain degrades, it never
fails hard.

### Day-to-day commands

| Command | What it does |
|---|---|
| `/model` | show chains and the active one |
| `/model <chain>` | switch the active chain mid-session (logged as `polyglot/chain`) |
| `/polyglot` | status: active chain, entries, provider cooldowns |
| `/polyglot usage` | per-provider tally from the session log: calls, ok/failed, tokens, est. cost |
| `/polyglot presets` | free-tier posture of the active chain's presets |

## Configuration

Override `chains` and `cooldown` from your profile patch:

```yaml
# your profile's cordis.patch.yml (or --patch overlay)
- patch:
    - id: polyglot
      config:
        chains:
          default:
            - preset: nous-portal
            - preset: opencode-zen
            - preset: deepseek-official
              model: deepseek-v4-flash
            - preset: kilo
          paid:
            - preset: deepseek-official
              model: deepseek-v4-pro
        cooldown:
          baseMs: 30000        # initial per-provider cooldown after a failure
          maxMs: 900000        # ceiling (also honors provider Retry-After)
          factor: 2            # exponential growth per consecutive failure
          jitterRatio: 0.1     # symmetric jitter around each delay
```

Per-entry overrides: `provider` (route name), `model`, `baseUrl`, `apiKeyEnv`,
`headers`, `quirks` — the `custom` preset is the escape hatch for
vLLM/Ollama/SGLang localhost and any other OpenAI-compatible endpoint
(Qwen/GLM/Kimi official APIs included).

### Quirks reference

| Flag | Default | Meaning |
|---|---|---|
| `reasoningField` | `'reasoning_content'` | wire delta field carrying reasoning text; `null` disables reasoning entirely |
| `maxTokensField` | `'max_tokens'` | output-cap wire field (`max_completion_tokens` for newer hosts) |
| `usage` | `'standard'` | `'deepseek'` subtracts cache hits folded into `prompt_tokens`; `'none'` when the host reports none |
| `streamOptions` | `true` | send `stream_options: {include_usage: true}` |
| `strictToolSchemas` | `false` | add `strict: true` to tool schemas |
| `thinkingField` | `false` | send `thinking: {type}` (DeepSeek spelling) |
| `reasoningEffortField` | `true` | send `reasoning_effort` for high/max efforts |

## Preset registry

All figures were re-verified 2026-08-14 against provider docs; **these move
weekly** — every preset carries `verifiedAt`, and a CI job pinging each
`baseUrl` with a 1-token request is the planned trust loop.

| Preset | What you get | Cost / limits | Notes |
|---|---|---|---|
| `deepseek-official` | V4-Flash, V4-Pro | $0.14/$0.28 per M (Flash); **5M free tokens new accounts, 30 days, no card** | Baseline; prices trending up |
| `opencode-zen` | `deepseek-v4-flash-free` (+ Qwen 3.6 Plus, MiniMax M3, MiMo…) | Free, no card, 200k context; rate limits undocumented | Commercial terms unclear — flagged in the preset `notes` |
| `nous-portal` | `deepseek/deepseek-v4-flash:free` | Free, OAuth-gated, hard rate ceiling that returns errors | The poster child for fallback; put it first in a chain |
| `kilo` | V4-Pro, V4-Flash, V3.1 Terminus | Pay-as-you-go at **no markup** over provider rates | Good paid-fallback rung |
| `openrouter` | `:free` DeepSeek variants + everything else | Free variants throttled; paid at listed rates | Widest catalog, one key |
| `custom` | anything OpenAI-compatible | — | vLLM/Ollama/SGLang localhost; Qwen/GLM/Kimi official endpoints |
| `groq` / `together` / `fireworks` | DeepSeek hosting | fast but pricier | Latency upgrades, not savings |

## How it works

```
profile ──> provider route "polyglot" (the router meta-adapter)
              │  chain: nous-portal → opencode-zen → deepseek-official → kilo
              ▼
        ctx.llm.stream({provider: "nous-portal", ...})
              │  adapter per real route (OpenAiCompatAdapter, one per preset)
              ▼
        POST {baseUrl}/chat/completions   (SSE, usage, tools)
```

The router forwards the first attempt that completes. A fallback-eligible
failure that arrives **before any content flowed** — the free-tier ceiling
case — swaps to the next provider seamlessly; a failure after content flowed
cannot be unwritten and surfaces as a normal error finish. Which provider
actually served each turn is durable in the session log (`polyglot/served`),
so `/polyglot usage` is a pure fold over the log, not plugin-side accounting.

## ToS note

Free tiers are often gated for evaluation use (OpenCode Zen's commercial
terms are undocumented). Preset `notes` surface this at configure time —
dsh-polyglot does not silently launder usage.

## Development

```bash
pnpm install
pnpm typecheck    # strict TS
pnpm build        # tsc → lib/
pnpm test         # 56 tests: mock OpenAI-compat server with scripted 429/500/
                  # stream scenarios, golden wire assertions per quirk, and
                  # end-to-end cordis mounts proving fallback + session events
```

## Roadmap

- **v0.2** — per-role chains (planner → paid V4-Pro, executor/summarizer →
  free Flash); OAuth device flow for Nous Portal; preset auto-update check;
  provider benchmark/arena integration.
- **Non-goals** — proxying non-chat modalities; silent key laundering.

Install

dsh plugin --profile web add github:Jesse-njx/dsh-polyglot#4c939d75be7c24dcd74de219eb24f4a2355faad9

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
Source