Documentation
¶
Overview ¶
Package llm provides a unified abstraction layer for Large Language Model interactions within the Mattermost AI plugin.
This package defines the core interfaces and data structures for working with various LLM providers (OpenAI, Anthropic, etc.) in a consistent manner. It handles:
- LanguageModel interface abstraction for different LLM providers
- Conversation management with structured posts, roles, and context
- Prompt template system with embedded templates and variable substitution
- Streaming text responses for real-time chat interactions
- Tool/function calling capabilities with JSON schema validation
- Request/response structures with token counting and truncation
- Context management including user info, channels, and bot configurations
The package is designed to be provider-agnostic, allowing the plugin to work with multiple LLM services through a common interface while preserving provider-specific capabilities like vision, JSON output, and tool calling.
Index ¶
- Constants
- Variables
- func BareMCPToolName(toolName string) string
- func BatchSkippedToolResult(toolName string, unavailableNames []string) string
- func CloneHTTPClientWithTransport(client *http.Client, transport http.RoundTripper) *http.Client
- func CountTrailingFailedToolCalls(posts []Post) int
- func CreateTokenLogger() (*mlog.Logger, error)
- func EnrichToolCall(tc *ToolCall, store *ToolStore, opts EnrichToolCallOptions)
- func EscapePromptContent(s string) string
- func EstimateRequestTokens(inputs []CompositionInput) int
- func EstimateTokens(text string) int
- func GenerateBenchText(size int) string
- func IsBareMCPToolName(name string) bool
- func IsBatchSkippedToolResult(result string) bool
- func IsSupportedImageMimeType(mimeType string) bool
- func IsToolRetryExempt(name string) bool
- func IsValidService(service ServiceConfig) bool
- func MCPToolNameMatches(runtimeName, configuredName string) bool
- func NamespaceMCPToolName(serverSlug, bareToolName string) string
- func NewJSONSchemaFromStruct[T any]() *jsonschema.Schema
- func NormalizeMCPServerOrigin(origin string) string
- func NormalizeMCPServerOrigins(origins []string) []string
- func SanitizeNonPrintableChars(s string) string
- func SanitizeProviderError(err error, configuredAPIKeys ...string) error
- func SanitizeProviderErrorMessage(message string, configuredAPIKeys ...string) string
- func ServiceUsesResponsesAPI(cfg ServiceConfig) bool
- func StripMarkdownCodeFencing(s string) string
- func UTF16CodeUnitCount(s string) int
- type Annotation
- type AnnotationType
- type BenchmarkScenario
- type BotConfig
- type ChannelAccessLevel
- type CompletionRequest
- type Composition
- type CompositionComponent
- type CompositionInput
- type CompositionSource
- type Context
- func (c *Context) CustomPromptVars() map[string]string
- func (c *Context) MarkMCPDynamicToolLoaded(name string)
- func (c *Context) MarkMCPDynamicToolSearch()
- func (c *Context) ObserveMCPDynamicToolEvent(event, result string)
- func (c *Context) SetBotFields(...)
- func (c *Context) ShouldRecordMCPDynamicSearchLoadCallSuccess(name string) bool
- func (c Context) String() string
- type ContextOption
- type CustomAuthTransport
- type EnabledMCPTool
- type EnrichToolCallOptions
- type EventType
- type File
- type LanguageModel
- type LanguageModelConfig
- type LanguageModelOption
- func WithJSONOutput[T any]() LanguageModelOption
- func WithMaxGeneratedTokens(maxGeneratedTokens int) LanguageModelOption
- func WithModel(model string) LanguageModelOption
- func WithNativeWebSearchAllowed() LanguageModelOption
- func WithReasoningDisabled() LanguageModelOption
- func WithToolsDisabled() LanguageModelOption
- type LanguageModelTestLogWrapper
- func (w *LanguageModelTestLogWrapper) ChatCompletion(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (*TextStreamResult, error)
- func (w *LanguageModelTestLogWrapper) ChatCompletionNoStream(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (string, error)
- func (w *LanguageModelTestLogWrapper) CountTokens(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (int, error)
- func (w *LanguageModelTestLogWrapper) InputTokenLimit() int
- func (w *LanguageModelTestLogWrapper) OutputTokenLimit() int
- type LanguageModelWrapper
- type MCPDynamicToolTelemetry
- type MetricsObserver
- type ModelInfo
- type OpenAICompatibleProvider
- type Post
- type PostRole
- type Prompts
- type ReasoningData
- type SanitizedProviderError
- type ServiceConfig
- type StreamGenerator
- type StructuredOutputFallbackWrapper
- func (w *StructuredOutputFallbackWrapper) ChatCompletion(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (*TextStreamResult, error)
- func (w *StructuredOutputFallbackWrapper) ChatCompletionNoStream(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (string, error)
- func (w *StructuredOutputFallbackWrapper) CountTokens(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (int, error)
- func (w *StructuredOutputFallbackWrapper) InputTokenLimit() int
- func (w *StructuredOutputFallbackWrapper) OutputTokenLimit() int
- type TextStreamEvent
- type TextStreamResult
- type TokenUsage
- type TokenUsageLoggingWrapper
- func (w *TokenUsageLoggingWrapper) ChatCompletion(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (*TextStreamResult, error)
- func (w *TokenUsageLoggingWrapper) ChatCompletionNoStream(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (string, error)
- func (w *TokenUsageLoggingWrapper) CountTokens(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (int, error)
- func (w *TokenUsageLoggingWrapper) InputTokenLimit() int
- func (w *TokenUsageLoggingWrapper) OutputTokenLimit() int
- type TokenUsagePluginLogger
- type TokenUsageSinks
- func (s *TokenUsageSinks) FileLogger() *mlog.Logger
- func (s *TokenUsageSinks) LoggingEnabled() bool
- func (s *TokenUsageSinks) PluginLogger() TokenUsagePluginLogger
- func (s *TokenUsageSinks) SetFileEnabled(enabled bool)
- func (s *TokenUsageSinks) SetFileLogger(logger *mlog.Logger)
- func (s *TokenUsageSinks) SetLoggingEnabled(enabled bool)
- func (s *TokenUsageSinks) SetPluginEnabled(enabled bool)
- type Tool
- type ToolArgumentGetter
- type ToolAuthError
- type ToolCall
- type ToolCallStatus
- type ToolCatalogContext
- type ToolInfo
- type ToolLookup
- type ToolResolver
- type ToolRuntimeContext
- func (t *ToolRuntimeContext) MarkMCPDynamicToolLoaded(name string)
- func (t *ToolRuntimeContext) MarkMCPDynamicToolSearch()
- func (t *ToolRuntimeContext) ObserveMCPDynamicToolEvent(botName, event, result string)
- func (t *ToolRuntimeContext) ShouldRecordMCPDynamicSearchLoadCallSuccess(name string) bool
- type ToolStore
- func (s *ToolStore) AddAuthError(authError ToolAuthError)
- func (s *ToolStore) AddTools(tools []Tool)
- func (s *ToolStore) GetAuthErrors() []ToolAuthError
- func (s *ToolStore) GetServerOrigin(toolName string) string
- func (s *ToolStore) GetTool(name string) *Tool
- func (s *ToolStore) GetTools() []Tool
- func (s *ToolStore) GetToolsInfo() []ToolInfo
- func (s *ToolStore) GetUnloadedMCPToolInfo(name string) (ToolInfo, bool)
- func (s *ToolStore) HasUnloadedMCPTools() bool
- func (s *ToolStore) IsUnloadedMCPTool(name string) bool
- func (s *ToolStore) KeepToolsIf(keep func(Tool) bool)
- func (s *ToolStore) LoadMCPTools(names []string) []Tool
- func (s *ToolStore) LookupTool(name, serverOrigin string) (ToolLookup, bool)
- func (s *ToolStore) RemoveToolsByServerOrigin(disabledOrigins []string)
- func (s *ToolStore) ResolveTool(ctx context.Context, name string, argsGetter ToolArgumentGetter, ...) (string, error)
- func (s *ToolStore) RetainOnlyMCPTools(allowlist []EnabledMCPTool)
- func (s *ToolStore) SetUnloadedMCPTools(tools []Tool)
- type TruncationWrapper
- func (w *TruncationWrapper) ChatCompletion(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (*TextStreamResult, error)
- func (w *TruncationWrapper) ChatCompletionNoStream(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (string, error)
- func (w *TruncationWrapper) CountTokens(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (int, error)
- func (w *TruncationWrapper) InputTokenLimit() int
- func (w *TruncationWrapper) OutputTokenLimit() int
- type UserAccessLevel
Constants ¶
const ( // CompositionTotalCounted means the total came from a provider // CountTokens call (most accurate, pre-call). CompositionTotalCounted = "counted" // CompositionTotalProvider means the total came from the provider's // post-call usage report (most accurate, post-call). CompositionTotalProvider = "provider" // CompositionTotalEstimated means we fell back to EstimateTokens because // neither a counter nor a provider report was available. CompositionTotalEstimated = "estimated" )
CompositionTotalSource enumerates the provenance of Composition.Total.
const ( ServiceTypeOpenAI = "openai" ServiceTypeOpenAICompatible = "openaicompatible" ServiceTypeAzure = "azure" ServiceTypeAnthropic = "anthropic" ServiceTypeCohere = "cohere" ServiceTypeBedrock = "bedrock" ServiceTypeMistral = "mistral" ServiceTypeScale = "scale" ServiceTypeGemini = "gemini" ServiceTypeVertex = "vertex" ServiceTypeLoadTestMock = "loadtest_mock" )
const ( // TokenUsageLogEvent is the canonical event name for structured token usage logs. // #nosec G101 -- this is a non-secret log event identifier. TokenUsageLogEvent = "llm_token_usage" // TokenUsageLogSchemaVersion is the version of the token usage log field // contract. Bump only on breaking changes; new optional fields don't count. TokenUsageLogSchemaVersion = 1 // TokenUsageUnknown is the normalized value for missing dimensions. TokenUsageUnknown = "unknown" )
const ( OperationConversation = "conversation" OperationConversationToolFollowup = "conversation_tool_followup" OperationTitleGeneration = "title_generation" OperationChannelSummary = "channel_summary" OperationChannelInterval = "channel_interval" OperationThreadAnalysis = "thread_analysis" OperationSearch = "search" OperationMeetingSummary = "meeting_summary" OperationMeetingChunkSummary = "meeting_chunk_summary" OperationEmojiSelection = "emoji_selection" OperationWebSearchSummarization = "web_search_summarization" OperationEvalGrading = "eval_grading" OperationBridgeAgent = "bridge_agent" OperationBridgeService = "bridge_service" )
operation identifies the high-level feature or action producing token usage.
const ( SubTypeStreaming = "streaming" SubTypeNoStream = "nostream" SubTypeToolCall = "tool_call" SubTypeTranscriptionChunk = "transcription_chunk" SubTypeChunkedTrue = "chunked_true" SubTypeChunkedFalse = "chunked_false" )
operation_subtype is a low-cardinality detail for the operation. Typical values represent modality or a small scenario class (for example streaming vs non-streaming, tool calls, or chunk modes).
const DefaultMaxToolTurns = 30
DefaultMaxToolTurns is the default tool-call-execute-recall ceiling per LLM turn. Agents that store 0 (legacy config bots, freshly-migrated rows before the column was added) fall back to this value via BotConfig.EffectiveMaxToolTurns.
const FunctionsTokenBudget = 200
const MCPServerToolWildcard = "*"
MCPServerToolWildcard in EnabledMCPTool.ToolName means every tool from that ServerOrigin is allowed.
const MCPToolNameSeparator = "__"
const MaxAllowedMaxToolTurns = 250
MaxAllowedMaxToolTurns caps user-provided MaxToolTurns to keep runaway loops bounded even if a misconfigured agent requests an unreasonably high value.
const MaxConsecutiveToolCallFailures = 3
const MaxCustomInstructionsRunes = 16384
MaxCustomInstructionsRunes caps BotConfig.CustomInstructions at a length that keeps the system prompt bounded on every conversation turn.
const MinTokens = 100
const PlaceholderAPIKey = "custom-auth"
PlaceholderAPIKey is a sentinel value for SDKs that require a non-empty API key when real authentication is handled by the transport (e.g., custom auth headers).
const PromptExtension = "tmpl"
const SafetyCheckThreshold = 0.8
SafetyCheckThreshold gates the provider-side count call. We only ask for an exact count when the heuristic estimate is at or above this fraction of the truncation budget.
const TokenLimitBufferSize = 0.9
const ToolIterationLimitUserMessage = "" /* 233-byte string literal not displayed */
const ToolRetryLimitSystemMessage = "" /* 142-byte string literal not displayed */
const UserInteractionSelect = "select"
UserInteractionSelect identifies tools answered by the user picking from a set of options presented in the Mattermost UI.
Variables ¶
var ErrUnsupportedTokenCount = errors.New("token counting not supported by this provider")
ErrUnsupportedTokenCount signals that the underlying provider does not support exact input-token counting. Callers should fall back to EstimateTokens when they see this error.
Functions ¶
func BareMCPToolName ¶
func BatchSkippedToolResult ¶
BatchSkippedToolResult marks a tool result as skipped because another tool in the same batch was unavailable. The message is still surfaced to the LLM and UI as an error, but it must not count toward MaxConsecutiveToolCallFailures.
func CloneHTTPClientWithTransport ¶
CloneHTTPClientWithTransport creates a shallow copy of the given http.Client with the specified transport, preserving Timeout, CheckRedirect, and Jar. If client is nil, a new http.Client with only the transport is returned.
func CountTrailingFailedToolCalls ¶
CountTrailingFailedToolCalls counts consecutive trailing tool executions that failed. A successful tool execution resets the streak. Posts without executed tool results stop the scan because they represent a new agent turn.
func CreateTokenLogger ¶
CreateTokenLogger creates a dedicated logger for token usage metrics
func EnrichToolCall ¶
func EnrichToolCall(tc *ToolCall, store *ToolStore, opts EnrichToolCallOptions)
EnrichToolCall fills a tool call's Description, Schema, ServerOrigin, and MCPBareName from the resolved store entry. MCPBareName is only set for MCP tools (those with a server origin); builtins are left untouched.
func EscapePromptContent ¶
EscapePromptContent replaces angle brackets in user-generated content to prevent injection of fake XML structural elements into prompt templates.
func EstimateRequestTokens ¶
func EstimateRequestTokens(inputs []CompositionInput) int
EstimateRequestTokens is the fallback total used when no provider counter is available. It mirrors the same weighting as ComputeComposition, so an image-heavy request still contributes via imageWeightPlaceholder rather than silently rounding to zero (image CompositionInputs carry no Text).
func EstimateTokens ¶
EstimateTokens is a fast, synchronous, provider-agnostic approximation. For an exact count, call LanguageModel.CountTokens instead.
func GenerateBenchText ¶
GenerateBenchText creates a string of the specified size using a repeating pattern. Uses a realistic text pattern rather than random bytes.
func IsBareMCPToolName ¶
IsBareMCPToolName reports whether name is non-empty and has no MCP server namespace prefix (e.g. "get_issue" rather than "jira__get_issue").
func IsToolRetryExempt ¶
IsToolRetryExempt identifies MCP dynamic-loading meta-tools. Keep these names in sync with mcp.SearchToolsName and mcp.LoadToolName without importing mcp here, which would create a package cycle.
func IsValidService ¶
func IsValidService(service ServiceConfig) bool
IsValidService validates a service configuration
func MCPToolNameMatches ¶
func NamespaceMCPToolName ¶
func NewJSONSchemaFromStruct ¶
func NewJSONSchemaFromStruct[T any]() *jsonschema.Schema
NewJSONSchemaFromStruct creates a JSONSchema from a Go struct using generics It's a helper function for tool providers that currently define schemas as structs
func NormalizeMCPServerOrigin ¶
NormalizeMCPServerOrigin trims formatting variants used around MCP server origins.
func NormalizeMCPServerOrigins ¶
NormalizeMCPServerOrigins returns unique, non-empty normalized MCP origins.
func SanitizeNonPrintableChars ¶
SanitizeNonPrintableChars replaces non-printable Unicode characters with their escaped representation [U+XXXX] to prevent text spoofing attacks such as bidirectional text attacks that can make URLs appear to point to different domains. Uses [U+XXXX] format instead of \uXXXX to avoid JSON parsers converting it back. Allows newline, tab, and carriage return for JSON formatting. Also escapes variation selectors and other default ignorable code points which are technically "printable" but render invisibly and can be used for spoofing.
func SanitizeProviderError ¶
SanitizeProviderError redacts API keys, bearer tokens, and similar material from provider errors before those strings are logged, streamed to clients, or returned to callers.
func SanitizeProviderErrorMessage ¶
SanitizeProviderErrorMessage applies the same redaction rules as SanitizeProviderError to a plain string. Each configured API key is additionally redacted when it appears as a substring (word-boundary safe). Pass the primary key plus any fallback keys so a fallback provider's credential in a custom key format (e.g. Gemini, Mistral, or a local OpenAI-compatible key) is redacted even when the generic patterns miss it.
func ServiceUsesResponsesAPI ¶
func ServiceUsesResponsesAPI(cfg ServiceConfig) bool
ServiceUsesResponsesAPI reports whether the Responses API path is used for this service. Direct OpenAI always uses it; OpenAI-compatible and Azure honor the operator toggle. All other service types ignore UseResponsesAPI — a stale flag carried over from a previous service type must not be allowed to route the request through Responses.
func StripMarkdownCodeFencing ¶
StripMarkdownCodeFencing removes markdown code block fencing (e.g. ```json ... ```) that LLMs sometimes wrap around JSON responses despite being instructed not to.
func UTF16CodeUnitCount ¶
UTF16CodeUnitCount returns the length of a string in JavaScript-compatible UTF-16 code units. The frontend applies annotation indices with JS string slicing, so locally computed offsets must use this unit.
Types ¶
type Annotation ¶
type Annotation struct {
Type AnnotationType `json:"type"` // Type of annotation
StartIndex int `json:"start_index"` // Start position in message text (0-based, JS UTF-16 code units)
EndIndex int `json:"end_index"` // End position in message text (0-based, JS UTF-16 code units)
URL string `json:"url,omitempty"` // Source URL (for url_citation)
Title string `json:"title,omitempty"` // Source title (for url_citation)
CitedText string `json:"cited_text,omitempty"` // Optional: text being cited (for context)
Index int `json:"index"` // Display index (1-based for UI)
}
Annotation represents an inline annotation/citation in the response text. Indices are stored in JavaScript UTF-16 code units so they can be applied directly by the webapp's string slicing.
type AnnotationType ¶
type AnnotationType string
AnnotationType represents different types of annotations
const ( // AnnotationTypeURLCitation represents a web search citation AnnotationTypeURLCitation AnnotationType = "url_citation" )
type BenchmarkScenario ¶
type BenchmarkScenario struct {
Name string
Generator StreamGenerator
}
BenchmarkScenario defines a benchmark test scenario
func BenchmarkScenarios ¶
func BenchmarkScenarios() []BenchmarkScenario
BenchmarkScenarios returns common scenarios for stream benchmarks. This combines size-based scenarios with event-type scenarios.
type BotConfig ¶
type BotConfig struct {
ID string `json:"id"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
CustomInstructions string `json:"customInstructions"`
ServiceID string `json:"serviceID"`
// Model is the optional model override for this bot.
// If not specified, the service's DefaultModel will be used.
Model string `json:"model"`
// Service is deprecated and kept only for backwards compatibility during migration.
Service *ServiceConfig `json:"service,omitempty"`
EnableVision bool `json:"enableVision"`
DisableTools bool `json:"disableTools"`
ChannelAccessLevel ChannelAccessLevel `json:"channelAccessLevel"`
ChannelIDs []string `json:"channelIDs"`
UserAccessLevel UserAccessLevel `json:"userAccessLevel"`
UserIDs []string `json:"userIDs"`
TeamIDs []string `json:"teamIDs"`
MaxFileSize int64 `json:"maxFileSize"`
// EnabledNativeTools contains the list of enabled native tools for this bot.
// Supported values by provider:
// - OpenAI / Azure: ["web_search", "file_search", "code_interpreter"]
// (only works when UseResponsesAPI is true for OpenAI-compatible and Azure)
// - Anthropic: ["web_search"]
// - Gemini / Vertex AI: ["web_search"] (mapped to Google Search / grounding
// via Bifrost's Responses API)
// For other providers these values are filtered out at request time.
EnabledNativeTools []string `json:"enabledNativeTools"`
// EnabledMCPTools is the per-agent allowlist of MCP tools:
// only tools matching these (ServerOrigin, ToolName) pairs are kept.
// Ignored when AutoEnableNewMCPTools is true.
EnabledMCPTools []EnabledMCPTool `json:"enabledMCPTools"`
// AutoEnableNewMCPTools, when true, gives this agent access to every currently
// configured MCP tool and any MCP tool added later. EnabledMCPTools is ignored
// in that mode. When false, only tools listed in EnabledMCPTools are available.
AutoEnableNewMCPTools bool `json:"autoEnableNewMCPTools"`
// MCPDynamicToolLoading controls whether this bot uses the JIT MCP tool loading flow.
// It defaults to true for omitted legacy config.
MCPDynamicToolLoading bool `json:"mcpDynamicToolLoading"`
// ReasoningEnabled determines whether reasoning/thinking is enabled for this bot.
// Applicable to OpenAI (with ResponsesAPI), Anthropic, and Gemini / Vertex AI.
ReasoningEnabled bool `json:"reasoningEnabled"`
// ReasoningEffort determines the reasoning effort level.
// Valid values: "minimal", "low", "medium", "high".
// Applicable to OpenAI (with ResponsesAPI) and Gemini / Vertex AI (maps to
// Gemini's thinkingLevel on 3.0+, and to a thinkingBudget estimate on 2.5).
// Default: "medium".
ReasoningEffort string `json:"reasoningEffort"`
// ThinkingBudget determines the token budget for reasoning/thinking.
// - Anthropic: must be at least 1024 and cannot exceed the OutputTokenLimit.
// Default: 1/4 of OutputTokenLimit, capped at 8192.
// - Gemini / Vertex AI: maps to thinkingConfig.thinkingBudget. When set, it
// takes priority over ReasoningEffort.
ThinkingBudget int `json:"thinkingBudget"`
// StructuredOutputEnabled controls how a requested JSONOutputFormat schema is handled.
// When enabled, the schema is sent natively to the provider to constrain the model's
// output. When disabled, the schema is converted into prompt instructions and stripped
// from the provider request, for models/APIs without native structured output support.
StructuredOutputEnabled bool `json:"structuredOutputEnabled"`
// MaxToolTurns is the maximum number of LLM-call → tool-execute iterations
// the tool runner will perform for this agent before stopping. A non-positive
// value falls back to DefaultMaxToolTurns. Lower this when using a smaller
// model that tends to call tools in loops; raise it for agents that rely on
// long dynamic-tool-discovery chains (e.g. search → load → execute).
MaxToolTurns int `json:"maxToolTurns"`
// Admin / lifecycle metadata.
BotUserID string `json:"botUserID,omitempty"`
CreatorID string `json:"creatorID,omitempty"`
AdminUserIDs []string `json:"adminUserIDs,omitempty"`
CreateAt int64 `json:"createAt,omitempty"`
UpdateAt int64 `json:"updateAt,omitempty"`
DeleteAt int64 `json:"deleteAt,omitempty"`
}
func (BotConfig) EffectiveMaxToolTurns ¶
EffectiveMaxToolTurns returns the configured MaxToolTurns or DefaultMaxToolTurns when the value is non-positive (e.g. legacy config bots that never set the field).
func (*BotConfig) IsAdmin ¶
IsAdmin reports whether userID is the agent's creator or in the admin list. Returns false for the empty userID to avoid matching legacy bots (CreatorID == "").
func (*BotConfig) IsCreator ¶
IsCreator reports whether userID is the agent's creator. Returns false for migrated/config bots whose CreatorID is empty.
func (*BotConfig) IsValid ¶
IsValid reports whether the bot config is valid. Prefer Validate when a descriptive error is useful.
func (*BotConfig) UnmarshalJSON ¶
type ChannelAccessLevel ¶
type ChannelAccessLevel int
const ( ChannelAccessLevelAll ChannelAccessLevel = iota ChannelAccessLevelAllow ChannelAccessLevelBlock ChannelAccessLevelNone )
type CompletionRequest ¶
type CompletionRequest struct {
Posts []Post
Context *Context
Operation string
OperationSubType string
}
func (CompletionRequest) Composition ¶
func (r CompletionRequest) Composition() []CompositionInput
Composition derives the per-source attribution for this request from its posts and tool context. It is a pure function of the request, so it stays consistent through truncation and needs no stored state.
func (CompletionRequest) ExtractSystemMessage ¶
func (b CompletionRequest) ExtractSystemMessage() string
ExtractSystemMessage extracts the system message from the conversation.
func (CompletionRequest) String ¶
func (b CompletionRequest) String() string
type Composition ¶
type Composition struct {
Components []CompositionComponent `json:"components"`
Total int `json:"total"`
TotalSource string `json:"total_source"`
InputTokenLimit int `json:"input_token_limit,omitempty"`
Model string `json:"model,omitempty"`
}
Composition is the per-request, per-source token breakdown that powers the /context endpoint and the LLM-call span attributes.
func ComputeComposition ¶
func ComputeComposition(inputs []CompositionInput, total int, totalSource string) Composition
ComputeComposition returns the per-source breakdown for a set of inputs, scaled to the given total. Only the ratios from the cheap estimator are exposed — the published total always matches `total`. One row per source, emitted in compositionOrder.
func (Composition) SpanAttributes ¶
func (c Composition) SpanAttributes() []attribute.KeyValue
SpanAttributes returns OTel attribute key/value pairs for the per-source token totals, one per category. Zero-token buckets are omitted to keep trace cardinality bounded.
type CompositionComponent ¶
type CompositionComponent struct {
Source CompositionSource `json:"source"`
Proportion float64 `json:"proportion"`
Tokens int `json:"tokens"`
}
CompositionComponent is a single per-source row in a composition breakdown. Proportion is normalized so Components sum to 1.0 (modulo rounding); Tokens is round(Proportion * Total).
type CompositionInput ¶
type CompositionInput struct {
Source CompositionSource
Text string
}
CompositionInput is a single piece of content captured for attribution.
type CompositionSource ¶
type CompositionSource string
CompositionSource labels where a piece of an LLM request came from. Used to attribute token cost back to its origin (system prompt, history, tool definitions, tool results, images) without changing how a request is assembled or billed. Attachment text is part of the message, so it counts as history.
const ( SourceSystem CompositionSource = "system" SourceHistory CompositionSource = "history" SourceToolDefs CompositionSource = "tool_defs" SourceToolResults CompositionSource = "tool_results" SourceImage CompositionSource = "image" )
type Context ¶
type Context struct {
// Server
Time string
ServerName string
CompanyName string
SiteURL string
// Location
Team *model.Team
Channel *model.Channel
Thread []Post // Normalized posts that already have been formatted. nil if not in a thread or a root post
// User that is making the request
RequestingUser *model.User
// Bot Specific
BotName string
BotUsername string
BotUserID string
BotModel string
BotServiceType string
CustomInstructions string
Tools *ToolStore
DisabledToolsInfo []ToolInfo // Info about tools that are unavailable in the current context (e.g., DM-only tools in a channel)
Parameters map[string]interface{}
// ToolCatalog holds request-scoped inputs used while building the tool store.
ToolCatalog ToolCatalogContext
// ToolRuntime holds non-prompt tool execution state for this turn.
ToolRuntime ToolRuntimeContext
}
Context represents the per-turn data necessary to build the context of the LLM. For consumers none of the fields can be assumed to be present.
func NewContext ¶
func NewContext(opts ...ContextOption) *Context
NewContext creates a new Context with the given options
func (*Context) CustomPromptVars ¶
CustomPromptVars returns a flat map of whitelisted variables for use in user-created custom prompt templates. Only safe, useful fields are exposed.
func (*Context) MarkMCPDynamicToolLoaded ¶
func (*Context) MarkMCPDynamicToolSearch ¶
func (c *Context) MarkMCPDynamicToolSearch()
func (*Context) ObserveMCPDynamicToolEvent ¶
func (*Context) SetBotFields ¶
func (c *Context) SetBotFields(displayName, username, userID, defaultModel, serviceType, customInstructions string)
SetBotFields populates bot-related context fields from config and service values. This avoids duplicating bot field assignment across multiple packages.
func (*Context) ShouldRecordMCPDynamicSearchLoadCallSuccess ¶
type ContextOption ¶
type ContextOption func(*Context)
ContextOption defines a function that configures a Context
type CustomAuthTransport ¶
type CustomAuthTransport struct {
// Base is the underlying RoundTripper. If nil, http.DefaultTransport is used.
Base http.RoundTripper
// RemoveHeaders is a list of header names to remove from the request.
RemoveHeaders []string
// SetHeaders is a map of header names to values to set on the request.
SetHeaders map[string]string
}
CustomAuthTransport is an http.RoundTripper that removes and sets headers on outgoing requests. It clones requests to avoid mutating the original.
type EnabledMCPTool ¶
type EnabledMCPTool struct {
ServerOrigin string `json:"server_origin"`
ToolName string `json:"tool_name"`
}
EnabledMCPTool identifies a single MCP tool on a specific server (config bots and persisted agents).
type EnrichToolCallOptions ¶
type EnrichToolCallOptions struct {
// OverwriteDescription replaces an existing Description with the store's
// value. Rehydration trusts the store; approval preserves the model's text.
OverwriteDescription bool
// BareNameFallback retries the lookup by MCPBareName when the primary
// (name, origin) lookup misses (needed when rehydrating persisted blocks).
BareNameFallback bool
}
EnrichToolCallOptions controls how EnrichToolCall fills a tool call from the store.
type EventType ¶
type EventType int
EventType represents the type of event in the text stream
const ( // EventTypeText represents a text chunk event EventTypeText EventType = iota // EventTypeEnd represents the end of the stream EventTypeEnd // EventTypeError represents an error event EventTypeError // EventTypeToolCalls represents a tool call event EventTypeToolCalls // EventTypeReasoning represents a reasoning summary chunk event EventTypeReasoning // EventTypeReasoningEnd represents the end of reasoning summary EventTypeReasoningEnd // EventTypeAnnotations represents annotations/citations in the response EventTypeAnnotations // EventTypeUsage represents token usage data EventTypeUsage )
type LanguageModel ¶
type LanguageModel interface {
ChatCompletion(ctx context.Context, conversation CompletionRequest, opts ...LanguageModelOption) (*TextStreamResult, error)
ChatCompletionNoStream(ctx context.Context, conversation CompletionRequest, opts ...LanguageModelOption) (string, error)
// CountTokens returns the exact input-token count. Implementations that
// can't reach a provider counting endpoint return ErrUnsupportedTokenCount
// so callers can fall back to EstimateTokens.
CountTokens(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (int, error)
InputTokenLimit() int
OutputTokenLimit() int
}
type LanguageModelConfig ¶
type LanguageModelOption ¶
type LanguageModelOption func(*LanguageModelConfig)
func WithJSONOutput ¶
func WithJSONOutput[T any]() LanguageModelOption
func WithMaxGeneratedTokens ¶
func WithMaxGeneratedTokens(maxGeneratedTokens int) LanguageModelOption
func WithModel ¶
func WithModel(model string) LanguageModelOption
func WithNativeWebSearchAllowed ¶
func WithNativeWebSearchAllowed() LanguageModelOption
func WithReasoningDisabled ¶
func WithReasoningDisabled() LanguageModelOption
func WithToolsDisabled ¶
func WithToolsDisabled() LanguageModelOption
type LanguageModelTestLogWrapper ¶
type LanguageModelTestLogWrapper struct {
// contains filtered or unexported fields
}
func NewLanguageModelTestLogWrapper ¶
func NewLanguageModelTestLogWrapper(t *testing.T, wrapped LanguageModel) *LanguageModelTestLogWrapper
func (*LanguageModelTestLogWrapper) ChatCompletion ¶
func (w *LanguageModelTestLogWrapper) ChatCompletion(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (*TextStreamResult, error)
func (*LanguageModelTestLogWrapper) ChatCompletionNoStream ¶
func (w *LanguageModelTestLogWrapper) ChatCompletionNoStream(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (string, error)
func (*LanguageModelTestLogWrapper) CountTokens ¶
func (w *LanguageModelTestLogWrapper) CountTokens(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (int, error)
func (*LanguageModelTestLogWrapper) InputTokenLimit ¶
func (w *LanguageModelTestLogWrapper) InputTokenLimit() int
func (*LanguageModelTestLogWrapper) OutputTokenLimit ¶
func (w *LanguageModelTestLogWrapper) OutputTokenLimit() int
type LanguageModelWrapper ¶
type LanguageModelWrapper func(LanguageModel) LanguageModel
type MCPDynamicToolTelemetry ¶
type MCPDynamicToolTelemetry interface {
ObserveMCPDynamicToolEvent(botName, event, result string)
}
type MetricsObserver ¶
type MetricsObserver interface {
ObserveTokenUsage(botName, teamID, userID string, inputTokens, outputTokens int)
}
MetricsObserver defines the interface for observing token usage metrics
type ModelInfo ¶
type ModelInfo struct {
ID string `json:"id"`
DisplayName string `json:"displayName"`
InputTokenLimit *int `json:"inputTokenLimit,omitempty"`
OutputTokenLimit *int `json:"outputTokenLimit,omitempty"`
ContextLength *int `json:"contextLength,omitempty"`
}
ModelInfo represents information about an available model. The pointer limit fields are nil when the provider doesn't report them.
type OpenAICompatibleProvider ¶
type OpenAICompatibleProvider struct {
// DefaultModel used when none is configured.
DefaultModel string
// CreateTransport returns a custom RoundTripper for non-standard auth.
// If nil, the default HTTP client is used (standard Bearer token auth).
CreateTransport func(cfg ServiceConfig, base http.RoundTripper) http.RoundTripper
// DisableStreamOptions disables the stream_options parameter.
DisableStreamOptions bool
// UseMaxTokens uses max_tokens instead of max_completion_tokens.
UseMaxTokens bool
}
OpenAICompatibleProvider describes the configuration for an OpenAI-compatible provider that can be registered in the provider registry. Adding an entry to the registry is all that is needed to support a new provider — no changes to bots.go or api.go are required.
func GetOpenAICompatibleProvider ¶
func GetOpenAICompatibleProvider(serviceType string) (OpenAICompatibleProvider, bool)
GetOpenAICompatibleProvider returns the provider configuration for the given service type, if it is registered.
type Post ¶
type Post struct {
Role PostRole
Message string
Files []File
ToolUse []ToolCall
Reasoning string // Extended thinking/reasoning content from models that support it
ReasoningSignature string // Signature for thinking blocks (opaque verification field)
}
type Prompts ¶
type Prompts struct {
// contains filtered or unexported fields
}
type ReasoningData ¶
type ReasoningData struct {
Text string // The reasoning/thinking text content
Signature string // Opaque verification signature from the model
}
ReasoningData represents the complete reasoning/thinking data including signature
type SanitizedProviderError ¶
type SanitizedProviderError struct {
// contains filtered or unexported fields
}
SanitizedProviderError wraps an upstream LLM error after redacting secrets from its message. It implements errors.Unwrap so errors.Is / errors.As chains on the original error are preserved.
func (*SanitizedProviderError) Error ¶
func (e *SanitizedProviderError) Error() string
func (*SanitizedProviderError) Unwrap ¶
func (e *SanitizedProviderError) Unwrap() error
type ServiceConfig ¶
type ServiceConfig struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
APIKey string `json:"apiKey"`
OrgID string `json:"orgId"`
DefaultModel string `json:"defaultModel"`
APIURL string `json:"apiURL"`
Region string `json:"region"` // For AWS Bedrock region
// AWS IAM credentials for Bedrock (optional, takes precedence over APIKey)
AWSAccessKeyID string `json:"awsAccessKeyID"`
AWSSecretAccessKey string `json:"awsSecretAccessKey"`
// Vertex AI (GCP) configuration. Region is reused from the shared Region field.
// VertexAuthCredentials holds the service-account JSON; when empty, Bifrost
// falls back to Application Default Credentials / attached IAM role.
VertexProjectID string `json:"vertexProjectID"`
VertexProjectNumber string `json:"vertexProjectNumber"`
VertexAuthCredentials string `json:"vertexAuthCredentials"`
// Renaming the JSON field to inputTokenLimit would require a migration, leaving as is for now.
InputTokenLimit int `json:"tokenLimit"`
StreamingTimeoutSeconds int `json:"streamingTimeoutSeconds"`
// Otherwise known as maxTokens
OutputTokenLimit int `json:"outputTokenLimit"`
// UseResponsesAPI determines whether to use the new OpenAI Responses API
// Only applicable to OpenAI and OpenAI-compatible services
UseResponsesAPI bool `json:"useResponsesAPI"`
// FallbackServiceID is the ID of another service to fall back to when this
// service's provider/model fails (e.g. network error, rate limit, model
// unavailable). The fallback service's DefaultModel is used. Chains are
// followed (A→B→C) with cycle detection.
FallbackServiceID string `json:"fallbackServiceID,omitempty"`
// LoadTestMockConfig is raw JSON merged by loadtest.ParseProfile for ServiceTypeLoadTestMock.
// Nil, empty, or whitespace-only means the default read/search-heavy profile.
LoadTestMockConfig json.RawMessage `json:"loadTestMockConfig,omitempty"`
}
func ResolveFallbackChain ¶
func ResolveFallbackChain(primaryServiceID string, getServiceByID func(id string) (ServiceConfig, bool)) ([]ServiceConfig, error)
ResolveFallbackChain walks the fallback chain starting from the service identified by primaryServiceID, returning an ordered slice of fallback ServiceConfigs. A misconfigured chain — a cycle, or a fallback ID that is missing or invalid — returns an error so the problem surfaces at setup instead of silently leaving the bot without the configured fallback. A missing primary returns an empty chain; the caller surfaces that error when it resolves the primary itself.
type StreamGenerator ¶
type StreamGenerator struct {
// TotalTextSize is the total bytes of text to generate
TotalTextSize int
// ChunkSize is the size of each text chunk
ChunkSize int
// IncludeReasoning adds reasoning events before text events
IncludeReasoning bool
// IncludeToolCalls ends with tool calls instead of normal end event
IncludeToolCalls bool
// IncludeUsage adds a usage event before end
IncludeUsage bool
// IncludeAnnotations adds annotation events
IncludeAnnotations bool
}
StreamGenerator creates synthetic streams for benchmarking. It generates TextStreamResult with configurable event patterns.
func (*StreamGenerator) Generate ¶
func (g *StreamGenerator) Generate() *TextStreamResult
Generate creates a new TextStreamResult with synthetic events. The stream is generated in a goroutine and returned immediately.
type StructuredOutputFallbackWrapper ¶
type StructuredOutputFallbackWrapper struct {
// contains filtered or unexported fields
}
StructuredOutputFallbackWrapper wraps a LanguageModel and encapsulates the structured output capability decision. When structured output is enabled, requests pass through untouched and any JSON schema is sent natively to the provider. When disabled and a JSON schema is requested, the schema is stripped from the provider request and converted into a prompt-level system instruction, and markdown code fencing is stripped from non-streaming responses.
func NewStructuredOutputFallbackWrapper ¶
func NewStructuredOutputFallbackWrapper(llm LanguageModel, structuredOutputEnabled bool) *StructuredOutputFallbackWrapper
func (*StructuredOutputFallbackWrapper) ChatCompletion ¶
func (w *StructuredOutputFallbackWrapper) ChatCompletion(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (*TextStreamResult, error)
func (*StructuredOutputFallbackWrapper) ChatCompletionNoStream ¶
func (w *StructuredOutputFallbackWrapper) ChatCompletionNoStream(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (string, error)
func (*StructuredOutputFallbackWrapper) CountTokens ¶
func (w *StructuredOutputFallbackWrapper) CountTokens(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (int, error)
CountTokens applies the fallback so counts reflect the request actually sent.
func (*StructuredOutputFallbackWrapper) InputTokenLimit ¶
func (w *StructuredOutputFallbackWrapper) InputTokenLimit() int
func (*StructuredOutputFallbackWrapper) OutputTokenLimit ¶
func (w *StructuredOutputFallbackWrapper) OutputTokenLimit() int
type TextStreamEvent ¶
TextStreamEvent represents an event in the text stream
type TextStreamResult ¶
type TextStreamResult struct {
Stream <-chan TextStreamEvent
}
TextStreamResult represents a stream of text events
func NewStreamFromString ¶
func NewStreamFromString(text string) *TextStreamResult
func (*TextStreamResult) ReadAll ¶
func (t *TextStreamResult) ReadAll() (string, error)
type TokenUsage ¶
type TokenUsage struct {
InputTokens int64 `json:"input_tokens"`
OutputTokens int64 `json:"output_tokens"`
CachedReadTokens int64 `json:"cached_read_tokens,omitempty"`
CachedWriteTokens int64 `json:"cached_write_tokens,omitempty"`
ReasoningTokens int64 `json:"reasoning_tokens,omitempty"`
Cost float64 `json:"cost,omitempty"`
}
TokenUsage represents token usage statistics for an LLM request. Cached, reasoning, and cost fields stay zero when the provider doesn't report them.
type TokenUsageLoggingWrapper ¶
type TokenUsageLoggingWrapper struct {
// contains filtered or unexported fields
}
TokenUsageLoggingWrapper wraps a LanguageModel to log token usage
func NewTokenUsageLoggingWrapper ¶
func NewTokenUsageLoggingWrapper(wrapped LanguageModel, botUsername string, sinks *TokenUsageSinks, metrics MetricsObserver) *TokenUsageLoggingWrapper
NewTokenUsageLoggingWrapper creates a wrapper using a shared sink controller.
func (*TokenUsageLoggingWrapper) ChatCompletion ¶
func (w *TokenUsageLoggingWrapper) ChatCompletion(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (*TextStreamResult, error)
ChatCompletion intercepts the streaming response to extract and log token usage
func (*TokenUsageLoggingWrapper) ChatCompletionNoStream ¶
func (w *TokenUsageLoggingWrapper) ChatCompletionNoStream(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (string, error)
ChatCompletionNoStream uses the streaming method internally, so token usage logging happens automatically when ReadAll() processes the intercepted stream
func (*TokenUsageLoggingWrapper) CountTokens ¶
func (w *TokenUsageLoggingWrapper) CountTokens(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (int, error)
CountTokens delegates to the wrapped model
func (*TokenUsageLoggingWrapper) InputTokenLimit ¶
func (w *TokenUsageLoggingWrapper) InputTokenLimit() int
InputTokenLimit delegates to the wrapped model
func (*TokenUsageLoggingWrapper) OutputTokenLimit ¶
func (w *TokenUsageLoggingWrapper) OutputTokenLimit() int
OutputTokenLimit delegates to the wrapped model
type TokenUsagePluginLogger ¶
TokenUsagePluginLogger is the logger interface used for plugin JSON logs.
type TokenUsageSinks ¶
type TokenUsageSinks struct {
// contains filtered or unexported fields
}
TokenUsageSinks stores shared sink state for token usage logging. Wrappers can read these atomically so config toggles do not require rebuilding bot wrappers.
func NewTokenUsageSinks ¶
func NewTokenUsageSinks(pluginLogger TokenUsagePluginLogger) *TokenUsageSinks
NewTokenUsageSinks creates a sink controller with the provided plugin logger.
func (*TokenUsageSinks) FileLogger ¶
func (s *TokenUsageSinks) FileLogger() *mlog.Logger
func (*TokenUsageSinks) LoggingEnabled ¶
func (s *TokenUsageSinks) LoggingEnabled() bool
func (*TokenUsageSinks) PluginLogger ¶
func (s *TokenUsageSinks) PluginLogger() TokenUsagePluginLogger
func (*TokenUsageSinks) SetFileEnabled ¶
func (s *TokenUsageSinks) SetFileEnabled(enabled bool)
func (*TokenUsageSinks) SetFileLogger ¶
func (s *TokenUsageSinks) SetFileLogger(logger *mlog.Logger)
func (*TokenUsageSinks) SetLoggingEnabled ¶
func (s *TokenUsageSinks) SetLoggingEnabled(enabled bool)
func (*TokenUsageSinks) SetPluginEnabled ¶
func (s *TokenUsageSinks) SetPluginEnabled(enabled bool)
type Tool ¶
type Tool struct {
Name string
Description string
Schema any
Resolver ToolResolver
// ServerOrigin identifies the MCP server this tool came from (the BaseURL).
// Empty for built-in (non-MCP) tools. Used for auto-approval decisions.
ServerOrigin string
// UserInteraction marks a tool whose pending call is answered by the
// requesting user in the Mattermost UI instead of executed by the server;
// the Resolver is only an error backstop. Empty for normal tools.
UserInteraction string
// CallMetadata is forwarded to the tool implementation as MCP CallToolParams.Meta.
// It is invisible to the LLM, not part of the input schema, and not parsed from the
// model's arguments. Set it at scope-time via WithCallMetadata when callers need to
// plumb runtime/protocol info (e.g. before-hook keys) that the underlying server
// needs but the model shouldn't see or be able to manipulate.
CallMetadata map[string]any
}
Tool represents a function that can be called by the language model during a conversation.
Each tool has a name, description, and schema that defines its parameters. These are passed to the LLM for it to understand what capabilities it has. It is the Resolver function that implements the actual functionality.
The Schema field should contain a JSONSchema that defines the expected structure of the tool's arguments. The Resolver function receives the request context, conversation context, and parsed arguments, and returns either a result that will be passed to the LLM or an error.
func FilterMCPToolsByAllowlist ¶
FilterMCPToolsByAllowlist returns a new slice containing every built-in tool (empty ServerOrigin) plus every MCP tool whose (ServerOrigin, Name) pair is present in the allowlist map. Allowlist keys use the format "serverOrigin\x00toolName"; both the namespaced runtime name and the bare name (see BareMCPToolName) are checked, so persisted allowlists with legacy bare names continue to match.
An empty or nil allowlist drops every MCP tool while still keeping built-in tools. The input slice is never mutated. Use FilterMCPToolsByEnabledAllowlist for EnabledMCPTool wildcard semantics.
func FilterMCPToolsByEnabledAllowlist ¶
func FilterMCPToolsByEnabledAllowlist(tools []Tool, allowlist []EnabledMCPTool) []Tool
FilterMCPToolsByEnabledAllowlist filters a plain tool slice using configured MCP allowlist entries, including wildcard expansion and normalized origins.
func (Tool) WithBoundParams ¶
WithBoundParams creates a new Tool with parameters bound to fixed values. Bound parameters are: - Removed from the schema (LLM cannot see or manipulate them) - Automatically injected when the resolver is called
func (Tool) WithCallMetadata ¶
WithCallMetadata returns a copy of the tool with CallMetadata set. Use this to attach per-call MCP metadata (like before-hook keys) at scope-time without leaking it into the LLM-visible schema or making the resolver fish it out of llm.Context. Passing an empty map clears the field.
type ToolArgumentGetter ¶
type ToolAuthError ¶
type ToolAuthError struct {
ServerName string `json:"server_name"`
ServerOrigin string `json:"server_origin"`
AuthURL string `json:"auth_url"`
Error error `json:"error"`
}
ToolAuthError represents an authentication error that occurred during tool creation
type ToolCall ¶
type ToolCall struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Arguments json.RawMessage `json:"arguments"`
Schema any `json:"schema,omitempty"`
Result string `json:"result"`
Status ToolCallStatus `json:"status"`
MCPBareName string `json:"mcp_bare_name,omitempty"`
// UserInteraction mirrors Tool.UserInteraction so the webapp can render
// the matching interaction UI (e.g. a question card) for pending calls.
UserInteraction string `json:"user_interaction,omitempty"`
// WouldAutoExecute marks any pending call that passed the auto-execution
// policy. The webapp must not show approval controls for it; the server
// re-checks the policy before executing it on resume.
WouldAutoExecute bool `json:"would_auto_execute,omitempty"`
// ServerOrigin identifies the MCP server this tool came from (the BaseURL).
// Empty for built-in tools. Used for auto-approval decisions.
ServerOrigin string `json:"server_origin,omitempty"`
}
ToolCall represents a tool call. An empty result indicates that the tool has not yet been resolved.
func (*ToolCall) SanitizeArguments ¶
func (tc *ToolCall) SanitizeArguments()
SanitizeArguments sanitizes the Arguments field to prevent bidirectional text and other Unicode spoofing attacks. Also ensures Arguments is valid JSON (defaults to "{}" if empty/nil).
type ToolCallStatus ¶
type ToolCallStatus int
ToolCallStatus represents the current status of a tool call
const ( // ToolCallStatusPending indicates the tool is waiting for user approval/rejection ToolCallStatusPending ToolCallStatus = iota // ToolCallStatusAccepted indicates the user has accepted the tool call but it's not resolved yet ToolCallStatusAccepted // ToolCallStatusRejected indicates the user has rejected the tool call ToolCallStatusRejected // ToolCallStatusError indicates the tool call was accepted but errored during resolution ToolCallStatusError // ToolCallStatusSuccess indicates the tool call was accepted and resolved successfully ToolCallStatusSuccess // ToolCallStatusAutoApproved indicates the tool call was auto-approved and executed // by the MCP approved servers feature per admin configuration. // This status is set by the stream wrapper and consumed by the streaming layer // to skip the call-approval UI and proceed directly to result-sharing. ToolCallStatusAutoApproved )
type ToolCatalogContext ¶
type ToolCatalogContext struct {
// MCPDynamicToolLoading indicates this context uses strict MCP dynamic loading.
MCPDynamicToolLoading bool
// DisabledMCPServerOrigins contains per-user disabled MCP server origins that
// must be removed before strict registry construction.
DisabledMCPServerOrigins []string
// KeepMCPTool, when non-nil, is applied to MCP tools before strict registry
// construction and before flag-off visible MCP insertion.
KeepMCPTool func(Tool) bool
// PreloadedMCPTools contains exact-or-bare MCP tool selectors for internal
// predefined flows. They are selected only from the already-authorized MCP
// catalog and are request scoped.
PreloadedMCPTools []EnabledMCPTool
// InteractiveUserPresent indicates the requesting user is interactively
// present in Mattermost (DM or human channel mention) and can answer
// pending tool approvals. Tools that require a user response (see
// Tool.UserInteraction) are only cataloged when this is set.
InteractiveUserPresent bool
}
ToolCatalogContext holds request-scoped tool catalog build inputs.
type ToolInfo ¶
ToolInfo represents basic information about a tool without its full implementation. Used to inform LLMs about tools that are unavailable in the current context.
type ToolLookup ¶
ToolLookup describes how a tool call name resolved in a ToolStore.
type ToolResolver ¶
type ToolRuntimeContext ¶
type ToolRuntimeContext struct {
// MCPDynamicToolTelemetry receives low-cardinality dynamic MCP tool events.
MCPDynamicToolTelemetry MCPDynamicToolTelemetry
MCPDynamicToolSearchUsed bool
MCPDynamicLoadedToolNames map[string]bool
MCPDynamicSearchLoadCallSuccessRecorded map[string]bool
}
ToolRuntimeContext holds request-scoped tool runtime state that should not be rendered into the prompt.
func (*ToolRuntimeContext) MarkMCPDynamicToolLoaded ¶
func (t *ToolRuntimeContext) MarkMCPDynamicToolLoaded(name string)
func (*ToolRuntimeContext) MarkMCPDynamicToolSearch ¶
func (t *ToolRuntimeContext) MarkMCPDynamicToolSearch()
func (*ToolRuntimeContext) ObserveMCPDynamicToolEvent ¶
func (t *ToolRuntimeContext) ObserveMCPDynamicToolEvent(botName, event, result string)
func (*ToolRuntimeContext) ShouldRecordMCPDynamicSearchLoadCallSuccess ¶
func (t *ToolRuntimeContext) ShouldRecordMCPDynamicSearchLoadCallSuccess(name string) bool
type ToolStore ¶
type ToolStore struct {
// contains filtered or unexported fields
}
func NewNoTools ¶
func NewNoTools() *ToolStore
func NewToolStore ¶
func NewToolStore() *ToolStore
func (*ToolStore) AddAuthError ¶
func (s *ToolStore) AddAuthError(authError ToolAuthError)
AddAuthError adds an authentication error to the tool store
func (*ToolStore) GetAuthErrors ¶
func (s *ToolStore) GetAuthErrors() []ToolAuthError
GetAuthErrors returns all authentication errors collected during tool creation
func (*ToolStore) GetServerOrigin ¶
GetServerOrigin returns the ServerOrigin for a tool by name. Returns empty string if the tool is not found or has no server origin (built-in tools).
func (*ToolStore) GetToolsInfo ¶
GetToolsInfo returns basic information (name and description) about all tools in the store. This is useful for informing LLMs about tools that are available in other contexts (e.g., DM-only tools when in a channel).
func (*ToolStore) GetUnloadedMCPToolInfo ¶
func (*ToolStore) HasUnloadedMCPTools ¶
func (*ToolStore) IsUnloadedMCPTool ¶
func (*ToolStore) KeepToolsIf ¶
KeepToolsIf removes tools for which keep returns false.
func (*ToolStore) LoadMCPTools ¶
LoadMCPTools moves the named tools from the unloaded MCP set into the active tool store, returning the tools that were loaded. Names must be exact (namespaced) registry names; bare names are ignored.
func (*ToolStore) LookupTool ¶
func (s *ToolStore) LookupTool(name, serverOrigin string) (ToolLookup, bool)
LookupTool resolves exact names and unique bare MCP names, optionally scoped to a server origin.
func (*ToolStore) RemoveToolsByServerOrigin ¶
RemoveToolsByServerOrigin removes all tools whose ServerOrigin matches any of the provided origins. This is used for user-disabled provider filtering in Copilot DM contexts.
func (*ToolStore) ResolveTool ¶
func (*ToolStore) RetainOnlyMCPTools ¶
func (s *ToolStore) RetainOnlyMCPTools(allowlist []EnabledMCPTool)
RetainOnlyMCPTools filters the tool store to only retain MCP tools whose (ServerOrigin, Name) pair appears in the allowlist. Built-in tools (those with empty ServerOrigin) are never removed by this method.
An empty or nil allowlist removes all MCP tools. Callers that want to keep every MCP tool (e.g. agents with AutoEnableNewMCPTools=true) should skip calling this method entirely.
func (*ToolStore) SetUnloadedMCPTools ¶
type TruncationWrapper ¶
type TruncationWrapper struct {
// contains filtered or unexported fields
}
func NewLLMTruncationWrapper ¶
func NewLLMTruncationWrapper(llm LanguageModel) *TruncationWrapper
func (*TruncationWrapper) ChatCompletion ¶
func (w *TruncationWrapper) ChatCompletion(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (*TextStreamResult, error)
func (*TruncationWrapper) ChatCompletionNoStream ¶
func (w *TruncationWrapper) ChatCompletionNoStream(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (string, error)
func (*TruncationWrapper) CountTokens ¶
func (w *TruncationWrapper) CountTokens(ctx context.Context, request CompletionRequest, opts ...LanguageModelOption) (int, error)
func (*TruncationWrapper) InputTokenLimit ¶
func (w *TruncationWrapper) InputTokenLimit() int
func (*TruncationWrapper) OutputTokenLimit ¶
func (w *TruncationWrapper) OutputTokenLimit() int
type UserAccessLevel ¶
type UserAccessLevel int
const ( UserAccessLevelAll UserAccessLevel = iota UserAccessLevelAllow UserAccessLevelBlock UserAccessLevelNone )
Source Files
¶
- annotations.go
- completion_request.go
- composition.go
- configuration.go
- context.go
- estimate.go
- json_sanitize.go
- language_model.go
- loadtest_validation.go
- logging.go
- model_fetcher.go
- prompts.go
- provider_error.go
- providers.go
- service_types.go
- stream.go
- stream_generator.go
- string_indices.go
- structured_output_fallback.go
- token_tracking.go
- token_usage_fields.go
- token_usage_sinks.go
- tool_retry.go
- tools.go
- transport.go
- truncation.go