feat(waker): l'esito del runner non e' piu' un turno dell'utente (chat.send + provenance) #16

Merged
claudia merged 1 commit from feat/wake-chatsend into main 2026-09-14 15:51:59 +00:00
Owner

Problema

Il wake di fine task via hook (GW_WAKE_MODE=cli / http) accoda un system event. OpenClaw non lo rende come messaggio di ruolo system: lo antepone al body del turno successivo (prependEvents in buildReplyPromptBodies), e il set di systemNotice della Control UI e' chiuso e non include i wake dei hook.

Risultato: in chat il report del runner sembra scritto dall'utente.

Fix

Nuovo trasporto GW_WAKE_MODE=chatsend: chat.send sul Gateway WS di OpenClaw (ws://127.0.0.1:18789) con systemInputProvenance:

{"kind": "inter_session", "sourceTool": "agent_harness_task",
 "sourceChannel": "soltea-agent-gateway", "sourceSessionKey": "<sessione>"}
  • kind: inter_session -> il messaggio arriva al modello marcato [Inter-session message] ... isUser=false.
  • sourceTool di default agent_harness_task: e' uno dei source tool che OpenClaw riconosce come completion report (isCompletionReportInputProvenance), quindi shouldHideProjectedHistoryMessage lo nasconde dalla cronologia proiettata e shouldPreserveUserFacingSessionStateForInputProvenance lascia intatto lo stato user-facing della sessione. In chat resta solo la risposta dell'agente, come per le completion dei subagent. Con un sourceTool fuori da quella lista (es. soltea_agent_runner) il messaggio resta visibile, marcato come inter-sessione.

E' lo stesso meccanismo del bridge ACP di OpenClaw.

Ripieghi (meglio un esito attribuito male che un esito perso)

  1. chat.send rifiutato per scope (system provenance fields require admin scope) -> retry stessa idempotency key senza provenance, con warning.
  2. WS non praticabile (gateway in restart, token errato) e GW_WAKE_HTTP_URL valorizzato -> ripiego su http.

Config

env default
GW_WAKE_WS_URL ws://127.0.0.1:18789
GW_WAKE_WS_TOKEN "" — token operator OpenClaw, serve scope operator.admin
GW_WAKE_SOURCE_TOOL agent_harness_task
GW_WAKE_SOURCE_CHANNEL soltea-agent-gateway

GW_WAKE_MODE resta none di default: nessun cambiamento di comportamento senza intervento sull'env.

Test

11 test nuovi (handshake + scope + params di provenance, retry senza provenance, ripiego http, frame estranei ignorati). Suite: 94 passed.

Deploy (dopo il merge)

/etc/soltea-gateway/gateway.env su srv20: GW_WAKE_MODE=chatsend + GW_WAKE_WS_TOKEN=<token operator OpenClaw con admin scope>, lasciando GW_WAKE_HTTP_URL dov'e' come fallback. Poi systemctl restart soltea-gateway.

## Problema Il wake di fine task via hook (`GW_WAKE_MODE=cli` / `http`) accoda un **system event**. OpenClaw non lo rende come messaggio di ruolo `system`: lo **antepone al body del turno successivo** (`prependEvents` in `buildReplyPromptBodies`), e il set di `systemNotice` della Control UI e' chiuso e non include i wake dei hook. Risultato: in chat il report del runner sembra **scritto dall'utente**. ## Fix Nuovo trasporto `GW_WAKE_MODE=chatsend`: `chat.send` sul Gateway WS di OpenClaw (`ws://127.0.0.1:18789`) con `systemInputProvenance`: ```json {"kind": "inter_session", "sourceTool": "agent_harness_task", "sourceChannel": "soltea-agent-gateway", "sourceSessionKey": "<sessione>"} ``` - `kind: inter_session` -> il messaggio arriva al modello marcato `[Inter-session message] ... isUser=false`. - `sourceTool` di default `agent_harness_task`: e' uno dei source tool che OpenClaw riconosce come **completion report** (`isCompletionReportInputProvenance`), quindi `shouldHideProjectedHistoryMessage` lo **nasconde dalla cronologia proiettata** e `shouldPreserveUserFacingSessionStateForInputProvenance` lascia intatto lo stato user-facing della sessione. In chat resta solo la risposta dell'agente, come per le completion dei subagent. Con un `sourceTool` fuori da quella lista (es. `soltea_agent_runner`) il messaggio resta visibile, marcato come inter-sessione. E' lo stesso meccanismo del bridge ACP di OpenClaw. ## Ripieghi (meglio un esito attribuito male che un esito perso) 1. `chat.send` rifiutato per scope (`system provenance fields require admin scope`) -> retry **stessa idempotency key** senza provenance, con warning. 2. WS non praticabile (gateway in restart, token errato) e `GW_WAKE_HTTP_URL` valorizzato -> ripiego su `http`. ## Config | env | default | |---|---| | `GW_WAKE_WS_URL` | `ws://127.0.0.1:18789` | | `GW_WAKE_WS_TOKEN` | "" — token operator OpenClaw, serve **scope `operator.admin`** | | `GW_WAKE_SOURCE_TOOL` | `agent_harness_task` | | `GW_WAKE_SOURCE_CHANNEL` | `soltea-agent-gateway` | `GW_WAKE_MODE` resta `none` di default: **nessun cambiamento di comportamento senza intervento sull'env**. ## Test 11 test nuovi (handshake + scope + params di provenance, retry senza provenance, ripiego http, frame estranei ignorati). Suite: **94 passed**. ## Deploy (dopo il merge) `/etc/soltea-gateway/gateway.env` su srv20: `GW_WAKE_MODE=chatsend` + `GW_WAKE_WS_TOKEN=<token operator OpenClaw con admin scope>`, lasciando `GW_WAKE_HTTP_URL` dov'e' come fallback. Poi `systemctl restart soltea-gateway`.
I trasporti cli/http accodano un *system event*, che OpenClaw non rende come
messaggio di ruolo system: lo antepone al body del turno successivo
(prependEvents in buildReplyPromptBodies). Risultato: in chat il report del
runner sembra scritto dall'utente.

Nuovo trasporto `chatsend`: chat.send sul Gateway WS di OpenClaw con
systemInputProvenance (kind: inter_session, isUser=false). Con il sourceTool di
default (agent_harness_task, riconosciuto da OpenClaw come completion report) il
messaggio di risveglio viene nascosto dalla cronologia proiettata e in chat resta
solo la risposta dell'agente, come per le completion dei subagent.

I campi di provenance sono admin-only: serve un token operator con scope
operator.admin (GW_WAKE_WS_TOKEN). Se lo scope manca si ripiega su chat.send
senza provenance (stesso comportamento del bridge ACP di OpenClaw); se il WS non
e' praticabile e GW_WAKE_HTTP_URL e' configurato si ripiega su http: meglio un
esito attribuito male che un esito perso.

Default invariati: GW_WAKE_MODE resta `none`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Soltea-org/soltea-agent-gateway!16
No description provided.