connector

package
v0.0.0-...-c29cf6f Latest Latest
Warning

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

Go to latest
Published: Mar 10, 2026 License: MIT Imports: 107 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ToolNameCalculator = toolspec.CalculatorName
	ToolNameWebSearch  = toolspec.WebSearchName
)

Tool name constants

View Source
const (
	AIMaxTextLength = 100000
	AIEditMaxAge    = 24 * time.Hour
)

AI bridge capability constants

View Source
const (
	DefaultDedupeTTL     = 20 * time.Minute
	DefaultDedupeMaxSize = 5000
)
View Source
const (
	AIRateLimited   status.BridgeStateErrorCode = "ai-rate-limited"
	AIAuthFailed    status.BridgeStateErrorCode = "ai-auth-failed"
	AIProviderError status.BridgeStateErrorCode = "ai-provider-error"
	AIBillingError  status.BridgeStateErrorCode = "ai-billing-error"
)

Bridge state error codes for AI-specific errors

View Source
const (
	ToolStatusPending          = matrixevents.ToolStatusPending
	ToolStatusRunning          = matrixevents.ToolStatusRunning
	ToolStatusCompleted        = matrixevents.ToolStatusCompleted
	ToolStatusFailed           = matrixevents.ToolStatusFailed
	ToolStatusTimeout          = matrixevents.ToolStatusTimeout
	ToolStatusCancelled        = matrixevents.ToolStatusCancelled
	ToolStatusApprovalRequired = matrixevents.ToolStatusApprovalRequired
)
View Source
const (
	ResultStatusSuccess = matrixevents.ResultStatusSuccess
	ResultStatusError   = matrixevents.ResultStatusError
	ResultStatusPartial = matrixevents.ResultStatusPartial
	ResultStatusDenied  = matrixevents.ResultStatusDenied
)
View Source
const (
	ToolTypeBuiltin  = matrixevents.ToolTypeBuiltin
	ToolTypeProvider = matrixevents.ToolTypeProvider
	ToolTypeFunction = matrixevents.ToolTypeFunction
	ToolTypeMCP      = matrixevents.ToolTypeMCP
)
View Source
const (
	ToolWebSearch       = "web_search"
	ToolFunctionCalling = "function_calling"
)
View Source
const (
	RelReplace   = matrixevents.RelReplace
	RelReference = matrixevents.RelReference
	RelThread    = matrixevents.RelThread
)

Relation types

View Source
const (
	ResolvedTargetUnknown = ""
	ResolvedTargetModel   = "model"
	ResolvedTargetAgent   = "agent"
)
View Source
const (
	ProviderBeeper     = "beeper"      // Beeper's OpenRouter proxy
	ProviderOpenAI     = "openai"      // Direct OpenAI API
	ProviderOpenRouter = "openrouter"  // Direct OpenRouter API
	ProviderMagicProxy = "magic_proxy" // Magic Proxy (OpenRouter-compatible)
	FlowCustom         = "custom"      // Custom login flow (provider resolved during login)
)

Provider constants - all use OpenAI SDK with different base URLs

View Source
const (
	DefaultModelOpenAI = "openai/gpt-5.2"
	// OpenRouter-compatible backends (OpenRouter + Magic Proxy) should default to Opus.
	DefaultModelOpenRouter = "anthropic/claude-opus-4.6"
	DefaultModelBeeper     = "anthropic/claude-opus-4.6"
)

Default models for each provider

View Source
const (
	ToolNameGravatarFetch      = toolspec.GravatarFetchName
	ToolNameGravatarSet        = toolspec.GravatarSetName
	ToolNameBeeperDocs         = toolspec.BeeperDocsName
	ToolNameBeeperSendFeedback = toolspec.BeeperSendFeedbackName
	ToolNameRead               = toolspec.ReadName
	ToolNameApplyPatch         = toolspec.ApplyPatchName
	ToolNameWrite              = toolspec.WriteName
	ToolNameEdit               = toolspec.EditName
)
View Source
const (
	BeeperAIKey = matrixevents.BeeperAIKey
)

Content field keys

View Source
const DefaultDebounceMs = 0

DefaultDebounceMs is the default debounce delay in milliseconds.

View Source
const DefaultImageModel = "google/gemini-3-pro-image-preview"
View Source
const ImageResultPrefix = "IMAGE:"
View Source
const ImagesResultPrefix = "IMAGES:"
View Source
const TTSResultPrefix = "AUDIO:"
View Source
const ToolNameImage = toolspec.ImageName
View Source
const ToolNameImageGenerate = toolspec.ImageGenerateName
View Source
const ToolNameMessage = toolspec.MessageName

Variables

View Source
var (
	ErrAPIKeyRequired = bridgev2.RespError{
		ErrCode:    "IO.AI_BRIDGE.API_KEY_REQUIRED",
		Err:        "Enter an API key.",
		StatusCode: http.StatusBadRequest,
	}
	ErrBaseURLRequired = bridgev2.RespError{
		ErrCode:    "IO.AI_BRIDGE.BASE_URL_REQUIRED",
		Err:        "Enter a base URL.",
		StatusCode: http.StatusBadRequest,
	}
	ErrOpenAIOrOpenRouterRequired = bridgev2.RespError{
		ErrCode:    "IO.AI_BRIDGE.OPENAI_OR_OPENROUTER_REQUIRED",
		Err:        "Enter an OpenAI or OpenRouter API key.",
		StatusCode: http.StatusBadRequest,
	}
)

Pre-defined bridgev2.RespError constants for consistent error responses

View Source
var AgentsEventType = matrixevents.AgentsEventType

AgentsEventType configures active agents in a room

View Source
var CommandDescriptionEventType = matrixevents.CommandDescriptionEventType

CommandDescriptionEventType is the state event type for MSC4391 command descriptions.

View Source
var CompactionStatusEventType = matrixevents.CompactionStatusEventType

CompactionStatusEventType notifies clients about context compaction

View Source
var ErrDMGhostImmutable = errors.New("can't change the counterpart ghost in a DM")
View Source
var HelpSectionAI = commands.HelpSection{
	Name:  "AI Chat",
	Order: 30,
}

HelpSectionAI is the help section for AI-related commands.

View Source
var ModelManifest = struct {
	Models  map[string]ModelInfo
	Aliases map[string]string
}{
	Models: map[string]ModelInfo{
		"anthropic/claude-haiku-4.5": {
			ID:                  "anthropic/claude-haiku-4.5",
			Name:                "Claude Haiku 4.5",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       200000,
			MaxOutputTokens:     64000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"anthropic/claude-opus-4.1": {
			ID:                  "anthropic/claude-opus-4.1",
			Name:                "Claude 4.1 Opus",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       200000,
			MaxOutputTokens:     32000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"anthropic/claude-opus-4.5": {
			ID:                  "anthropic/claude-opus-4.5",
			Name:                "Claude Opus 4.5",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       200000,
			MaxOutputTokens:     64000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"anthropic/claude-opus-4.6": {
			ID:                  "anthropic/claude-opus-4.6",
			Name:                "Claude Opus 4.6",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       1000000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"anthropic/claude-sonnet-4": {
			ID:                  "anthropic/claude-sonnet-4",
			Name:                "Claude 4 Sonnet",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       200000,
			MaxOutputTokens:     64000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"anthropic/claude-sonnet-4.5": {
			ID:                  "anthropic/claude-sonnet-4.5",
			Name:                "Claude Sonnet 4.5",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       1000000,
			MaxOutputTokens:     64000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"anthropic/claude-sonnet-4.6": {
			ID:                  "anthropic/claude-sonnet-4.6",
			Name:                "Claude Sonnet 4.6",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       1000000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"deepseek/deepseek-chat-v3-0324": {
			ID:                  "deepseek/deepseek-chat-v3-0324",
			Name:                "DeepSeek v3 (0324)",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       163840,
			MaxOutputTokens:     163840,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"deepseek/deepseek-chat-v3.1": {
			ID:                  "deepseek/deepseek-chat-v3.1",
			Name:                "DeepSeek v3.1",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       32768,
			MaxOutputTokens:     7168,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"deepseek/deepseek-r1": {
			ID:                  "deepseek/deepseek-r1",
			Name:                "DeepSeek R1 (Original)",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       64000,
			MaxOutputTokens:     16000,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"deepseek/deepseek-r1-0528": {
			ID:                  "deepseek/deepseek-r1-0528",
			Name:                "DeepSeek R1 (0528)",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       163840,
			MaxOutputTokens:     65536,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"deepseek/deepseek-r1-distill-qwen-32b": {
			ID:                  "deepseek/deepseek-r1-distill-qwen-32b",
			Name:                "DeepSeek R1 (Qwen Distilled)",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: false,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       32768,
			MaxOutputTokens:     32768,
			AvailableTools:      []string{},
		},
		"deepseek/deepseek-v3.1-terminus": {
			ID:                  "deepseek/deepseek-v3.1-terminus",
			Name:                "DeepSeek v3.1 Terminus",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       163840,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"deepseek/deepseek-v3.2": {
			ID:                  "deepseek/deepseek-v3.2",
			Name:                "DeepSeek v3.2",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       163840,
			MaxOutputTokens:     65536,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"google/gemini-2.0-flash-001": {
			ID:                  "google/gemini-2.0-flash-001",
			Name:                "Gemini 2.0 Flash",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       true,
			SupportsVideo:       true,
			SupportsPDF:         true,
			ContextWindow:       1048576,
			MaxOutputTokens:     8192,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"google/gemini-2.0-flash-lite-001": {
			ID:                  "google/gemini-2.0-flash-lite-001",
			Name:                "Gemini 2.0 Flash Lite",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       true,
			SupportsVideo:       true,
			SupportsPDF:         true,
			ContextWindow:       1048576,
			MaxOutputTokens:     8192,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"google/gemini-2.5-flash": {
			ID:                  "google/gemini-2.5-flash",
			Name:                "Gemini 2.5 Flash",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       true,
			SupportsVideo:       true,
			SupportsPDF:         true,
			ContextWindow:       1048576,
			MaxOutputTokens:     65535,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"google/gemini-2.5-flash-image": {
			ID:                  "google/gemini-2.5-flash-image",
			Name:                "Nano Banana",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: false,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    true,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       32768,
			MaxOutputTokens:     32768,
			AvailableTools:      []string{},
		},
		"google/gemini-2.5-flash-lite": {
			ID:                  "google/gemini-2.5-flash-lite",
			Name:                "Gemini 2.5 Flash Lite",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       true,
			SupportsVideo:       true,
			SupportsPDF:         true,
			ContextWindow:       1048576,
			MaxOutputTokens:     65535,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"google/gemini-2.5-pro": {
			ID:                  "google/gemini-2.5-pro",
			Name:                "Gemini 2.5 Pro",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       true,
			SupportsVideo:       true,
			SupportsPDF:         true,
			ContextWindow:       1048576,
			MaxOutputTokens:     65536,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"google/gemini-3-flash-preview": {
			ID:                  "google/gemini-3-flash-preview",
			Name:                "Gemini 3 Flash",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       true,
			SupportsVideo:       true,
			SupportsPDF:         true,
			ContextWindow:       1048576,
			MaxOutputTokens:     65536,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"google/gemini-3-pro-image-preview": {
			ID:                  "google/gemini-3-pro-image-preview",
			Name:                "Nano Banana Pro",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: false,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    true,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       65536,
			MaxOutputTokens:     32768,
			AvailableTools:      []string{},
		},
		"google/gemini-3.1-flash-lite-preview": {
			ID:                  "google/gemini-3.1-flash-lite-preview",
			Name:                "Gemini 3.1 Flash Lite",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       true,
			SupportsVideo:       true,
			SupportsPDF:         true,
			ContextWindow:       1048576,
			MaxOutputTokens:     65536,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"google/gemini-3.1-pro-preview": {
			ID:                  "google/gemini-3.1-pro-preview",
			Name:                "Gemini 3.1 Pro",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       true,
			SupportsVideo:       true,
			SupportsPDF:         true,
			ContextWindow:       1048576,
			MaxOutputTokens:     65536,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"meta-llama/llama-3.3-70b-instruct": {
			ID:                  "meta-llama/llama-3.3-70b-instruct",
			Name:                "Llama 3.3 70B",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       131072,
			MaxOutputTokens:     16384,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"meta-llama/llama-4-maverick": {
			ID:                  "meta-llama/llama-4-maverick",
			Name:                "Llama 4 Maverick",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       1048576,
			MaxOutputTokens:     16384,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"meta-llama/llama-4-scout": {
			ID:                  "meta-llama/llama-4-scout",
			Name:                "Llama 4 Scout",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       327680,
			MaxOutputTokens:     16384,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"minimax/minimax-m2": {
			ID:                  "minimax/minimax-m2",
			Name:                "MiniMax M2",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       196608,
			MaxOutputTokens:     196608,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"minimax/minimax-m2.1": {
			ID:                  "minimax/minimax-m2.1",
			Name:                "MiniMax M2.1",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       196608,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"minimax/minimax-m2.5": {
			ID:                  "minimax/minimax-m2.5",
			Name:                "MiniMax M2.5",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       196608,
			MaxOutputTokens:     196608,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"moonshotai/kimi-k2": {
			ID:                  "moonshotai/kimi-k2",
			Name:                "Kimi K2 (0711)",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       131000,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"moonshotai/kimi-k2-0905": {
			ID:                  "moonshotai/kimi-k2-0905",
			Name:                "Kimi K2 (0905)",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       131072,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"moonshotai/kimi-k2.5": {
			ID:                  "moonshotai/kimi-k2.5",
			Name:                "Kimi K2.5",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       262144,
			MaxOutputTokens:     65535,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"openai/gpt-4.1": {
			ID:                  "openai/gpt-4.1",
			Name:                "GPT-4.1",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       1047576,
			MaxOutputTokens:     32768,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-4.1-mini": {
			ID:                  "openai/gpt-4.1-mini",
			Name:                "GPT-4.1 Mini",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       1047576,
			MaxOutputTokens:     32768,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-4.1-nano": {
			ID:                  "openai/gpt-4.1-nano",
			Name:                "GPT-4.1 Nano",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       1047576,
			MaxOutputTokens:     32768,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-4o-mini": {
			ID:                  "openai/gpt-4o-mini",
			Name:                "GPT-4o-mini",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       128000,
			MaxOutputTokens:     16384,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-5": {
			ID:                  "openai/gpt-5",
			Name:                "GPT-5",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       400000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-5-image": {
			ID:                  "openai/gpt-5-image",
			Name:                "GPT ImageGen 1.5",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    true,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       400000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-5-image-mini": {
			ID:                  "openai/gpt-5-image-mini",
			Name:                "GPT ImageGen",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    true,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       400000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-5-mini": {
			ID:                  "openai/gpt-5-mini",
			Name:                "GPT-5 mini",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       400000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-5-nano": {
			ID:                  "openai/gpt-5-nano",
			Name:                "GPT-5 nano",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       400000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-5.1": {
			ID:                  "openai/gpt-5.1",
			Name:                "GPT-5.1",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       400000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-5.2": {
			ID:                  "openai/gpt-5.2",
			Name:                "GPT-5.2",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       400000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-5.2-pro": {
			ID:                  "openai/gpt-5.2-pro",
			Name:                "GPT-5.2 Pro",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       400000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-5.3-chat": {
			ID:                  "openai/gpt-5.3-chat",
			Name:                "GPT-5.3 Instant",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       128000,
			MaxOutputTokens:     16384,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-5.4": {
			ID:                  "openai/gpt-5.4",
			Name:                "GPT-5.4",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       1050000,
			MaxOutputTokens:     128000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/gpt-oss-120b": {
			ID:                  "openai/gpt-oss-120b",
			Name:                "GPT OSS 120B",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       131072,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"openai/gpt-oss-20b": {
			ID:                  "openai/gpt-oss-20b",
			Name:                "GPT OSS 20B",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       131072,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"openai/o3": {
			ID:                  "openai/o3",
			Name:                "o3",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       200000,
			MaxOutputTokens:     100000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/o3-mini": {
			ID:                  "openai/o3-mini",
			Name:                "o3-mini",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       200000,
			MaxOutputTokens:     100000,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"openai/o3-pro": {
			ID:                  "openai/o3-pro",
			Name:                "o3 Pro",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       200000,
			MaxOutputTokens:     100000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"openai/o4-mini": {
			ID:                  "openai/o4-mini",
			Name:                "o4-mini",
			Provider:            "openrouter",
			API:                 "openai-responses",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         true,
			ContextWindow:       200000,
			MaxOutputTokens:     100000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"qwen/qwen2.5-vl-32b-instruct": {
			ID:                  "qwen/qwen2.5-vl-32b-instruct",
			Name:                "Qwen 2.5 32B",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: false,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       128000,
			MaxOutputTokens:     0,
			AvailableTools:      []string{},
		},
		"qwen/qwen3-235b-a22b": {
			ID:                  "qwen/qwen3-235b-a22b",
			Name:                "Qwen 3 235B",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       131072,
			MaxOutputTokens:     8192,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"qwen/qwen3-32b": {
			ID:                  "qwen/qwen3-32b",
			Name:                "Qwen 3 32B",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       40960,
			MaxOutputTokens:     40960,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"qwen/qwen3-coder": {
			ID:                  "qwen/qwen3-coder",
			Name:                "Qwen 3 Coder",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       262144,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"x-ai/grok-3": {
			ID:                  "x-ai/grok-3",
			Name:                "Grok 3",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   false,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       131072,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"x-ai/grok-3-mini": {
			ID:                  "x-ai/grok-3-mini",
			Name:                "Grok 3 Mini",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       131072,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"x-ai/grok-4": {
			ID:                  "x-ai/grok-4",
			Name:                "Grok 4",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       256000,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"x-ai/grok-4-fast": {
			ID:                  "x-ai/grok-4-fast",
			Name:                "Grok 4 Fast",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       2000000,
			MaxOutputTokens:     30000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"x-ai/grok-4.1-fast": {
			ID:                  "x-ai/grok-4.1-fast",
			Name:                "Grok 4.1 Fast",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   true,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       2000000,
			MaxOutputTokens:     30000,
			AvailableTools:      []string{ToolWebSearch, ToolFunctionCalling},
		},
		"z-ai/glm-4.5": {
			ID:                  "z-ai/glm-4.5",
			Name:                "GLM 4.5",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       131072,
			MaxOutputTokens:     98304,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"z-ai/glm-4.5-air": {
			ID:                  "z-ai/glm-4.5-air",
			Name:                "GLM 4.5 Air",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       131072,
			MaxOutputTokens:     98304,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"z-ai/glm-4.5v": {
			ID:                  "z-ai/glm-4.5v",
			Name:                "GLM 4.5V",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       65536,
			MaxOutputTokens:     16384,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"z-ai/glm-4.6": {
			ID:                  "z-ai/glm-4.6",
			Name:                "GLM 4.6",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       204800,
			MaxOutputTokens:     204800,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"z-ai/glm-4.6v": {
			ID:                  "z-ai/glm-4.6v",
			Name:                "GLM 4.6V",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      true,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       true,
			SupportsPDF:         false,
			ContextWindow:       131072,
			MaxOutputTokens:     131072,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"z-ai/glm-4.7": {
			ID:                  "z-ai/glm-4.7",
			Name:                "GLM 4.7",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       202752,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolFunctionCalling},
		},
		"z-ai/glm-5": {
			ID:                  "z-ai/glm-5",
			Name:                "GLM 5",
			Provider:            "openrouter",
			API:                 "openai-completions",
			SupportsVision:      false,
			SupportsToolCalling: true,
			SupportsReasoning:   true,
			SupportsWebSearch:   false,
			SupportsImageGen:    false,
			SupportsAudio:       false,
			SupportsVideo:       false,
			SupportsPDF:         false,
			ContextWindow:       202752,
			MaxOutputTokens:     0,
			AvailableTools:      []string{ToolFunctionCalling},
		},
	},
	Aliases: map[string]string{
		"beeper/default":   "anthropic/claude-opus-4.6",
		"beeper/fast":      "openai/gpt-5-mini",
		"beeper/reasoning": "openai/gpt-5.2",
		"beeper/smart":     "openai/gpt-5.2",
	},
}

ModelManifest contains all model definitions and aliases. Models are fetched from OpenRouter API, aliases are defined in the generator config.

View Source
var ScheduleTickEventType = event.Type{
	Type:  "com.beeper.ai.schedule.tick",
	Class: event.MessageEventType,
}
View Source
var StreamEventMessageType = matrixevents.StreamEventMessageType

StreamEventMessageType is the unified event type for AI streaming updates (ephemeral).

Functions

func AddModelPrefix

func AddModelPrefix(backend ModelBackend, modelID string) string

AddModelPrefix adds a prefix to a model ID if it doesn't have one

func BuildDebounceKey

func BuildDebounceKey(roomID id.RoomID, sender id.UserID) string

BuildDebounceKey creates a key for debouncing: room+sender.

func CombineDebounceEntries

func CombineDebounceEntries(entries []DebounceEntry) (string, int)

CombineDebounceEntries combines multiple entries into a single body. Returns the combined body and the count of combined messages.

func EnqueueReactionFeedback

func EnqueueReactionFeedback(roomID id.RoomID, feedback ReactionFeedback)

EnqueueReactionFeedback adds reaction feedback for a room.

func EstimateTokens

func EstimateTokens(messages []openai.ChatCompletionMessageParamUnion, model string) (int, error)

EstimateTokens counts tokens for a list of chat messages Based on OpenAI's cookbook: https://github.com/openai/openai-cookbook

func ExtractBeeperPreviews

func ExtractBeeperPreviews(previews []*PreviewWithImage) []*event.BeeperLinkPreview

ExtractBeeperPreviews extracts just the BeeperLinkPreview from PreviewWithImage slice.

func ExtractURLs

func ExtractURLs(text string, maxURLs int) []string

ExtractURLs extracts URLs from text, returning up to maxURLs unique URLs. It strips markdown link syntax to avoid detecting the same URL twice.

func FallbackReasoningLevel

func FallbackReasoningLevel(current string) string

FallbackReasoningLevel returns a lower reasoning level to try when the current one fails. Returns empty string if there's no fallback available (already at "none" or unknown level).

func FormatPreviewsForContext

func FormatPreviewsForContext(previews []*event.BeeperLinkPreview, maxChars int) string

FormatPreviewsForContext formats link previews for injection into LLM context.

func FormatProxyError

func FormatProxyError(proxyErr *ProxyError) string

FormatProxyError formats a proxy error for user display

func FormatReactionFeedback

func FormatReactionFeedback(feedback []ReactionFeedback) string

FormatReactionFeedback formats reaction feedback as context for the AI. Keep the string stable and channel-specific so the model can reason about where the reaction happened.

func FormatUserFacingError

func FormatUserFacingError(err error) string

FormatUserFacingError transforms an API error into a user-friendly message. Returns a sanitized message suitable for display to end users.

func FromAgentDefinitionContent

func FromAgentDefinitionContent(content *AgentDefinitionContent) *agents.AgentDefinition

FromAgentDefinitionContent converts a Matrix event form to AgentDefinition.

func GetModelDisplayName

func GetModelDisplayName(modelID string) string

GetModelDisplayName returns the canonical model identifier for display.

func GetPDFEngineFromContext

func GetPDFEngineFromContext(ctx context.Context) string

GetPDFEngineFromContext retrieves the PDF engine override from context

func HasValidPrefix

func HasValidPrefix(modelID string) bool

func IsAuthError

func IsAuthError(err error) bool

IsAuthError checks if the error is an authentication error. Checks openai.Error status codes first, then falls back to string pattern matching.

func IsBillingError

func IsBillingError(err error) bool

IsBillingError checks if the error is a billing/payment error (402)

func IsGoogleModel

func IsGoogleModel(modelID string) bool

IsGoogleModel returns true if the model ID looks like a Google/Gemini model.

func IsImageError

func IsImageError(err error) bool

IsImageError checks if the error is related to image size or dimensions

func IsMissingToolCallInputError

func IsMissingToolCallInputError(err error) bool

IsMissingToolCallInputError checks if the error indicates a corrupted session where tool call inputs are missing (e.g., from interrupted streaming).

func IsModelNotFound

func IsModelNotFound(err error) bool

IsModelNotFound checks if the error is a model not found (404) error

func IsOverloadedError

func IsOverloadedError(err error) bool

IsOverloadedError checks if the error indicates the service is overloaded

func IsRateLimitError

func IsRateLimitError(err error) bool

IsRateLimitError checks if the error is a rate limit (429) error

func IsReasoningError

func IsReasoningError(err error) bool

IsReasoningError checks if the error is related to unsupported reasoning/thinking levels

func IsRoleOrderingError

func IsRoleOrderingError(err error) bool

IsRoleOrderingError checks if the error is related to message role ordering conflicts

func IsServerError

func IsServerError(err error) bool

IsServerError checks if the error is a server-side (5xx) error

func IsTimeoutError

func IsTimeoutError(err error) bool

IsTimeoutError checks if the error is a timeout error

func IsToolSchemaError

func IsToolSchemaError(err error) bool

IsToolSchemaError checks if the error indicates a tool schema validation failure.

func IsToolUseIDFormatError

func IsToolUseIDFormatError(err error) bool

IsToolUseIDFormatError checks if the error is caused by an invalid tool_use ID format (e.g., when IDs from one provider are replayed to another).

func MakePDFPluginMiddleware

func MakePDFPluginMiddleware(defaultEngine string) option.Middleware

MakePDFPluginMiddleware creates middleware that injects the file-parser plugin for PDFs. The defaultEngine parameter is used as a fallback when no per-request engine is set in context. To set a per-request engine, use WithPDFEngine() to add it to the request context.

func MakeToolDedupMiddleware

func MakeToolDedupMiddleware(log zerolog.Logger) option.Middleware

MakeToolDedupMiddleware removes duplicate tool names from outbound Responses requests.

func NewAITextMessage

func NewAITextMessage(
	portal *bridgev2.Portal,
	login *bridgev2.UserLogin,
	text string,
	meta *PortalMetadata,
	agentID string,
	modelID string,
) *bridgeadapter.RemoteMessage

NewAITextMessage creates a RemoteMessage for a plain text assistant message.

func NewCallID

func NewCallID() string

NewCallID generates a new unique call ID for tool calls

func NewTurnID

func NewTurnID() string

NewTurnID generates a new unique turn ID

func ParseExistingLinkPreviews

func ParseExistingLinkPreviews(rawContent map[string]any) []*event.BeeperLinkPreview

ParseExistingLinkPreviews extracts link previews from a Matrix event's raw content.

func PreviewsToMapSlice

func PreviewsToMapSlice(previews []*event.BeeperLinkPreview) []map[string]any

PreviewsToMapSlice converts BeeperLinkPreviews to a format suitable for JSON serialization.

func PromptContextToChatCompletionMessages

func PromptContextToChatCompletionMessages(ctx PromptContext, supportsVideoURL bool) []openai.ChatCompletionMessageParamUnion

PromptContextToChatCompletionMessages converts the canonical prompt model into Chat Completions messages.

func PromptContextToResponsesInput

func PromptContextToResponsesInput(ctx PromptContext) responses.ResponseInputParam

PromptContextToResponsesInput converts the canonical prompt model into Responses input items.

func ResolveAlias

func ResolveAlias(modelID string) string

ResolveAlias is intentionally strict in hard-cut mode: only trim whitespace.

func SanitizeGoogleTurnOrdering

SanitizeGoogleTurnOrdering fixes prompt ordering for Google models:

  • Merges consecutive user messages
  • Merges consecutive assistant messages
  • Prepends a synthetic user turn if history starts with an assistant message

func SanitizeToolCallID

func SanitizeToolCallID(id string, mode string) string

SanitizeToolCallID cleans a tool call ID for provider compatibility.

Modes:

  • "strict": strips all non-alphanumeric characters, preserves "call_" prefix
  • "strict9": strips non-alphanumeric, truncates to 9 chars (some providers require short IDs)

If the ID is empty after sanitization, a new random call ID is generated.

func ShouldDebounce

func ShouldDebounce(evt *event.Event, body string) bool

ShouldDebounce returns false for messages that shouldn't be debounced. Media, commands, and empty messages are processed immediately.

func ToOpenAIChatTools

func ToOpenAIChatTools(tools []ToolDefinition, log *zerolog.Logger) []openai.ChatCompletionToolUnionParam

ToOpenAIChatTools converts tool definitions to OpenAI Chat Completions tool format.

func ToOpenAIResponsesInput

func ToOpenAIResponsesInput(messages []UnifiedMessage) responses.ResponseInputParam

ToOpenAIResponsesInput converts legacy unified messages to OpenAI Responses input.

func ToOpenAITools

func ToOpenAITools(tools []ToolDefinition, strictMode ToolStrictMode, log *zerolog.Logger) []responses.ToolUnionParam

ToOpenAITools converts tool definitions to OpenAI Responses API format

func UploadPreviewImages

func UploadPreviewImages(ctx context.Context, previews []*PreviewWithImage, intent bridgev2.MatrixAPI, roomID id.RoomID) []*event.BeeperLinkPreview

UploadPreviewImages uploads images from PreviewWithImage to Matrix and returns final BeeperLinkPreviews.

func WithBridgeToolContext

func WithBridgeToolContext(ctx context.Context, btc *BridgeToolContext) context.Context

WithBridgeToolContext adds bridge context to a context

func WithPDFEngine

func WithPDFEngine(ctx context.Context, engine string) context.Context

WithPDFEngine adds a PDF engine override to the context

func WithTypingContext

func WithTypingContext(ctx context.Context, typing *TypingContext) context.Context

Types

type AIClient

type AIClient struct {
	UserLogin *bridgev2.UserLogin
	// contains filtered or unexported fields
}

AIClient handles communication with AI providers

func (*AIClient) BackgroundContext

func (oc *AIClient) BackgroundContext(ctx context.Context) context.Context

func (*AIClient) BroadcastCommandDescriptions

func (oc *AIClient) BroadcastCommandDescriptions(ctx context.Context, portal *bridgev2.Portal)

BroadcastCommandDescriptions sends MSC4391 command-description state events for all registered AI commands into the given room. This enables clients to discover and render slash commands with autocomplete.

func (*AIClient) BroadcastRoomState

func (oc *AIClient) BroadcastRoomState(ctx context.Context, portal *bridgev2.Portal) error

BroadcastRoomState refreshes standard Matrix room capabilities and command descriptions.

func (*AIClient) Connect

func (oc *AIClient) Connect(ctx context.Context)

func (*AIClient) CreateChatWithGhost

func (oc *AIClient) CreateChatWithGhost(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.CreateChatResponse, error)

CreateChatWithGhost creates a DM for a known model or agent ghost.

func (*AIClient) Disconnect

func (oc *AIClient) Disconnect()

func (*AIClient) GetCapabilities

func (oc *AIClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *event.RoomFeatures

func (*AIClient) GetChatInfo

func (oc *AIClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.ChatInfo, error)

func (*AIClient) GetContactList

func (oc *AIClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveIdentifierResponse, error)

GetContactList returns a list of available AI agents and models as contacts

func (*AIClient) GetUserInfo

func (oc *AIClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.UserInfo, error)

func (*AIClient) HandleMarkedUnread

func (oc *AIClient) HandleMarkedUnread(ctx context.Context, msg *bridgev2.MatrixMarkedUnread) error

HandleMarkedUnread tracks unread state for portals. No remote forwarding needed.

func (*AIClient) HandleMatrixDisappearingTimer

func (oc *AIClient) HandleMatrixDisappearingTimer(ctx context.Context, msg *bridgev2.MatrixDisappearingTimer) (bool, error)

HandleMatrixDisappearingTimer handles disappearing message timer changes from Matrix For AI bridge, we just update the portal's disappear field - the bridge framework handles the actual deletion

func (*AIClient) HandleMatrixEdit

func (oc *AIClient) HandleMatrixEdit(ctx context.Context, edit *bridgev2.MatrixEdit) error

HandleMatrixEdit handles edits to previously sent messages

func (*AIClient) HandleMatrixMessage

func (oc *AIClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (*bridgev2.MatrixMessageResponse, error)

HandleMatrixMessage processes incoming Matrix messages and dispatches them to the AI

func (*AIClient) HandleMatrixMessageRemove

func (oc *AIClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridgev2.MatrixMessageRemove) error

HandleMatrixMessageRemove handles message deletions from Matrix For AI bridge, we just delete from our database - there's no "remote" to sync to

func (*AIClient) HandleMatrixReaction

func (oc *AIClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (*database.Reaction, error)

func (*AIClient) HandleMatrixReactionRemove

func (oc *AIClient) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error

func (*AIClient) HandleMatrixReadReceipt

func (oc *AIClient) HandleMatrixReadReceipt(ctx context.Context, msg *bridgev2.MatrixReadReceipt) error

HandleMatrixReadReceipt tracks read receipt positions. AI-bridge is the authoritative side so there is nothing to forward to a remote network.

func (*AIClient) HandleMatrixRoomAvatar

func (oc *AIClient) HandleMatrixRoomAvatar(ctx context.Context, msg *bridgev2.MatrixRoomAvatar) (bool, error)

HandleMatrixRoomAvatar handles room avatar change events from Matrix. Returns true to indicate the avatar change was accepted.

func (*AIClient) HandleMatrixRoomName

func (oc *AIClient) HandleMatrixRoomName(ctx context.Context, msg *bridgev2.MatrixRoomName) (bool, error)

HandleMatrixRoomName handles room rename events from Matrix. Returns true to indicate the name change was accepted (no remote to forward to).

func (*AIClient) HandleMatrixRoomTopic

func (oc *AIClient) HandleMatrixRoomTopic(ctx context.Context, msg *bridgev2.MatrixRoomTopic) (bool, error)

HandleMatrixRoomTopic handles room topic change events from Matrix. Returns true to indicate the topic change was accepted.

func (*AIClient) HandleMatrixTyping

func (oc *AIClient) HandleMatrixTyping(ctx context.Context, typing *bridgev2.MatrixTyping) error

HandleMatrixTyping tracks local user typing state for auto-greeting delays.

func (*AIClient) HandleMute

func (oc *AIClient) HandleMute(ctx context.Context, msg *bridgev2.MatrixMute) error

HandleMute tracks mute state for portals. No remote forwarding needed.

func (*AIClient) IsLoggedIn

func (oc *AIClient) IsLoggedIn() bool

func (*AIClient) IsThisUser

func (oc *AIClient) IsThisUser(ctx context.Context, userID networkid.UserID) bool

func (*AIClient) Log

func (oc *AIClient) Log() *zerolog.Logger

func (*AIClient) Login

func (oc *AIClient) Login() *bridgev2.UserLogin

func (*AIClient) LogoutRemote

func (oc *AIClient) LogoutRemote(ctx context.Context)

func (*AIClient) PreHandleMatrixReaction

func (oc *AIClient) PreHandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error)

func (*AIClient) ResolveIdentifier

func (oc *AIClient) ResolveIdentifier(ctx context.Context, identifier string, createChat bool) (*bridgev2.ResolveIdentifierResponse, error)

ResolveIdentifier resolves an agent ID to a ghost and optionally creates a chat.

func (*AIClient) SearchUsers

func (oc *AIClient) SearchUsers(ctx context.Context, query string) ([]*bridgev2.ResolveIdentifierResponse, error)

SearchUsers searches available AI models and agents by name/ID.

type AIProvider

type AIProvider interface {
	// Name returns the provider name (e.g., "openai", "openrouter")
	Name() string

	// GenerateStream generates a streaming response
	GenerateStream(ctx context.Context, params GenerateParams) (<-chan StreamEvent, error)

	// Generate generates a non-streaming response
	Generate(ctx context.Context, params GenerateParams) (*GenerateResponse, error)

	// ListModels returns available models for this provider
	ListModels(ctx context.Context) ([]ModelInfo, error)
}

AIProvider defines a common interface for OpenAI-compatible AI providers

type AIRemoteMessageRemove

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

AIRemoteMessageRemove is a RemoteMessageRemove for redacting AI or user messages.

func (*AIRemoteMessageRemove) AddLogContext

func (r *AIRemoteMessageRemove) AddLogContext(c zerolog.Context) zerolog.Context

func (*AIRemoteMessageRemove) GetPortalKey

func (r *AIRemoteMessageRemove) GetPortalKey() networkid.PortalKey

func (*AIRemoteMessageRemove) GetSender

func (*AIRemoteMessageRemove) GetTargetMessage

func (r *AIRemoteMessageRemove) GetTargetMessage() networkid.MessageID

func (*AIRemoteMessageRemove) GetType

type AIRemoteReaction

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

AIRemoteReaction is a RemoteReaction for AI-generated reactions.

func (*AIRemoteReaction) AddLogContext

func (r *AIRemoteReaction) AddLogContext(c zerolog.Context) zerolog.Context

func (*AIRemoteReaction) GetPortalKey

func (r *AIRemoteReaction) GetPortalKey() networkid.PortalKey

func (*AIRemoteReaction) GetReactionDBMetadata

func (r *AIRemoteReaction) GetReactionDBMetadata() any

func (*AIRemoteReaction) GetReactionEmoji

func (r *AIRemoteReaction) GetReactionEmoji() (string, networkid.EmojiID)

func (*AIRemoteReaction) GetReactionExtraContent

func (r *AIRemoteReaction) GetReactionExtraContent() map[string]any

func (*AIRemoteReaction) GetSender

func (r *AIRemoteReaction) GetSender() bridgev2.EventSender

func (*AIRemoteReaction) GetTargetMessage

func (r *AIRemoteReaction) GetTargetMessage() networkid.MessageID

func (*AIRemoteReaction) GetTimestamp

func (r *AIRemoteReaction) GetTimestamp() time.Time

func (*AIRemoteReaction) GetType

type AIRemoteReactionRemove

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

AIRemoteReactionRemove is a RemoteReactionRemove for removing AI reactions.

func (*AIRemoteReactionRemove) AddLogContext

func (*AIRemoteReactionRemove) GetPortalKey

func (r *AIRemoteReactionRemove) GetPortalKey() networkid.PortalKey

func (*AIRemoteReactionRemove) GetRemovedEmojiID

func (r *AIRemoteReactionRemove) GetRemovedEmojiID() networkid.EmojiID

func (*AIRemoteReactionRemove) GetSender

func (*AIRemoteReactionRemove) GetTargetMessage

func (r *AIRemoteReactionRemove) GetTargetMessage() networkid.MessageID

func (*AIRemoteReactionRemove) GetType

type AckReactionGateParams

type AckReactionGateParams struct {
	Scope              AckReactionScope
	IsDirect           bool
	IsGroup            bool
	IsMentionableGroup bool
	RequireMention     bool
	CanDetectMention   bool
	EffectiveMention   bool
	ShouldBypass       bool
}

type AckReactionScope

type AckReactionScope string
const (
	AckScopeAll          AckReactionScope = "all"
	AckScopeDirect       AckReactionScope = "direct"
	AckScopeGroupAll     AckReactionScope = "group-all"
	AckScopeGroupMention AckReactionScope = "group-mentions"
	AckScopeOff          AckReactionScope = "off"
	AckScopeNone         AckReactionScope = "none"
)

type AgentConfig

type AgentConfig struct {
	AgentID     string   `json:"agent_id"`
	Name        string   `json:"name"`
	Model       string   `json:"model"`
	UserID      string   `json:"user_id"` // Matrix user ID for this agent
	Role        string   `json:"role"`    // "primary", "specialist"
	Description string   `json:"description,omitempty"`
	AvatarURL   string   `json:"avatar_url,omitempty"` // mxc:// URL
	Triggers    []string `json:"triggers,omitempty"`   // e.g., ["@researcher", "/research"]
}

AgentConfig describes an AI agent

type AgentDefaultsConfig

type AgentDefaultsConfig struct {
	Subagents         *agents.SubagentConfig `yaml:"subagents"`
	SkipBootstrap     bool                   `yaml:"skip_bootstrap"`
	BootstrapMaxChars int                    `yaml:"bootstrap_max_chars"`
	TimeoutSeconds    int                    `yaml:"timeoutSeconds"`
	SoulEvil          *agents.SoulEvilConfig `yaml:"soul_evil"`
	Heartbeat         *HeartbeatConfig       `yaml:"heartbeat"`
	UserTimezone      string                 `yaml:"userTimezone"`
	EnvelopeTimezone  string                 `yaml:"envelopeTimezone"`  // local|utc|user|IANA
	EnvelopeTimestamp string                 `yaml:"envelopeTimestamp"` // on|off
	EnvelopeElapsed   string                 `yaml:"envelopeElapsed"`   // on|off
	TypingMode        string                 `yaml:"typingMode"`        // never|instant|thinking|message
	TypingIntervalSec *int                   `yaml:"typingIntervalSeconds"`
}

AgentDefaultsConfig defines default agent settings.

type AgentDefinitionContent

type AgentDefinitionContent struct {
	ID              string                       `json:"id"`
	Name            string                       `json:"name"`
	Description     string                       `json:"description,omitempty"`
	AvatarURL       string                       `json:"avatar_url,omitempty"`
	Model           string                       `json:"model,omitempty"`
	ModelFallback   []string                     `json:"model_fallback,omitempty"`
	SystemPrompt    string                       `json:"system_prompt,omitempty"`
	PromptMode      string                       `json:"prompt_mode,omitempty"`
	Tools           *toolpolicy.ToolPolicyConfig `json:"tools,omitempty"`
	Temperature     float64                      `json:"temperature,omitempty"`
	ReasoningEffort string                       `json:"reasoning_effort,omitempty"`
	IdentityName    string                       `json:"identity_name,omitempty"`
	IdentityPersona string                       `json:"identity_persona,omitempty"`
	IsPreset        bool                         `json:"is_preset,omitempty"`
	MemorySearch    any                          `json:"memory_search,omitempty"`
	HeartbeatPrompt string                       `json:"heartbeat_prompt,omitempty"`
	CreatedAt       int64                        `json:"created_at"`
	UpdatedAt       int64                        `json:"updated_at"`
}

AgentDefinitionContent stores agent configuration in Matrix state events. This is the serialized form of agents.AgentDefinition for Matrix storage.

func ToAgentDefinitionContent

func ToAgentDefinitionContent(agent *agents.AgentDefinition) *AgentDefinitionContent

ToAgentDefinitionContent converts an AgentDefinition to its Matrix event form.

type AgentEntryConfig

type AgentEntryConfig struct {
	ID                string           `yaml:"id"`
	Heartbeat         *HeartbeatConfig `yaml:"heartbeat"`
	TypingMode        string           `yaml:"typingMode"` // never|instant|thinking|message
	TypingIntervalSec *int             `yaml:"typingIntervalSeconds"`
}

AgentEntryConfig defines per-agent overrides.

type AgentStoreAdapter

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

AgentStoreAdapter implements agents.AgentStore with UserLogin metadata as source of truth.

func NewAgentStoreAdapter

func NewAgentStoreAdapter(client *AIClient) *AgentStoreAdapter

func (*AgentStoreAdapter) DeleteAgent

func (s *AgentStoreAdapter) DeleteAgent(ctx context.Context, agentID string) error

DeleteAgent implements agents.AgentStore. It deletes a custom agent from UserLogin metadata.

func (*AgentStoreAdapter) GetAgentByID

func (s *AgentStoreAdapter) GetAgentByID(ctx context.Context, agentID string) (*agents.AgentDefinition, error)

GetAgentByID looks up an agent by ID, returning preset or custom agents.

func (*AgentStoreAdapter) GetAgentForRoom

func (s *AgentStoreAdapter) GetAgentForRoom(ctx context.Context, meta *PortalMetadata) (*agents.AgentDefinition, error)

Falls back to the Quick Chatter if no specific agent is set.

func (*AgentStoreAdapter) ListAvailableTools

func (s *AgentStoreAdapter) ListAvailableTools(_ context.Context) ([]tools.ToolInfo, error)

ListAvailableTools implements agents.AgentStore.

func (*AgentStoreAdapter) ListModels

func (s *AgentStoreAdapter) ListModels(ctx context.Context) ([]agents.ModelInfo, error)

ListModels implements agents.AgentStore.

func (*AgentStoreAdapter) LoadAgents

func (s *AgentStoreAdapter) LoadAgents(ctx context.Context) (map[string]*agents.AgentDefinition, error)

LoadAgents implements agents.AgentStore. It loads agents from presets and metadata-backed custom agents.

func (*AgentStoreAdapter) SaveAgent

func (s *AgentStoreAdapter) SaveAgent(ctx context.Context, agent *agents.AgentDefinition) error

SaveAgent implements agents.AgentStore. It saves custom agents to UserLogin metadata.

type AgentsConfig

type AgentsConfig struct {
	Defaults *AgentDefaultsConfig `yaml:"defaults"`
	List     []AgentEntryConfig   `yaml:"list"`
}

AgentsConfig configures agent defaults.

type AgentsEventContent

type AgentsEventContent struct {
	Agents        []AgentConfig        `json:"agents"`
	Orchestration *OrchestrationConfig `json:"orchestration,omitempty"`
}

AgentsEventContent configures active agents in a room

type ApplyPatchToolsConfig

type ApplyPatchToolsConfig struct {
	Enabled     *bool    `yaml:"enabled"`
	AllowModels []string `yaml:"allow_models"`
}

ApplyPatchToolsConfig configures apply_patch availability.

type BeeperConfig

type BeeperConfig struct {
	UserMXID string `yaml:"user_mxid"` // Owning Matrix user for the built-in managed Beeper Cloud login
	BaseURL  string `yaml:"base_url"`  // Beeper Cloud proxy endpoint
	Token    string `yaml:"token"`     // Beeper Matrix access token
}

BeeperConfig contains Beeper Cloud proxy credentials for automatic login. If UserMXID, BaseURL, and Token are set, users don't need to manually log in.

type BossStoreAdapter

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

BossStoreAdapter implements tools.AgentStoreInterface for boss tool execution. This adapter converts between our agent types and the tools package types.

func NewBossStoreAdapter

func NewBossStoreAdapter(client *AIClient) *BossStoreAdapter

func (*BossStoreAdapter) CreateRoom

func (b *BossStoreAdapter) CreateRoom(ctx context.Context, room tools.RoomData) (string, error)

CreateRoom implements tools.AgentStoreInterface.

func (*BossStoreAdapter) DeleteAgent

func (b *BossStoreAdapter) DeleteAgent(ctx context.Context, agentID string) error

DeleteAgent implements tools.AgentStoreInterface.

func (*BossStoreAdapter) ListAvailableTools

func (b *BossStoreAdapter) ListAvailableTools(ctx context.Context) ([]tools.ToolInfo, error)

ListAvailableTools implements tools.AgentStoreInterface.

func (*BossStoreAdapter) ListModels

func (b *BossStoreAdapter) ListModels(ctx context.Context) ([]tools.ModelData, error)

ListModels implements tools.AgentStoreInterface.

func (*BossStoreAdapter) ListRooms

func (b *BossStoreAdapter) ListRooms(ctx context.Context) ([]tools.RoomData, error)

ListRooms implements tools.AgentStoreInterface.

func (*BossStoreAdapter) LoadAgents

func (b *BossStoreAdapter) LoadAgents(ctx context.Context) (map[string]tools.AgentData, error)

LoadAgents implements tools.AgentStoreInterface.

func (*BossStoreAdapter) ModifyRoom

func (b *BossStoreAdapter) ModifyRoom(ctx context.Context, roomID string, updates tools.RoomData) error

ModifyRoom implements tools.AgentStoreInterface.

func (*BossStoreAdapter) RunInternalCommand

func (b *BossStoreAdapter) RunInternalCommand(ctx context.Context, roomID string, command string) (string, error)

RunInternalCommand implements tools.AgentStoreInterface.

func (*BossStoreAdapter) SaveAgent

func (b *BossStoreAdapter) SaveAgent(ctx context.Context, agent tools.AgentData) error

SaveAgent implements tools.AgentStoreInterface.

type BridgeConfig

type BridgeConfig = bridgeconfig.BridgeConfig

BridgeConfig is an alias for the shared bridge config.

type BridgeToolContext

type BridgeToolContext struct {
	Client        *AIClient
	Portal        *bridgev2.Portal
	Meta          *PortalMetadata
	SourceEventID id.EventID // The triggering message's event ID (for reactions/replies)
	SenderID      string     // The triggering sender ID (owner-only tool gating)
}

BridgeToolContext provides bridge-specific context for tool execution

func GetBridgeToolContext

func GetBridgeToolContext(ctx context.Context) *BridgeToolContext

type BuiltinAlwaysAllowRule

type BuiltinAlwaysAllowRule struct {
	ToolName string `json:"tool_name,omitempty"`
	Action   string `json:"action,omitempty"`
}

type ChannelConfig

type ChannelConfig struct {
	Heartbeat     *ChannelHeartbeatVisibilityConfig `yaml:"heartbeat"`
	ReplyToMode   string                            `yaml:"replyToMode"`   // off|first|all (Matrix)
	ThreadReplies string                            `yaml:"threadReplies"` // off|inbound|always (Matrix)
}

type ChannelDefaultsConfig

type ChannelDefaultsConfig struct {
	Heartbeat *ChannelHeartbeatVisibilityConfig `yaml:"heartbeat"`
}

type ChannelHeartbeatVisibilityConfig

type ChannelHeartbeatVisibilityConfig struct {
	ShowOk       *bool `yaml:"showOk"`
	ShowAlerts   *bool `yaml:"showAlerts"`
	UseIndicator *bool `yaml:"useIndicator"`
}

type ChannelsConfig

type ChannelsConfig struct {
	Defaults *ChannelDefaultsConfig `yaml:"defaults"`
	Matrix   *ChannelConfig         `yaml:"matrix"`
}

ChannelsConfig defines per-channel settings.

type CommandsConfig

type CommandsConfig struct {
	OwnerAllowFrom []string `yaml:"ownerAllowFrom"`
}

CommandsConfig defines command authorization settings.

type CompactionEvent

type CompactionEvent struct {
	Type           CompactionEventType `json:"type"`
	SessionID      string              `json:"session_id,omitempty"`
	MessagesBefore int                 `json:"messages_before,omitempty"`
	MessagesAfter  int                 `json:"messages_after,omitempty"`
	TokensBefore   int                 `json:"tokens_before,omitempty"`
	TokensAfter    int                 `json:"tokens_after,omitempty"`
	Summary        string              `json:"summary,omitempty"`
	WillRetry      bool                `json:"will_retry,omitempty"`
	Error          string              `json:"error,omitempty"`
}

CompactionEvent is emitted to clients for overflow compaction visibility.

type CompactionEventType

type CompactionEventType string

CompactionEventType represents a compaction lifecycle event type.

const (
	CompactionEventStart CompactionEventType = "compaction_start"
	CompactionEventEnd   CompactionEventType = "compaction_end"
)

type Config

type Config struct {
	Beeper        BeeperConfig                       `yaml:"beeper"`
	Providers     ProvidersConfig                    `yaml:"providers"`
	Models        *ModelsConfig                      `yaml:"models"`
	Bridge        BridgeConfig                       `yaml:"bridge"`
	Tools         ToolProvidersConfig                `yaml:"tools"`
	ToolApprovals *ToolApprovalsRuntimeConfig        `yaml:"tool_approvals"`
	ToolPolicy    *toolpolicy.GlobalToolPolicyConfig `yaml:"tool_policy"`
	Agents        *AgentsConfig                      `yaml:"agents"`
	Channels      *ChannelsConfig                    `yaml:"channels"`
	Messages      *MessagesConfig                    `yaml:"messages"`
	Commands      *CommandsConfig                    `yaml:"commands"`
	Session       *SessionConfig                     `yaml:"session"`

	// Global settings
	DefaultSystemPrompt string        `yaml:"default_system_prompt"`
	ModelCacheDuration  time.Duration `yaml:"model_cache_duration"`

	// Context pruning configuration
	Pruning *airuntime.PruningConfig `yaml:"pruning"`

	// Link preview configuration
	LinkPreviews *LinkPreviewConfig `yaml:"link_previews"`

	// Inbound message processing configuration
	Inbound *InboundConfig `yaml:"inbound"`

	// Integration registration toggles.
	Integrations *IntegrationsConfig `yaml:"integrations"`

	// Module-level configs captured generically (e.g., cron:, memory:, memory_search:).
	Modules map[string]any `yaml:",inline"`
}

Config represents the connector-specific configuration that is nested under the `network:` block in the main bridge config.

type ContentPart

type ContentPart struct {
	Type        ContentPartType
	Text        string
	ImageURL    string
	ImageB64    string
	MimeType    string
	PDFURL      string
	PDFB64      string
	AudioB64    string
	AudioFormat string
	VideoURL    string
	VideoB64    string
}

ContentPart represents a legacy piece of content (text, image, PDF, audio, or video).

type ContentPartType

type ContentPartType string

ContentPartType identifies the type of content in a legacy unified message.

const (
	ContentTypeText  ContentPartType = "text"
	ContentTypeImage ContentPartType = "image"
	ContentTypePDF   ContentPartType = "pdf"
	ContentTypeAudio ContentPartType = "audio"
	ContentTypeVideo ContentPartType = "video"
)

type ContextLengthError

type ContextLengthError struct {
	ModelMaxTokens  int
	RequestedTokens int
	OriginalError   error
}

ContextLengthError contains parsed details from context_length_exceeded errors

func ParseContextLengthError

func ParseContextLengthError(err error) *ContextLengthError

ParseContextLengthError checks if err is a context length exceeded error and extracts the token counts from the error message

func (*ContextLengthError) Error

func (e *ContextLengthError) Error() string

type DebounceBuffer

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

DebounceBuffer holds pending messages for a key.

type DebounceEntry

type DebounceEntry struct {
	Event        *event.Event
	Portal       *bridgev2.Portal
	Meta         *PortalMetadata
	InboundCtx   airuntime.InboundContext
	RawBody      string
	SenderName   string
	RoomName     string
	IsGroup      bool
	WasMentioned bool
	AckEventID   id.EventID // Track ack reaction for removal after flush
	PendingSent  bool       // Whether a pending status was already sent for this event
}

DebounceEntry represents a buffered message waiting to be processed.

type Debouncer

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

Debouncer buffers rapid messages and combines them. Based on clawdbot's inbound-debounce.ts implementation.

func NewDebouncer

func NewDebouncer(delayMs int, onFlush func([]DebounceEntry), onError func(error, []DebounceEntry)) *Debouncer

NewDebouncer creates a new debouncer with the given delay and callbacks.

func NewDebouncerWithLogger

func NewDebouncerWithLogger(delayMs int, onFlush func([]DebounceEntry), onError func(error, []DebounceEntry), log zerolog.Logger) *Debouncer

NewDebouncerWithLogger creates a new debouncer with logging support.

func (*Debouncer) Enqueue

func (d *Debouncer) Enqueue(key string, entry DebounceEntry, shouldDebounce bool)

Enqueue adds a message to the debounce buffer. If shouldDebounce is false, the message is processed immediately.

func (*Debouncer) EnqueueWithDelay

func (d *Debouncer) EnqueueWithDelay(key string, entry DebounceEntry, shouldDebounce bool, delayMs int)

EnqueueWithDelay adds a message with a custom debounce delay. delayMs: 0 = use default, -1 = immediate (no debounce), >0 = custom delay

func (*Debouncer) FlushAll

func (d *Debouncer) FlushAll()

FlushAll flushes all pending buffers (e.g., on shutdown).

func (*Debouncer) FlushKey

func (d *Debouncer) FlushKey(key string)

FlushKey immediately flushes the buffer for a key (e.g., when media arrives).

func (*Debouncer) PendingCount

func (d *Debouncer) PendingCount() int

PendingCount returns the number of keys with pending buffers.

type DedupeCache

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

Based on clawdbot's dedupe.ts implementation.

func NewDedupeCache

func NewDedupeCache(ttl time.Duration, maxSize int) *DedupeCache

func (*DedupeCache) Check

func (c *DedupeCache) Check(key string) bool

Also records the key for future checks.

func (*DedupeCache) Clear

func (c *DedupeCache) Clear()

Clear removes all entries from the cache.

func (*DedupeCache) Size

func (c *DedupeCache) Size() int

type DesktopAPIInstance

type DesktopAPIInstance struct {
	Token   string `json:"token,omitempty"`
	BaseURL string `json:"base_url,omitempty"`
}

type DirectChatConfig

type DirectChatConfig struct {
	HistoryLimit int `yaml:"historyLimit"`
}

DirectChatConfig defines direct message defaults.

type FailoverReason

type FailoverReason string

FailoverReason is a typed enum for classifying why a model failover happened.

const (
	FailoverAuth      FailoverReason = "auth"
	FailoverBilling   FailoverReason = "billing"
	FailoverRateLimit FailoverReason = "rate_limit"
	FailoverTimeout   FailoverReason = "timeout"
	FailoverFormat    FailoverReason = "format"
	FailoverOverload  FailoverReason = "overload"
	FailoverServer    FailoverReason = "server"
	FailoverUnknown   FailoverReason = "unknown"
)

func ClassifyFailoverReason

func ClassifyFailoverReason(err error) FailoverReason

ClassifyFailoverReason returns a structured reason for why a model failover should occur. Wraps the existing Is*Error functions into a single classifier.

type FetchConfig

type FetchConfig struct {
	Provider  string   `yaml:"provider"`
	Fallbacks []string `yaml:"fallbacks"`

	Exa    ProviderExaConfig    `yaml:"exa"`
	Direct ProviderDirectConfig `yaml:"direct"`
}

type FileAnnotation

type FileAnnotation struct {
	FileHash   string `json:"file_hash"`            // SHA256 hash of the file content
	ParsedText string `json:"parsed_text"`          // Extracted text content
	PageCount  int    `json:"page_count,omitempty"` // Number of pages
	CreatedAt  int64  `json:"created_at"`           // Unix timestamp when cached
}

FileAnnotation stores cached parsed PDF content from OpenRouter's file-parser plugin

type GenerateParams

type GenerateParams struct {
	Model               string
	Context             PromptContext
	PreviousResponseID  string
	Temperature         float64
	MaxCompletionTokens int
	ReasoningEffort     string // none, low, medium, high (for reasoning models)
	WebSearchEnabled    bool
}

GenerateParams contains parameters for generation requests

type GenerateResponse

type GenerateResponse struct {
	Content      string
	FinishReason string
	ResponseID   string // For Responses API continuation
	ToolCalls    []ToolCallResult
	Usage        UsageInfo
}

GenerateResponse contains the result of a non-streaming generation

type GeneratedFileRef

type GeneratedFileRef = bridgeadapter.GeneratedFileRef

type GhostMetadata

type GhostMetadata struct {
	LastSync jsontime.Unix `json:"last_sync,omitempty"`
}

GhostMetadata stores metadata for AI model ghosts

type GravatarProfile

type GravatarProfile struct {
	Email     string         `json:"email,omitempty"`
	Hash      string         `json:"hash,omitempty"`
	Profile   map[string]any `json:"profile,omitempty"` // Full profile payload
	FetchedAt int64          `json:"fetched_at,omitempty"`
}

GravatarProfile stores the selected Gravatar profile for a login.

type GravatarState

type GravatarState struct {
	Primary *GravatarProfile `json:"primary,omitempty"`
}

GravatarState stores Gravatar profile state for a login.

type GroupChatConfig

type GroupChatConfig struct {
	MentionPatterns []string `yaml:"mentionPatterns"`
	Activation      string   `yaml:"activation"` // mention|always
	HistoryLimit    int      `yaml:"historyLimit"`
}

GroupChatConfig defines group chat settings.

type HeartbeatActiveHoursConfig

type HeartbeatActiveHoursConfig struct {
	Start    string `yaml:"start"`
	End      string `yaml:"end"`
	Timezone string `yaml:"timezone"`
}

type HeartbeatConfig

type HeartbeatConfig struct {
	Every            *string                     `yaml:"every"`
	ActiveHours      *HeartbeatActiveHoursConfig `yaml:"activeHours"`
	Model            *string                     `yaml:"model"`
	Session          *string                     `yaml:"session"`
	Target           *string                     `yaml:"target"`
	To               *string                     `yaml:"to"`
	Prompt           *string                     `yaml:"prompt"`
	AckMaxChars      *int                        `yaml:"ackMaxChars"`
	IncludeReasoning *bool                       `yaml:"includeReasoning"`
}

HeartbeatConfig configures periodic heartbeat runs.

type HeartbeatEventPayload

type HeartbeatEventPayload struct {
	TS            int64                   `json:"ts"`
	Status        string                  `json:"status"`
	To            string                  `json:"to,omitempty"`
	Preview       string                  `json:"preview,omitempty"`
	DurationMs    int64                   `json:"durationMs,omitempty"`
	HasMedia      bool                    `json:"hasMedia,omitempty"`
	Reason        string                  `json:"reason,omitempty"`
	Channel       string                  `json:"channel,omitempty"`
	Silent        bool                    `json:"silent,omitempty"`
	IndicatorType *HeartbeatIndicatorType `json:"indicatorType,omitempty"`
}

type HeartbeatIndicatorType

type HeartbeatIndicatorType string
const (
	HeartbeatIndicatorOK    HeartbeatIndicatorType = "ok"
	HeartbeatIndicatorAlert HeartbeatIndicatorType = "alert"
	HeartbeatIndicatorError HeartbeatIndicatorType = "error"
)

type HeartbeatRunConfig

type HeartbeatRunConfig struct {
	Reason           string
	AckMaxChars      int
	ShowOk           bool
	ShowAlerts       bool
	UseIndicator     bool
	IncludeReasoning bool
	ExecEvent        bool
	SessionKey       string
	StoreAgentID     string
	PrevUpdatedAt    int64
	TargetRoom       id.RoomID
	TargetReason     string
	SuppressSend     bool
	AgentID          string
	Channel          string
	SuppressSave     bool
}

type HeartbeatRunOutcome

type HeartbeatRunOutcome struct {
	Status  string
	Reason  string
	Text    string
	Preview string
	Sent    bool
	Silent  bool
	Skipped bool
}

type HeartbeatState

type HeartbeatState struct {
	LastHeartbeatText   string `json:"last_heartbeat_text,omitempty"`
	LastHeartbeatSentAt int64  `json:"last_heartbeat_sent_at,omitempty"`
}

HeartbeatState tracks last heartbeat delivery for dedupe.

type ImageDimensionError

type ImageDimensionError struct {
	MaxDimensionPx int
}

ImageDimensionError contains parsed details from image dimension errors.

func ParseImageDimensionError

func ParseImageDimensionError(err error) *ImageDimensionError

ParseImageDimensionError extracts max dimension from an image error. Returns nil if the error is not an image dimension error.

type ImageSizeError

type ImageSizeError struct {
	MaxMB float64
}

ImageSizeError contains parsed details from image size errors.

func ParseImageSizeError

func ParseImageSizeError(err error) *ImageSizeError

ParseImageSizeError extracts max size in MB from an image error. Returns nil if the error is not an image size error.

type InboundConfig

type InboundConfig struct {
	// Deduplication settings
	DedupeTTL     time.Duration `yaml:"dedupe_ttl"`      // Time-to-live for dedupe entries (default: 20m)
	DedupeMaxSize int           `yaml:"dedupe_max_size"` // Max entries in dedupe cache (default: 5000)

	// Debounce settings
	DefaultDebounceMs int `yaml:"default_debounce_ms"` // Default debounce delay in ms (default: 500)
}

InboundConfig contains settings for inbound message processing including deduplication and debouncing.

func (*InboundConfig) WithDefaults

func (c *InboundConfig) WithDefaults() *InboundConfig

WithDefaults returns the InboundConfig with default values applied.

type InboundDebounceConfig

type InboundDebounceConfig struct {
	DebounceMs int            `yaml:"debounceMs"`
	ByChannel  map[string]int `yaml:"byChannel"`
}

InboundDebounceConfig defines inbound debounce behavior.

type IntegrationsConfig

type IntegrationsConfig struct {
	Modules map[string]any `yaml:",inline"`
}

IntegrationsConfig controls compile-time-available integration registration. Module names are keys in the Modules map. A bool value (true/false) enables/disables the module. A map value configures the module (with an optional "enabled" key). Absent modules default to enabled.

type LinkPreviewConfig

type LinkPreviewConfig struct {
	Enabled         bool          `yaml:"enabled"`
	MaxURLsInbound  int           `yaml:"max_urls_inbound"`  // Max URLs to process from user messages
	MaxURLsOutbound int           `yaml:"max_urls_outbound"` // Max URLs to preview in AI responses
	FetchTimeout    time.Duration `yaml:"fetch_timeout"`     // Timeout for fetching each URL
	MaxContentChars int           `yaml:"max_content_chars"` // Max chars for description in context
	MaxPageBytes    int64         `yaml:"max_page_bytes"`    // Max page size to download
	MaxImageBytes   int64         `yaml:"max_image_bytes"`   // Max image size to download
	CacheTTL        time.Duration `yaml:"cache_ttl"`         // How long to cache previews
}

func DefaultLinkPreviewConfig

func DefaultLinkPreviewConfig() LinkPreviewConfig

type LinkPreviewer

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

func NewLinkPreviewer

func NewLinkPreviewer(config LinkPreviewConfig) *LinkPreviewer

func (*LinkPreviewer) FetchPreview

func (lp *LinkPreviewer) FetchPreview(ctx context.Context, urlStr string) (*PreviewWithImage, error)

FetchPreview fetches and generates a link preview for a URL, including the image data.

func (*LinkPreviewer) FetchPreviews

func (lp *LinkPreviewer) FetchPreviews(ctx context.Context, urls []string) []*PreviewWithImage

FetchPreviews fetches previews for multiple URLs in parallel.

func (*LinkPreviewer) FetchPreviewsWithCitations

func (lp *LinkPreviewer) FetchPreviewsWithCitations(ctx context.Context, urls []string, cits []citations.SourceCitation) []*PreviewWithImage

FetchPreviewsWithCitations fetches previews for multiple URLs, using SourceCitation metadata when available to skip HTML fetching.

func (*LinkPreviewer) PreviewFromCitation

func (lp *LinkPreviewer) PreviewFromCitation(ctx context.Context, urlStr string, c citations.SourceCitation) *PreviewWithImage

PreviewFromCitation builds a PreviewWithImage from a SourceCitation without fetching HTML. It downloads the image directly from the citation's Image URL.

type MCPAlwaysAllowRule

type MCPAlwaysAllowRule struct {
	ServerLabel string `json:"server_label,omitempty"`
	ToolName    string `json:"tool_name,omitempty"`
}

type MCPServerConfig

type MCPServerConfig struct {
	Transport string   `json:"transport,omitempty"` // streamable_http|stdio
	Endpoint  string   `json:"endpoint,omitempty"`  // streamable HTTP endpoint
	Command   string   `json:"command,omitempty"`   // stdio command path/binary
	Args      []string `json:"args,omitempty"`      // stdio command args
	AuthType  string   `json:"auth_type,omitempty"` // bearer|apikey|none
	Token     string   `json:"token,omitempty"`
	AuthURL   string   `json:"auth_url,omitempty"` // Optional browser auth URL for manual token retrieval.
	Connected bool     `json:"connected,omitempty"`
	Kind      string   `json:"kind,omitempty"` // generic
}

MCPServerConfig stores one MCP server connection for a login. The map key in ServiceTokens.MCPServers is the server name.

type MCPToolsConfig

type MCPToolsConfig struct {
	EnableStdio bool `yaml:"enable_stdio"`
}

MCPToolsConfig configures generic MCP behavior.

type MatrixReactionSummary

type MatrixReactionSummary struct {
	Key   string   `json:"key"`   // The emoji
	Count int      `json:"count"` // Number of reactions with this emoji
	Users []string `json:"users"` // User IDs who reacted
}

MatrixReactionSummary represents a summary of reactions on a message.

type MatrixRoomInfo

type MatrixRoomInfo struct {
	RoomID      string `json:"room_id"`
	Name        string `json:"name,omitempty"`
	Topic       string `json:"topic,omitempty"`
	MemberCount int    `json:"member_count,omitempty"`
}

MatrixRoomInfo represents room information.

type MatrixUserProfile

type MatrixUserProfile struct {
	UserID      string `json:"user_id"`
	DisplayName string `json:"display_name,omitempty"`
	AvatarURL   string `json:"avatar_url,omitempty"`
}

MatrixUserProfile represents a user's profile information.

type MediaToolsConfig

type MediaToolsConfig struct {
	Models      []MediaUnderstandingModelConfig `yaml:"models"`
	Concurrency int                             `yaml:"concurrency"`
	Image       *MediaUnderstandingConfig       `yaml:"image"`
	Audio       *MediaUnderstandingConfig       `yaml:"audio"`
	Video       *MediaUnderstandingConfig       `yaml:"video"`
}

MediaToolsConfig configures media understanding/transcription.

func (*MediaToolsConfig) ConfigForCapability

func (cfg *MediaToolsConfig) ConfigForCapability(capability MediaUnderstandingCapability) *MediaUnderstandingConfig

type MediaUnderstandingAttachmentDecision

type MediaUnderstandingAttachmentDecision struct {
	AttachmentIndex int                               `json:"attachment_index"`
	Attempts        []MediaUnderstandingModelDecision `json:"attempts,omitempty"`
	Chosen          *MediaUnderstandingModelDecision  `json:"chosen,omitempty"`
}

MediaUnderstandingAttachmentDecision records attempts for one attachment.

type MediaUnderstandingAttachmentsConfig

type MediaUnderstandingAttachmentsConfig struct {
	Mode           string `yaml:"mode"`
	MaxAttachments int    `yaml:"maxAttachments"`
	Prefer         string `yaml:"prefer"`
}

MediaUnderstandingAttachmentsConfig controls how media attachments are selected.

type MediaUnderstandingCapability

type MediaUnderstandingCapability string

MediaUnderstandingCapability identifies the type of media being understood.

const (
	MediaCapabilityImage MediaUnderstandingCapability = "image"
	MediaCapabilityAudio MediaUnderstandingCapability = "audio"
	MediaCapabilityVideo MediaUnderstandingCapability = "video"
)

type MediaUnderstandingConfig

type MediaUnderstandingConfig struct {
	Enabled         *bool                                `yaml:"enabled"`
	Scope           *MediaUnderstandingScopeConfig       `yaml:"scope"`
	MaxBytes        int                                  `yaml:"maxBytes"`
	MaxChars        int                                  `yaml:"maxChars"`
	Prompt          string                               `yaml:"prompt"`
	TimeoutSeconds  int                                  `yaml:"timeoutSeconds"`
	Language        string                               `yaml:"language"`
	ProviderOptions map[string]map[string]any            `yaml:"providerOptions"`
	BaseURL         string                               `yaml:"baseUrl"`
	Headers         map[string]string                    `yaml:"headers"`
	Attachments     *MediaUnderstandingAttachmentsConfig `yaml:"attachments"`
	Models          []MediaUnderstandingModelConfig      `yaml:"models"`
}

MediaUnderstandingConfig defines defaults for media understanding of a capability.

type MediaUnderstandingDecision

type MediaUnderstandingDecision struct {
	Capability  MediaUnderstandingCapability           `json:"capability"`
	Outcome     MediaUnderstandingOutcome              `json:"outcome,omitempty"`
	Attachments []MediaUnderstandingAttachmentDecision `json:"attachments,omitempty"`
}

MediaUnderstandingDecision summarizes the overall outcome for a capability.

type MediaUnderstandingEntryType

type MediaUnderstandingEntryType string

MediaUnderstandingEntryType identifies how a model entry is executed.

const (
	MediaEntryTypeProvider MediaUnderstandingEntryType = "provider"
	MediaEntryTypeCLI      MediaUnderstandingEntryType = "cli"
)

type MediaUnderstandingKind

type MediaUnderstandingKind string

MediaUnderstandingKind identifies the output kind.

const (
	MediaKindAudioTranscription MediaUnderstandingKind = "audio.transcription"
	MediaKindImageDescription   MediaUnderstandingKind = "image.description"
	MediaKindVideoDescription   MediaUnderstandingKind = "video.description"
)

type MediaUnderstandingModelConfig

type MediaUnderstandingModelConfig struct {
	Provider         string                    `yaml:"provider"`
	Model            string                    `yaml:"model"`
	Capabilities     []string                  `yaml:"capabilities"`
	Type             string                    `yaml:"type"`
	Command          string                    `yaml:"command"`
	Args             []string                  `yaml:"args"`
	Prompt           string                    `yaml:"prompt"`
	MaxChars         int                       `yaml:"maxChars"`
	MaxBytes         int                       `yaml:"maxBytes"`
	TimeoutSeconds   int                       `yaml:"timeoutSeconds"`
	Language         string                    `yaml:"language"`
	ProviderOptions  map[string]map[string]any `yaml:"providerOptions"`
	BaseURL          string                    `yaml:"baseUrl"`
	Headers          map[string]string         `yaml:"headers"`
	Profile          string                    `yaml:"profile"`
	PreferredProfile string                    `yaml:"preferredProfile"`
}

MediaUnderstandingModelConfig defines a single media understanding model entry.

func (MediaUnderstandingModelConfig) ResolvedType

type MediaUnderstandingModelDecision

type MediaUnderstandingModelDecision struct {
	Type     MediaUnderstandingEntryType `json:"type,omitempty"`
	Provider string                      `json:"provider,omitempty"`
	Model    string                      `json:"model,omitempty"`
	Outcome  MediaUnderstandingOutcome   `json:"outcome,omitempty"`
	Reason   string                      `json:"reason,omitempty"`
}

MediaUnderstandingModelDecision records a single model attempt.

type MediaUnderstandingOutcome

type MediaUnderstandingOutcome string

MediaUnderstandingOutcome represents a decision outcome.

const (
	MediaOutcomeSuccess      MediaUnderstandingOutcome = "success"
	MediaOutcomeSkipped      MediaUnderstandingOutcome = "skipped"
	MediaOutcomeFailed       MediaUnderstandingOutcome = "failed"
	MediaOutcomeDisabled     MediaUnderstandingOutcome = "disabled"
	MediaOutcomeScopeDeny    MediaUnderstandingOutcome = "scope-deny"
	MediaOutcomeNoAttachment MediaUnderstandingOutcome = "no-attachment"
)

type MediaUnderstandingOutput

type MediaUnderstandingOutput struct {
	Kind            MediaUnderstandingKind `json:"kind"`
	AttachmentIndex int                    `json:"attachment_index"`
	Text            string                 `json:"text"`
	Provider        string                 `json:"provider"`
	Model           string                 `json:"model,omitempty"`
}

MediaUnderstandingOutput represents a single media understanding result.

type MediaUnderstandingScopeConfig

type MediaUnderstandingScopeConfig struct {
	Default string                        `yaml:"default"`
	Rules   []MediaUnderstandingScopeRule `yaml:"rules"`
}

MediaUnderstandingScopeConfig controls allow/deny gating for media understanding.

type MediaUnderstandingScopeMatch

type MediaUnderstandingScopeMatch struct {
	Channel   string `yaml:"channel"`
	ChatType  string `yaml:"chatType"`
	KeyPrefix string `yaml:"keyPrefix"`
}

MediaUnderstandingScopeMatch defines match criteria for media understanding scope rules.

type MediaUnderstandingScopeRule

type MediaUnderstandingScopeRule struct {
	Action string                        `yaml:"action"`
	Match  *MediaUnderstandingScopeMatch `yaml:"match"`
}

MediaUnderstandingScopeRule defines a single allow/deny rule.

type MessageMetadata

type MessageMetadata struct {
	bridgeadapter.BaseMessageMetadata

	CompletionID       string `json:"completion_id,omitempty"`
	Model              string `json:"model,omitempty"`
	HasToolCalls       bool   `json:"has_tool_calls,omitempty"`
	Transcript         string `json:"transcript,omitempty"`
	FirstTokenAtMs     int64  `json:"first_token_at_ms,omitempty"`
	ThinkingTokenCount int    `json:"thinking_token_count,omitempty"`
	ExcludeFromHistory bool   `json:"exclude_from_history,omitempty"`

	// Media understanding (OpenClaw-style)
	MediaUnderstanding          []MediaUnderstandingOutput   `json:"media_understanding,omitempty"`
	MediaUnderstandingDecisions []MediaUnderstandingDecision `json:"media_understanding_decisions,omitempty"`

	// Multimodal history: media attached to this message for re-injection into prompts.
	MediaURL string `json:"media_url,omitempty"` // mxc:// URL for user-sent media (image, PDF, audio, video)
	MimeType string `json:"mime_type,omitempty"` // MIME type of user-sent media
}

MessageMetadata keeps a tiny summary of each exchange so we can rebuild prompts using database history.

func (*MessageMetadata) CopyFrom

func (mm *MessageMetadata) CopyFrom(other any)

CopyFrom allows the metadata struct to participate in mautrix's meta merge.

type MessageRole

type MessageRole string

MessageRole represents the role of a legacy unified message sender.

const (
	RoleSystem    MessageRole = "system"
	RoleUser      MessageRole = "user"
	RoleAssistant MessageRole = "assistant"
	RoleTool      MessageRole = "tool"
)

type MessagesConfig

type MessagesConfig struct {
	AckReaction      string                 `yaml:"ackReaction"`
	AckReactionScope string                 `yaml:"ackReactionScope"` // group-mentions|group-all|direct|all|off|none
	RemoveAckAfter   bool                   `yaml:"removeAckAfter"`
	GroupChat        *GroupChatConfig       `yaml:"groupChat"`
	DirectChat       *DirectChatConfig      `yaml:"directChat"`
	Queue            *QueueConfig           `yaml:"queue"`
	InboundDebounce  *InboundDebounceConfig `yaml:"inbound"`
}

MessagesConfig defines message rendering settings.

type ModelAPI

type ModelAPI string
const (
	ModelAPIResponses       ModelAPI = "responses"
	ModelAPIChatCompletions ModelAPI = "chat_completions"
)

type ModelBackend

type ModelBackend string

ModelBackend identifies which backend to use for a model All backends use the OpenAI SDK with different base URLs

const (
	BackendOpenAI     ModelBackend = "openai"
	BackendOpenRouter ModelBackend = "openrouter"
)

func ParseModelPrefix

func ParseModelPrefix(modelID string) (backend ModelBackend, actualModel string)

ParseModelPrefix extracts the backend and actual model ID from a prefixed model Examples:

  • "openai/gpt-5.2" → (BackendOpenAI, "gpt-5.2")
  • "anthropic/claude-sonnet-4.5" (no routing prefix) → ("", "anthropic/claude-sonnet-4.5")
  • "gpt-4.1" (no prefix) → ("", "gpt-4.1")

type ModelCache

type ModelCache struct {
	Models        []ModelInfo `json:"models,omitempty"`
	LastRefresh   int64       `json:"last_refresh,omitempty"`
	CacheDuration int64       `json:"cache_duration,omitempty"` // seconds
}

ModelCache stores available models (cached in UserLoginMetadata) Uses provider-agnostic ModelInfo instead of openai.Model

type ModelCapabilities

type ModelCapabilities struct {
	SupportsVision      bool `json:"supports_vision"`
	SupportsReasoning   bool `json:"supports_reasoning"` // Models that support reasoning_effort parameter
	SupportsPDF         bool `json:"supports_pdf"`
	SupportsImageGen    bool `json:"supports_image_gen"`
	SupportsAudio       bool `json:"supports_audio"`        // Models that accept audio input
	SupportsVideo       bool `json:"supports_video"`        // Models that accept video input
	SupportsToolCalling bool `json:"supports_tool_calling"` // Models that support function calling
}

ModelCapabilities stores computed capabilities for a model This is NOT sent to the API, just used for local caching

type ModelCatalogEntry

type ModelCatalogEntry struct {
	ID              string   `json:"id"`
	Name            string   `json:"name,omitempty"`
	Provider        string   `json:"provider"`
	ContextWindow   int      `json:"contextWindow,omitempty"`
	MaxOutputTokens int      `json:"maxTokens,omitempty"`
	Reasoning       bool     `json:"reasoning,omitempty"`
	Input           []string `json:"input,omitempty"`
}

type ModelDefinitionConfig

type ModelDefinitionConfig struct {
	ID            string   `yaml:"id"`
	Name          string   `yaml:"name"`
	Reasoning     bool     `yaml:"reasoning"`
	Input         []string `yaml:"input"`
	ContextWindow int      `yaml:"context_window"`
	MaxTokens     int      `yaml:"max_tokens"`
}

ModelDefinitionConfig defines a model entry for catalog seeding.

type ModelInfo

type ModelInfo struct {
	ID                  string   `json:"id"`
	Name                string   `json:"name"`
	Provider            string   `json:"provider"`
	API                 string   `json:"api,omitempty"`
	Description         string   `json:"description,omitempty"`
	SupportsVision      bool     `json:"supports_vision"`
	SupportsToolCalling bool     `json:"supports_tool_calling"`
	SupportsPDF         bool     `json:"supports_pdf,omitempty"`
	SupportsReasoning   bool     `json:"supports_reasoning"`
	SupportsWebSearch   bool     `json:"supports_web_search"`
	SupportsImageGen    bool     `json:"supports_image_gen,omitempty"`
	SupportsAudio       bool     `json:"supports_audio,omitempty"`
	SupportsVideo       bool     `json:"supports_video,omitempty"`
	ContextWindow       int      `json:"context_window,omitempty"`
	MaxOutputTokens     int      `json:"max_output_tokens,omitempty"`
	AvailableTools      []string `json:"available_tools,omitempty"`
}

ModelInfo describes a single AI model's capabilities

type ModelProviderConfig

type ModelProviderConfig struct {
	Models []ModelDefinitionConfig `yaml:"models"`
}

ModelProviderConfig describes models for a specific provider.

type ModelsConfig

type ModelsConfig struct {
	Mode      string                         `yaml:"mode"` // merge | replace
	Providers map[string]ModelProviderConfig `yaml:"providers"`
}

ModelsConfig configures model catalog seeding.

type NonFallbackError

type NonFallbackError struct {
	Err error
}

NonFallbackError marks an error as ineligible for fallback retries once output has been sent.

func (*NonFallbackError) Error

func (e *NonFallbackError) Error() string

func (*NonFallbackError) Unwrap

func (e *NonFallbackError) Unwrap() error

type NormalizedLocation

type NormalizedLocation struct {
	Latitude  float64
	Longitude float64
	Accuracy  *float64
	Name      string
	Address   string
	Caption   string
	Source    string // pin|place|live
	IsLive    bool
}

type OpenAIConnector

type OpenAIConnector struct {
	Config Config
	// contains filtered or unexported fields
}

OpenAIConnector wires mautrix bridgev2 to the OpenAI chat APIs.

func NewAIConnector

func NewAIConnector() *OpenAIConnector

func (*OpenAIConnector) CreateLogin

func (oc *OpenAIConnector) CreateLogin(ctx context.Context, user *bridgev2.User, flowID string) (bridgev2.LoginProcess, error)

func (*OpenAIConnector) FillPortalBridgeInfo

func (oc *OpenAIConnector) FillPortalBridgeInfo(portal *bridgev2.Portal, content *event.BridgeEventContent)

FillPortalBridgeInfo sets bridge metadata for AI rooms.

func (*OpenAIConnector) GetBridgeInfoVersion

func (oc *OpenAIConnector) GetBridgeInfoVersion() (info, capabilities int)

func (*OpenAIConnector) GetCapabilities

func (oc *OpenAIConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities

func (*OpenAIConnector) GetConfig

func (oc *OpenAIConnector) GetConfig() (example string, data any, upgrader configupgrade.Upgrader)

func (*OpenAIConnector) GetDBMetaTypes

func (oc *OpenAIConnector) GetDBMetaTypes() database.MetaTypes

func (*OpenAIConnector) GetLoginFlows

func (oc *OpenAIConnector) GetLoginFlows() []bridgev2.LoginFlow

Package-level flow definitions (use Provider* constants as flow IDs)

func (*OpenAIConnector) GetName

func (oc *OpenAIConnector) GetName() bridgev2.BridgeName

func (*OpenAIConnector) Init

func (oc *OpenAIConnector) Init(bridge *bridgev2.Bridge)

func (*OpenAIConnector) LoadUserLogin

func (oc *OpenAIConnector) LoadUserLogin(ctx context.Context, login *bridgev2.UserLogin) error

func (*OpenAIConnector) Start

func (oc *OpenAIConnector) Start(ctx context.Context) error

func (*OpenAIConnector) Stop

func (oc *OpenAIConnector) Stop(ctx context.Context)

func (*OpenAIConnector) ValidateUserID

func (oc *OpenAIConnector) ValidateUserID(id networkid.UserID) bool

type OpenAILogin

type OpenAILogin struct {
	User      *bridgev2.User
	Connector *OpenAIConnector
	FlowID    string
}

OpenAILogin maps a Matrix user to a synthetic OpenAI "login".

func (*OpenAILogin) Cancel

func (ol *OpenAILogin) Cancel()

func (*OpenAILogin) Start

func (ol *OpenAILogin) Start(ctx context.Context) (*bridgev2.LoginStep, error)

func (*OpenAILogin) SubmitUserInput

func (ol *OpenAILogin) SubmitUserInput(ctx context.Context, input map[string]string) (*bridgev2.LoginStep, error)

type OpenAIProvider

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

OpenAIProvider implements AIProvider for OpenAI's API

func NewOpenAIProviderWithBaseURL

func NewOpenAIProviderWithBaseURL(apiKey, baseURL string, log zerolog.Logger) (*OpenAIProvider, error)

NewOpenAIProviderWithBaseURL creates an OpenAI provider with custom base URL Used for OpenRouter, Beeper proxy, or custom endpoints

func NewOpenAIProviderWithPDFPlugin

func NewOpenAIProviderWithPDFPlugin(apiKey, baseURL, userID, pdfEngine string, headers map[string]string, log zerolog.Logger) (*OpenAIProvider, error)

NewOpenAIProviderWithPDFPlugin creates an OpenAI provider with PDF plugin middleware. Used for OpenRouter/Beeper to enable universal PDF support via file-parser plugin.

func NewOpenAIProviderWithUserID

func NewOpenAIProviderWithUserID(apiKey, baseURL, userID string, log zerolog.Logger) (*OpenAIProvider, error)

NewOpenAIProviderWithUserID creates an OpenAI provider that passes user_id with each request. Used for Beeper proxy to ensure correct rate limiting and feature flags per user.

func (*OpenAIProvider) Client

func (o *OpenAIProvider) Client() openai.Client

Client returns the underlying OpenAI client for direct access Used by the bridge for advanced features like Responses API

func (*OpenAIProvider) Generate

func (o *OpenAIProvider) Generate(ctx context.Context, params GenerateParams) (*GenerateResponse, error)

Generate performs a non-streaming generation using the Responses API.

func (*OpenAIProvider) GenerateStream

func (o *OpenAIProvider) GenerateStream(ctx context.Context, params GenerateParams) (<-chan StreamEvent, error)

GenerateStream generates a streaming response from OpenAI using the Responses API.

func (*OpenAIProvider) ListModels

func (o *OpenAIProvider) ListModels(ctx context.Context) ([]ModelInfo, error)

ListModels returns available OpenAI models

func (*OpenAIProvider) Name

func (o *OpenAIProvider) Name() string

type OpenAIRemoteMessage

type OpenAIRemoteMessage struct {
	PortalKey networkid.PortalKey
	ID        networkid.MessageID
	Sender    bridgev2.EventSender
	Content   string
	Timestamp time.Time
	Metadata  *MessageMetadata

	FormattedContent string
	ReplyToEventID   id.EventID
	ToolCallEventIDs []string
	ImageEventIDs    []string
}

OpenAIRemoteMessage represents a GPT answer that should be bridged to Matrix.

func (*OpenAIRemoteMessage) AddLogContext

func (m *OpenAIRemoteMessage) AddLogContext(c zerolog.Context) zerolog.Context

func (*OpenAIRemoteMessage) ConvertMessage

func (m *OpenAIRemoteMessage) ConvertMessage(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI) (*bridgev2.ConvertedMessage, error)

func (*OpenAIRemoteMessage) GetID

func (*OpenAIRemoteMessage) GetPortalKey

func (m *OpenAIRemoteMessage) GetPortalKey() networkid.PortalKey

func (*OpenAIRemoteMessage) GetSender

func (m *OpenAIRemoteMessage) GetSender() bridgev2.EventSender

func (*OpenAIRemoteMessage) GetStreamOrder

func (m *OpenAIRemoteMessage) GetStreamOrder() int64

func (*OpenAIRemoteMessage) GetTimestamp

func (m *OpenAIRemoteMessage) GetTimestamp() time.Time

func (*OpenAIRemoteMessage) GetTransactionID

func (m *OpenAIRemoteMessage) GetTransactionID() networkid.TransactionID

GetTransactionID implements RemoteMessageWithTransactionID

func (*OpenAIRemoteMessage) GetType

type OrchestrationConfig

type OrchestrationConfig struct {
	Mode          string `json:"mode"` // "user_directed", "auto"
	AllowParallel bool   `json:"allow_parallel"`
	MaxConcurrent int    `json:"max_concurrent,omitempty"`
}

OrchestrationConfig defines how agents work together

type PDFConfig

type PDFConfig struct {
	Engine string `json:"engine,omitempty"` // pdf-text (free), mistral-ocr (OCR, paid, default), native
}

PDFConfig stores per-room PDF processing configuration

type PortalInitOpts

type PortalInitOpts struct {
	ModelID   string
	Title     string
	CopyFrom  *PortalMetadata // For forked chats - copies config from source
	PortalKey *networkid.PortalKey
}

PortalInitOpts contains options for initializing a chat portal

type PortalMetadata

type PortalMetadata struct {
	AckReactionEmoji       string     `json:"ack_reaction_emoji,omitempty"`
	AckReactionRemoveAfter bool       `json:"ack_reaction_remove_after,omitempty"`
	PDFConfig              *PDFConfig `json:"pdf_config,omitempty"`

	Slug             string `json:"slug,omitempty"`
	Title            string `json:"title,omitempty"`
	TitleGenerated   bool   `json:"title_generated,omitempty"` // True if title was auto-generated
	WelcomeSent      bool   `json:"welcome_sent,omitempty"`
	AutoGreetingSent bool   `json:"auto_greeting_sent,omitempty"`

	SessionResetAt          int64            `json:"session_reset_at,omitempty"`
	AbortedLastRun          bool             `json:"aborted_last_run,omitempty"`
	CompactionCount         int              `json:"compaction_count,omitempty"`
	SessionBootstrappedAt   int64            `json:"session_bootstrapped_at,omitempty"`
	SessionBootstrapByAgent map[string]int64 `json:"session_bootstrap_by_agent,omitempty"`

	ModuleMeta           map[string]any `json:"module_meta,omitempty"`             // Generic per-module metadata (e.g., cron room markers, memory flush state)
	SubagentParentRoomID string         `json:"subagent_parent_room_id,omitempty"` // Parent room ID for subagent sessions

	// Runtime-only overrides (not persisted)
	DisabledTools        []string        `json:"-"`
	ResolvedTarget       *ResolvedTarget `json:"-"`
	RuntimeModelOverride string          `json:"-"`
	RuntimeReasoning     string          `json:"-"`

	// Debounce configuration (0 = use default, -1 = disabled)
	DebounceMs int `json:"debounce_ms,omitempty"`

	// Per-session typing overrides (OpenClaw-style).
	TypingMode            string `json:"typing_mode,omitempty"`             // never|instant|thinking|message
	TypingIntervalSeconds *int   `json:"typing_interval_seconds,omitempty"` // Optional per-session override

}

PortalMetadata stores non-derivable per-room runtime state.

type PreDeltaError

type PreDeltaError struct {
	Err error
}

PreDeltaError indicates a failure before any assistant output was streamed.

func (*PreDeltaError) Error

func (e *PreDeltaError) Error() string

func (*PreDeltaError) Unwrap

func (e *PreDeltaError) Unwrap() error

type PreviewWithImage

type PreviewWithImage struct {
	Preview   *event.BeeperLinkPreview
	ImageData []byte
	ImageURL  string // Original image URL for reference
}

PreviewWithImage holds a preview along with its downloaded image data.

type PromptBlock

type PromptBlock struct {
	Type PromptBlockType

	Text string

	ImageURL string
	ImageB64 string
	MimeType string

	FileURL  string
	FileB64  string
	Filename string

	ToolCallID        string
	ToolName          string
	ToolCallArguments string

	AudioB64    string
	AudioFormat string

	VideoURL string
	VideoB64 string
}

PromptBlock is the canonical provider-agnostic content unit.

type PromptBlockType

type PromptBlockType string

PromptBlockType identifies the type of content in a prompt message.

Audio/video are retained as compatibility block types for the existing media-understanding call sites while the wider connector migrates.

const (
	PromptBlockText     PromptBlockType = "text"
	PromptBlockImage    PromptBlockType = "image"
	PromptBlockFile     PromptBlockType = "file"
	PromptBlockThinking PromptBlockType = "thinking"
	PromptBlockToolCall PromptBlockType = "tool_call"
	PromptBlockAudio    PromptBlockType = "audio"
	PromptBlockVideo    PromptBlockType = "video"
)

type PromptContext

type PromptContext struct {
	SystemPrompt    string
	DeveloperPrompt string
	Messages        []PromptMessage
	Tools           []ToolDefinition
}

PromptContext is the canonical provider-facing prompt representation.

func ChatMessagesToPromptContext

func ChatMessagesToPromptContext(messages []openai.ChatCompletionMessageParamUnion) PromptContext

ChatMessagesToPromptContext converts chat-completions-shaped messages into the canonical prompt model.

func ToPromptContext

func ToPromptContext(systemPrompt string, tools []ToolDefinition, messages []UnifiedMessage) PromptContext

ToPromptContext converts legacy UnifiedMessage payloads into the canonical prompt model. System messages are lifted into PromptContext.SystemPrompt.

type PromptMessage

type PromptMessage struct {
	Role       PromptRole
	Blocks     []PromptBlock
	ToolCallID string
	ToolName   string
	IsError    bool
}

PromptMessage is the canonical provider-agnostic prompt message.

func (PromptMessage) Text

func (m PromptMessage) Text() string

Text returns the text content of a canonical prompt message.

type PromptRole

type PromptRole string

PromptRole is the canonical provider-agnostic role used by PromptContext.

const (
	PromptRoleUser       PromptRole = "user"
	PromptRoleAssistant  PromptRole = "assistant"
	PromptRoleToolResult PromptRole = "tool_result"
)

type ProviderConfig

type ProviderConfig struct {
	APIKey           string `yaml:"api_key"`
	BaseURL          string `yaml:"base_url"`
	DefaultModel     string `yaml:"default_model"`
	DefaultPDFEngine string `yaml:"default_pdf_engine"` // pdf-text, mistral-ocr (default), native
}

ProviderConfig holds settings for a specific AI provider.

type ProviderDirectConfig

type ProviderDirectConfig struct {
	Enabled      *bool  `yaml:"enabled"`
	TimeoutSecs  int    `yaml:"timeout_seconds"`
	UserAgent    string `yaml:"user_agent"`
	Readability  bool   `yaml:"readability"`
	MaxChars     int    `yaml:"max_chars"`
	MaxRedirects int    `yaml:"max_redirects"`
	CacheTtlSecs int    `yaml:"cache_ttl_seconds"`
}

type ProviderExaConfig

type ProviderExaConfig struct {
	Enabled           *bool  `yaml:"enabled"`
	BaseURL           string `yaml:"base_url"`
	APIKey            string `yaml:"api_key"`
	Type              string `yaml:"type"`
	Category          string `yaml:"category"`
	NumResults        int    `yaml:"num_results"`
	IncludeText       bool   `yaml:"include_text"`
	TextMaxCharacters int    `yaml:"text_max_chars"`
	Highlights        bool   `yaml:"highlights"`
}

type ProvidersConfig

type ProvidersConfig struct {
	Beeper     ProviderConfig `yaml:"beeper"`
	OpenAI     ProviderConfig `yaml:"openai"`
	OpenRouter ProviderConfig `yaml:"openrouter"`
}

ProvidersConfig contains per-provider configuration.

type ProvisioningAPI

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

ProvisioningAPI handles login-scoped profile, agent, and MCP configuration.

type ProxyError

type ProxyError struct {
	Code      string `json:"code"`
	Message   string `json:"message"`
	Details   string `json:"details"`
	Provider  string `json:"provider"`
	Retryable bool   `json:"retryable"`
	Type      string `json:"type"`
	Status    int    `json:"status"`
}

ProxyError represents a structured error from the hungryserv proxy

func ParseProxyError

func ParseProxyError(err error) *ProxyError

ParseProxyError attempts to parse a structured proxy error from an error message

type ProxyErrorResponse

type ProxyErrorResponse struct {
	Error ProxyError `json:"error"`
}

ProxyErrorResponse is the wrapper for proxy errors

type QueueConfig

type QueueConfig struct {
	Mode                string            `yaml:"mode"`
	ByChannel           map[string]string `yaml:"byChannel"`
	DebounceMs          *int              `yaml:"debounceMs"`
	DebounceMsByChannel map[string]int    `yaml:"debounceMsByChannel"`
	Cap                 *int              `yaml:"cap"`
	Drop                string            `yaml:"drop"`
}

QueueConfig defines queue behavior.

type ReactionFeedback

type ReactionFeedback struct {
	Emoji     string    // The emoji used (e.g., "👍", "👎")
	Timestamp time.Time // When the reaction was added
	Sender    string    // Who sent the reaction (display name or user ID)
	MessageID string    // Which message was reacted to (event ID or timestamp)
	RoomName  string    // Room/channel name for context
	Action    string    // "added" or "removed"
}

ReactionFeedback represents a user reaction to an AI message. Similar to OpenClaw's system events, these are queued and drained when building the next prompt.

func DrainReactionFeedback

func DrainReactionFeedback(roomID id.RoomID) []ReactionFeedback

DrainReactionFeedback returns and clears all reaction feedback for a room. The map entry is removed once drained so that idle rooms do not leak memory.

type ReactionQueue

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

ReactionQueue holds reaction feedback for a room.

func (*ReactionQueue) DrainFeedback

func (q *ReactionQueue) DrainFeedback() []ReactionFeedback

DrainFeedback returns all queued feedback and clears the queue.

type ReplyTarget

type ReplyTarget struct {
	ReplyTo    id.EventID
	ThreadRoot id.EventID
}

func (ReplyTarget) EffectiveReplyTo

func (t ReplyTarget) EffectiveReplyTo() id.EventID

type ResolvedHeartbeatVisibility

type ResolvedHeartbeatVisibility struct {
	ShowOk       bool
	ShowAlerts   bool
	UseIndicator bool
}

type ResolvedTarget

type ResolvedTarget struct {
	Kind    string
	GhostID networkid.UserID
	ModelID string
	AgentID string
}

type ResultStatus

type ResultStatus = matrixevents.ResultStatus

type ScheduleTickContent

type ScheduleTickContent struct {
	Kind           string `json:"kind"`
	EntityID       string `json:"entityId"`
	Revision       int    `json:"revision"`
	ScheduledForMs int64  `json:"scheduledForMs"`
	RunKey         string `json:"runKey"`
	Reason         string `json:"reason,omitempty"`
}

type SearchConfig

type SearchConfig struct {
	Provider  string   `yaml:"provider"`
	Fallbacks []string `yaml:"fallbacks"`

	Exa ProviderExaConfig `yaml:"exa"`
}

type ServiceConfig

type ServiceConfig struct {
	BaseURL string
	APIKey  string
}

type ServiceConfigMap

type ServiceConfigMap map[string]ServiceConfig

type ServiceTokens

type ServiceTokens struct {
	OpenAI              string                        `json:"openai,omitempty"`
	OpenRouter          string                        `json:"openrouter,omitempty"`
	Exa                 string                        `json:"exa,omitempty"`
	Brave               string                        `json:"brave,omitempty"`
	Perplexity          string                        `json:"perplexity,omitempty"`
	DesktopAPI          string                        `json:"desktop_api,omitempty"`
	DesktopAPIInstances map[string]DesktopAPIInstance `json:"desktop_api_instances,omitempty"`
	MCPServers          map[string]MCPServerConfig    `json:"mcp_servers,omitempty"`
}

ServiceTokens stores optional per-login credentials for external services.

type SessionConfig

type SessionConfig struct {
	Scope   string `yaml:"scope"`
	MainKey string `yaml:"mainKey"`
}

SessionConfig configures session behavior.

type SettingSource

type SettingSource string

SettingSource indicates where a setting or availability decision came from.

const (
	SourceAgentPolicy    SettingSource = "agent_policy"
	SourceProviderConfig SettingSource = "provider_config"
	SourceGlobalDefault  SettingSource = "global_default"
	SourceModelLimit     SettingSource = "model_limitation"
	SourceProviderLimit  SettingSource = "provider_limitation"
)

type StreamEvent

type StreamEvent struct {
	Type           StreamEventType
	Delta          string          // Text chunk for delta events
	ReasoningDelta string          // Thinking/reasoning chunk
	ToolCall       *ToolCallResult // For tool_call events
	FinishReason   string          // For complete events
	ResponseID     string          // Response ID (for Responses API)
	Usage          *UsageInfo      // Token usage (usually on complete)
	Error          error           // For error events
}

StreamEvent represents a single event from a streaming response

type StreamEventType

type StreamEventType string

StreamEventType identifies the type of streaming event

const (
	StreamEventDelta     StreamEventType = "delta"     // Text content delta
	StreamEventReasoning StreamEventType = "reasoning" // Reasoning/thinking delta
	StreamEventToolCall  StreamEventType = "tool_call" // Tool call request
	StreamEventComplete  StreamEventType = "complete"  // Generation complete
	StreamEventError     StreamEventType = "error"     // Error occurred
)

type SystemEvent

type SystemEvent struct {
	Text string
	TS   int64
}

type ToolApprovalKind

type ToolApprovalKind string
const (
	ToolApprovalKindMCP     ToolApprovalKind = "mcp"
	ToolApprovalKindBuiltin ToolApprovalKind = "builtin"
)

type ToolApprovalParams

type ToolApprovalParams struct {
	ApprovalID string
	RoomID     id.RoomID
	TurnID     string

	ToolCallID string
	ToolName   string

	ToolKind     ToolApprovalKind
	RuleToolName string
	ServerLabel  string
	Action       string

	TTL time.Duration
}

ToolApprovalParams holds the parameters for registering a tool approval request.

type ToolApprovalsConfig

type ToolApprovalsConfig struct {
	// MCPAlwaysAllow contains exact-match allow rules for MCP approvals.
	// Matching is done on normalized (trim + lowercase) server label + tool name.
	MCPAlwaysAllow []MCPAlwaysAllowRule `json:"mcp_always_allow,omitempty"`

	// BuiltinAlwaysAllow contains exact-match allow rules for builtin tool approvals.
	// Matching is done on normalized (trim + lowercase) tool name + action.
	// Action "" means "any action".
	BuiltinAlwaysAllow []BuiltinAlwaysAllowRule `json:"builtin_always_allow,omitempty"`
}

ToolApprovalsConfig stores per-login persisted tool approval rules. This is used by the tool approval system to support "always allow" decisions.

type ToolApprovalsRuntimeConfig

type ToolApprovalsRuntimeConfig struct {
	Enabled         *bool    `yaml:"enabled"`
	TTLSeconds      int      `yaml:"ttlSeconds"`
	RequireForMCP   *bool    `yaml:"requireForMcp"`
	RequireForTools []string `yaml:"requireForTools"`
}

ToolApprovalsRuntimeConfig controls runtime behaviour for tool approvals. This gates OpenAI MCP approvals (mcp_approval_request) and selected dangerous builtin tools.

func (*ToolApprovalsRuntimeConfig) WithDefaults

type ToolCallMetadata

type ToolCallMetadata = bridgeadapter.ToolCallMetadata

type ToolCallResult

type ToolCallResult struct {
	ID        string
	Name      string
	Arguments string // JSON string of arguments
}

ToolCallResult represents a tool/function call from the model

type ToolDefinition

type ToolDefinition = integrationruntime.ToolDefinition

ToolDefinition defines a tool that can be used by the AI.

func BuiltinTools

func BuiltinTools() []ToolDefinition

BuiltinTools returns all builtin tool definitions (computed once and cached).

func GetBuiltinTool

func GetBuiltinTool(name string) *ToolDefinition

type ToolInfo

type ToolInfo struct {
	Name        string        `json:"name"`
	DisplayName string        `json:"display_name"`
	Type        string        `json:"type"`
	Description string        `json:"description,omitempty"`
	Enabled     bool          `json:"enabled"`
	Available   bool          `json:"available"`
	Source      SettingSource `json:"source,omitempty"`
	Reason      string        `json:"reason,omitempty"`
}

ToolInfo describes a tool and its status for internal UI/config rendering.

type ToolProvidersConfig

type ToolProvidersConfig struct {
	Search *SearchConfig     `yaml:"search"`
	Fetch  *FetchConfig      `yaml:"fetch"`
	Media  *MediaToolsConfig `yaml:"media"`
	MCP    *MCPToolsConfig   `yaml:"mcp"`
	VFS    *VFSToolsConfig   `yaml:"vfs"`
}

ToolProvidersConfig configures external tool providers like search and fetch.

type ToolStatus

type ToolStatus = matrixevents.ToolStatus

type ToolStrictMode

type ToolStrictMode int
const (
	ToolStrictOff ToolStrictMode = iota
	ToolStrictAuto
	ToolStrictOn
)

type ToolType

type ToolType = matrixevents.ToolType

type TypingContext

type TypingContext struct {
	IsGroup      bool
	WasMentioned bool
}

type TypingController

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

TypingController manages typing indicators with TTL and refresh. Similar to OpenClaw's TypingController pattern.

func NewTypingController

func NewTypingController(client *AIClient, ctx context.Context, portal *bridgev2.Portal, opts TypingControllerOptions) *TypingController

func (*TypingController) IsActive

func (tc *TypingController) IsActive() bool

func (*TypingController) MarkDispatchIdle

func (tc *TypingController) MarkDispatchIdle()

MarkDispatchIdle marks the dispatcher as idle.

func (*TypingController) MarkRunComplete

func (tc *TypingController) MarkRunComplete()

MarkRunComplete marks the AI run as complete. Typing will stop when both run is complete and dispatch is idle.

func (*TypingController) RefreshTTL

func (tc *TypingController) RefreshTTL()

RefreshTTL resets the TTL timer, keeping typing active longer. Call this when activity occurs (tool calls, text chunks).

func (*TypingController) Start

func (tc *TypingController) Start()

Start begins the typing indicator with automatic refresh.

func (*TypingController) Stop

func (tc *TypingController) Stop()

Stop stops the typing indicator and cleans up.

type TypingControllerOptions

type TypingControllerOptions struct {
	Interval time.Duration
	TTL      time.Duration
}

type TypingMode

type TypingMode string
const (
	TypingModeNever    TypingMode = "never"
	TypingModeInstant  TypingMode = "instant"
	TypingModeThinking TypingMode = "thinking"
	TypingModeMessage  TypingMode = "message"
)

type TypingSignaler

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

func NewTypingSignaler

func NewTypingSignaler(typing *TypingController, mode TypingMode, isHeartbeat bool) *TypingSignaler

func (*TypingSignaler) SignalReasoningDelta

func (ts *TypingSignaler) SignalReasoningDelta()

func (*TypingSignaler) SignalRunStart

func (ts *TypingSignaler) SignalRunStart()

func (*TypingSignaler) SignalTextDelta

func (ts *TypingSignaler) SignalTextDelta(text string)

func (*TypingSignaler) SignalToolStart

func (ts *TypingSignaler) SignalToolStart()

type UnifiedMessage

type UnifiedMessage struct {
	Role       MessageRole
	Content    []ContentPart
	ToolCalls  []ToolCallResult
	ToolCallID string
	Name       string
}

UnifiedMessage is the legacy provider-agnostic message format used by a few call sites.

func (*UnifiedMessage) Text

func (m *UnifiedMessage) Text() string

Text returns the text content of a legacy message.

type UsageInfo

type UsageInfo struct {
	PromptTokens     int
	CompletionTokens int
	TotalTokens      int
	ReasoningTokens  int // For models with extended thinking
}

UsageInfo contains token usage information

type UserLoginMetadata

type UserLoginMetadata struct {
	Provider             string         `json:"provider,omitempty"` // Selected provider (beeper, openai, openrouter)
	APIKey               string         `json:"api_key,omitempty"`
	BaseURL              string         `json:"base_url,omitempty"`               // Per-user API endpoint
	TitleGenerationModel string         `json:"title_generation_model,omitempty"` // Model to use for generating chat titles
	NextChatIndex        int            `json:"next_chat_index,omitempty"`
	DefaultChatPortalID  string         `json:"default_chat_portal_id,omitempty"`
	ModelCache           *ModelCache    `json:"model_cache,omitempty"`
	ChatsSynced          bool           `json:"chats_synced,omitempty"` // True after initial bootstrap completed successfully
	Gravatar             *GravatarState `json:"gravatar,omitempty"`
	Timezone             string         `json:"timezone,omitempty"`
	Profile              *UserProfile   `json:"profile,omitempty"`

	// FileAnnotationCache stores parsed PDF content from OpenRouter's file-parser plugin
	// Key is the file hash (SHA256), pruned after 7 days
	FileAnnotationCache map[string]FileAnnotation `json:"file_annotation_cache,omitempty"`

	// Optional per-login tokens for external services
	ServiceTokens *ServiceTokens `json:"service_tokens,omitempty"`

	// Tool approval rules (e.g. "always allow" decisions for MCP approvals or dangerous builtin tools).
	ToolApprovals *ToolApprovalsConfig `json:"tool_approvals,omitempty"`

	// Custom agents store (source of truth for user-created agents).
	CustomAgents map[string]*AgentDefinitionContent `json:"custom_agents,omitempty"`
	// Last active room per agent (used for heartbeat delivery).
	LastActiveRoomByAgent map[string]string `json:"last_active_room_by_agent,omitempty"`
	// Heartbeat dedupe state per agent.
	HeartbeatState map[string]HeartbeatState `json:"heartbeat_state,omitempty"`
	// LastHeartbeatEvent is the last emitted heartbeat event for this login (command-only debug surface).
	LastHeartbeatEvent *HeartbeatEventPayload `json:"last_heartbeat_event,omitempty"`

	// Provider health tracking
	ConsecutiveErrors int   `json:"consecutive_errors,omitempty"`
	LastErrorAt       int64 `json:"last_error_at,omitempty"` // Unix timestamp
}

UserLoginMetadata is stored on each login row to keep per-user settings.

type UserProfile

type UserProfile struct {
	Name               string `json:"name,omitempty"`
	Occupation         string `json:"occupation,omitempty"`
	AboutUser          string `json:"about_user,omitempty"`
	CustomInstructions string `json:"custom_instructions,omitempty"`
}

type VFSToolsConfig

type VFSToolsConfig struct {
	ApplyPatch *ApplyPatchToolsConfig `yaml:"apply_patch"`
}

VFSToolsConfig configures virtual filesystem tools.

Source Files

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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