server

package
v1.168.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 47 Imported by: 0

Documentation

Overview

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

Package server provides a production-grade gRPC server for ChatCLI with enterprise security controls.

The server acts as a centralized LLM gateway that teams can share, supporting multiple providers with automatic failover, persistent sessions, and Kubernetes-native observability.

Security

  • JWT authentication with RBAC roles (admin, user, readonly)
  • Legacy Bearer token authentication (backward compatible)
  • Per-client token-bucket rate limiting
  • SSRF prevention blocking private IPs and cloud metadata endpoints
  • gRPC field validation interceptor for all request types
  • TLS 1.3 with optional mTLS (mutual TLS)
  • Structured audit logging in JSON lines format
  • Log rotation via lumberjack
  • Bind to localhost by default (configurable via CHATCLI_BIND_ADDRESS)

Features

  • Multi-provider LLM support (11 providers)

  • Streaming and unary prompt RPCs

  • Interactive bidirectional sessions

  • Remote plugin execution with role-based access control

  • Agent and skill discovery for connected clients

  • MCP (Model Context Protocol) integration

  • Prometheus metrics (gRPC, LLM, session counters)

  • Kubernetes watcher context injection

  • Provider fallback chain with health monitoring

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

  • ChatCLI - Command Line Interface for LLM interaction

  • Copyright (c) 2024 Edilson Freitas

  • License: Apache-2.0

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContextWithUser added in v1.97.0

func ContextWithUser(ctx context.Context, user *UserInfo) context.Context

ContextWithUser returns a new context with the UserInfo attached.

func NewRotatingLogger added in v1.97.0

func NewRotatingLogger(cfg LogRotationConfig) (*zap.Logger, error)

NewRotatingLogger creates a zap.Logger with log rotation support. If FilePath is empty, returns a standard production logger (stdout).

func ValidationInterceptor added in v1.97.0

func ValidationInterceptor() grpc.UnaryServerInterceptor

ValidationInterceptor returns a gRPC unary interceptor that validates request fields.

Types

type AlertInfo added in v1.58.0

type AlertInfo struct {
	Type       string
	Severity   string
	Message    string
	Object     string
	Namespace  string
	Deployment string
	Timestamp  time.Time
}

AlertInfo represents a watcher alert exposed to the AIOps operator.

type AuditEntry added in v1.97.0

type AuditEntry struct {
	Timestamp   string            `json:"timestamp"`
	RequestID   string            `json:"request_id"`
	ClientID    string            `json:"client_id"`
	ClientAddr  string            `json:"client_addr,omitempty"`
	Method      string            `json:"method"`
	Resource    string            `json:"resource,omitempty"`
	Result      string            `json:"result"` // "success", "error", "denied"
	Duration    string            `json:"duration,omitempty"`
	RequestSize int               `json:"request_size,omitempty"`
	Details     map[string]string `json:"details,omitempty"`
}

AuditEntry is a structured audit log event for security-relevant operations.

type AuditLogger added in v1.97.0

type AuditLogger struct {
	// contains filtered or unexported fields
}

AuditLogger provides structured audit logging for gRPC server operations.

func NewAuditLogger added in v1.97.0

func NewAuditLogger(logger *zap.Logger) *AuditLogger

NewAuditLogger creates an audit logger. If CHATCLI_AUDIT_LOG_PATH is set, audit entries are also written to that file in JSON-lines format.

func (*AuditLogger) Close added in v1.97.0

func (al *AuditLogger) Close()

Close shuts down the audit file writer.

func (*AuditLogger) Log added in v1.97.0

func (al *AuditLogger) Log(entry AuditEntry)

Log writes an audit entry to both the zap logger and the optional audit file.

func (*AuditLogger) UnaryInterceptor added in v1.97.0

func (al *AuditLogger) UnaryInterceptor() grpc.UnaryServerInterceptor

UnaryInterceptor returns a gRPC interceptor that logs all unary RPCs for audit.

type Config

type Config struct {
	Port             int
	Token            string // auth token (empty = no auth)
	TLSCertFile      string
	TLSKeyFile       string
	Provider         string
	Model            string
	EnableReflection bool // enable gRPC reflection (default: false, check CHATCLI_GRPC_REFLECTION env)
	MetricsPort      int  // Prometheus metrics HTTP port (0 = disabled, default: 9090)
}

Config holds server configuration.

type Handler

type Handler struct {
	pb.UnimplementedChatCLIServiceServer
	// contains filtered or unexported fields
}

Handler implements the ChatCLIService gRPC server.

func NewHandler

func NewHandler(llmMgr manager.LLMManager, sessionStore SessionStore, logger *zap.Logger, provider, model string) *Handler

NewHandler creates a new gRPC handler.

func (*Handler) AgenticStep added in v1.59.4

func (h *Handler) AgenticStep(ctx context.Context, req *pb.AgenticStepRequest) (*pb.AgenticStepResponse, error)

AgenticStep runs one step of the AI-driven remediation loop.

func (*Handler) AnalyzeIssue added in v1.58.0

func (h *Handler) AnalyzeIssue(ctx context.Context, req *pb.AnalyzeIssueRequest) (*pb.AnalyzeIssueResponse, error)

AnalyzeIssue uses the LLM to analyze an AIOps issue and return recommendations.

func (*Handler) AppendEvent added in v1.123.0

func (h *Handler) AppendEvent(ctx context.Context, req *pb.AppendEventRequest) (*pb.AppendEventResponse, error)

AppendEvent appends one dialog turn to a conversation's shared log.

func (*Handler) DeleteSession

func (h *Handler) DeleteSession(ctx context.Context, req *pb.DeleteSessionRequest) (*pb.DeleteSessionResponse, error)

DeleteSession removes a saved session.

func (*Handler) DownloadPlugin added in v1.60.0

DownloadPlugin streams the plugin binary to the client.

func (*Handler) ExecuteRemotePlugin added in v1.60.0

ExecuteRemotePlugin executes a plugin on the server and returns the output. Security (C1): Requires at least "user" role — readonly users cannot execute plugins.

func (*Handler) GetAgentDefinition added in v1.60.0

GetAgentDefinition returns the full definition of a server-side agent.

func (*Handler) GetAlerts added in v1.58.0

func (h *Handler) GetAlerts(ctx context.Context, req *pb.GetAlertsRequest) (*pb.GetAlertsResponse, error)

GetAlerts returns current watcher alerts for the AIOps operator.

func (*Handler) GetServerInfo

func (h *Handler) GetServerInfo(ctx context.Context, req *pb.GetServerInfoRequest) (*pb.GetServerInfoResponse, error)

GetServerInfo returns server metadata.

func (*Handler) GetSkillContent added in v1.60.0

func (h *Handler) GetSkillContent(ctx context.Context, req *pb.GetSkillContentRequest) (*pb.GetSkillContentResponse, error)

GetSkillContent returns the full content of a server-side skill.

func (*Handler) GetWatcherStatus

GetWatcherStatus returns the K8s watcher status.

func (*Handler) Health

func (h *Handler) Health(ctx context.Context, req *pb.HealthRequest) (*pb.HealthResponse, error)

Health returns the server health status.

func (*Handler) InteractiveSession

func (h *Handler) InteractiveSession(stream pb.ChatCLIService_InteractiveSessionServer) error

InteractiveSession handles bidirectional streaming for interactive mode.

func (*Handler) ListBindings added in v1.123.0

func (h *Handler) ListBindings(ctx context.Context, req *pb.ListBindingsRequest) (*pb.ListBindingsResponse, error)

ListBindings returns bindings. Non-admins only see their own.

func (*Handler) ListRemoteAgents added in v1.60.0

ListRemoteAgents returns all agents available on the server.

func (*Handler) ListRemotePlugins added in v1.60.0

ListRemotePlugins returns plugins installed on the server. Security (L12): Filters by role — admin sees all, user sees non-internal, readonly sees none.

func (*Handler) ListRemoteSkills added in v1.60.0

ListRemoteSkills returns all skills available on the server.

func (*Handler) ListSessions

func (h *Handler) ListSessions(ctx context.Context, req *pb.ListSessionsRequest) (*pb.ListSessionsResponse, error)

ListSessions returns all saved session names.

func (*Handler) LoadSession

func (h *Handler) LoadSession(ctx context.Context, req *pb.LoadSessionRequest) (*pb.LoadSessionResponse, error)

LoadSession loads a saved session.

func (*Handler) NewConversation added in v1.123.0

func (h *Handler) NewConversation(ctx context.Context, req *pb.NewConversationRequest) (*pb.NewConversationResponse, error)

NewConversation rotates the principal's active conversation to a fresh thread.

func (*Handler) ReadConversation added in v1.123.0

ReadConversation returns events after since_seq (hydration / resume).

func (*Handler) ResolveActiveConversation added in v1.123.0

ResolveActiveConversation returns (creating if needed) the principal's active conversation.

func (*Handler) SaveSession

func (h *Handler) SaveSession(ctx context.Context, req *pb.SaveSessionRequest) (*pb.SaveSessionResponse, error)

SaveSession saves the conversation history.

func (*Handler) SendPrompt

func (h *Handler) SendPrompt(ctx context.Context, req *pb.SendPromptRequest) (*pb.SendPromptResponse, error)

SendPrompt handles a single prompt request.

func (*Handler) SetBinding added in v1.123.0

func (h *Handler) SetBinding(ctx context.Context, req *pb.SetBindingRequest) (*pb.SetBindingResponse, error)

SetBinding maps a channel identity to a principal. A user may bind identities to themselves; binding to another principal requires admin.

func (*Handler) SetFallbackChain added in v1.66.0

func (h *Handler) SetFallbackChain(chain *fallback.Chain)

SetFallbackChain sets the provider fallback chain for automatic failover.

func (*Handler) SetHub added in v1.123.0

func (h *Handler) SetHub(broker hub.Broker)

SetHub attaches the conversation hub broker, enabling the cross-channel continuity RPCs. When nil, those RPCs return Unavailable.

For live tailing to span the gateway adapters and remote CLIs, the gateway daemon and this gRPC server must share one in-process broker (same process), since fan-out is in-memory. Remote clients connect over gRPC from anywhere.

func (*Handler) SetMCPManager added in v1.66.0

func (h *Handler) SetMCPManager(mgr *mcp.Manager)

SetMCPManager sets the MCP manager for tool interoperability.

func (*Handler) SetPersonaLoader added in v1.60.0

func (h *Handler) SetPersonaLoader(pl *persona.Loader)

SetPersonaLoader sets the persona loader for remote agent/skill discovery.

func (*Handler) SetPluginManager added in v1.60.0

func (h *Handler) SetPluginManager(pm *plugins.Manager)

func (*Handler) SetWatcher

func (h *Handler) SetWatcher(cfg WatcherConfig)

SetWatcher configures full watcher integration with context, status, and stats.

func (*Handler) SetWatcherContext

func (h *Handler) SetWatcherContext(fn func() string)

SetWatcherContext configures a function that provides K8s watcher context to be prepended to all LLM prompts.

func (*Handler) StreamPrompt

StreamPrompt handles a streaming prompt request.

func (*Handler) SubscribeConversation added in v1.123.0

SubscribeConversation live-tails a conversation. It streams the backlog after since_seq, then live events. On consumer overflow the stream ends with Aborted so the client resubscribes from its last seq to resync.

type LogRotationConfig added in v1.97.0

type LogRotationConfig struct {
	// FilePath is the log file path. Empty means stdout only.
	FilePath string
	// MaxSizeMB is the maximum size in megabytes before rotation.
	MaxSizeMB int
	// MaxBackups is the maximum number of old log files to retain.
	MaxBackups int
	// MaxAgeDays is the maximum age in days before a log file is deleted.
	MaxAgeDays int
	// Compress determines whether rotated files are gzipped.
	Compress bool
}

LogRotationConfig holds log rotation settings.

func DefaultLogRotationConfig added in v1.97.0

func DefaultLogRotationConfig() LogRotationConfig

DefaultLogRotationConfig returns production defaults from environment variables.

type PerClientRateLimiter added in v1.97.0

type PerClientRateLimiter struct {
	// contains filtered or unexported fields
}

PerClientRateLimiter provides per-client token-bucket rate limiting for gRPC.

func NewPerClientRateLimiter added in v1.97.0

func NewPerClientRateLimiter(cfg RateLimiterConfig, logger *zap.Logger) *PerClientRateLimiter

NewPerClientRateLimiter creates a rate limiter and starts background cleanup.

func (*PerClientRateLimiter) Stop added in v1.97.0

func (rl *PerClientRateLimiter) Stop()

Stop shuts down the background cleanup goroutine.

func (*PerClientRateLimiter) StreamInterceptor added in v1.97.0

func (rl *PerClientRateLimiter) StreamInterceptor() grpc.StreamServerInterceptor

StreamInterceptor returns a gRPC stream interceptor that enforces rate limits.

func (*PerClientRateLimiter) UnaryInterceptor added in v1.97.0

func (rl *PerClientRateLimiter) UnaryInterceptor() grpc.UnaryServerInterceptor

UnaryInterceptor returns a gRPC unary interceptor that enforces rate limits.

type RateLimiterConfig added in v1.97.0

type RateLimiterConfig struct {
	// RequestsPerSecond is the sustained rate limit per client.
	RequestsPerSecond float64
	// Burst is the maximum number of requests allowed in a burst.
	Burst int
	// CleanupInterval is how often idle client limiters are evicted.
	CleanupInterval time.Duration
	// MaxIdleTime is how long a limiter can be idle before eviction.
	MaxIdleTime time.Duration
}

RateLimiterConfig holds rate limiter configuration.

func DefaultRateLimiterConfig added in v1.97.0

func DefaultRateLimiterConfig() RateLimiterConfig

DefaultRateLimiterConfig returns production-safe defaults. Override via CHATCLI_RATE_LIMIT_RPS and CHATCLI_RATE_LIMIT_BURST env vars.

type SSRFValidator added in v1.97.0

type SSRFValidator struct {
	// contains filtered or unexported fields
}

SSRFValidator prevents Server-Side Request Forgery by blocking requests to private, loopback, and cloud metadata IP ranges.

func NewSSRFValidator added in v1.97.0

func NewSSRFValidator(logger *zap.Logger) *SSRFValidator

NewSSRFValidator creates a validator configured from environment. Set CHATCLI_ALLOW_HTTP_PROVIDERS=true to permit non-TLS provider URLs.

func (*SSRFValidator) ValidateProviderConfig added in v1.97.0

func (v *SSRFValidator) ValidateProviderConfig(config map[string]string) error

ValidateProviderConfig checks provider_config map for SSRF-prone fields.

func (*SSRFValidator) ValidateProviderURL added in v1.97.0

func (v *SSRFValidator) ValidateProviderURL(rawURL string) error

ValidateProviderURL checks whether a provider base URL is safe to connect to. Returns an error if the URL targets internal/private infrastructure.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server wraps the gRPC server and its dependencies.

func New

func New(cfg Config, llmMgr manager.LLMManager, sessionStore SessionStore, logger *zap.Logger) *Server

New creates a new ChatCLI gRPC server.

func (*Server) Hub added in v1.123.0

func (s *Server) Hub() hub.Broker

Hub returns the server's conversation hub broker, or nil when the hub is disabled. Used to co-locate the gateway in the server process so adapter appends publish to live subscribers through the same in-memory fan-out.

func (*Server) SetFallbackChain added in v1.66.0

func (s *Server) SetFallbackChain(chain *fallback.Chain)

SetFallbackChain configures the provider fallback chain for automatic failover.

func (*Server) SetMCPManager added in v1.66.0

func (s *Server) SetMCPManager(mgr *mcp.Manager)

SetMCPManager configures the MCP manager for tool interoperability.

func (*Server) SetPersonaLoader added in v1.60.0

func (s *Server) SetPersonaLoader(pl *persona.Loader)

SetPersonaLoader configures the persona loader for remote agent/skill discovery.

func (*Server) SetPluginManager added in v1.60.0

func (s *Server) SetPluginManager(pm *plugins.Manager)

SetPluginManager configures plugin management for remote discovery and execution.

func (*Server) SetWatcher

func (s *Server) SetWatcher(cfg WatcherConfig)

SetWatcher configures full K8s watcher integration with context, status, and stats.

func (*Server) SetWatcherContext

func (s *Server) SetWatcherContext(fn func() string)

SetWatcherContext configures K8s watcher context injection for all prompts.

func (*Server) Start

func (s *Server) Start() error

Start begins listening and serving gRPC requests. It blocks until the server is stopped via signal or Stop().

func (*Server) Stop

func (s *Server) Stop()

Stop gracefully stops the server and cleans up resources.

type SessionStore

type SessionStore interface {
	SaveSession(name string, history []models.Message) error
	LoadSession(name string) ([]models.Message, error)
	ListSessions() ([]string, error)
	DeleteSession(name string) error
}

SessionStore abstracts session persistence for testability.

type SessionStoreV2 added in v1.65.2

type SessionStoreV2 interface {
	SaveSessionV2(name string, sd *models.SessionData) error
	LoadSessionV2(name string) (*models.SessionData, error)
}

SessionStoreV2 extends SessionStore with v2 scoped-history support. Implementations that support v2 are detected via type assertion.

type TokenAuthInterceptor

type TokenAuthInterceptor struct {
	// contains filtered or unexported fields
}

TokenAuthInterceptor validates Bearer tokens from gRPC metadata. Supports both legacy shared token and JWT-based authentication.

func NewTokenAuthInterceptor

func NewTokenAuthInterceptor(token string, logger *zap.Logger) *TokenAuthInterceptor

NewTokenAuthInterceptor creates a new auth interceptor. If token is empty and no JWT config is set, authentication is disabled. JWT is configured via CHATCLI_JWT_SECRET environment variable.

func (*TokenAuthInterceptor) Stream

Stream returns a grpc.StreamServerInterceptor that validates credentials.

func (*TokenAuthInterceptor) Unary

Unary returns a grpc.UnaryServerInterceptor that validates credentials and injects UserInfo into the context for downstream access control.

type UserInfo added in v1.97.0

type UserInfo struct {
	// Subject is the unique user identifier (from JWT "sub" claim or token hash).
	Subject string
	// TenantID is the optional tenant/organization identifier.
	TenantID string
	// Role is the user's access level.
	Role UserRole
	// Email is an optional user email (from JWT "email" claim).
	Email string
}

UserInfo holds the identity and role information extracted from authentication.

func RequireRole added in v1.97.0

func RequireRole(ctx context.Context, required UserRole) (*UserInfo, error)

RequireRole checks that the context has a user with at least the given role. Returns the UserInfo on success or an error suitable for gRPC status responses.

func UserFromContext added in v1.97.0

func UserFromContext(ctx context.Context) *UserInfo

UserFromContext extracts the UserInfo from context. Returns nil if not present.

func (*UserInfo) HasRole added in v1.97.0

func (u *UserInfo) HasRole(required UserRole) bool

HasRole checks if the user has at least the given role level. Role hierarchy: admin > user > readonly

func (*UserInfo) String added in v1.97.0

func (u *UserInfo) String() string

String returns a human-readable representation (safe for logging).

type UserRole added in v1.97.0

type UserRole string

UserRole defines the access level for authenticated users.

const (
	RoleAdmin    UserRole = "admin"
	RoleUser     UserRole = "user"
	RoleReadonly UserRole = "readonly"
)

func ParseRole added in v1.97.0

func ParseRole(s string) UserRole

ParseRole converts a string to UserRole, defaulting to RoleUser for unknown values.

type WatcherConfig

type WatcherConfig struct {
	ContextFunc func() string                                    // full context for LLM
	StatusFunc  func() string                                    // compact status summary
	StatsFunc   func() (alertCount, snapshotCount, podCount int) // numeric stats
	AlertsFunc  func() []AlertInfo                               // raw alerts for AIOps operator
	Deployment  string
	Namespace   string
}

WatcherConfig holds the functions and metadata for K8s watcher integration.

Directories

Path Synopsis
Package hub holds the durable source of truth for cross-channel conversations.
Package hub holds the durable source of truth for cross-channel conversations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL