todo: a self-nudge control in the chat composer
wanted while leaving an agent to work overnight — "continue every hour if you have stalled", beside the background-job button. tonight's script does it from outside, polling the sessions api and speaking over the chat websocket exactly as a browser does, which is why the platform needed no changes. that is the workaround; this is the feature. records the two things the platform actually lacks — a recurring trigger, and any door into a live session that is not the chat websocket — and the three design notes that are easy to get wrong: never speak while isGenerating, the schedule cannot be owned by the session it nudges (a chat background job dies with its session, taking the watchdog with the agent), and bound the loop. the same trigger is what the watcher-loop proposal in COMMS has been waiting for, so it is one piece of infrastructure serving two asks.
This commit is contained in:
@@ -705,6 +705,32 @@ outside the example's new README:
|
||||
auto-loads `.env` into every PM2 process, so each one is readable from `/proc/<pid>/environ`
|
||||
of twenty processes that have no business with it.
|
||||
|
||||
- [ ] **A self-nudge control in the chat composer, beside the background-job button.** Wanted
|
||||
2026-08-20 while leaving an agent to work overnight: "continue every hour if you have stalled".
|
||||
|
||||
`scripts/nudge-agent.ts` does it from outside tonight — it polls `GET /api/chat/sessions?all=1`
|
||||
and speaks over the chat websocket, exactly as a browser does, so the platform needed no changes.
|
||||
That is the workaround, not the feature.
|
||||
|
||||
**Two things the platform genuinely lacks**, and they are the work:
|
||||
|
||||
1. **A recurring trigger.** The queue has retries and delays but nothing periodic, and
|
||||
`queue/handlers/index.ts` is empty. `officer-notify` is now a natural home for "fire this
|
||||
later" — it already runs as core and already fans out on a schedule-free signal.
|
||||
2. **A way to put a prompt into a live session.** `pushTurn` has exactly ONE caller, the chat
|
||||
websocket handler. Anything server-side that wants to speak to a session has no door.
|
||||
|
||||
Design notes worth keeping:
|
||||
|
||||
- **Never interrupt work.** Check `isGenerating` immediately before speaking. The point is to
|
||||
restart a stopped agent, not to hurry a busy one — the script already gets this right.
|
||||
- **It must outlive what it nudges.** A chat background job is owned by its session, so a nudge
|
||||
job launched from the session being nudged dies with it — the 30-minute idle GC, a clear, or a
|
||||
restart takes the watchdog with the agent. Whatever owns the schedule cannot be the session.
|
||||
- **Bound it.** The script stops after `--max` (12). A loop nobody is watching should end.
|
||||
- The same trigger would serve `COMMS/command-hq/watcher-loop-proposal.md`, which wants
|
||||
infrastructure to own a loop rather than a model holding a protocol across turns.
|
||||
|
||||
## Backburner
|
||||
|
||||
- [ ] **Four foreign keys are over Postgres's 63-character limit and re-create on every `db:push`.**
|
||||
|
||||
Reference in New Issue
Block a user