When the final result text is identical to the last progress update,
edit the progress message back to the previous progress text to avoid
showing the same content twice in Discord.
- Use system/task_progress subtype (not top-level type) for subagent events
- Extract intermediate assistant text between tool calls as progress
- Only show SDK-generated summaries for subagent progress (skip noisy per-tool updates)
- Truncate progress messages to Discord 2000 char limit
- Remove verbose debug logging from production
- Set agentProgressSummaries: true in SDK query options
- Handle task_progress and task_started events from subagents
- Subagent progress summaries streamed as progress phase to Discord
- Auto-suspend tasks after 3 consecutive quota/auth errors with
retry-after date parsing and Discord notification
- Add tool_progress and tool_use_summary streaming from Claude Agent SDK
- Prefix progress messages with invisible marker so bots ignore them
- Fix misleading provider label in codex service logs
Two v1/v2 regressions fixed:
1. Progress messages became too brittle: editMessage failure killed all
subsequent progress updates for the turn. Now resets progressMessageId
and recreates on next update instead of permanently stopping.
2. Follow-up messages stuck in active agent without output: after 10s of
no output, closeStdin and requeue the follow-up as a fresh run with
cursor rollback, instead of silently dropping it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove duplicate processGroupMessages, runAgent, startMessageLoop, and
recoverPendingMessages from index.ts. All message processing now flows
through createMessageRuntime() in message-runtime.ts, eliminating the
dual-path issue that caused the v1 follow-up turn reset bug.
index.ts reduced from ~2300 to ~1210 lines.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Major reliability improvements to the message processing pipeline:
- Add messages.seq monotonic cursor replacing timestamp-based cursors,
preventing message loss from timestamp collisions with LIMIT queries
- Add work_items table separating agent production from delivery,
enabling delivery retry without re-running the agent
- Propagate Discord send failures instead of silently swallowing them
- Add Claude 429 → Kimi K2.5 automatic provider fallback with cooldown
- Fix follow-up turn state reset in live index.ts path (not just
message-runtime.ts) to prevent final output from being lost
- Add restart context tracking for graceful restart announcements
- Lazy migration from timestamp cursors to seq cursors for existing data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
watch_ci tasks in perf channel were silently failing because
NANOCLAW_CHAT_JID was set to the group folder name (e.g. "eyejokerdb-4")
instead of the actual Discord JID. The scheduler rejected the task with
"target group not registered".
Also adds a fallback in ipc.ts to resolve folder names to registered
JIDs when a folder name is passed instead of a JID.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>