Files
unibots/pkg/sanitize/sanitize.go
T
agent fc644ecd6e feat: import agents_and_robots platform as unibots (Matrix-out, unibus transport)
Reemplaza el scaffold del echobot por la plataforma completa de bots traida
desde ~/DataProyects/Github/agents_and_robots tras la operacion Matrix-out:
los bots ya no hablan por Matrix sino por el bus unibus (modelo todo-rooms +
E2E via shell/transportunibus sobre github.com/enmanuel/unibus/pkg/client).

- go.mod: replace de unibus -> ../unibus y de fn-registry -> ../../../.. (paths
  relativos reajustados a la nueva ubicacion dentro de fn_registry).
- app.md: bump a 0.2.0, descripcion + arquitectura + comandos + gotchas reales.
- modulo Go conservado como github.com/enmanuel/agents (sin reescribir imports).

agents_and_robots queda archivado como museo de la era Matrix.
2026-06-07 11:50:13 +02:00

137 lines
3.1 KiB
Go

package sanitize
import "strings"
// Mode controls how the sanitizer handles detected patterns.
type Mode int
const (
ModeWarn Mode = iota // report warnings but don't modify the message
ModeStrip // remove matched patterns from the message
ModeReject // reject the message entirely if any pattern matches
)
func (m Mode) String() string {
switch m {
case ModeWarn:
return "warn"
case ModeStrip:
return "strip"
case ModeReject:
return "reject"
default:
return "unknown"
}
}
// ParseMode converts a string to a Mode. Returns ModeWarn for unrecognized values.
func ParseMode(s string) Mode {
switch strings.ToLower(s) {
case "strip":
return ModeStrip
case "reject":
return ModeReject
default:
return ModeWarn
}
}
// Options configures the sanitizer behavior.
type Options struct {
Mode Mode // how to handle detections
MinSeverity Severity // only act on patterns at or above this severity
Patterns []Pattern // patterns to check (nil = DefaultPatterns)
DisabledPatterns []string // pattern names to skip
}
// Warning represents a detected prompt injection pattern in the input.
type Warning struct {
PatternName string // which pattern matched
Severity Severity // threat level
Matched string // the text that matched (first match only)
}
// Result holds the output of a Sanitize call.
type Result struct {
Output string // the (possibly modified) message
Warnings []Warning // all detected patterns
Rejected bool // true if the message was rejected (ModeReject + match found)
}
// Sanitize checks the input for prompt injection patterns and returns
// the result according to the configured mode.
//
// This is a pure function: no I/O, no side effects.
func Sanitize(input string, opts Options) Result {
patterns := opts.Patterns
if patterns == nil {
patterns = DefaultPatterns()
}
disabled := make(map[string]bool, len(opts.DisabledPatterns))
for _, name := range opts.DisabledPatterns {
disabled[name] = true
}
var warnings []Warning
output := input
for _, p := range patterns {
if disabled[p.Name] {
continue
}
if p.Severity < opts.MinSeverity {
continue
}
loc := p.Regex.FindStringIndex(output)
if loc == nil {
continue
}
matched := output[loc[0]:loc[1]]
warnings = append(warnings, Warning{
PatternName: p.Name,
Severity: p.Severity,
Matched: matched,
})
if opts.Mode == ModeStrip {
output = p.Regex.ReplaceAllString(output, "")
}
}
result := Result{
Output: output,
Warnings: warnings,
}
if opts.Mode == ModeReject && len(warnings) > 0 {
result.Rejected = true
}
return result
}
// HasHighSeverity returns true if any warning is SeverityHigh.
func (r Result) HasHighSeverity() bool {
for _, w := range r.Warnings {
if w.Severity == SeverityHigh {
return true
}
}
return false
}
// MaxSeverity returns the highest severity among all warnings.
// Returns SeverityLow if there are no warnings.
func (r Result) MaxSeverity() Severity {
max := SeverityLow
for _, w := range r.Warnings {
if w.Severity > max {
max = w.Severity
}
}
return max
}