package spells import ( "bytes" "fmt" "sort" "sync" "gitea.maximumdirect.net/eric/notarius/internal/framework/contracts" "gitea.maximumdirect.net/eric/notarius/internal/framework/llm" "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/promptassets" ) const scriptoriumPromptRoot = "assets/scriptorium/prompts" func RegisterPromptAssets(registry *llm.AssetRegistry) error { if err := registry.RegisterPromptFS(embeddedAssets, scriptoriumPromptRoot); err != nil { return err } return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas") } func scriptoriumPromptMetadata() (string, error) { scriptoriumPromptHashOnce.Do(func() { parts := append([]llm.AssetHashPart{ {FS: embeddedAssets, Path: "assets/scriptorium/prompts/dnd.spells.yaml"}, {FS: embeddedAssets, Path: "assets/scriptorium/prompts/dnd/spells/task.md"}, {FS: embeddedAssets, Path: "assets/scriptorium/prompts/dnd/spells/instructions.md"}, }, append(promptassets.CommonHashParts(), promptassets.ReferenceHashParts()...)...) scriptoriumPromptHash, scriptoriumPromptHashErr = llm.HashAssets(parts) }) return scriptoriumPromptHash, scriptoriumPromptHashErr } func referencePromptInput(slot contracts.ResolvedReferenceSlot) []byte { if len(slot.Items) == 0 { return []byte(" ") } items := append([]contracts.ReferenceItem(nil), slot.Items...) sort.SliceStable(items, func(i, j int) bool { if items[i].Origin.URI != items[j].Origin.URI { return items[i].Origin.URI < items[j].Origin.URI } if items[i].Digest != items[j].Digest { return items[i].Digest < items[j].Digest } return string(items[i].Content) < string(items[j].Content) }) if len(items) == 1 { return append([]byte(nil), items[0].Content...) } var b bytes.Buffer for i, item := range items { if i > 0 { b.WriteString("\n\n") } fmt.Fprintf(&b, "Reference %d\n", i+1) if item.Origin.Type != "" { fmt.Fprintf(&b, "Origin-Type: %s\n", item.Origin.Type) } if item.Origin.URI != "" { fmt.Fprintf(&b, "Origin-URI: %s\n", item.Origin.URI) } if item.Digest != "" { fmt.Fprintf(&b, "Digest: %s\n", item.Digest) } if item.MediaType != "" { fmt.Fprintf(&b, "Media-Type: %s\n", item.MediaType) } if item.SizeBytes > 0 { fmt.Fprintf(&b, "Size-Bytes: %d\n", item.SizeBytes) } b.WriteString("\n") b.Write(item.Content) } return b.Bytes() } var ( scriptoriumPromptHashOnce sync.Once scriptoriumPromptHash string scriptoriumPromptHashErr error )