Background only the warm-up, and use the framework's own parameter name

The tool backgrounded EVERY long action and exposed an inverted `foreground`
flag. dsh-tool-bash does neither: its parameter is `run_in_background`, it
defaults to foreground, and the model opts in. That difference is what made a
finished job go uncollected.

The evidence, from this session's own log: the only slopo job that ever ran was
slopo-1, and the agent KILLED it — `kill()` sets `reported = true`, which
suppresses the completion notice by design, because a caller who asked to stop
something does not want to be told it stopped. The agent then worked around the
tool entirely and re-ran slopo through bash, which is where the six notices in
that session came from. Nothing was broken; the tool was asking the caller to
depend on a best-effort signal.

So the query actions return their report directly. Only `prepare` — index plus
embed, the genuinely long and watchable step, and the one the user asked to be
able to watch — backgrounds by default. Any action can still be backgrounded
with `run_in_background: true`.

The render now names the collect call explicitly (`job_output` for that id, with
`wait: true` when blocked on it) instead of the vaguer "read the job output when
it settles", so a caller that is not woken still has an unambiguous next step.

I checked the waiter path while I was in there: a timed-out `wait` decrements
`waiters` in a `finally`, so it does not leak and does not suppress the notice.
That was my first hypothesis and it is wrong — worth recording, since it was the
plausible one.
This commit is contained in:
dsh-slopo agent committed 2026-09-22 13:30:55 +01:00
1 parent 2d7a7d1e73
commit 5ff10eaefd
3 files changed
+71 -30

No files matched your search

+11 -4
View File
@@ -148,10 +148,17 @@ Or drive the tool directly:
| `analyze-one` | One cluster, optionally by `cluster` hash. |
| `update` | Upgrade the slopo CLI. |
The long actions run as **background jobs** by default (pass `foreground: true`
to run inline). Embedding takes minutes, and slopo writes its progress to a log
file rather than to stdout, so there is nothing to stream — the job handle
carries the log path instead.
`prepare` — the warm-up — starts a **background job** by default, because embedding
takes minutes and slopo writes its progress to a log file rather than to stdout,
so there is nothing to stream; the job handle carries the log path instead. The
other actions return their report directly, and any of them can be backgrounded
with `run_in_background: true` — the same parameter name `dsh-tool-bash` uses.
That asymmetry is deliberate. A completion notice is best-effort: a **killed** job
deliberately produces none, and an agent whose turn has already ended may have the
notice injected rather than be woken for it. So the action that returns a report
the caller can use immediately is worth more than a job id it has to remember to
collect — and only the genuinely long step depends on being watched.
## Where things live