Files
sm-golem-plugin/models/ai_model.go
Jakub Zych c93e2d9142 feat: AI models admin, settings import, Anthropic adapter and the rest of AIService
- golem15_golem_models (encrypted write-only api_key) with its cabana list
  and form under golem15.golem.access_settings, and the Settings lookups
  (Models, DefaultModel with PHP's position-0 quirk, Vision, Image, File,
  ByName), every one Trusted
- golem:import-settings copies the WinterCMS golem_settings repeater once
- AnthropicAdapter; SendStream, SendFile/SendFilePath/SendFileReader,
  SendWithModel, SendToImageModel, SendToVisionModel, GenerateImage, Ask
- PromptFactory; README documents the config keys, the environment
  variable, the command and the admin screen
2026-10-03 23:09:02 +02:00

63 lines
2.5 KiB
Go

package models
import (
"time"
"git.golem15.com/golem15/summercms/modules/lagoon"
)
// AiModel is one AI model an operator configured in the admin
// (golem15_golem_models), the Go form of one item of the WinterCMS
// plugin's models repeater. APIKey is encrypted at rest, never serialized
// (json:"-", Hidden) and never echoed by the admin form. BaseURL nil or
// empty means the adapter's default. SortOrder keeps the repeater's order.
type AiModel struct {
ID uint `gorm:"column:id;primaryKey"`
Name string `gorm:"column:name"`
Adapter string `gorm:"column:adapter"`
APIKey lagoon.Encrypted `gorm:"column:api_key" json:"-"`
BaseURL *string `gorm:"column:base_url"`
Model string `gorm:"column:model"`
SystemPrompt *string `gorm:"column:system_prompt"`
IsEnabled bool `gorm:"column:is_enabled"`
IsDefault bool `gorm:"column:is_default"`
GeneratesImages bool `gorm:"column:generates_images"`
AcceptsImages bool `gorm:"column:accepts_images"`
HasFilesEndpoint bool `gorm:"column:has_files_endpoint"`
MaxCompletionTokens *int `gorm:"column:max_completion_tokens"`
SortOrder int `gorm:"column:sort_order"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
}
// TableName is golem15_golem_models.
func (AiModel) TableName() string { return "golem15_golem_models" }
// Fillable is every column the admin form writes.
func (AiModel) Fillable() []string {
return []string{
"name", "adapter", "api_key", "base_url", "model", "system_prompt",
"is_enabled", "is_default", "generates_images", "accepts_images",
"has_files_endpoint", "max_completion_tokens", "sort_order",
}
}
// Hidden keeps the API key out of every serialization.
func (AiModel) Hidden() []string { return []string{"api_key"} }
// Rules are the form's checks: a name, a model id, a known adapter and an
// integer token budget.
func (AiModel) Rules() map[string]string {
return map[string]string{
"name": "required",
"model": "required",
"adapter": "required|in:openai,anthropic",
"max_completion_tokens": "nullable|integer|min:1",
"sort_order": "nullable|integer",
}
}
func init() {
Register(AiModel{})
}