Plugin (Go server + React webapp): - Custom post type 'custom_livestatus' with terminal-style rendering - WebSocket broadcasts for real-time updates (no PUT, no '(edited)') - KV store for session persistence across reconnects - Shared secret auth for daemon-to-plugin communication - Auto-scroll terminal with user scroll override - Collapsible sub-agent sections - Theme-compatible CSS (light/dark) Daemon integration: - PluginClient for structured data push to plugin - Auto-detection: GET /health on startup + periodic re-check - Graceful fallback: if plugin unavailable, uses REST API (PUT) - Per-session mode tracking: sessions created via plugin stay on plugin - Mid-session fallback: if plugin update fails, auto-switch to REST Plugin deployed and active on Mattermost v11.4.0.
108 lines
4.9 KiB
Markdown
108 lines
4.9 KiB
Markdown
# Discovery Findings: Live Status v4
|
|
|
|
## Overview
|
|
|
|
Planner sub-agent (proj035-planner) conducted inline discovery before drafting the plan. Key findings are documented here.
|
|
|
|
## Discovery 1: JSONL Transcript Format
|
|
|
|
**Confirmed format (JSONL, version 3):**
|
|
|
|
Each line is a JSON object with `type` field:
|
|
|
|
- `session` — First line only. Contains `id` (UUID), `version: 3`, `cwd`
|
|
- `model_change` — `provider`, `modelId` change events
|
|
- `thinking_level_change` — thinking on/off
|
|
- `custom` — Subtypes: `model-snapshot`, `openclaw.cache-ttl` (turn boundary marker)
|
|
- `message` — Main event type. `role` = `user`, `assistant`, or `toolResult`
|
|
|
|
Message content types:
|
|
|
|
- `{type: "text", text: "..."}` — plain text from any role
|
|
- `{type: "toolCall", id, name, arguments: {...}}` — tool invocations in assistant messages
|
|
- `{type: "thinking", thinking: "..."}` — internal reasoning (thinking mode)
|
|
|
|
Assistant messages carry extra fields: `api`, `provider`, `model`, `usage`, `stopReason`, `timestamp`
|
|
|
|
ToolResult messages carry: `toolCallId`, `toolName`, `isError`, `content: [{type, text}]`
|
|
|
|
**Key signals for watcher:**
|
|
|
|
- `stopReason: "stop"` + no new lines → agent turn complete → idle
|
|
- `stopReason: "toolUse"` → agent waiting for tool results → NOT idle
|
|
- `custom.customType: "openclaw.cache-ttl"` → turn boundary marker
|
|
|
|
## Discovery 2: Session Keying
|
|
|
|
Session keys in sessions.json follow the pattern: `agent:{agentId}:{context}`
|
|
|
|
Examples:
|
|
|
|
- `agent:main:main` — direct session
|
|
- `agent:main:mattermost:channel:{channelId}` — channel session
|
|
- `agent:main:mattermost:channel:{channelId}:thread:{threadId}` — thread session
|
|
- `agent:main:subagent:{uuid}` — SUB-AGENT SESSION (has `spawnedBy`, `spawnDepth`, `label`)
|
|
- `agent:main:hook:gitea:{repo}:issue:{n}` — hook-triggered session
|
|
- `agent:main:cron:{name}` — cron session
|
|
|
|
Sub-agent entry fields relevant to watcher:
|
|
|
|
- `sessionId` — maps to `{sessionId}.jsonl` filename
|
|
- `spawnedBy` — parent session key (for nesting)
|
|
- `spawnDepth` — nesting depth (1 = direct child of main)
|
|
- `label` — human-readable name (e.g., "proj035-planner")
|
|
- `channel` — delivery channel (mattermost, etc.)
|
|
|
|
Sessions files: `/home/node/.openclaw/agents/{agentId}/sessions/`
|
|
|
|
- `sessions.json` — registry (updated on every message)
|
|
- `{uuid}.jsonl` — transcript files
|
|
- `{uuid}-topic-{topicId}.jsonl` — topic-scoped transcripts
|
|
|
|
## Discovery 3: OpenClaw Hook Events
|
|
|
|
Available internal hook events (confirmed from source):
|
|
|
|
- `command:new`, `command:reset`, `command:stop` — user commands
|
|
- `command` — all commands
|
|
- `agent:bootstrap` — before workspace files injected
|
|
- `gateway:startup` — gateway startup (250ms after channels start)
|
|
|
|
**NO session:start or session:end hooks exist.** The hooks system covers commands and gateway lifecycle only, NOT individual agent runs.
|
|
|
|
Sub-agent lifecycle hooks (`subagent_spawned`, `subagent_ended`) are channel plugin hooks, not internal hooks — not directly usable from workspace hooks.
|
|
|
|
**Hook handler files:** workspace hooks support `handler.ts` OR `handler.js` (both discovered automatically via `handlerCandidates` in workspace.ts).
|
|
|
|
## Discovery 4: Mattermost API
|
|
|
|
- `PostEditTimeLimit = -1` — unlimited edits on this server
|
|
- Bot token: `<redacted>` (default/main bot account, set via MM_BOT_TOKEN env var)
|
|
- Multiple bot accounts available per agent (see openclaw.json `accounts`)
|
|
- API base: `https://slack.solio.tech/api/v4`
|
|
- Post update: `PUT /api/v4/posts/{id}` — no time limit, no count limit
|
|
|
|
## Discovery 5: Current v1 Failure Modes
|
|
|
|
- Agents call `live-status create/update/complete` manually
|
|
- `deploy-to-agents.sh` injects verbose 200-word protocol into AGENTS.md
|
|
- Agents forget to call it (no enforcement mechanism)
|
|
- IDs get lost between tool calls (no persistent state)
|
|
- No sub-agent visibility (sub-agents have separate sessions)
|
|
- Thread sessions create separate OpenClaw sessions → IDs not shared
|
|
- Final response dumps multiple status updates (spam from forgotten updates)
|
|
|
|
## Discovery 6: Repo State
|
|
|
|
- Workspace copy: `/home/node/.openclaw/workspace/projects/openclaw-live-status/`
|
|
- `src/live-status.js` — 283 lines, v2 CLI with --agent, --channel, --reply-to, create/update/complete/delete
|
|
- `deploy-to-agents.sh` — AGENTS.md injection approach
|
|
- `skill/SKILL.md` — manual usage instructions
|
|
- `src/agent-accounts.json` — agent→bot account mapping
|
|
- Remote repo (ROOH/MATTERMOST_OPENCLAW_LIVESTATUS): `src/live-status.js` is outdated (114 lines v1)
|
|
- Makefile with check/test/lint/fmt targets already exists in remote repo
|
|
|
|
## Synthesis
|
|
|
|
The transcript-tailing daemon approach is sound and the format is stable. The key implementation insight is: **watch sessions.json to discover new sessions, then watch each JSONL file for that session**. Sub-agents are automatically discoverable via `spawnedBy` fields. The hook system can auto-start the daemon on gateway startup via `gateway:startup` event. No new OpenClaw core changes are needed.
|