feat(filters): Add configurable filters for incoming jobs
Signed-off-by: Richard Palethorpe <io@richiejp.com>
This commit is contained in:
86
services/filters/regex.go
Normal file
86
services/filters/regex.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package filters
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"regexp"
|
||||
|
||||
"github.com/mudler/LocalAGI/core/types"
|
||||
"github.com/mudler/LocalAGI/pkg/config"
|
||||
)
|
||||
|
||||
const FilterRegex = "regex"
|
||||
|
||||
type RegexFilter struct {
|
||||
name string
|
||||
pattern *regexp.Regexp
|
||||
allowOnMatch bool
|
||||
isTrigger bool
|
||||
}
|
||||
|
||||
type RegexFilterConfig struct {
|
||||
Name string `json:"name"`
|
||||
Pattern string `json:"pattern"`
|
||||
AllowOnMatch bool `json:"allow_on_match"`
|
||||
IsTrigger bool `json:"is_trigger"`
|
||||
}
|
||||
|
||||
func NewRegexFilter(configJSON string) (*RegexFilter, error) {
|
||||
var cfg RegexFilterConfig
|
||||
if err := json.Unmarshal([]byte(configJSON), &cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
re, err := regexp.Compile(cfg.Pattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RegexFilter{
|
||||
name: cfg.Name,
|
||||
pattern: re,
|
||||
allowOnMatch: cfg.AllowOnMatch,
|
||||
isTrigger: cfg.IsTrigger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f *RegexFilter) Name() string { return f.name }
|
||||
func (f *RegexFilter) Apply(job *types.Job) (bool, error) {
|
||||
input := extractInputFromJob(job)
|
||||
if f.pattern.MatchString(input) {
|
||||
return f.allowOnMatch, nil
|
||||
}
|
||||
return !f.allowOnMatch, nil
|
||||
}
|
||||
|
||||
func (f *RegexFilter) IsTrigger() bool {
|
||||
return f.isTrigger
|
||||
}
|
||||
|
||||
func RegexFilterConfigMeta() config.FieldGroup {
|
||||
return config.FieldGroup{
|
||||
Name: FilterRegex,
|
||||
Label: "Regex Filter/Trigger",
|
||||
Fields: []config.Field{
|
||||
{Name: "name", Label: "Name", Type: "text", Required: true},
|
||||
{Name: "pattern", Label: "Pattern", Type: "text", Required: true},
|
||||
{Name: "allow_on_match", Label: "Allow on Match", Type: "checkbox", Required: true},
|
||||
{Name: "is_trigger", Label: "Is Trigger", Type: "checkbox", Required: true},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// extractInputFromJob attempts to extract a string input for filtering.
|
||||
func extractInputFromJob(job *types.Job) string {
|
||||
if job.Metadata != nil {
|
||||
if v, ok := job.Metadata["input"]; ok {
|
||||
if s, ok := v.(string); ok {
|
||||
return s
|
||||
}
|
||||
}
|
||||
}
|
||||
// fallback: try to use conversation history if available
|
||||
if len(job.ConversationHistory) > 0 {
|
||||
// Use the last message content
|
||||
last := job.ConversationHistory[len(job.ConversationHistory)-1]
|
||||
return last.Content
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user