Documentation
¶
Index ¶
- Constants
- Variables
- func ParseClientFrame(data []byte) (any, error)
- func ValidateKeyInput(name string, scopes []string) error
- type APIKeyRecord
- type ApprovalResponseFrame
- type CancelFrame
- type ChatRequestFrame
- type Deps
- type KeyStore
- func (ks *KeyStore) Create(ctx context.Context, name string, scopes []string) (APIKeyRecord, string, error)
- func (ks *KeyStore) Delete(ctx context.Context, id string) error
- func (ks *KeyStore) FindActiveByHash(ctx context.Context, tokenHash string) (*storedKey, error)
- func (ks *KeyStore) HasActiveKey(ctx context.Context) (bool, error)
- func (ks *KeyStore) List(ctx context.Context) ([]APIKeyRecord, error)
- func (ks *KeyStore) Revoke(ctx context.Context, id string) error
- func (ks *KeyStore) Rotate(ctx context.Context, id string) (APIKeyRecord, string, error)
- func (ks *KeyStore) TouchLastUsed(ctx context.Context, id string)
- type OAuthDeps
- type OIDCProvider
- type PingFrame
- type PongFrame
- type ReplayBuffer
- type ReplayStore
- type SSEStreamSession
- type Server
- type Session
- type SessionManager
- type StreamSession
- type WSClientFrame
- type WSConn
- type WSErrorFrame
- type WSEventFrame
- type WSHub
Constants ¶
const ( FrameTypeChatRequest = "chat_request" FrameTypeApprovalResponse = "approval_response" FrameTypeCancel = "cancel" FrameTypePong = "pong" FrameTypePing = "ping" FrameTypeError = "error" )
Variables ¶
var ValidScopes = scope.Valid
ValidScopes is the set of scope values accepted by the key management system. It delegates to the canonical list in the scope package.
Functions ¶
func ParseClientFrame ¶ added in v0.16.0
ParseClientFrame reads a raw JSON message from a WebSocket client and returns the appropriate typed frame. Returns an error for unknown or malformed frames.
func ValidateKeyInput ¶ added in v0.1.0
ValidateKeyInput checks that name is within the length limit and every scope is in the ValidScopes allowlist. Returns a user-facing error on failure.
Types ¶
type APIKeyRecord ¶
type APIKeyRecord struct {
ID string `json:"id"`
Name string `json:"name"`
Scopes []string `json:"scopes"`
CreatedAt time.Time `json:"created_at"`
LastUsedAt *time.Time `json:"last_used_at,omitempty"`
Revoked bool `json:"revoked"`
}
APIKeyRecord is the public representation returned by the API (no hash exposed).
type ApprovalResponseFrame ¶ added in v0.16.0
type ApprovalResponseFrame struct {
Type string `json:"type"` // "approval_response"
ApprovalID string `json:"approval_id"` // approval request ID
Action string `json:"action"` // "approve", "deny", "auto_session", "auto_always"
}
ApprovalResponseFrame is sent by the client to resolve a pending tool approval.
type CancelFrame ¶ added in v0.16.0
type CancelFrame struct {
Type string `json:"type"` // "cancel"
SessionID string `json:"session_id"` // session to cancel
}
CancelFrame is sent by the client to abort an in-progress agent turn.
type ChatRequestFrame ¶ added in v0.16.0
type ChatRequestFrame struct {
Type string `json:"type"` // "chat_request"
SessionID string `json:"session_id,omitempty"` // omit to create new session
Agent string `json:"agent,omitempty"` // agent name; defaults to "default"
Message string `json:"message"` // user message text
UserID string `json:"user_id,omitempty"` // optional user identifier
UserName string `json:"user_name,omitempty"` // optional display name
Seq int64 `json:"seq,omitempty"` // monotonically increasing per session
ResumeAfterSeq int64 `json:"resume_after_seq,omitempty"` // replay events after this seq on reconnect
}
ChatRequestFrame is sent by the client to start or continue a chat session.
type Deps ¶
type Deps struct {
Dispatcher *agent.Dispatcher
Scheduler *scheduler.Scheduler
CostTracker *llm.CostTracker
Memory agent.MemoryStore
Config *config.Config
Approvals *approval.Manager // nil = approval endpoints return 503
LifecycleMgr *tool.LifecycleManager // nil = tool CRUD endpoints return 503
BrowserProfiles *browser.ProfileService // nil = browser endpoints return 503
WebHandler http.Handler // nil = no web dashboard served
MetricsHandler http.Handler // nil = no /metrics endpoint
KeyStore *KeyStore // nil = API key CRUD endpoints return 503
KVStore kv.Store // nil = KV endpoints return 503
ConfigPath string // TOML config path for schedule persistence
Sessions *SessionManager // nil = no session-based auth
OIDCProvider *OIDCProvider // nil = no OIDC endpoints
PasswordHash string // bcrypt hash for password login
SetupPIN string // one-time PIN for account setup (empty = disabled)
ModelLister func(ctx context.Context) []string // returns available LLM models; nil = endpoint returns 503
OAuthDeps *OAuthDeps // nil = OAuth tool endpoints return 503
}
Deps holds the application dependencies the API server needs to serve data.
type KeyStore ¶
type KeyStore struct {
// contains filtered or unexported fields
}
KeyStore manages API keys persisted in SQLite.
func NewInMemoryKeyStore ¶
NewInMemoryKeyStore creates a KeyStore backed by an in-memory SQLite database. Intended for tests.
func NewKeyStore ¶
NewKeyStore opens (or creates) a SQLite DB at dbPath and applies the key schema. WAL mode is used so it can coexist with other connections to the same file.
func (*KeyStore) Create ¶
func (ks *KeyStore) Create(ctx context.Context, name string, scopes []string) (APIKeyRecord, string, error)
Create inserts a new API key. Returns the record and plaintext key (shown once).
func (*KeyStore) Delete ¶ added in v0.1.0
Delete permanently removes a revoked key from the store. Returns an error if the key does not exist or is still active (not revoked).
func (*KeyStore) FindActiveByHash ¶
FindActiveByHash returns the matching active key row for a given token hash, or nil if not found.
func (*KeyStore) HasActiveKey ¶ added in v0.1.0
HasActiveKey reports whether at least one non-revoked key exists in the store.
func (*KeyStore) List ¶
func (ks *KeyStore) List(ctx context.Context) ([]APIKeyRecord, error)
List returns all key records ordered by creation date descending.
func (*KeyStore) Revoke ¶
Revoke marks a key as revoked. Returns an error if the key does not exist or is already revoked.
type OAuthDeps ¶ added in v0.16.0
type OAuthDeps struct {
TokenStore *oauth.TokenStore
PendingMgr *oauth.PendingManager
}
OAuthDeps holds OAuth-specific dependencies for the API server.
type OIDCProvider ¶ added in v0.12.0
type OIDCProvider struct {
// contains filtered or unexported fields
}
OIDCProvider wraps the OIDC discovery provider and OAuth2 config.
func NewOIDCProvider ¶ added in v0.12.0
func NewOIDCProvider(ctx context.Context, issuer, clientID, clientSecret, redirectURL string, scopes, allowedEmails []string, sessions *SessionManager, logger *slog.Logger) (*OIDCProvider, error)
NewOIDCProvider creates an OIDCProvider by performing OIDC discovery.
func (*OIDCProvider) HandleCallback ¶ added in v0.12.0
func (op *OIDCProvider) HandleCallback(w http.ResponseWriter, r *http.Request)
HandleCallback completes the OIDC authorization code flow.
func (*OIDCProvider) HandleLogin ¶ added in v0.12.0
func (op *OIDCProvider) HandleLogin(w http.ResponseWriter, r *http.Request)
HandleLogin starts the OIDC authorization code flow with PKCE and nonce.
type PingFrame ¶ added in v0.16.0
type PingFrame struct {
Type string `json:"type"` // "ping"
}
PingFrame is the server's keepalive probe.
type PongFrame ¶ added in v0.16.0
type PongFrame struct {
Type string `json:"type"` // "pong"
}
PongFrame is the client's keepalive response to a server ping.
type ReplayBuffer ¶ added in v0.16.0
type ReplayBuffer struct {
// contains filtered or unexported fields
}
ReplayBuffer is a fixed-size circular buffer of WSEventFrames with time-based eviction. It is safe for concurrent use.
func NewReplayBuffer ¶ added in v0.16.0
func NewReplayBuffer(capacity int, ttl time.Duration) *ReplayBuffer
NewReplayBuffer creates a buffer with the given capacity and TTL.
func (*ReplayBuffer) Append ¶ added in v0.16.0
func (b *ReplayBuffer) Append(frame WSEventFrame)
Append adds a frame to the buffer. Old entries beyond capacity are overwritten. Entries older than the TTL are logically evicted on read.
func (*ReplayBuffer) Len ¶ added in v0.16.0
func (b *ReplayBuffer) Len() int
Len returns the number of entries currently in the buffer (including expired ones that haven't been overwritten yet).
func (*ReplayBuffer) ReplaySince ¶ added in v0.16.0
func (b *ReplayBuffer) ReplaySince(afterSeq int64) []WSEventFrame
ReplaySince returns all buffered frames with Seq > afterSeq that are within the TTL window. Frames are returned in insertion order.
type ReplayStore ¶ added in v0.16.0
type ReplayStore struct {
// contains filtered or unexported fields
}
ReplayStore manages per-session replay buffers.
func NewReplayStore ¶ added in v0.16.0
func NewReplayStore(capacity int, ttl time.Duration) *ReplayStore
NewReplayStore creates a store that allocates replay buffers on demand.
func (*ReplayStore) Buffer ¶ added in v0.16.0
func (s *ReplayStore) Buffer(sessionID string) *ReplayBuffer
Buffer returns the replay buffer for the given session, creating one if it does not exist.
func (*ReplayStore) Cleanup ¶ added in v0.16.0
func (s *ReplayStore) Cleanup()
Cleanup removes all buffers that have no entries within the TTL window. Call periodically to prevent unbounded growth.
func (*ReplayStore) Len ¶ added in v0.16.0
func (s *ReplayStore) Len() int
Len returns the number of tracked sessions.
func (*ReplayStore) Remove ¶ added in v0.16.0
func (s *ReplayStore) Remove(sessionID string)
Remove deletes the replay buffer for a session.
type SSEStreamSession ¶ added in v0.16.0
type SSEStreamSession struct {
// contains filtered or unexported fields
}
SSEStreamSession writes Server-Sent Events to an http.ResponseWriter.
func NewSSEStreamSession ¶ added in v0.16.0
func NewSSEStreamSession(w http.ResponseWriter) *SSEStreamSession
NewSSEStreamSession creates an SSE session. The caller must set SSE headers and write the status code before calling this.
func (*SSEStreamSession) SendContent ¶ added in v0.16.0
func (s *SSEStreamSession) SendContent(text string)
func (*SSEStreamSession) SendDone ¶ added in v0.16.0
func (s *SSEStreamSession) SendDone(sessionID string)
func (*SSEStreamSession) SendError ¶ added in v0.16.0
func (s *SSEStreamSession) SendError(message string)
func (*SSEStreamSession) SendEvent ¶ added in v0.16.0
func (s *SSEStreamSession) SendEvent(evt agent.ChatEvent)
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the external REST API server.
func (*Server) HTTPHandler ¶ added in v0.11.0
HTTPHandler returns the server's HTTP handler for use in tests.
func (*Server) RequireScope ¶
func (s *Server) RequireScope(scope string, next http.HandlerFunc) http.HandlerFunc
RequireScope returns middleware that checks for a valid API key with the required scope. Use this to wrap individual route handlers.
type Session ¶ added in v0.12.0
type Session struct {
Email string `json:"email"`
Scopes []string `json:"scopes"`
ExpiresAt int64 `json:"exp"` // Unix timestamp
}
Session represents a dashboard login session stored in an encrypted cookie.
type SessionManager ¶ added in v0.12.0
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager handles AES-256-GCM encrypted session cookies.
func NewSessionManager ¶ added in v0.12.0
NewSessionManager creates a SessionManager from a hex-encoded AES key (≥32 bytes).
func (*SessionManager) Clear ¶ added in v0.12.0
func (sm *SessionManager) Clear(w http.ResponseWriter)
Clear removes the session cookie.
func (*SessionManager) Create ¶ added in v0.12.0
func (sm *SessionManager) Create(w http.ResponseWriter, s Session) error
Create encrypts the session and sets it as an HttpOnly cookie.
type StreamSession ¶ added in v0.16.0
type StreamSession interface {
// SendEvent streams an intermediate pipeline event to the client.
SendEvent(evt agent.ChatEvent)
// SendContent streams the final response text.
SendContent(text string)
// SendDone signals that the agent turn is complete.
SendDone(sessionID string)
// SendError reports a fatal error for the stream.
SendError(message string)
}
StreamSession abstracts the transport used to deliver chat events. Both SSE and WebSocket implement this interface.
type WSClientFrame ¶ added in v0.16.0
type WSClientFrame struct {
Type string `json:"type"`
}
WSClientFrame is the envelope used to determine the type of a client frame.
type WSConn ¶ added in v0.16.0
type WSConn struct {
// contains filtered or unexported fields
}
WSConn wraps a gorilla/websocket connection with read/write pump goroutines.
type WSErrorFrame ¶ added in v0.16.0
type WSErrorFrame struct {
Type string `json:"type"` // "error"
SessionID string `json:"session_id,omitempty"` // session this error relates to
Code string `json:"code"` // "rate_limited", "permission_denied", "agent_not_found", "internal", "replay_unavailable"
Message string `json:"message"` // human-readable detail
}
WSErrorFrame reports an error for a specific session without closing the connection.
type WSEventFrame ¶ added in v0.16.0
type WSEventFrame struct {
agent.ChatEvent
SessionID string `json:"session_id,omitempty"` // session this event belongs to
Seq int64 `json:"seq,omitempty"` // monotonically increasing per session
}
WSEventFrame wraps a ChatEvent with session routing and sequence info.
type WSHub ¶ added in v0.16.0
type WSHub struct {
// contains filtered or unexported fields
}
WSHub tracks active WebSocket connections and provides graceful shutdown.
func (*WSHub) ConnCount ¶ added in v0.16.0
ConnCount returns the current number of active connections.
func (*WSHub) Register ¶ added in v0.16.0
Register adds a connection. Returns false if the hub is at capacity.
func (*WSHub) Shutdown ¶ added in v0.16.0
func (h *WSHub) Shutdown()
Shutdown closes all active connections gracefully.
func (*WSHub) StartCleanup ¶ added in v0.16.3
StartCleanup launches a background goroutine that periodically removes stale replay buffers. It stops when ctx is cancelled.
func (*WSHub) Unregister ¶ added in v0.16.0
Unregister removes a connection from the hub.