storkit: done 365_story_surface_api_rate_limit_warnings_in_chat

This commit is contained in:
dave
2026-03-22 19:28:48 +00:00
parent 24dd3d9fa9
commit 69936f457f

View File

@@ -0,0 +1,64 @@
---
name: "Surface API rate limit warnings in chat"
---
# Story 365: Surface API rate limit warnings in chat
## User Story
As a project owner watching the chat, I want to see rate limit warnings surfaced directly in the conversation when they appear in the agent's PTY output, so that I know immediately when an agent is being throttled without having to watch server logs.
## Acceptance Criteria
- [x] Server detects rate limit warnings in pty-debug output lines
- [x] When a rate limit warning is detected, a notification is sent to the active chat (Matrix/Slack/WhatsApp)
- [x] The notification includes which agent/story triggered the rate limit
- [x] Rate limit notifications are debounced to avoid spamming the chat with repeated warnings
## Technical Context
Claude Code emits `rate_limit_event` JSON in its streaming output:
```json
{
"type": "rate_limit_event",
"rate_limit_info": {
"status": "allowed_warning",
"resetsAt": 1774443600,
"rateLimitType": "seven_day",
"utilization": 0.82,
"isUsingOverage": false,
"surpassedThreshold": 0.75
}
}
```
Key fields:
- `status`: `"allowed_warning"` when approaching limit, likely `"blocked"` or similar when hard-limited
- `rateLimitType`: e.g. `"seven_day"` rolling window
- `utilization`: 0.01.0 fraction of limit consumed
- `resetsAt`: Unix timestamp when the window resets
- `surpassedThreshold`: the threshold that triggered the warning (e.g. 0.75 = 75%)
These events are already logged as `[pty-debug] raw line:` in the server logs. The PTY reader in `server/src/llm/providers/claude_code.rs` (line ~234) sees them but doesn't currently parse or act on them.
## Out of Scope
- TBD
## Test Results
<!-- storkit-test-results: {"unit":[{"name":"rate_limit_event_json_sends_watcher_warning","status":"pass","details":"PTY reader detects rate_limit_event JSON and emits RateLimitWarning watcher event"},{"name":"rate_limit_warning_sends_notification_with_agent_and_story","status":"pass","details":"Notification listener sends chat message with agent and story info"},{"name":"rate_limit_warning_is_debounced","status":"pass","details":"Second warning within 60s window is suppressed"},{"name":"rate_limit_warnings_for_different_agents_both_notify","status":"pass","details":"Different agents are debounced independently"},{"name":"format_rate_limit_notification_includes_agent_and_story","status":"pass","details":"Notification text includes story number, name, and agent name"},{"name":"format_rate_limit_notification_falls_back_to_item_id","status":"pass","details":"Falls back to item_id when story name is unavailable"}],"integration":[]} -->
### Unit Tests (6 passed, 0 failed)
- ✅ rate_limit_event_json_sends_watcher_warning — PTY reader detects rate_limit_event JSON and emits RateLimitWarning watcher event
- ✅ rate_limit_warning_sends_notification_with_agent_and_story — Notification listener sends chat message with agent and story info
- ✅ rate_limit_warning_is_debounced — Second warning within 60s window is suppressed
- ✅ rate_limit_warnings_for_different_agents_both_notify — Different agents are debounced independently
- ✅ format_rate_limit_notification_includes_agent_and_story — Notification text includes story number, name, and agent name
- ✅ format_rate_limit_notification_falls_back_to_item_id — Falls back to item_id when story name is unavailable
### Integration Tests (0 passed, 0 failed)
*No integration tests recorded.*