* feat: refresh dashboard settings UX and Codex feature toggles
Improve settings/tasks mobile layout, model effort validation by agent type, and preset models for GPT 5.5 and Opus 4.7. Store Codex fast mode and goals in config.toml with Claude fastMode session sync and updated docs for Codex 0.133.
Co-authored-by: Cursor <cursoragent@cursor.com>
* style: apply pre-commit formatting after dashboard settings commit
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Voice messages (Discord IsVoiceMessage flag or attachment with duration)
are still transcribed via Whisper. Regular audio file attachments (WAV,
MP3, etc.) are now downloaded to disk and the path is passed to the
agent, matching image attachment behavior.
- Remove UNIFIED_MODE legacy: single service manages all 3 Discord bots
- Add OWNER_AGENT_TYPE / REVIEWER_AGENT_TYPE env vars for configurable agent selection
- Fix Discord channel routing: reviewer output goes through correct bot (discord/discord-review)
- Fix channel name assignment: explicit names prevent agentTypeFilter collision
- Remove silent output suppression system: harness-level protections replace prompt workarounds
- Add reviewer approval detection: DONE marker on first line stops ping-pong
- Include user's original message in reviewer prompt for context
- Fix round_trip_count auto-reset on new user message
- Fix session ID conflict: reviewer doesn't reuse owner's session
- Fix pending progress text flush in runner on close sentinel
- Promote buffered intermediate text to final result when result event has no text
- Remove legacy files: .env.codex.example, .env.codex-review.example, migrate-unify.cjs
- Update CLAUDE.md: server-side build deployment, unified architecture docs
- Add UNIFIED_MODE flag (default on, disable with UNIFIED_MODE=0)
- Register all 3 Discord bots in one process (claude, codex, review)
- Load all registered groups regardless of agent_type (codex/owner priority)
- Start credential proxy and container cleanup at unified startup
- shouldServiceProcessChat returns true in unified mode
- Add findChannelByName for role-based response routing
- Backward compatible: UNIFIED_MODE=0 restores per-service behavior
The narrowed list (.txt, .md, .csv, .json, .log) was for outbound,
but was mistakenly applied to inbound. Restore full list for user
file uploads (input direction).
Restrict Discord attachment inline parsing to .txt, .md, .csv, .json, .log
and text/* content type. Code files (.ts, .tsx, .js, .py, etc.) now show
filename only instead of being inlined into the message.
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>
The codex service uses its own DISCORD_BOT_TOKEN via systemd
EnvironmentFile, so the discord-codex secondary channel is only
relevant for the primary service. Removes spurious credential
missing warning on codex service startup.
Download and inline content of .txt and other text-based file
attachments instead of showing just the filename placeholder.
Handles long copy-pastes that Discord auto-converts to .txt files.
Truncates at 8000 chars with a note.
Groq runs the same whisper-large-v3-turbo model at 200x+ real-time speed.
Falls back to OpenAI Whisper if GROQ_API_KEY is not set.
Logs elapsed time per transcription for monitoring.
Both services (nanoclaw + nanoclaw-codex) now share cache/transcriptions/
directory. When one service transcribes audio, the other reads from cache
instead of making a second Whisper API call. Uses .pending file to
coordinate concurrent transcription attempts.