rdev/ai-lookup/services/webhooks.md
jordan 39df51defd feat: Add multi-provider code agent interface with Claude Code and OpenCode adapters
Implements weeks 1-4 of the multi-provider architecture:

Week 1 - Foundation:
- Add domain models (AgentProvider, AgentRequest, AgentEvent, AgentResult)
- Define CodeAgent port interface with Execute, Cancel, Capabilities
- Create thread-safe provider registry with first-registered default

Week 2 - Claude Code Adapter:
- Extract kubectl exec logic into CodeAgent implementation
- Parse stream-json output format (init, message, tool_use, result)
- Support session continuation via --resume flag

Week 3 - OpenCode Adapter:
- HTTP/SSE client for opencode serve API
- Session management (create, send message, abort)
- Event streaming with documented buffer rationale

Week 4 - Quality & Polish:
- Fix race condition in OpenCode Cancel method
- Add AgentRequest.Validate() with ErrPromptRequired, ErrInvalidTimeout
- Document DefaultAvailabilityTimeout constants
- Add HTTP error context for debugging

Also includes:
- Work queue system with PostgreSQL adapter
- Credential store for infrastructure secrets
- Project templates with Woodpecker CI integration
- Comprehensive test coverage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 09:25:51 -07:00

1.2 KiB

Webhooks

Last Updated: 2025-01 Confidence: High

Summary

Webhooks notify external systems when events occur in rdev. Subscriptions are created via API, and events are delivered with automatic retries.

Key Facts:

  • Event types: command.started, command.completed, command.failed
  • Retry policy: 3 attempts, 5s initial backoff, exponential
  • Delivery history stored for debugging
  • Worker pool (10 workers) for parallel delivery

File Pointers:

  • Handler: internal/handlers/webhooks.go
  • Dispatcher: internal/webhook/dispatcher.go
  • Repository: internal/adapter/postgres/webhook.go
  • Domain: internal/domain/webhook.go

Subscription

POST /webhooks
{
    "url": "https://example.com/webhook",
    "events": ["command.completed", "command.failed"]
}

Event Payload

{
    "event": "command.completed",
    "timestamp": "2025-01-15T10:30:00Z",
    "data": {
        "command_id": "cmd-123",
        "project": "my-project",
        "type": "claude",
        "exit_code": 0,
        "duration_ms": 5432
    }
}