Files
audita/internal/prompts/registry.go

108 lines
3.2 KiB
Go

package prompts
import (
"embed"
"fmt"
"io/fs"
"sort"
"strings"
)
//go:embed assets/**
var embeddedAssets embed.FS
const (
SourceBuiltin = "builtin"
AssetRoot = "assets/prompts"
PromptIDModuleGlossaryProposal = "audita/modules.glossary.proposal"
PromptIDModuleHomophonesProposal = "audita/modules.homophones.proposal"
PromptIDModuleSpokenWordProposal = "audita/modules.spoken_word.proposal"
PromptIDModuleGrammarProposal = "audita/modules.grammar.proposal"
PromptIDValidatorSpokenFormPlausibility = "audita/validators.spoken_form_plausibility"
PromptIDValidatorMeaningReversalReview = "audita/validators.meaning_reversal_review"
PromptIDValidatorEditorialReview = "audita/validators.editorial_review"
)
var promptIDs = []string{
PromptIDModuleGlossaryProposal, PromptIDModuleHomophonesProposal,
PromptIDModuleSpokenWordProposal, PromptIDModuleGrammarProposal,
PromptIDValidatorSpokenFormPlausibility, PromptIDValidatorMeaningReversalReview, PromptIDValidatorEditorialReview,
}
type Metadata struct {
PromptID string `json:"prompt_id"`
PromptSource string `json:"prompt_source"`
EmbeddedPath string `json:"embedded_path"`
}
func (m Metadata) DiagnosticsMap() map[string]any {
return map[string]any{
"prompt_id": m.PromptID,
"prompt_source": m.PromptSource, "embedded_path": m.EmbeddedPath,
}
}
// Filesystem contains the PromptKit definitions and shared instruction fragments.
func Filesystem() fs.FS { return embeddedAssets }
func LookupMetadata(promptID string) (Metadata, bool) {
id := strings.TrimSpace(promptID)
for _, known := range promptIDs {
if known == id {
return Metadata{PromptID: id, PromptSource: SourceBuiltin, EmbeddedPath: AssetRoot + "/" + strings.TrimPrefix(id, "audita/") + ".yaml"}, true
}
}
return Metadata{}, false
}
func MustLookupMetadata(promptID string) Metadata {
m, ok := LookupMetadata(promptID)
if !ok {
panic(fmt.Sprintf("unknown prompt id %q", promptID))
}
return m
}
func RegisteredMetadata() []Metadata {
ids := append([]string(nil), promptIDs...)
sort.Strings(ids)
out := make([]Metadata, 0, len(ids))
for _, id := range ids {
out = append(out, MustLookupMetadata(id))
}
return out
}
// SharedVariables supplies embedded instructions through the normal PromptKit variables.
func SharedVariables() map[string]string {
return map[string]string{
"HardeningPolicy": HardeningText(),
"ProposalContract": sharedText("proposal_contract.md"),
"ValidationContract": sharedText("validation_contract.md"),
}
}
// WithSharedVariables fills missing Audita instruction variables without replacing caller values.
func WithSharedVariables(values map[string]string) map[string]string {
result := make(map[string]string, len(values)+3)
for key, value := range values {
result[key] = value
}
for key, value := range SharedVariables() {
if _, exists := result[key]; !exists {
result[key] = value
}
}
return result
}
func HardeningText() string { return sharedText("prompt_hardening.md") }
func sharedText(name string) string {
raw, err := embeddedAssets.ReadFile("assets/shared/" + name)
if err != nil {
panic(fmt.Sprintf("read embedded prompt fragment %s: %v", name, err))
}
return string(raw)
}