@grilling-sleek/dsh-tool-grill-user
English | 中文
A DeepSeek Harness (dsh) plugin that gives the agent the grill_user tool:
one decision-tree branch of structured questions per call, each question with
a recommended answer, and the user's decisions returned as structured JSON.
It is the dsh distribution channel of grill-me-sleek — the same Hub and
answer page the CLI and the packaged skill use, mounted natively as a Cordis
plugin.
How it answers
grill_user asks on two links at once and the first answer wins:
- Downstream — the native
userQuestions waterfall: desktop cards, IM
bridges, remote apps. Every answerer already in the composition works with
zero code.
- Hub — a grill-me-sleek round on the configured Hub. The user opens the
answer page (
https://<hub>/#session_id) on any network and answers there.
The Hub round opens before the card goes out (bounded by a 2 s reveal
budget), so the answer-page URL rides the question card — on the first
question's detail line, the one page every answerer sees — and is logged once
per round; answer on whichever surface you see first. A
Hub round that cannot be opened in time degrades that round to the card only
(warned; the result then carries no hub).
The loser is converged: a Hub win withdraws the downstream question
everywhere (the gateway's cancel frame); a downstream win proxy-submits the
answers to the Hub and revises on conflict so both agree. The Harness session
log records the round through the tool call itself — arguments carry the
questions, the result carries the answers and the opened Hub linkage — so
replay and history see what was asked and answered.
How revisions reach the agent
The Hub is the source of truth for answers, and the user can revise any
answered round on the answer page at any time while the session is active.
Everything the agent was delivered is a cached view with a per-round revision
watermark, and three layers converge it — the watcher accelerates delivery,
the other two make it lossless:
- The revision watcher. From the first successfully opened round, the
plugin reads the session's SSE stream (the same one the answer page uses).
Every
response.revised fetches that round's latest answers and delivers
them to the agent out-of-band — an idle agent is woken (followup), a busy
one is handed an inject for its next step boundary — under a small
consecutive-wake budget that an answered round refills. Every
(re)connection replays the round summaries, so a missed event or a dropped
stream heals by the watermark comparison. Node has no dependable global
EventSource, so the reader is a small fetch-body parser with reconnect
and backoff.
- The result delta. Before each new round opens, the plugin aligns the
watermarks with the Hub and carries any newly revised rounds in the
result's
revisions[] field — each entry holds the round number, its
branch name, the revision, and the full latest answers.
- The wait notices. The long-poll loop collects the revision notices the
Hub attaches to pending responses, and the result delivers those rounds'
latest answers too.
Layered this way, a revision is lost only when every layer fails at once; the
watermark comparison collapses duplicates across layers. A failed or aborted
round cancels the Hub session and resets the linkage (the next call opens a
fresh session), and agent disposal cancels the session best-effort — the
answer page then says so instead of collecting revisions nobody will read.
Beyond that the plugin never closes a session: sessions live to their TTL
(one hour on the public Hub), and that lifetime is the user's revision
window. The skill body teaches the model the matching discipline: the latest
revision of every round supersedes earlier deliveries, and no close action
exists or is needed.
Install
Prerequisite: DeepSeek Harness
(dsh) itself. Then one command:
dsh plugin --profile web add @grilling-sleek/dsh-tool-grill-user
Restart the profile — that is the whole install. The package ships its
cordis.patch.yml bundle patch, so the CLI's plugin coordinator mounts it
into the profile's bundle stack; no profile file edits.
Out of the box every round races on the public Hub at
https://grillingsleek.online — the same answer page the CLI and the
packaged skill use — so the browser answer surface works with zero
configuration. Point the plugin at a self-hosted Hub instead (or go
hubless) by re-inserting the plugin row with a config block in any later
layer — the profile's own cordis.patch.yml or a --patch overlay; later
layers win per row:
- insert:
- id: tool-grill-user
name: "@grilling-sleek/dsh-tool-grill-user"
config:
baseUrl: "https://your-hub.example.com"
With baseUrl: "" the plugin runs hubless: user questions are then the
only answer surface, and a profile without any answerer fails the call
immediately instead of hanging.
| Field | Default | Meaning |
|---|
baseUrl | https://grillingsleek.online | Hub origin serving the answer page; '' switches to hubless |
maxQuestionsPerRound | 16 | Largest accepted question batch per round (1..64) |
roundTimeoutMs | 14400000 | How long one round may stay pending before closing as expired |
The plugin also registers the grilling-sleek interview skill at runtime
(when a skill registry is present), so /grilling-sleek and model-matched
triggering work with no separate skill installation.
Secondary channels: every dsh-v* GitHub Release carries the packed
tarball — dsh plugin --profile web add ./grilling-sleek-dsh-tool-grill-user-<version>.tgz
— and a git pin also works (dsh plugin --profile web add github:jukanntenn/grill-me-sleek#<sha>).
A git install fetches sources and runs the prepare build, so allowlist
the package in the profile's pnpm-workspace.yaml allowBuilds first.
Version line
0.0.x cuts are dogfooding, published as npm latest — an untagged
install rides the current one. From 0.1.0-rc.1 on, pre-releases publish
under next and 0.1.0 hands latest to the stable line. A release is
cut by pushing a dsh/package.json version bump to main; the workflow
publishes, tags dsh-v<version>, and opens the GitHub Release with the
tarball (GS-RFC 2026-09-01).
The interview discipline
One branch per call; stable grill_-prefixed snake_case question ids; two or
more options with the recommendation marked (recommended + explanation);
optionless questions are free text. Main agent only — an owned subagent has
no human answerer and its call is rejected before any round exists. Answers
return as { roundId, hub?: { sessionId, url }, revisions?: [...], answers: [{ id, selected, custom? }] } — hub present whenever the round raced on
one, revisions present whenever earlier rounds changed — including the
synthesized grill_additional_notes catch-all.
The runtime skill body carries these as an explicit Construction rules
checklist. The tool schema's enforced subset cannot express value
constraints (no pattern, minItems, or minimum), so mapping.ts checks them
at execute time; the checklist is the model's only pre-call view of them,
kept in step with the checks by JSDoc cross-references until a mechanical
gate replaces the prose anchor
(GS-RFC 2026-09-02).
Known limitations
- No custom session events. The Harness persistence read path refuses
event types outside its generated catalog, which only in-repo packages can
enter — so this plugin records rounds through the standard tool call and
result instead of a dedicated
grilling/* event family. A future upstream
contribution could restore the dedicated family without changing the tool.
- The losing surface sees a bare withdrawal. The cancel frame carries no
payload: other ends learn the question was cancelled, not the winning
answers.
- Hub convergence is best effort. A failed proxy submit or revise is
logged and swallowed; the round is already answered in the session log.
- A Hub round that cannot open degrades the round. The call answers on
the card alone (warned, and the result carries no
hub); a misconfigured
baseUrl therefore converges nothing — the warning and the missing field
are the diagnosis surface.
- Late answers are dropped by design. An answer submitted in the
milliseconds between the race settling and the withdrawal arriving is
accepted by its surface and silently discarded.
- Revision delivery degrades, never gates. The watcher is an accelerator:
a deployment that blocks SSE still converges every revision at the next
grill_user call's result delta, and the wake budget means a long run of
idle revisions past three without an answered round in between is injected
(parked for the next step boundary) rather than waking the agent.
- The package tracks the published dsh alpha channel (
0.1.2-alpha.x);
pre-release Harness may rename seams, and this package follows.
Design rationale and the alternatives that lost live in
GS-RFC 2026-08-31
and, for the revision model,
GS-RFC 2026-09-02.