Make D&D prompt assets provider neutral
This commit is contained in:
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
In progress. The dependency, framework adapter, and version 4 PromptKit
|
In progress. The dependency, framework adapter, version 4 PromptKit
|
||||||
configuration migration are implemented; module asset terminology and remaining
|
configuration migration, and provider-neutral module prompt-asset support are
|
||||||
provenance alignment are still planned.
|
implemented; remaining provenance alignment is still planned.
|
||||||
|
|
||||||
## Objective
|
## Objective
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ func (c *Chunker) ReferenceSlots() []contracts.ReferenceSlot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chunker) ManifestMetadata() map[string]any {
|
func (c *Chunker) ManifestMetadata() map[string]any {
|
||||||
promptSHA, err := scriptoriumPromptMetadata()
|
promptSHA, err := promptAssetMetadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
promptSHA = ""
|
promptSHA = ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
const scriptoriumPromptRoot = "assets/prompts"
|
const promptAssetRoot = "assets/prompts"
|
||||||
|
|
||||||
var promptAssetManifest = shared.PromptAssetManifest{
|
var promptAssetManifest = shared.PromptAssetManifest{
|
||||||
ModuleDir: "dnd.scenes",
|
ModuleDir: "dnd.scenes",
|
||||||
@@ -30,21 +30,21 @@ func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("prepare scene prompt assets: %w", err)
|
return fmt.Errorf("prepare scene prompt assets: %w", err)
|
||||||
}
|
}
|
||||||
if err := registry.RegisterPromptFS(promptFS, scriptoriumPromptRoot); err != nil {
|
if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
func scriptoriumPromptMetadata() (string, error) {
|
func promptAssetMetadata() (string, error) {
|
||||||
scriptoriumPromptHashOnce.Do(func() {
|
promptAssetHashOnce.Do(func() {
|
||||||
scriptoriumPromptHash, scriptoriumPromptHashErr = promptAssetManifest.Hash(embeddedAssets)
|
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets)
|
||||||
})
|
})
|
||||||
return scriptoriumPromptHash, scriptoriumPromptHashErr
|
return promptAssetHash, promptAssetHashErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scriptoriumPromptHashOnce sync.Once
|
promptAssetHashOnce sync.Once
|
||||||
scriptoriumPromptHash string
|
promptAssetHash string
|
||||||
scriptoriumPromptHashErr error
|
promptAssetHashErr error
|
||||||
)
|
)
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/promptkit"
|
"gitea.maximumdirect.net/eric/promptkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestScriptoriumPromptPreparesTranscriptAndTaskMessages(t *testing.T) {
|
func TestPromptAssetsPrepareTranscriptAndTaskMessages(t *testing.T) {
|
||||||
transcript := []byte(`{"sentinel":"scene-transcript"}`)
|
transcript := []byte(`{"sentinel":"scene-transcript"}`)
|
||||||
prepared := prepareScenesPrompt(t, transcript, "scene-players", "scene-party", "scene-glossary")
|
prepared := prepareScenesPrompt(t, transcript, "scene-players", "scene-party", "scene-glossary")
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ func TestScriptoriumPromptPreparesTranscriptAndTaskMessages(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScriptoriumPromptDiagnosticsOmitRawMaterials(t *testing.T) {
|
func TestPromptAssetDiagnosticsOmitRawMaterials(t *testing.T) {
|
||||||
transcript := []byte(`{"secret":"source text"}`)
|
transcript := []byte(`{"secret":"source text"}`)
|
||||||
prepared := prepareScenesPrompt(t, transcript, "private player note", "private party note", "private glossary note")
|
prepared := prepareScenesPrompt(t, transcript, "private player note", "private party note", "private glossary note")
|
||||||
metadata := newChunker(t, &fakeScenesLLMClient{}).ManifestMetadata()
|
metadata := newChunker(t, &fakeScenesLLMClient{}).ManifestMetadata()
|
||||||
@@ -100,7 +100,7 @@ func prepareScenesPrompt(t *testing.T, transcript []byte, players string, party
|
|||||||
if err := RegisterPromptAssets(registry); err != nil {
|
if err := RegisterPromptAssets(registry); err != nil {
|
||||||
t.Fatalf("register scene prompt assets: %v", err)
|
t.Fatalf("register scene prompt assets: %v", err)
|
||||||
}
|
}
|
||||||
engine := newScenesScriptoriumEngine(t, registry)
|
engine := newScenesPromptEngine(t, registry)
|
||||||
prepared, err := engine.Prepare(context.Background(), promptkit.RunRequest{
|
prepared, err := engine.Prepare(context.Background(), promptkit.RunRequest{
|
||||||
PromptID: PromptID,
|
PromptID: PromptID,
|
||||||
PromptVersion: ResponseSchemaVersion,
|
PromptVersion: ResponseSchemaVersion,
|
||||||
@@ -118,7 +118,7 @@ func prepareScenesPrompt(t *testing.T, transcript []byte, players string, party
|
|||||||
return prepared
|
return prepared
|
||||||
}
|
}
|
||||||
|
|
||||||
func newScenesScriptoriumEngine(t *testing.T, registry *llm.AssetRegistry) *promptkit.Engine {
|
func newScenesPromptEngine(t *testing.T, registry *llm.AssetRegistry) *promptkit.Engine {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
options, err := registry.PromptKitOptions()
|
options, err := registry.PromptKitOptions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -96,7 +96,7 @@ func New(llmClient contracts.StructuredLLMClient, _ Options, references ...contr
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, extractorErrorf("prepare scene eligibility: %w", err)
|
return nil, extractorErrorf("prepare scene eligibility: %w", err)
|
||||||
}
|
}
|
||||||
promptSHA, err := scriptoriumPromptMetadata()
|
promptSHA, err := promptAssetMetadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, extractorErrorf("load prompt metadata: %w", err)
|
return nil, extractorErrorf("load prompt metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
const scriptoriumPromptRoot = "assets/prompts"
|
const promptAssetRoot = "assets/prompts"
|
||||||
|
|
||||||
var promptAssetManifest = shared.PromptAssetManifest{
|
var promptAssetManifest = shared.PromptAssetManifest{
|
||||||
ModuleDir: "dnd.combat_turns",
|
ModuleDir: "dnd.combat_turns",
|
||||||
@@ -33,21 +33,21 @@ func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("prepare combat-turn prompt assets: %w", err)
|
return fmt.Errorf("prepare combat-turn prompt assets: %w", err)
|
||||||
}
|
}
|
||||||
if err := registry.RegisterPromptFS(promptFS, scriptoriumPromptRoot); err != nil {
|
if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
func scriptoriumPromptMetadata() (string, error) {
|
func promptAssetMetadata() (string, error) {
|
||||||
scriptoriumPromptHashOnce.Do(func() {
|
promptAssetHashOnce.Do(func() {
|
||||||
scriptoriumPromptHash, scriptoriumPromptHashErr = promptAssetManifest.Hash(embeddedAssets)
|
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets)
|
||||||
})
|
})
|
||||||
return scriptoriumPromptHash, scriptoriumPromptHashErr
|
return promptAssetHash, promptAssetHashErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scriptoriumPromptHashOnce sync.Once
|
promptAssetHashOnce sync.Once
|
||||||
scriptoriumPromptHash string
|
promptAssetHash string
|
||||||
scriptoriumPromptHashErr error
|
promptAssetHashErr error
|
||||||
)
|
)
|
||||||
@@ -23,13 +23,13 @@ func TestRegisterPromptAssetsAndPrepareCombatPrompt(t *testing.T) {
|
|||||||
if _, err := fs.ReadFile(schemaFS, "dnd_combat_turns_llm.v1.json"); err != nil {
|
if _, err := fs.ReadFile(schemaFS, "dnd_combat_turns_llm.v1.json"); err != nil {
|
||||||
t.Fatalf("response schema asset: %v", err)
|
t.Fatalf("response schema asset: %v", err)
|
||||||
}
|
}
|
||||||
hash, err := scriptoriumPromptMetadata()
|
hash, err := promptAssetMetadata()
|
||||||
if err != nil || !strings.HasPrefix(hash, "sha256:") {
|
if err != nil || !strings.HasPrefix(hash, "sha256:") {
|
||||||
t.Fatalf("scriptoriumPromptMetadata() = %q, %v; want digest", hash, err)
|
t.Fatalf("promptAssetMetadata() = %q, %v; want digest", hash, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScriptoriumPromptPreparesRequiredInputs(t *testing.T) {
|
func TestPromptAssetsPrepareRequiredInputs(t *testing.T) {
|
||||||
registry := llm.NewAssetRegistry()
|
registry := llm.NewAssetRegistry()
|
||||||
if err := RegisterPromptAssets(registry); err != nil {
|
if err := RegisterPromptAssets(registry); err != nil {
|
||||||
t.Fatalf("RegisterPromptAssets() error = %v, want nil", err)
|
t.Fatalf("RegisterPromptAssets() error = %v, want nil", err)
|
||||||
@@ -54,7 +54,7 @@ func New(llmClient contracts.StructuredLLMClient, _ Options, references ...contr
|
|||||||
if len(references) > 1 {
|
if len(references) > 1 {
|
||||||
return nil, extractorErrorf("at most one reference set may be supplied")
|
return nil, extractorErrorf("at most one reference set may be supplied")
|
||||||
}
|
}
|
||||||
promptSHA, err := scriptoriumPromptMetadata()
|
promptSHA, err := promptAssetMetadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, extractorErrorf("load prompt metadata: %w", err)
|
return nil, extractorErrorf("load prompt metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
const scriptoriumPromptRoot = "assets/prompts"
|
const promptAssetRoot = "assets/prompts"
|
||||||
|
|
||||||
var promptAssetManifest = shared.PromptAssetManifest{
|
var promptAssetManifest = shared.PromptAssetManifest{
|
||||||
ModuleDir: "dnd.item_events",
|
ModuleDir: "dnd.item_events",
|
||||||
@@ -32,21 +32,21 @@ func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("prepare item event prompt assets: %w", err)
|
return fmt.Errorf("prepare item event prompt assets: %w", err)
|
||||||
}
|
}
|
||||||
if err := registry.RegisterPromptFS(promptFS, scriptoriumPromptRoot); err != nil {
|
if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
func scriptoriumPromptMetadata() (string, error) {
|
func promptAssetMetadata() (string, error) {
|
||||||
scriptoriumPromptHashOnce.Do(func() {
|
promptAssetHashOnce.Do(func() {
|
||||||
scriptoriumPromptHash, scriptoriumPromptHashErr = promptAssetManifest.Hash(embeddedAssets)
|
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets)
|
||||||
})
|
})
|
||||||
return scriptoriumPromptHash, scriptoriumPromptHashErr
|
return promptAssetHash, promptAssetHashErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scriptoriumPromptHashOnce sync.Once
|
promptAssetHashOnce sync.Once
|
||||||
scriptoriumPromptHash string
|
promptAssetHash string
|
||||||
scriptoriumPromptHashErr error
|
promptAssetHashErr error
|
||||||
)
|
)
|
||||||
@@ -46,9 +46,9 @@ func TestPromptAssetsPrepareItemEventPrompt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPromptAssetsDoNotLeakIntoMetadata(t *testing.T) {
|
func TestPromptAssetsDoNotLeakIntoMetadata(t *testing.T) {
|
||||||
hash, err := scriptoriumPromptMetadata()
|
hash, err := promptAssetMetadata()
|
||||||
if err != nil || !strings.HasPrefix(hash, "sha256:") {
|
if err != nil || !strings.HasPrefix(hash, "sha256:") {
|
||||||
t.Fatalf("scriptoriumPromptMetadata() = %q, %v", hash, err)
|
t.Fatalf("promptAssetMetadata() = %q, %v", hash, err)
|
||||||
}
|
}
|
||||||
metadata := newExtractor(t, &fakeItemEventsLLMClient{}).ManifestMetadata()
|
metadata := newExtractor(t, &fakeItemEventsLLMClient{}).ManifestMetadata()
|
||||||
payload, err := json.Marshal(metadata)
|
payload, err := json.Marshal(metadata)
|
||||||
@@ -80,7 +80,7 @@ func New(llmClient contracts.StructuredLLMClient, _ Options, references ...contr
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, extractorErrorf("prepare NPC registry prompt input: %w", err)
|
return nil, extractorErrorf("prepare NPC registry prompt input: %w", err)
|
||||||
}
|
}
|
||||||
promptSHA, err := scriptoriumPromptMetadata()
|
promptSHA, err := promptAssetMetadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, extractorErrorf("load prompt metadata: %w", err)
|
return nil, extractorErrorf("load prompt metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
const scriptoriumPromptRoot = "assets/prompts"
|
const promptAssetRoot = "assets/prompts"
|
||||||
|
|
||||||
var promptAssetManifest = shared.PromptAssetManifest{
|
var promptAssetManifest = shared.PromptAssetManifest{
|
||||||
ModuleDir: "dnd.npc_interactions",
|
ModuleDir: "dnd.npc_interactions",
|
||||||
@@ -33,21 +33,21 @@ func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("prepare NPC-interaction prompt assets: %w", err)
|
return fmt.Errorf("prepare NPC-interaction prompt assets: %w", err)
|
||||||
}
|
}
|
||||||
if err := registry.RegisterPromptFS(promptFS, scriptoriumPromptRoot); err != nil {
|
if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
func scriptoriumPromptMetadata() (string, error) {
|
func promptAssetMetadata() (string, error) {
|
||||||
scriptoriumPromptHashOnce.Do(func() {
|
promptAssetHashOnce.Do(func() {
|
||||||
scriptoriumPromptHash, scriptoriumPromptHashErr = promptAssetManifest.Hash(embeddedAssets)
|
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets)
|
||||||
})
|
})
|
||||||
return scriptoriumPromptHash, scriptoriumPromptHashErr
|
return promptAssetHash, promptAssetHashErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scriptoriumPromptHashOnce sync.Once
|
promptAssetHashOnce sync.Once
|
||||||
scriptoriumPromptHash string
|
promptAssetHash string
|
||||||
scriptoriumPromptHashErr error
|
promptAssetHashErr error
|
||||||
)
|
)
|
||||||
@@ -54,9 +54,9 @@ func TestRegisterPromptAssetsAndPrepareInteractionPrompt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPromptMetadataDoesNotExposeAssetContent(t *testing.T) {
|
func TestPromptMetadataDoesNotExposeAssetContent(t *testing.T) {
|
||||||
hash, err := scriptoriumPromptMetadata()
|
hash, err := promptAssetMetadata()
|
||||||
if err != nil || !strings.HasPrefix(hash, "sha256:") {
|
if err != nil || !strings.HasPrefix(hash, "sha256:") {
|
||||||
t.Fatalf("scriptoriumPromptMetadata() = %q, %v", hash, err)
|
t.Fatalf("promptAssetMetadata() = %q, %v", hash, err)
|
||||||
}
|
}
|
||||||
metadata := newExtractor(t, &fakeInteractionsLLMClient{}).ManifestMetadata()
|
metadata := newExtractor(t, &fakeInteractionsLLMClient{}).ManifestMetadata()
|
||||||
for _, forbidden := range []string{"common-dnd-system", "dnd_npc_interactions_llm.v1.json"} {
|
for _, forbidden := range []string{"common-dnd-system", "dnd_npc_interactions_llm.v1.json"} {
|
||||||
@@ -54,7 +54,7 @@ func New(llmClient contracts.StructuredLLMClient, _ Options, references ...contr
|
|||||||
if len(references) > 1 {
|
if len(references) > 1 {
|
||||||
return nil, extractorErrorf("at most one reference set may be supplied")
|
return nil, extractorErrorf("at most one reference set may be supplied")
|
||||||
}
|
}
|
||||||
promptSHA, err := scriptoriumPromptMetadata()
|
promptSHA, err := promptAssetMetadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, extractorErrorf("load prompt metadata: %w", err)
|
return nil, extractorErrorf("load prompt metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
const scriptoriumPromptRoot = "assets/prompts"
|
const promptAssetRoot = "assets/prompts"
|
||||||
|
|
||||||
var promptAssetManifest = shared.PromptAssetManifest{
|
var promptAssetManifest = shared.PromptAssetManifest{
|
||||||
ModuleDir: "dnd.npcs",
|
ModuleDir: "dnd.npcs",
|
||||||
@@ -32,21 +32,21 @@ func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("prepare NPC prompt assets: %w", err)
|
return fmt.Errorf("prepare NPC prompt assets: %w", err)
|
||||||
}
|
}
|
||||||
if err := registry.RegisterPromptFS(promptFS, scriptoriumPromptRoot); err != nil {
|
if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
func scriptoriumPromptMetadata() (string, error) {
|
func promptAssetMetadata() (string, error) {
|
||||||
scriptoriumPromptHashOnce.Do(func() {
|
promptAssetHashOnce.Do(func() {
|
||||||
scriptoriumPromptHash, scriptoriumPromptHashErr = promptAssetManifest.Hash(embeddedAssets)
|
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets)
|
||||||
})
|
})
|
||||||
return scriptoriumPromptHash, scriptoriumPromptHashErr
|
return promptAssetHash, promptAssetHashErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scriptoriumPromptHashOnce sync.Once
|
promptAssetHashOnce sync.Once
|
||||||
scriptoriumPromptHash string
|
promptAssetHash string
|
||||||
scriptoriumPromptHashErr error
|
promptAssetHashErr error
|
||||||
)
|
)
|
||||||
@@ -45,9 +45,9 @@ func TestRegisterPromptAssetsAndPrepareNPCPrompt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPromptMetadataAndDiagnosticsDoNotContainRawAssets(t *testing.T) {
|
func TestPromptMetadataAndDiagnosticsDoNotContainRawAssets(t *testing.T) {
|
||||||
hash, err := scriptoriumPromptMetadata()
|
hash, err := promptAssetMetadata()
|
||||||
if err != nil || !strings.HasPrefix(hash, "sha256:") {
|
if err != nil || !strings.HasPrefix(hash, "sha256:") {
|
||||||
t.Fatalf("scriptoriumPromptMetadata() = %q, %v; want hash", hash, err)
|
t.Fatalf("promptAssetMetadata() = %q, %v; want hash", hash, err)
|
||||||
}
|
}
|
||||||
metadata := newExtractor(t, &fakeNPCsLLMClient{}).ManifestMetadata()
|
metadata := newExtractor(t, &fakeNPCsLLMClient{}).ManifestMetadata()
|
||||||
payload, err := json.Marshal(metadata)
|
payload, err := json.Marshal(metadata)
|
||||||
@@ -59,7 +59,7 @@ func New(llmClient contracts.StructuredLLMClient, _ Options, references ...contr
|
|||||||
if len(references) > 1 {
|
if len(references) > 1 {
|
||||||
return nil, extractorErrorf("at most one reference set may be supplied")
|
return nil, extractorErrorf("at most one reference set may be supplied")
|
||||||
}
|
}
|
||||||
promptSHA, err := scriptoriumPromptMetadata()
|
promptSHA, err := promptAssetMetadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, extractorErrorf("load prompt metadata: %w", err)
|
return nil, extractorErrorf("load prompt metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
const scriptoriumPromptRoot = "assets/prompts"
|
const promptAssetRoot = "assets/prompts"
|
||||||
|
|
||||||
var promptAssetManifest = shared.PromptAssetManifest{
|
var promptAssetManifest = shared.PromptAssetManifest{
|
||||||
ModuleDir: "dnd.scene_descriptions",
|
ModuleDir: "dnd.scene_descriptions",
|
||||||
@@ -31,21 +31,21 @@ func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("prepare scene-description prompt assets: %w", err)
|
return fmt.Errorf("prepare scene-description prompt assets: %w", err)
|
||||||
}
|
}
|
||||||
if err := registry.RegisterPromptFS(promptFS, scriptoriumPromptRoot); err != nil {
|
if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
func scriptoriumPromptMetadata() (string, error) {
|
func promptAssetMetadata() (string, error) {
|
||||||
scriptoriumPromptHashOnce.Do(func() {
|
promptAssetHashOnce.Do(func() {
|
||||||
scriptoriumPromptHash, scriptoriumPromptHashErr = promptAssetManifest.Hash(embeddedAssets)
|
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets)
|
||||||
})
|
})
|
||||||
return scriptoriumPromptHash, scriptoriumPromptHashErr
|
return promptAssetHash, promptAssetHashErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scriptoriumPromptHashOnce sync.Once
|
promptAssetHashOnce sync.Once
|
||||||
scriptoriumPromptHash string
|
promptAssetHash string
|
||||||
scriptoriumPromptHashErr error
|
promptAssetHashErr error
|
||||||
)
|
)
|
||||||
@@ -45,9 +45,9 @@ func TestRegisterPromptAssetsPreparesSceneDescriptionPrompt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPromptMetadataAndDiagnosticsDoNotContainRawAssets(t *testing.T) {
|
func TestPromptMetadataAndDiagnosticsDoNotContainRawAssets(t *testing.T) {
|
||||||
hash, err := scriptoriumPromptMetadata()
|
hash, err := promptAssetMetadata()
|
||||||
if err != nil || !strings.HasPrefix(hash, "sha256:") {
|
if err != nil || !strings.HasPrefix(hash, "sha256:") {
|
||||||
t.Fatalf("scriptoriumPromptMetadata() = %q, %v; want hash", hash, err)
|
t.Fatalf("promptAssetMetadata() = %q, %v; want hash", hash, err)
|
||||||
}
|
}
|
||||||
payload, err := json.Marshal(newExtractor(t, &fakeSceneDescriptionsLLMClient{}).ManifestMetadata())
|
payload, err := json.Marshal(newExtractor(t, &fakeSceneDescriptionsLLMClient{}).ManifestMetadata())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -94,7 +94,7 @@ func New(llmClient contracts.StructuredLLMClient, _ Options, references ...contr
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, extractorErrorf("prepare NPC registry prompt input: %w", err)
|
return nil, extractorErrorf("prepare NPC registry prompt input: %w", err)
|
||||||
}
|
}
|
||||||
promptSHA, err := scriptoriumPromptMetadata()
|
promptSHA, err := promptAssetMetadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, extractorErrorf("load prompt metadata: %w", err)
|
return nil, extractorErrorf("load prompt metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
const scriptoriumPromptRoot = "assets/prompts"
|
const promptAssetRoot = "assets/prompts"
|
||||||
|
|
||||||
var promptAssetManifest = shared.PromptAssetManifest{
|
var promptAssetManifest = shared.PromptAssetManifest{
|
||||||
ModuleDir: "dnd.spells",
|
ModuleDir: "dnd.spells",
|
||||||
@@ -34,21 +34,21 @@ func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("prepare spell prompt assets: %w", err)
|
return fmt.Errorf("prepare spell prompt assets: %w", err)
|
||||||
}
|
}
|
||||||
if err := registry.RegisterPromptFS(promptFS, scriptoriumPromptRoot); err != nil {
|
if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
func scriptoriumPromptMetadata() (string, error) {
|
func promptAssetMetadata() (string, error) {
|
||||||
scriptoriumPromptHashOnce.Do(func() {
|
promptAssetHashOnce.Do(func() {
|
||||||
scriptoriumPromptHash, scriptoriumPromptHashErr = promptAssetManifest.Hash(embeddedAssets)
|
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets)
|
||||||
})
|
})
|
||||||
return scriptoriumPromptHash, scriptoriumPromptHashErr
|
return promptAssetHash, promptAssetHashErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scriptoriumPromptHashOnce sync.Once
|
promptAssetHashOnce sync.Once
|
||||||
scriptoriumPromptHash string
|
promptAssetHash string
|
||||||
scriptoriumPromptHashErr error
|
promptAssetHashErr error
|
||||||
)
|
)
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/promptkit"
|
"gitea.maximumdirect.net/eric/promptkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestScriptoriumPromptPreparesSpellPrompt(t *testing.T) {
|
func TestPromptAssetsPrepareSpellPrompt(t *testing.T) {
|
||||||
transcript := []byte(`{"id":"session-1","segments":[{"id":"u1","text":"Mira casts shield."}]}`)
|
transcript := []byte(`{"id":"session-1","segments":[{"id":"u1","text":"Mira casts shield."}]}`)
|
||||||
prepared := prepareSpellsPrompt(t, transcript, "Dana: Mira", "Mira: wizard", "Shield: abjuration")
|
prepared := prepareSpellsPrompt(t, transcript, "Dana: Mira", "Mira: wizard", "Shield: abjuration")
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ func TestScriptoriumPromptPreparesSpellPrompt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScriptoriumPromptPreparesWithMissingOptionalReferences(t *testing.T) {
|
func TestPromptAssetsPrepareWithMissingOptionalReferences(t *testing.T) {
|
||||||
transcript := []byte(`{"id":"session-1","segments":[]}`)
|
transcript := []byte(`{"id":"session-1","segments":[]}`)
|
||||||
prepared := prepareSpellsPrompt(t, transcript, " ", " ", " ")
|
prepared := prepareSpellsPrompt(t, transcript, " ", " ", " ")
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ func TestScriptoriumPromptPreparesWithMissingOptionalReferences(t *testing.T) {
|
|||||||
t.Fatalf("reference message did not render empty optional reference placeholders")
|
t.Fatalf("reference message did not render empty optional reference placeholders")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScriptoriumPromptDiagnosticsOmitRawMaterials(t *testing.T) {
|
func TestPromptAssetDiagnosticsOmitRawMaterials(t *testing.T) {
|
||||||
transcript := []byte(`{"secret":"source text"}`)
|
transcript := []byte(`{"secret":"source text"}`)
|
||||||
reference := "private party note"
|
reference := "private party note"
|
||||||
prepared := prepareSpellsPrompt(t, transcript, "private player note", reference, " ")
|
prepared := prepareSpellsPrompt(t, transcript, "private player note", reference, " ")
|
||||||
@@ -53,7 +53,7 @@ func New(llmClient contracts.StructuredLLMClient, _ Options) (*Normalizer, error
|
|||||||
if llmClient == nil {
|
if llmClient == nil {
|
||||||
return nil, normalizerErrorf("LLM client must not be nil")
|
return nil, normalizerErrorf("LLM client must not be nil")
|
||||||
}
|
}
|
||||||
promptSHA, err := scriptoriumPromptMetadata()
|
promptSHA, err := promptAssetMetadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, normalizerErrorf("load prompt metadata: %w", err)
|
return nil, normalizerErrorf("load prompt metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
const scriptoriumPromptRoot = "assets/prompts"
|
const promptAssetRoot = "assets/prompts"
|
||||||
|
|
||||||
var promptAssetManifest = shared.PromptAssetManifest{
|
var promptAssetManifest = shared.PromptAssetManifest{
|
||||||
ModuleDir: PromptID,
|
ModuleDir: PromptID,
|
||||||
@@ -30,21 +30,21 @@ func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("prepare NPC normalization prompt assets: %w", err)
|
return fmt.Errorf("prepare NPC normalization prompt assets: %w", err)
|
||||||
}
|
}
|
||||||
if err := registry.RegisterPromptFS(promptFS, scriptoriumPromptRoot); err != nil {
|
if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
func scriptoriumPromptMetadata() (string, error) {
|
func promptAssetMetadata() (string, error) {
|
||||||
scriptoriumPromptHashOnce.Do(func() {
|
promptAssetHashOnce.Do(func() {
|
||||||
scriptoriumPromptHash, scriptoriumPromptHashErr = promptAssetManifest.Hash(embeddedAssets)
|
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets)
|
||||||
})
|
})
|
||||||
return scriptoriumPromptHash, scriptoriumPromptHashErr
|
return promptAssetHash, promptAssetHashErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scriptoriumPromptHashOnce sync.Once
|
promptAssetHashOnce sync.Once
|
||||||
scriptoriumPromptHash string
|
promptAssetHash string
|
||||||
scriptoriumPromptHashErr error
|
promptAssetHashErr error
|
||||||
)
|
)
|
||||||
@@ -15,8 +15,8 @@ func TestRegisterPromptAssetsPreparesNormalizationPrompt(t *testing.T) {
|
|||||||
if want := []string{"common-dnd-system.md", "common-dnd-transcript.md"}; !reflect.DeepEqual(promptAssetManifest.SharedFiles, want) {
|
if want := []string{"common-dnd-system.md", "common-dnd-transcript.md"}; !reflect.DeepEqual(promptAssetManifest.SharedFiles, want) {
|
||||||
t.Fatalf("shared prompt assets = %#v, want %#v", promptAssetManifest.SharedFiles, want)
|
t.Fatalf("shared prompt assets = %#v, want %#v", promptAssetManifest.SharedFiles, want)
|
||||||
}
|
}
|
||||||
if promptHash, err := scriptoriumPromptMetadata(); err != nil || promptHash == "" {
|
if promptHash, err := promptAssetMetadata(); err != nil || promptHash == "" {
|
||||||
t.Fatalf("scriptoriumPromptMetadata() = %q, %v; want prompt fingerprint", promptHash, err)
|
t.Fatalf("promptAssetMetadata() = %q, %v; want prompt fingerprint", promptHash, err)
|
||||||
}
|
}
|
||||||
registry := llm.NewAssetRegistry()
|
registry := llm.NewAssetRegistry()
|
||||||
if err := RegisterPromptAssets(registry); err != nil {
|
if err := RegisterPromptAssets(registry); err != nil {
|
||||||
Reference in New Issue
Block a user