Documentation
¶
Overview ¶
Package daemon provides a Telegram gateway for hawk. Allows users to interact with hawk via Telegram bot messages.
Index ¶
- func SetVersion(v string)
- type ChatRequest
- type ChatResponse
- type Config
- type DiscordConfig
- type DiscordGateway
- type ErrorResponse
- type Gateway
- type GatewaysConfig
- type HealthResponse
- type MessageResponse
- type ModelStatResp
- type PaginatedResponse
- type Preheater
- type ReadyResponse
- type ReviewRequest
- type ReviewResponse
- type Server
- type Session
- type SessionDetailResponse
- type SessionFactory
- type SlackConfig
- type SlackGateway
- type StatsResponse
- type TelegramConfig
- type TelegramGateway
- type TelegramMessage
- type TelegramUpdate
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SetVersion ¶
func SetVersion(v string)
SetVersion propagates the canonical hawk version into the daemon.
Types ¶
type ChatRequest ¶
type ChatRequest struct {
Prompt string `json:"prompt"`
SessionID string `json:"session_id,omitempty"`
Model string `json:"model,omitempty"`
MaxTurns int `json:"max_turns,omitempty"`
Autonomy string `json:"autonomy,omitempty"`
CWD string `json:"cwd,omitempty"`
Agent string `json:"agent,omitempty"`
}
ChatRequest is the JSON body for POST /v1/chat.
type ChatResponse ¶
type ChatResponse struct {
SessionID string `json:"session_id"`
Response string `json:"response"`
TokensIn int `json:"tokens_in"`
TokensOut int `json:"tokens_out"`
TurnsTaken int `json:"turns_taken"`
Duration string `json:"duration"`
}
ChatResponse is the JSON response from POST /v1/chat.
type Config ¶
type Config struct {
Port int `json:"port"`
Host string `json:"host"`
LogFile string `json:"log_file"`
APIKey string `json:"api_key,omitempty"`
// Gateways configures optional messaging bridges (Telegram/Discord/Slack).
// All are disabled by default; the daemon starts normally when none are set.
Gateways GatewaysConfig `json:"gateways,omitempty"`
}
Config holds daemon configuration.
type DiscordConfig ¶
type DiscordConfig struct {
Enabled bool `json:"enabled,omitempty"`
Token string `json:"token,omitempty"` // bot token
// AppID is the application/bot user ID, used to detect @mentions.
AppID string `json:"app_id,omitempty"`
PairingCode string `json:"pairing_code,omitempty"`
AllowList []string `json:"allow_list,omitempty"`
}
DiscordConfig configures the Discord gateway.
type DiscordGateway ¶
type DiscordGateway struct {
// contains filtered or unexported fields
}
DiscordGateway bridges hawk to Discord. Because no WebSocket library is present in go.mod, the gateway uses a REST long-poll-equivalent strategy: it does not open the Discord Gateway socket but instead relies on a poll over the bot's accessible channels for new @mentions/DMs. This keeps the bridge dependency-free while remaining bidirectional (it posts replies in-thread via the REST API).
The polling transport is intentionally minimal and pluggable: fetchMessages is a field so a real Gateway-WebSocket implementation (or a test) can be swapped in without changing the message-handling logic.
func (*DiscordGateway) Start ¶
func (g *DiscordGateway) Start(ctx context.Context) error
Start implements Gateway: poll watched channels until ctx is cancelled.
func (*DiscordGateway) Stop ¶
func (g *DiscordGateway) Stop() error
Stop implements Gateway. Polling is driven by the Start context.
type ErrorResponse ¶
type ErrorResponse struct {
Error string `json:"error"`
Code string `json:"code,omitempty"`
Details string `json:"details,omitempty"`
}
ErrorResponse is the standard error envelope.
type Gateway ¶
type Gateway interface {
// Name returns a short identifier for the gateway (e.g. "telegram").
Name() string
// Start begins processing messages. It should block until ctx is cancelled
// (long-poll gateways) or return promptly after registering handlers
// (webhook gateways). Implementations must respect ctx cancellation.
Start(ctx context.Context) error
// Stop releases any resources held by the gateway. It is safe to call Stop
// even if Start was never called or already returned.
Stop() error
}
Gateway is a bidirectional messaging bridge between an external chat platform (Telegram, Discord, Slack, ...) and the hawk daemon. Implementations forward inbound messages to the daemon's /v1/chat endpoint and relay the reply back.
type GatewaysConfig ¶
type GatewaysConfig struct {
Telegram TelegramConfig `json:"telegram,omitempty"`
Discord DiscordConfig `json:"discord,omitempty"`
Slack SlackConfig `json:"slack,omitempty"`
}
GatewaysConfig groups the per-platform messaging bridge configuration. All gateways are disabled by default; a gateway only starts when its Enabled flag is set and its required credentials are present.
type HealthResponse ¶
type HealthResponse struct {
Status string `json:"status"`
Version string `json:"version"`
Uptime string `json:"uptime"`
Sessions int `json:"active_sessions"`
StartedAt string `json:"started_at"`
}
HealthResponse is the JSON response from GET /v1/health.
type MessageResponse ¶
type MessageResponse struct {
Role string `json:"role"`
Content string `json:"content,omitempty"`
ToolUse interface{} `json:"tool_use,omitempty"`
ToolResult interface{} `json:"tool_results,omitempty"`
}
MessageResponse is a message in GET /v1/sessions/{id}/messages.
type ModelStatResp ¶
type ModelStatResp struct {
Model string `json:"model"`
Requests int `json:"requests"`
CostUSD float64 `json:"cost_usd"`
}
ModelStatResp is per-model statistics within StatsResponse.
type PaginatedResponse ¶
type PaginatedResponse struct {
Data interface{} `json:"data"`
Total int `json:"total"`
Offset int `json:"offset"`
Limit int `json:"limit"`
HasMore bool `json:"has_more"`
}
PaginatedResponse wraps paginated list results.
type Preheater ¶
type Preheater struct {
// contains filtered or unexported fields
}
Preheater maintains warm connections and pre-initialized state to eliminate cold-start latency on first request.
func NewPreheater ¶
NewPreheater creates a preheater with the given warmup interval.
func (*Preheater) Ready ¶
Ready reports whether the preheater has completed at least one warmup cycle.
type ReadyResponse ¶
type ReadyResponse struct {
// Ready is true only when every dependency is initialized.
Ready bool `json:"ready"`
// Reason describes why the daemon is not ready (empty when ready).
Reason string `json:"reason,omitempty"`
// Uptime is the time since the server started.
Uptime string `json:"uptime"`
}
ReadyResponse is the JSON response from GET /v1/ready.
type ReviewRequest ¶
type ReviewRequest struct {
SHA string `json:"sha"`
Background bool `json:"background,omitempty"`
Model string `json:"model,omitempty"`
Concerns string `json:"concerns,omitempty"`
}
ReviewRequest is the JSON body for POST /v1/review.
type ReviewResponse ¶
type ReviewResponse struct {
ID int64 `json:"id"`
SHA string `json:"sha"`
Status string `json:"status"`
Message string `json:"message,omitempty"`
}
ReviewResponse is the JSON response from POST /v1/review.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the hawk daemon HTTP server for programmatic/CI access.
func New ¶
func New(cfg Config, factory SessionFactory) *Server
New creates a new daemon server. If factory is nil, chat endpoint returns an error.
func (*Server) RegisterReviewRoutes ¶
func (s *Server) RegisterReviewRoutes()
RegisterReviewRoutes adds review endpoints to the daemon. Called from routes() if review support is enabled.
func (*Server) SetReadyFn ¶
SetReadyFn installs a custom readiness probe. The probe should return (true, "") when all dependencies (session store, provider connectivity) are initialized, or (false, reason) otherwise. Passing nil restores the default probe. This is additive and safe to call concurrently with serving.
type Session ¶
type Session struct {
ID string `json:"id"`
CreatedAt time.Time `json:"created_at"`
LastUsed time.Time `json:"last_used"`
Turns int `json:"turns"`
CWD string `json:"cwd"`
}
Session tracks an active daemon session.
type SessionDetailResponse ¶
type SessionDetailResponse struct {
ID string `json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Model string `json:"model"`
Provider string `json:"provider"`
CWD string `json:"cwd"`
Name string `json:"name"`
MessageCount int `json:"message_count"`
ToolCalls int `json:"tool_calls"`
}
SessionDetailResponse is the response for GET /v1/sessions/{id}.
type SessionFactory ¶
type SessionFactory func(req ChatRequest) (*engine.Session, error)
SessionFactory creates a configured engine session for a given request. The caller (cmd package) provides this, wiring system prompts, tools, keys.
type SlackConfig ¶
type SlackConfig struct {
Enabled bool `json:"enabled,omitempty"`
SigningSecret string `json:"signing_secret,omitempty"`
BotToken string `json:"bot_token,omitempty"` // xoxb- token for chat.postMessage
// Path is the HTTP route registered on the daemon mux for the Events API
// webhook. Defaults to "/v1/slack/events" when empty.
Path string `json:"path,omitempty"`
PairingCode string `json:"pairing_code,omitempty"`
AllowList []string `json:"allow_list,omitempty"`
}
SlackConfig configures the Slack Events API gateway.
type SlackGateway ¶
type SlackGateway struct {
// contains filtered or unexported fields
}
SlackGateway implements the Slack Events API bridge. Unlike Telegram/Discord it is webhook-driven: Start registers an HTTP handler on the daemon mux and returns after blocking on ctx (so the gatewayManager lifecycle is uniform). Inbound app_mention events are verified against the signing secret, forwarded to the daemon, and answered as threaded replies.
type StatsResponse ¶
type StatsResponse struct {
TotalSessions int `json:"total_sessions"`
TotalMessages int `json:"total_messages"`
TotalToolCalls int `json:"total_tool_calls"`
TotalCostUSD float64 `json:"total_cost_usd"`
ActiveDays int `json:"active_days"`
Models []ModelStatResp `json:"models"`
}
StatsResponse is the response for GET /v1/stats.
type TelegramConfig ¶
type TelegramConfig struct {
Enabled bool `json:"enabled,omitempty"`
Token string `json:"token,omitempty"`
// PairingCode, when non-empty, requires senders to issue "/pair <code>"
// once before their sender ID is added to the allowlist.
PairingCode string `json:"pairing_code,omitempty"`
// AllowList is an optional set of pre-authorized sender IDs (Telegram usernames
// or numeric chat IDs as strings). When both PairingCode and AllowList are
// empty, the gateway refuses all senders (fail closed).
AllowList []string `json:"allow_list,omitempty"`
}
TelegramConfig configures the Telegram long-poll gateway.
type TelegramGateway ¶
type TelegramGateway struct {
Token string
DaemonAddr string // hawk daemon address to forward messages to
// contains filtered or unexported fields
}
TelegramGateway connects hawk to a Telegram bot.
func NewTelegramGateway ¶
func NewTelegramGateway(token, daemonAddr string) *TelegramGateway
NewTelegramGateway creates a gateway with the given bot token.
func (*TelegramGateway) Run ¶
func (tg *TelegramGateway) Run(ctx context.Context) error
Run starts the long-polling loop. Blocks until context is cancelled.
func (*TelegramGateway) Start ¶
func (tg *TelegramGateway) Start(ctx context.Context) error
Start implements Gateway by delegating to the long-poll Run loop.
func (*TelegramGateway) Stop ¶
func (tg *TelegramGateway) Stop() error
Stop implements Gateway. The long-poll loop is driven by the context passed to Start, so there is nothing to release here.
type TelegramMessage ¶
type TelegramMessage struct {
MessageID int `json:"message_id"`
Text string `json:"text"`
Chat struct {
ID int64 `json:"id"`
} `json:"chat"`
From struct {
Username string `json:"username"`
} `json:"from"`
}
TelegramMessage is a Telegram chat message.
type TelegramUpdate ¶
type TelegramUpdate struct {
UpdateID int `json:"update_id"`
Message *TelegramMessage `json:"message,omitempty"`
}
TelegramUpdate represents an incoming Telegram message.