lion231226/dsh-freellmapi ↗★ 0
dsh-freellmapi
Self-contained free-tier LLM routing for DeepSeek Harness: one `auto` model that scores each request's complexity and picks the best of 12 free providers, failing over automatically. Unconfigured providers collapse to a single 'add your key' entry instead of dead models, and pinning a specific model is strict -- never silently swapped. Works with zero credentials out of the box. 适合需要自动评估请求复杂度并分流至免费API的用户。
インストール
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:lion231226/dsh-freellmapiドキュメント
README 全文を読む ↗Configuration
Every field is live (a settings edit applies to the next request, no restart) and validated totally — a malformed value falls back to its default instead of preventing the plugin from loading.
| Field | Type | Default | Meaning |
|---|---|---|---|
mode | direct | gateway | direct | Self-contained routing, or forward to an external gateway |
baseURL | string | http://localhost:3001/v1 | Gateway mode only: OpenAI-compatible root of the freellmapi gateway |
apiKeyEnv | string | FREELLMAPI_API_KEY | Gateway mode only: credential reference name (not the key) |
apiKey | string (secret) | '' | Gateway mode only: optional inline credential; prefer apiKeyEnv |
providers | dict or array | {} | Per-provider overrides for the built-in pool (see below) |
routing | dict | {maxAttempts: 6, budgetMs: 45000} | Routing-engine knobs (see below) |
logRouting | boolean | true | Log the direct-mode routing decision (tier, winner, candidates tried) |
logRoutedVia | boolean | true | Log X-Routed-Via / fallback trail (gateway mode) |
vision | boolean | true | Advertise image input when the chosen model supports it; set false to force text-only |
contextWindow | number | 131072 | Context window assumed for ids the pool does not describe |
maxTokens | number | 0 | Output cap declared to DSH; 0 = declare none and let the provider decide |
timeoutMs | number | 600000 | Per-attempt timeout in milliseconds; 0 disables it |
includeFusion | boolean | true | Gateway mode: advertise the gateway's fusion route |
exposeDiscoveredModels | boolean | true | Gateway mode: merge GET /v1/models into the picker |
discoveryTimeoutMs | number | 5000 | Gateway mode: timeout for that discovery request |
discoveryCacheMs | number | 60000 | Gateway mode: how long a discovery result stays fresh |
maxTokensField | max_tokens | max_completion_tokens | max_tokens | Which wire field carries the cap. max_tokens is the canonical field; the gateway also accepts the other |
headers | map | {} | Extra request headers. user-agent, authorization, content-type, accept are reserved |
taskType | '' | auto | code | chat | '' | Gateway mode: optional X-FreeLLM-Task-Type hint (empty sends no header) |
cacheMode | '' | on | off | '' | Gateway mode: optional X-FreeLLM-Cache switch (empty sends no header) |
The settings form is generated when the host resolves
@deepseek-ai/schemastery(it normally does in a DSH profile). If it does not, the plugin still loads and runs with exactly these defaults — you just configure it through the profile patch instead. No configuration value, however malformed, can stop the plugin from loading.
One environment escape hatch worth knowing: FREELLMAPI_BASE_URL overrides the gateway endpoint from
the environment, and it is honoured only while baseURL still holds its built-in default, so an
explicit setting always wins over the environment.
providers. — override one pool entry
| Key | Meaning |
|---|---|
enabled | Turn a provider on/off. This is how you enable the seven providers that ship disabled |
displayName | Label used in the picker and logs |
baseURL | Endpoint root — fix a hostname without waiting for a release (see zhipu) |
apiKeyEnv | Your own credential reference name for this provider |
apiKey | Inline credential for this provider (stored in the profile patch — prefer apiKeyEnv) |
keyless | Mark a custom endpoint as usable without a credential |
models | Replaces the built-in model list for that provider. Each entry: id, name, and capability / speed (1–5), contextWindow, maxTokens, vision, toolCalling — either inline or under caps |
A provider that is not in the built-in pool at all is added the same way: give it id/baseURL and a
models list (see Adding keys).
routing — engine knobs
| Key | Default | Meaning |
|---|---|---|
maxAttempts | 6 | Maximum candidates tried for one request |
budgetMs | 45000 | Total failover time budget; 0 = unlimited |
contextSafetyFactor | 1.15 | Safety margin on the context gate: a candidate must satisfy contextWindow >= estimated tokens × this factor. The token estimate is a heuristic and undercounts, so one model of headroom is cheaper than a 400 from upstream. A value below 1 is rejected and the default applies |
thresholds.medium | 0.34 | Score at which simple becomes medium |
thresholds.complex | 0.67 | Score at which medium becomes complex |
weights | per-tier defaults | {capability, speed} or {simple: {…}, medium: {…}, complex: {…}} |
preferredOrder | [] | Provider ids you want preferred; a bounded bonus of at most 0.05 |
Three ways to set them
-
Settings page — Settings → Plugins → dsh-freellmapi (every top-level field, with the generated form described above).
-
Profile patch —
$DSH_HOME/profiles/ /cordis.patch.yml; the recommended place forprovidersandrouting:- id: freellmapi config: mode: direct logRouting: true providers: cerebras: enabled: true kilo: enabled: false # if you do not accept its training-recording terms routing: maxAttempts: 4 preferredOrder: [cerebras, groq] -
Environment — the per-provider
apiKeyEnvnames in Adding keys.