Add retry button for failed chat messages and disable continuation on error
When a chat thread ends in error, users can no longer continue the
conversation (which made no semantic sense). Instead, a retry button
appears inline after the error message to re-attempt the failed request.
Backend changes:
- Add get_agent_end_state() to detect finish vs error terminal states
- Add /api/chat/<id>/retry endpoint to re-send failed prompts
- Return can_continue and end_state in chat events response
- Extract API key validation to _get_backend_api_key() helper (DRY)
Frontend changes:
- Add showRetryButton()/hideRetryButton() and retryChat() functions
- Disable input and show retry button on error (live and historical)
- Add enableInput parameter to showError() to prevent state conflicts
- Add retry button CSS with hover/active states
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>