Documentation
¶
Index ¶
- Constants
- Variables
- func ComputeUsagePeriodBounds(now time.Time, period codersdk.ChatUsageLimitPeriod) (start, end time.Time)
- func ResolveUsageLimitStatus(ctx context.Context, db database.Store, userID uuid.UUID, now time.Time) (*codersdk.ChatUsageLimitStatus, error)
- func SanitizePromptText(s string) string
- type AgentConnFunc
- type Config
- type CreateOptions
- type DialFunc
- type DialResult
- type EditMessageOptions
- type EditMessageResult
- type PromoteQueuedOptions
- type PromoteQueuedResult
- type SendMessageBusyBehavior
- type SendMessageOptions
- type SendMessageResult
- type Server
- func (p *Server) ArchiveChat(ctx context.Context, chat database.Chat) error
- func (p *Server) Close() error
- func (p *Server) CreateChat(ctx context.Context, opts CreateOptions) (database.Chat, error)
- func (p *Server) DeleteQueued(ctx context.Context, chatID uuid.UUID, queuedMessageID int64) error
- func (p *Server) EditMessage(ctx context.Context, opts EditMessageOptions) (EditMessageResult, error)
- func (p *Server) InterruptChat(ctx context.Context, chat database.Chat) database.Chat
- func (p *Server) PromoteQueued(ctx context.Context, opts PromoteQueuedOptions) (PromoteQueuedResult, error)
- func (p *Server) PublishDiffStatusChange(ctx context.Context, chatID uuid.UUID) error
- func (p *Server) RefreshStatus(ctx context.Context, chatID uuid.UUID) error
- func (p *Server) RegenerateChatTitle(ctx context.Context, chat database.Chat) (database.Chat, error)
- func (p *Server) SendMessage(ctx context.Context, opts SendMessageOptions) (SendMessageResult, error)
- func (p *Server) Subscribe(ctx context.Context, chatID uuid.UUID, requestHeader http.Header, ...) ([]codersdk.ChatStreamEvent, <-chan codersdk.ChatStreamEvent, func(), bool)
- func (p *Server) UnarchiveChat(ctx context.Context, chat database.Chat) error
- type StatusNotification
- type SubscribeFn
- type SubscribeFnParams
- type UsageLimitExceededError
- type ValidateFunc
Constants ¶
const ( // DefaultPendingChatAcquireInterval is the default time between attempts to // acquire pending chats. DefaultPendingChatAcquireInterval = time.Second // DefaultInFlightChatStaleAfter is the default age after which a running // chat is considered stale and should be recovered. DefaultInFlightChatStaleAfter = 5 * time.Minute // DefaultChatHeartbeatInterval is the default time between chat // heartbeat updates while a chat is being processed. DefaultChatHeartbeatInterval = 30 * time.Second // DefaultMaxChatsPerAcquire is the maximum number of chats to // acquire in a single processOnce call. Batching avoids // waiting a full polling interval between acquisitions // when many chats are pending. DefaultMaxChatsPerAcquire int32 = 10 )
const DefaultSystemPrompt = `` /* 4978-byte string literal not displayed */
DefaultSystemPrompt is used for new chats when no deployment override is configured.
const MaxQueueSize = 20
MaxQueueSize is the maximum number of queued user messages per chat.
Variables ¶
var ( // ErrMessageQueueFull indicates the per-chat queue limit was reached. ErrMessageQueueFull = xerrors.New("chat message queue is full") // ErrEditedMessageNotFound indicates the edited message does not exist // in the target chat. ErrEditedMessageNotFound = xerrors.New("edited message not found") // ErrEditedMessageNotUser indicates a non-user message edit attempt. ErrEditedMessageNotUser = xerrors.New("only user messages can be edited") )
var ErrManualTitleRegenerationInProgress = xerrors.New(
"manual title regeneration already in progress",
)
var ErrSubagentNotDescendant = xerrors.New("target chat is not a descendant of current chat")
Functions ¶
func ComputeUsagePeriodBounds ¶
func ComputeUsagePeriodBounds(now time.Time, period codersdk.ChatUsageLimitPeriod) (start, end time.Time)
ComputeUsagePeriodBounds returns the UTC-aligned start and end bounds for the active usage-limit period containing now.
func ResolveUsageLimitStatus ¶
func ResolveUsageLimitStatus(ctx context.Context, db database.Store, userID uuid.UUID, now time.Time) (*codersdk.ChatUsageLimitStatus, error)
ResolveUsageLimitStatus resolves the current usage-limit status for userID.
Note: There is a potential race condition where two concurrent messages from the same user can both pass the limit check if processed in parallel, allowing brief overage. This is acceptable because:
- Cost is only known after the LLM API returns.
- Overage is bounded by message cost × concurrency.
- Fail-open is the deliberate design choice for this feature.
Architecture note: today this path enforces one period globally (day/week/month) from config. To support simultaneous periods, add nullable daily/weekly/monthly_limit_micros columns on override tables, where NULL means no limit for that period. Then scan spend once over the widest active window with conditional SUMs for each period and compare each spend/limit pair Go-side, blocking on whichever period is tightest.
func SanitizePromptText ¶
SanitizePromptText strips invisible Unicode characters that could hide prompt-injection content from human reviewers, normalizes line endings, collapses excessive blank lines, and trims surrounding whitespace.
The stripped codepoints are truly invisible and have no legitimate use in prompt text. An explicit codepoint list is used rather than blanket unicode.Cf stripping to avoid breaking subdivision flag emoji (🏴) and other legitimate format characters.
Note: U+200D (ZWJ) is stripped even though it joins compound emoji (e.g. 👨👩👦 → 👨👩👦). This is an acceptable trade-off because system prompts are not emoji art, and ZWJ is actively exploited in zero-width steganography schemes as a delimiter character.
Types ¶
type AgentConnFunc ¶
type AgentConnFunc func(ctx context.Context, agentID uuid.UUID) (workspacesdk.AgentConn, func(), error)
AgentConnFunc provides access to workspace agent connections.
type Config ¶
type Config struct {
Logger slog.Logger
Database database.Store
ReplicaID uuid.UUID
SubscribeFn SubscribeFn
PendingChatAcquireInterval time.Duration
MaxChatsPerAcquire int32
InFlightChatStaleAfter time.Duration
ChatHeartbeatInterval time.Duration
AgentConn AgentConnFunc
AgentInactiveDisconnectTimeout time.Duration
InstructionLookupTimeout time.Duration
CreateWorkspace chattool.CreateWorkspaceFn
StartWorkspace chattool.StartWorkspaceFn
Pubsub pubsub.Pubsub
ProviderAPIKeys chatprovider.ProviderAPIKeys
WebpushDispatcher webpush.Dispatcher
UsageTracker *workspacestats.UsageTracker
Clock quartz.Clock
}
Config configures a chat processor.
type CreateOptions ¶
type CreateOptions struct {
OwnerID uuid.UUID
WorkspaceID uuid.NullUUID
BuildID uuid.NullUUID
AgentID uuid.NullUUID
ParentChatID uuid.NullUUID
RootChatID uuid.NullUUID
Title string
ModelConfigID uuid.UUID
ChatMode database.NullChatMode
SystemPrompt string
InitialUserContent []codersdk.ChatMessagePart
MCPServerIDs []uuid.UUID
Labels database.StringMap
}
CreateOptions controls chat creation in the shared chat mutation path.
type DialResult ¶
type DialResult struct {
Conn workspacesdk.AgentConn
Release func()
AgentID uuid.UUID // The agent that was actually dialed.
WasSwitched bool // True if validation discovered a different agent.
}
DialResult contains the outcome of dialWithLazyValidation.
type EditMessageOptions ¶
type EditMessageOptions struct {
ChatID uuid.UUID
CreatedBy uuid.UUID
EditedMessageID int64
Content []codersdk.ChatMessagePart
}
EditMessageOptions controls user message edits via soft-delete and re-insert.
type EditMessageResult ¶
type EditMessageResult struct {
Message database.ChatMessage
Chat database.Chat
}
EditMessageResult contains the replacement user message and chat status.
type PromoteQueuedOptions ¶
type PromoteQueuedOptions struct {
ChatID uuid.UUID
CreatedBy uuid.UUID
QueuedMessageID int64
ModelConfigID *uuid.UUID
}
PromoteQueuedOptions controls queued-message promotion.
type PromoteQueuedResult ¶
type PromoteQueuedResult struct {
PromotedMessage database.ChatMessage
}
PromoteQueuedResult contains post-promotion message metadata.
type SendMessageBusyBehavior ¶
type SendMessageBusyBehavior string
SendMessageBusyBehavior controls what happens when a chat is already active.
const ( // SendMessageBusyBehaviorQueue queues user messages while the chat is busy. SendMessageBusyBehaviorQueue SendMessageBusyBehavior = "queue" // SendMessageBusyBehaviorInterrupt queues the message and // interrupts the active run. The queued message is // auto-promoted after the interrupted assistant response is // persisted, ensuring correct message ordering. SendMessageBusyBehaviorInterrupt SendMessageBusyBehavior = "interrupt" )
type SendMessageOptions ¶
type SendMessageOptions struct {
ChatID uuid.UUID
CreatedBy uuid.UUID
Content []codersdk.ChatMessagePart
ModelConfigID *uuid.UUID
BusyBehavior SendMessageBusyBehavior
MCPServerIDs *[]uuid.UUID
}
SendMessageOptions controls user message insertion with busy-state behavior.
type SendMessageResult ¶
type SendMessageResult struct {
Queued bool
QueuedMessage *database.ChatQueuedMessage
Message database.ChatMessage
Chat database.Chat
}
SendMessageResult contains the outcome of user message processing.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server handles background processing of pending chats.
func New ¶
New creates a new chat processor. The processor polls for pending chats and processes them. It is the caller's responsibility to call Close on the returned instance.
func (*Server) ArchiveChat ¶
ArchiveChat archives a chat family and broadcasts deleted events for each affected chat so watching clients converge without a full refetch. If the target chat is pending or running, it first transitions the chat back to waiting so active processing stops before the archive is broadcast.
func (*Server) CreateChat ¶
CreateChat creates a chat, inserts optional system prompt and initial user message, and moves the chat into pending status.
func (*Server) DeleteQueued ¶
func (p *Server) DeleteQueued( ctx context.Context, chatID uuid.UUID, queuedMessageID int64, ) error
DeleteQueued removes a queued user message and publishes the queue update.
func (*Server) EditMessage ¶
func (p *Server) EditMessage( ctx context.Context, opts EditMessageOptions, ) (EditMessageResult, error)
EditMessage marks the old user message as deleted, soft-deletes all following messages, inserts a new message with the updated content, clears queued messages, and moves the chat into pending status.
func (*Server) InterruptChat ¶
InterruptChat interrupts execution, sets waiting status, and broadcasts status updates.
func (*Server) PromoteQueued ¶
func (p *Server) PromoteQueued( ctx context.Context, opts PromoteQueuedOptions, ) (PromoteQueuedResult, error)
PromoteQueued promotes a queued message into chat history and marks the chat pending.
func (*Server) PublishDiffStatusChange ¶
PublishDiffStatusChange broadcasts a diff_status_change event for the given chat so that watching clients know to re-fetch the diff status. This is called from the HTTP layer after the diff status is updated in the database.
func (*Server) RefreshStatus ¶
RefreshStatus loads the latest chat status and publishes it to stream subscribers.
func (*Server) RegenerateChatTitle ¶
func (p *Server) RegenerateChatTitle( ctx context.Context, chat database.Chat, ) (database.Chat, error)
RegenerateChatTitle regenerates a chat title from the chat's visible messages, persists it when it changes, and broadcasts the update.
func (*Server) SendMessage ¶
func (p *Server) SendMessage( ctx context.Context, opts SendMessageOptions, ) (SendMessageResult, error)
SendMessage inserts a user message and optionally queues it while the chat is busy, then publishes stream + pubsub updates.
type StatusNotification ¶
type StatusNotification struct {
Status database.ChatStatus
WorkerID uuid.UUID
}
StatusNotification informs the enterprise relay manager of chat status changes so it can open or close relay connections.
type SubscribeFn ¶
type SubscribeFn func( ctx context.Context, params SubscribeFnParams, ) <-chan codersdk.ChatStreamEvent
SubscribeFn replaces the default local-only subscription with a multi-replica-aware implementation that merges pubsub notifications, remote relay streams, and local parts into a single event channel. When set, Subscribe delegates the event-merge goroutine to this function instead of using simple local forwarding.
Parameters:
- ctx: subscription lifetime context (canceled on unsubscribe).
- params: all state needed to build the merged stream.
Returns the merged event channel. Cleanup is driven by ctx cancellation — the merge goroutine tears down all relay state in its defer when ctx is done. Set by enterprise for HA deployments. Nil in AGPL single-replica.
type SubscribeFnParams ¶
type SubscribeFnParams struct {
ChatID uuid.UUID
Chat database.Chat
WorkerID uuid.UUID
StatusNotifications <-chan StatusNotification
RequestHeader http.Header
DB database.Store
Logger slog.Logger
}
SubscribeFnParams carries the state that the enterprise SubscribeFn implementation needs from the OSS Subscribe preamble.
type UsageLimitExceededError ¶
UsageLimitExceededError indicates the user has exceeded their chat spend limit.
func (*UsageLimitExceededError) Error ¶
func (e *UsageLimitExceededError) Error() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package chaterror classifies provider/runtime failures into stable, user-facing chat error payloads.
|
Package chaterror classifies provider/runtime failures into stable, user-facing chat error payloads. |
|
Package chatretry provides retry logic for transient LLM provider errors.
|
Package chatretry provides retry logic for transient LLM provider errors. |
|
internal
|
|