95 lines
1.9 KiB
Go
95 lines
1.9 KiB
Go
|
|
package prompt
|
||
|
|
|
||
|
|
import (
|
||
|
|
"embed"
|
||
|
|
"strings"
|
||
|
|
"sync"
|
||
|
|
)
|
||
|
|
|
||
|
|
//go:embed files
|
||
|
|
var files embed.FS
|
||
|
|
|
||
|
|
const (
|
||
|
|
fileOverlay = "files/overlay.md"
|
||
|
|
fileStyle8DSystem = "files/style8d.system.md"
|
||
|
|
fileStyle8DSchema = "files/style8d.schema.md"
|
||
|
|
fileAIChatSystem = "files/ai.chat.system.md"
|
||
|
|
fileIslanderSystem = "files/ai.islander.system.md"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Keys identify prompt slots loaded from internal/library/prompt/files/*.md.
|
||
|
|
const (
|
||
|
|
KeyStyle8DSystem = "style8d.system"
|
||
|
|
KeyStyle8DSchema = "style8d.schema"
|
||
|
|
KeyAIChatSystem = "ai.chat.system"
|
||
|
|
KeyIslanderSystem = "ai.islander.system"
|
||
|
|
)
|
||
|
|
|
||
|
|
var slotFiles = map[string]string{
|
||
|
|
KeyStyle8DSystem: fileStyle8DSystem,
|
||
|
|
KeyStyle8DSchema: fileStyle8DSchema,
|
||
|
|
KeyAIChatSystem: fileAIChatSystem,
|
||
|
|
KeyIslanderSystem: fileIslanderSystem,
|
||
|
|
}
|
||
|
|
|
||
|
|
var (
|
||
|
|
loadOnce sync.Once
|
||
|
|
loadErr error
|
||
|
|
overlay string
|
||
|
|
slotTexts map[string]string
|
||
|
|
)
|
||
|
|
|
||
|
|
func initRegistry() {
|
||
|
|
overlay, loadErr = readFile(fileOverlay)
|
||
|
|
if loadErr != nil {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
slotTexts = make(map[string]string, len(slotFiles))
|
||
|
|
for key, path := range slotFiles {
|
||
|
|
text, err := readFile(path)
|
||
|
|
if err != nil {
|
||
|
|
loadErr = err
|
||
|
|
return
|
||
|
|
}
|
||
|
|
slotTexts[key] = text
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func readFile(path string) (string, error) {
|
||
|
|
raw, err := files.ReadFile(path)
|
||
|
|
if err != nil {
|
||
|
|
return "", err
|
||
|
|
}
|
||
|
|
return strings.TrimSpace(string(raw)), nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func ensureLoaded() error {
|
||
|
|
loadOnce.Do(initRegistry)
|
||
|
|
return loadErr
|
||
|
|
}
|
||
|
|
|
||
|
|
// Overlay returns the global prepend text (Agents.md style).
|
||
|
|
func Overlay() (string, error) {
|
||
|
|
if err := ensureLoaded(); err != nil {
|
||
|
|
return "", err
|
||
|
|
}
|
||
|
|
return overlay, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// Slot returns one configured prompt body.
|
||
|
|
func Slot(key string) (string, error) {
|
||
|
|
if err := ensureLoaded(); err != nil {
|
||
|
|
return "", err
|
||
|
|
}
|
||
|
|
text, ok := slotTexts[key]
|
||
|
|
if !ok {
|
||
|
|
return "", ErrUnknownKey(key)
|
||
|
|
}
|
||
|
|
return text, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// KnownKey reports whether key is registered.
|
||
|
|
func KnownKey(key string) bool {
|
||
|
|
_, ok := slotFiles[key]
|
||
|
|
return ok
|
||
|
|
}
|