DeepSeek Harness Plugin

TYEclipse/dsh-units

Stars ★ 3 Category Tools & Capabilities Added 2026-09-10

Unit conversion toolbox covering 20 categories — length, mass, temperature, area, volume (incl. US cooking units), speed, time, data sizes (decimal MB vs binary MiB), data transfer rates (Mbps vs MB/s), acceleration incl. g-force, illumination (lux / foot-candle), pressure, energy, angle, frequency, power incl. three horsepower definitions, force, torque, typography (px/pt/em/rem), and fuel economy (mpg ↔ L/100km). Two tools — convert_unit and list_units — zero runtime dependencies, pure arithmetic; each result includes the formula applied.

Install

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

dsh plugin --profile web add github:TYEclipse/dsh-units

Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).

README

Unit conversion toolbox for DeepSeek Harness (dsh) — 22 categories, 3 tools, zero runtime dependencies, pure arithmetic over a static unit table (no network, no filesystem, no code execution).

When your agent needs to answer "how many miles is 100 km?", "is 1 MB bigger than 1 MiB?", "is 100 Mbps the same as 100 MB/s?", "what's 350°F in Celsius?", "how many tablespoons in 2 cups?", "16px is how many pt?", "20 mpg in L/100km?", "150 kW is how much mechanical horsepower?", "how many g is 9.8 m/s²?", "100 CFM in m³/h?", "is $3.99/lb cheaper than $8.50/kg?" or "500 g for $4.29 vs 1 lb for $3.59?" — instead of doing error-prone mental math, it can call these tools and read exact results.

中文简介:dsh-units 是 DeepSeek Harness 的单位换算工具箱插件,覆盖长度、质量、温度、面积、体积(含美制烹饪单位)、速度、时长、数据大小(十进制 MB 与二进制 MiB 严格区分)、数据传输速率(Mbps 与 MB/s 严格区分)、加速度(g-force)、照度(lux / 英尺烛光)、压强、能量、角度、频率、功率(机械/公制/电动马力严格区分)、力、扭矩、排版印刷(px/pt/em/rem)、体积流量(m³/s、L/min、CFM、US gpm)、密度(kg/m³、g/cm³、lb/ft³、lb/gal)、油耗(L/100km ↔ mpg ↔ km/L)共 22 个类别,并提供单价归一与比价工具,零运行时依赖、纯算术实现,无网络无副作用。让 Agent 不再心算——特别是"MB/MiB 混淆""100 Mbps 不等于 100 MB/s""华氏摄氏互转""加仑换升""mpg 与 L/100km 互算""三种马力混淆""$3.99/lb 与 $8.50/kg 哪个便宜"这类高频出错点,直接调用工具拿精确结果。

Why it exists

  • LLMs are unreliable at unit math. Temperatures are affine (offset), data sizes mix decimal and binary prefixes, fuel economy is reciprocal (mpg vs. L/100km), and compound units (km/h, psi, kcal) hide awkward factors. A wrong conversion silently corrupts reports, recipes, travel plans, and capacity math.
  • Fully deterministic and offline. Every factor lives in the static table in src/units.ts — no API keys, no lookup services, nothing to drift.
  • Structured results. Each conversion returns the original value, both units (symbol + full name), the result, the formula applied, and the category — so the agent can explain its math instead of just asserting it.

Tools

Tool What it does
convert_unit Convert value from one unit to another within a category. Accepts symbols or full names (case-insensitive, °C, m², "miles", "MiB" all work). Rejects unknown units and cross-category pairs with clear errors.
list_units List all 22 categories with every unit symbol and full name (optionally one category, e.g. "data" or "temperature") — for discovering the exact symbols to pass to convert_unit and unit_price.
unit_price Normalize and compare unit prices: pass 1–6 offers as { price, per, quantity? } (quantity defaults to 1, so { price: 4.29, per: "g", quantity: 500 } is a 500 g pack) and get the price of one target unit for each offer (default: the category base unit), the cheapest offer and the spread in percent. Rejects temperatures (affine) and fuel economy (reciprocal) instead of returning a meaningless number.
unit_sum Add up 1–12 quantities that share one category, each in its own unit, and get the total and the mean in a target unit (default: the category base unit). Built for "5 ft 3 in + 1.2 m + 80 cm" and "1 h 30 min 45 s" without mental conversion: every quantity is converted to the base unit and summed with compensated (Neumaier) accumulation, so a long list of small addends does not drift. Negative values are allowed, so it answers differences too. Rejects temperatures (affine) and fuel economy (reciprocal).

Supported categories

Category Units (symbols)
length km, m, cm, mm, um, nm, in, ft, yd, mi, nmi
mass t (metric tonne), kg, g, mg, lb, oz
temperature c, f, k — affine conversion with offsets
area km2, ha, m2, cm2, mm2, mi2, acre, yd2, ft2, in2
volume (incl. cooking) m3, l, ml, cm3, gal, qt, pint, cup, floz, tbsp, tsp (US units)
speed km/h, m/s, mph, knot, ft/s
time duration yr (Julian, 365.25 d), wk, d, h, min, s, ms
data size tbit…bit, pb…b (decimal), pib…kib (binary) — MB ≠ MiB
data transfer rate tbit/s…bit/s (decimal bits), tb/s…b/s (decimal bytes), tib/s…kib/s (binary bytes) — 100 Mbps = 12.5 MB/s
acceleration m/s2, g0 (standard gravity 9.80665 m/s²), ft/s2, mph/s — g-force & automotive
illumination klx, lx (lux), fc (foot-candle), ph (phot) — 1 fc = 10.76391 lx
pressure mpa, kpa, bar, atm, psi, mmhg, torr, pa
energy kwh, wh, kcal, kj, cal, j, ev
angle deg, rad, grad
frequency / rotation ghz, mhz, khz, hz, rpm
typography (CSS / print) px, pt, pc (pica), em, rem — 96 dpi reference, 16 px base font for em/rem
fuel economy l/100km, l/km, mpg (US), mpg(uk) (imperial), km/l — reciprocal, mpg ≠ linear
power mw, kw, w, hp (mechanical = 550 ft·lbf/s), hp(m) (metric PS), hp(e) (electric 746 W), btu/h (IT), ftlb/s — three different horsepower definitions
force kn, n, dyn, lbf, kgf (kp), gf — lbf/kgf are weight-based at standard gravity 9.80665 m/s²
torque n.m, kgf.m, lbfft (pound-force foot), lbfin (pound-force inch) — force × length
volumetric flow rate m3/s, m3/h, l/s, l/min, l/h, cfm (cubic foot per minute), gpm (US gallon per minute) — flows, not volumes
density kg/m3, g/l (identical to kg/m³), g/cm3 (= g/mL = kg/L = t/m³), g/ml, kg/l, t/m3, lb/ft3, lb/gal — lb/gal is 119.8264 kg/m³

v0.2.0 note: pt now means the typography point (previously the US pint). Use pint for pints — convert_unit { value: 1, from: "pint", to: "l" } still works. em/rem assume the common 16 px browser default base font size; px assumes 96 dpi (documented assumptions, not physical absolutes).

v0.3.0 note (symbol disambiguation): typed input kn resolves to knot (speed) — reach kilonewton by its full name (convert_unit { value: 1, from: "kilonewton", to: "n" }). Likewise nm is the nanometer (length); the torque newton meter uses the symbol n.m (also n·m or full names).

v0.4.0 note (category split & disambiguation): the old data size / transfer category is now data size (sizes only); rates live in data transfer rate — mb/s means megabyte per second (following mb = megabyte in the data table), while mbps / mbit/s mean megabit per second, so 100 Mbps → 12.5 MB/s exactly. In acceleration, typed g stays the gram (mass) — gravity is g0 / gravity / g-force; gal stays the US gallon (no galileo unit); ph is the phot, not pH.

v0.5.0 note (flow rate, density, unit prices): two new categories — volumetric flow rate (m3/s, m3/h, l/s, l/min, l/h, cfm, gpm; a flow is not a volume, so l/min will not convert to l) and density (kg/m3, g/l, g/cm3, g/ml, kg/l, t/m3, lb/ft3, lb/gal). One new tool — unit_price — normalizes 1–6 offers onto one target unit and ranks them; it deliberately rejects temperature (affine zero point) and fuel economy (reciprocal), and every offer must share a category with the others and with to.

v0.6.0 note (adding quantities up): one new tool — unit_sum — adds 1–12 quantities that each carry their own unit of one category and returns the total (and the mean) in a target unit, so "5 ft 3 in + 1.2 m + 80 cm" and "1 h 30 min 45 s" need no mental conversion. The sum runs in the category base unit through compensated (Neumaier) accumulation: adding 1 m to 10¹⁶ m and taking 10¹⁶ m away still leaves 1 m, and the total does not depend on the order of the addends. Temperatures (affine zero point) and fuel economy (reciprocal) are rejected instead of returning a meaningless number; negative values are accepted, so the same tool answers differences.

Install

dsh plugin --profile default add github:TYEclipse/dsh-units

or clone and build locally:

git clone https://github.com/TYEclipse/dsh-units.git
cd dsh-units && pnpm install && pnpm build

Usage

The agent just calls the tools — no setup beyond installation:

convert_unit { value: 100, from: "km", to: "mi" }
→ 100 km = 62.137119 mi (length, × 0.621371192237334)

convert_unit { value: 500, from: "MiB", to: "MB" }
→ 500 mib = 524.288 mb (data size, × 1.048576)

convert_unit { value: 100, from: "Mbps", to: "MB/s" }
→ 100 mbit/s = 12.5 mb/s (data transfer rate, × 0.125)

convert_unit { value: 350, from: "fahrenheit", to: "celsius" }
→ 350 f = 176.666667 c (temperature, (x − 32) × 5/9)

convert_unit { value: 16, from: "px", to: "pt" }
→ 16 px = 12 pt (typography (CSS / print), × 0.75)

convert_unit { value: 20, from: "mpg", to: "l/100km" }
→ 20 mpg = 11.760729 l/100km (fuel economy, 235.214583 ÷ x → x)

convert_unit { value: 150, from: "kw", to: "hp" }
→ 150 kw = 201.153313 hp (power, × 1.3410220895950278)

convert_unit { value: 1, from: "lbfft", to: "n.m" }
→ 1 lbfft = 1.355818 n.m (torque, × 1.3558179483314003)

convert_unit { value: 9.8, from: "m/s2", to: "g0" }
→ 9.8 m/s2 = 0.999322 g0 (acceleration, × 0.10197162129779283)

convert_unit { value: 1, from: "fc", to: "lx" }
→ 1 fc = 10.76391 lx (illumination, × 10.763910416709722)

convert_unit { value: 1, from: "gpm", to: "l/s" }
→ 1 gpm = 0.0630902 l/s (volumetric flow rate, × 0.0630901964)

convert_unit { value: 100, from: "cfm", to: "m3/h" }
→ 100 cfm = 169.90108 m3/h (volumetric flow rate, × 1.6990107955200004)

convert_unit { value: 1, from: "lb/ft3", to: "kg/m3" }
→ 1 lb/ft3 = 16.018463 kg/m3 (density, × 16.018463373960138)

unit_price { offers: [{ price: 3.99, per: "lb" }, { price: 8.5, per: "kg" }], to: "kg" }
→ unit prices per kg (mass):
    #1 3.99 per lb → 8.796444 per kg
    #2 8.5 per kg → 8.5 per kg
  cheapest: #2 at 8.5 per kg (spread 3.370046%)

unit_price { offers: [{ price: 4.29, per: "g", quantity: 500 }, { price: 3.59, per: "lb" }], to: "kg" }
→ unit prices per kg (mass):
    #1 4.29 per g (500 g) = 0.5 kg → 8.58 per kg
    #2 3.59 per lb → 7.914595 per kg
  cheapest: #2 at 7.914595 per kg (spread 7.755301%)

unit_sum { items: [{ value: 5, unit: "ft" }, { value: 3, unit: "in" }, { value: 1.2, unit: "m" }, { value: 80, unit: "cm" }], to: "cm" }
→ sum of 4 quantities: 5 ft + 3 in + 1.2 m + 80 cm = 360.02 cm (3.6002 m); mean 90.005 cm

unit_sum { items: [{ value: 1, unit: "h" }, { value: 30, unit: "min" }, { value: 45, unit: "s" }] }
→ sum of 3 quantities: 1 h + 30 min + 45 s = 5445 s; mean 1815 s

list_units { category: "volume" }
→ volume (volume (incl. cooking), base: liter): m3 = cubic meter | l = liter | ...

list_units { category: "flow" }
→ flow (volumetric flow rate, base: cubic meter per second): m3/s = cubic meter per second | ... | gpm = US gallon per minute

All outputs above are captured from the built dist/ (v0.6.0).

Configuration

plugins:
  dsh-units:
    maxDecimals: 6   # display rounding: decimals ≥ 1, significant digits below (1–12)

Safety model

  • Pure math. No network, no filesystem access, no subprocesses, no code execution.
  • Strict input validation. Unknown units, cross-category pairs, and non-finite values throw descriptive errors instead of returning garbage.
  • Display-only rounding. Internal computation keeps full float precision; rounding applies to the returned result only.
  • No opinions about validity. Converting -10 K returns the arithmetic result; physical plausibility is the caller's business (documented so agents don't over-trust the tool).

Development

pnpm install
pnpm build   # tsc, strict
pnpm test    # vitest, fully offline fixtures
pnpm lint    # oxlint (src + test only)

License

MIT © 2026 TYEclipse

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.