dsh-jev-loop
在智能体循环关口引入Jev决策机制 适合需要在DSH智能体循环中嵌入TypeSafe System One决策的用户。
安裝
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:JWE24-code/dsh-jev-loop說明文件
閱讀完整 README ↗dsh-jev-loop
Jev (TypeSafe System One) judgments at the DeepSeek Harness agent-loop gates. No UI dependency: mount it in any Harness composition, headless or otherwise.
This is the core of the Jev loop for moqi. The optional /JevLoop control panel
ships separately as
moqi-jev-loop, and depends only
on the jevLoop service this package provides.
Published to npm as
dsh-jev-loop. This repository
carries the dsh-plugin topic — the
whole of the dshfind listing mechanism: the marketplace
indexes public repositories by that topic and syncs daily, so there is no
listing step per release.
Install
dsh plugin --profile
add dsh-jev-loop
Then give it a key: set TYPESAFE_API_KEY (or TYPESAFE_APIKEY) in the
environment, or store one in the Harness credential store under
TYPESAFE_API_KEY. The gates fail open — no key, timeout, 429, or bad JSON
never blocks the loop.
The gates
| Gate | Event | What Jev judges | Decision |
|---|---|---|---|
| Pre-step | agent/pre-step | is the request underspecified? | inject an "ask before guessing" instruction |
| Pre-execute | tools/pre-execute | destructive · exfiltration · off-task | log / ask / deny |
| Post-execute | tools/post-execute | did a successful call silently miss? | log / block with corrective feedback |
| Turn-stopping | agent/turn-stopping | "is the request actually done?" | nudge the turn onward, or pass |
All four are automatic. Jev supplies a calibrated probability; this package owns the thresholds and decisions, and every failure — no key, timeout, 429, bad JSON — fails open, so a judgment service that is down never blocks the loop.
Configure them on the dsh-jev-loop row in a profile's cordis.patch.yml (see
this package's cordis.patch.yml), or in a profile's own
patch layer. The *Enabled defaults can also be overridden at runtime from
moqi's /JevLoop panel, which persists to $DSH_HOME/jev-loop.json.
Cost envelope
- One
POST /v1/systemoneper judgment; pre-execute asks its three hazards in a single call. - State is capped (
maxStateChars); the transcript gates only send the lastturnStoppingMaxMessagesmessages. - Answers are cached by a SHA-256 of the exact request body, so an unchanged judgment is free.
- Every judgment is appended to
$DSH_HOME/jev-loop.jsonlwith probabilities, cache hit/miss, latency, and token usage.
Config
Set on the dsh-jev-loop row in a bundle patch, or in a profile's own patch
layer.
| Field | Default | Meaning |
|---|---|---|
apiKey | — | literal key; prefer apiKeyEnv so no secret is in a config file |
apiKeyEnv | TYPESAFE_API_KEY | env var read for the key; TYPESAFE_APIKEY is also read |
model | jev-latest | TypeSafe model alias |
baseUrl | https://api.typesafe.ai/v1/systemone | evaluation endpoint |
timeoutMs | 3000 | per-request timeout |
maxRetries | 2 | retries on 429/529, network errors, timeouts |
maxStateChars | 24000 | hard cap on state sent to Jev |
cacheEntries | 500 | in-memory cache entries |
auditPath | $DSH_HOME/jev-loop.jsonl | JSONL audit trail |
statePath | $DSH_HOME/jev-loop.json | persisted gate toggles |
preStepEnabled | false | judge the request before the first step |
preStepThreshold | 0.7 | clarification probability that injects a question |
preExecuteEnabled | true | judge tool calls before dispatch |
preExecuteMode | log | log observes, ask requests approval, deny refuses |
preExecuteThreshold | 0.7 | hazard probability that flags a call |
preExecuteSkip | [] | tool names to ignore |
postExecuteEnabled | true | check a successful tool result |
postExecuteMode | log | log observes, block turns feedback into an error |
postExecuteThreshold | 0.7 | miss probability that blocks a result |
turnStoppingEnabled | true | check the turn before it closes |
turnStoppingThreshold | 0.5 | completion probability below which to nudge |
turnStoppingMaxSteers | 2 | nudges per turn, so a wrong judgment cannot loop |
turnStoppingMaxMessages | 14 | transcript messages fed to the completion judgment |
Test it
npm install # typescript + @types/node
npm run link-harness # symlink the installed harness's @deepseek-ai packages
npm run build
npm test # gates, keyring, loop — no Harness, no network
npm run install-profile -- jev-core # throwaway profile with just this bundle
TYPESAFE_APIKEY=… dsh --profile jev-core
~/.dsh/jev-loop.jsonl records every judgment.
To exercise the Harness-only build inside your own profile, list just the core bundle:
bundles: ['@deepseek-ai/dsh-base', 'dsh-jev-loop']
Layout
src/gates.ts the four judgments and their copy, as pure functions
src/keyring.ts key resolution order, storing, probing, clearing
src/loop.ts JevLoop: state assembly, per-turn budgets, audit, one method per gate
src/jev.ts the TypeSafe client: a Judger port and its live adapter
src/render.ts derived session messages -> plain text
src/index.ts the Cordis adapter: config, event wiring, effects
tests/ the modules above, driven directly
scripts/ harness linking and the throwaway profile installer
Docs
The module boundaries, the seams, and the generated whiteboard are documented in docs/ARCHITECTURE.md.