Skip to content

feat: webhook alert when virtual key token threshold is crossed (Story 3.4)#136

Open
farovictor wants to merge 1 commit intomainfrom
feat/webhook-alerts
Open

feat: webhook alert when virtual key token threshold is crossed (Story 3.4)#136
farovictor wants to merge 1 commit intomainfrom
feat/webhook-alerts

Conversation

@farovictor
Copy link
Copy Markdown
Owner

Summary

  • Two new fields on VirtualKey: alert_threshold (int, tokens) and alert_webhook (URL)
  • After each proxied request, Bifrost checks if the cumulative token count just crossed the threshold — fires a POST to the webhook URL in a background goroutine
  • One-shot semantics: alert fires exactly once when prevTotal < threshold <= newTotal. Subsequent requests already above threshold are silent
  • Webhook is best-effort — failures are logged, never affect the proxied response
  • Migration 012_add_virtual_key_alert.sql

Webhook payload

{
  "event": "token_threshold_crossed",
  "key_id": "vk-abc",
  "service": "openai",
  "threshold": 100,
  "total_tokens": 101,
  "timestamp": "2026-04-06T19:00:00Z"
}

Test plan

  • TestWebhookAlert_FiredByProxyWhenTrackTokensOn — crossing fires exactly 1 webhook call with correct payload
  • TestWebhookAlert_NotFiredWhenBelowThreshold — no call when total stays below threshold
  • TestWebhookAlert_NotFiredWhenAlreadyOver — no call when prevTotal already >= threshold
  • TestWebhookAlert_FiredWhenThresholdCrossed — proxy request succeeds regardless of webhook outcome

🤖 Generated with Claude Code

…y 3.4)

- Two new fields on VirtualKey: alert_threshold (int) and alert_webhook (URL)
- After each proxied request, proxy checks if TotalTokens just crossed the
  threshold (prevTotal < threshold <= newTotal) and fires a non-blocking POST
- Alert fires once — subsequent requests already above threshold are ignored
- Payload: event, key_id, service, threshold, total_tokens, timestamp
- Migration 012_add_virtual_key_alert.sql
- 4 tests: fires on crossing, fires via proxy with token tracking, not fired
  below threshold, not fired when already above threshold

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant