PerryLink
dsh-translate
Vendor parameter translation and deterministic JSON repair for DeepSeek Harness: /translate maps temperature/top_p/max_tokens/stop/system across 11 vendors, and the post-execute repair layer (plus fix_json) fixes broken JSON tool output without ever fabricating data
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 16, 2026
- Updated
- Aug 16, 2026
Introduction
🔁 dsh-translate
Vendor parameter translation and deterministic JSON repair for DeepSeek Harness.
Same request, every vendor. Broken JSON, fixed without inventing data.
Compatibility
| Surface | Status |
|---|---|
| Harness | DeepSeek Harness 0.1.0-rc.6 (compat declared for 0.1.0-rc.5–0.1.0-rc.6) |
| Node | ^22.19.0 || >=24.0.0 |
| Form | Pure-host JS plugin (no browser half) |
| Model | Any model — repair is deterministic, no extra model calls |
What you get
Two independent surfaces, one bundle:
/translate— the vendor parameter translation table:temperature,top_p,max_tokens,stop,system, and 8 more canonical parameters mapped across 11 vendors (OpenAI, ERNIE, Qwen, Anthropic, Google, DeepSeek, Mistral, Cohere, xAI, Groq, Azure). Ask for a pairwise mapping, list vendors/params, or convert a whole standard request (transformRequestinlib/rosetta.mjs).- The repair layer — a
tools/post-executelistener plus thefix_jsontool. When a successful tool result carries broken JSON as a string (string-rooted orjson-rooted output schema, or a tool opted in by name), the layer repairs it deterministically: markdown-fence extraction, escape repair, trailing-comma removal, truncation closure, and required-field completion with explicitnullplaceholders. No value is ever invented — a result that still violates the schema fails closed, and failed tool results are never flipped into successes.
tool result (success, JSON text) ──▶ extract fence ──▶ parse
│ ok? ──▶ schema-validate ──▶ accept { kind: 'accept', value } (registry re-validates + re-renders)
│ broken ──▶ escape / trailing-comma / close / fill-null ──▶ validate
│ unrepairable ──▶ next() (original value preserved) + translate/fix audit (counts only)
Quick start
# 1. install the bundle into your profile
dsh plugin --profile web add "github:PerryLink/dsh-translate#main"
# or from npm (published releases)
dsh plugin --profile web add dsh-translate
# 2. restart and verify the row
dsh --profile web --dump-config | grep -A2 'id: dsh-translate'
Then ask the agent to check a mapping or repair a payload:
> /translate openai ernie max_tokens
> Use fix_json to repair: {"a": 1,} against {"type":"object","properties":{"a":{"type":"integer"}},"required":["a"]}
Install & uninstall
- git channel (latest
main):dsh plugin --profile web add "github:PerryLink/dsh-translate#main"— pure JS, no build step. - npm channel (published releases):
dsh plugin --profile web add dsh-translate. - tarball channel:
pnpm packin this repo, thendsh plugin --profile web add ./dsh-translate-<version>.tgz. - uninstall:
dsh plugin --profile web remove dsh-translate(or remove the row from the profile patch).
Configuration
All tunables are Schemastery Config fields (changeable from cordis.yml). An id-targeted override replaces the whole row — restate every key you need. cordis.patch.yml documents each key inline.
| Key | Default | Meaning |
|---|---|---|
enabled | true | Master switch; false registers nothing |
repair.enabled | true | Post-execute repair layer switch |
repair.toolNames | [] | Extra tool names whose JSON-text results may be repaired (on top of string-rooted / json-rooted schemas) |
repair.strategies.escapeRepair | true | Escape raw control characters inside strings |
repair.strategies.trailingComma | true | Remove commas directly before a closing bracket |
repair.strategies.truncationClosure | true | Close an unclosed string or container cut off by truncation |
repair.strategies.fieldCompletion | true | Complete missing required fields with explicit null placeholders |
repair.maxSteps | 8 | Strategy application budget (repair-loop passes, 1..64) |
diffMaxChars | 200 | Cap on one logged diff fragment, in characters |
diffMaxEntries | 50 | Cap on logged diff entries |
registerCommand | true | Register the /translate command |
registerTool | true | Register the fix_json tool |
Example override in your profile patch:
- insert:
- id: dsh-translate
name: dsh-translate
config:
enabled: true
repair:
enabled: true
toolNames: ['emit-json']
strategies:
escapeRepair: true
trailingComma: true
truncationClosure: true
fieldCompletion: true
maxSteps: 8
diffMaxChars: 200
diffMaxEntries: 50
registerCommand: true
registerTool: true
Tools & surfaces
| Surface | Kind | Notes |
|---|---|---|
/translate | command | vendors, params, or <from> <to> [param] pairwise mapping |
fix_json | tool | { text, schema?, strategies? } → { ok, repaired?, diff?, strategies, truncated, validated, error? }; diff fragments are bounded and sanitized |
| post-execute repair | listener | Automatic for successful string results from string-rooted / json-rooted schemas (plus repair.toolNames); always calls next() unless it claims the call |
Permissions & data
- Permissions: no network, no subprocess, no credentials — the plugin only consumes the official
commandsandtoolsservices and appends to the session log. - Data: repair never fabricates values; the only model-visible additions are the repaired canonical value and the
fix_jsondiff. Session audit events (translate/fix) carry tool name, call id, strategy names, edit counts, and truncation flags — never payloads.
Security boundaries
- Deterministic only. Repair is bounded text surgery; the upstream LLM-retry arm of JSON-Schema-Enforcer-Proxy was deliberately not ported — a post-execute listener never calls a model.
- Fail closed. Unrepairable syntax and schema violations leave the original result untouched (or return a structured error from
fix_json);nullplaceholders only land when the schema acceptsnull. - Hostile input bounded. Unsupported schema keywords and circular schemas are rejected;
oneOfvalidation is capped by depth (MAX_ONE_OF_DEPTH) and a branch budget (MAX_ONE_OF_BUDGET), so an exponential schema cannot exhaust the process. - No payload leakage. Logs and audit events never contain repaired payloads; diffs are truncated and capped before display or storage.
Known limitations
- The supported JSON Schema subset mirrors the harness tool registry (
type/oneOf/properties/required/additionalProperties/items/enum/const); other keywords are rejected as unsupported, not silently ignored. - Repair only applies to successful results whose canonical value is a JSON-text string; a value that already failed schema validation arrives as a failed result and is never flipped.
- The translation table covers 11 vendors × 13 canonical parameters;
extendedrows follow public API references (not the upstream trio) and are marked as such inlib/rosetta.mjs.
Development
pnpm install # node ^22.19 || >=24
pnpm test # node --test: 57 tests (pure lib suites + real-service assembly suite)
pnpm run check # tsc checkJs against types.d.ts
pnpm run verify:self-contained # dependency specs resolve from the registry
pnpm run verify:artifacts # ESM face imports under plain Node + lib exports present
node scripts/check-readme-sync.mjs # five-language README sync gate (also in CI)
pnpm pack # the published tarball
Topics
dsh, dsh-plugin, deepseek-harness, deepseek, cordis, json-repair, schema-validation, parameter-mapping, llm-api, tooling
Contributors
- @PerryLink — creator and maintainer: translation table and repair pipeline ports, plugin surfaces, tests, and the five-language docs.
License
Apache License 2.0 © 2026 dsh-translate contributors