108 lines
3.2 KiB
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)
|
|
}
|