Document D&D prompt conventions and verification
This commit is contained in:
@@ -185,13 +185,11 @@ func TestAssetRegistryFallbackProfileDigestTracksContentWithoutLeakingIt(t *test
|
||||
func TestAssetRegistryCombinesNamespacedPromptSources(t *testing.T) {
|
||||
registry := NewAssetRegistry()
|
||||
mustRegisterPromptFS(t, registry, fstest.MapFS{
|
||||
"dnd.spells/dnd.spells.yaml": {Data: []byte(validPromptYAML("schema.json"))},
|
||||
"dnd.spells/task.md": {Data: []byte("spell task")},
|
||||
"dnd.spells/prompt.yaml": {Data: []byte(validPromptYAML("schema.json"))},
|
||||
"dnd.spells/instructions.md": {Data: []byte("spell instructions")},
|
||||
}, ".")
|
||||
mustRegisterPromptFS(t, registry, fstest.MapFS{
|
||||
"dnd.scenes/dnd.scenes.yaml": {Data: []byte(validPromptYAML("schema.json"))},
|
||||
"dnd.scenes/task.md": {Data: []byte("scene task")},
|
||||
"dnd.scenes/prompt.yaml": {Data: []byte(validPromptYAML("schema.json"))},
|
||||
"dnd.scenes/instructions.md": {Data: []byte("scene instructions")},
|
||||
}, ".")
|
||||
|
||||
@@ -200,11 +198,9 @@ func TestAssetRegistryCombinesNamespacedPromptSources(t *testing.T) {
|
||||
t.Fatalf("PromptFS() error = %v, want nil", err)
|
||||
}
|
||||
for _, name := range []string{
|
||||
"dnd.spells/dnd.spells.yaml",
|
||||
"dnd.spells/task.md",
|
||||
"dnd.spells/prompt.yaml",
|
||||
"dnd.spells/instructions.md",
|
||||
"dnd.scenes/dnd.scenes.yaml",
|
||||
"dnd.scenes/task.md",
|
||||
"dnd.scenes/prompt.yaml",
|
||||
"dnd.scenes/instructions.md",
|
||||
} {
|
||||
if _, err := fsys.Open(name); err != nil {
|
||||
|
||||
@@ -14,11 +14,11 @@ func TestModulePromptFSCombinesModuleAndSharedPrompts(t *testing.T) {
|
||||
"nested/transcript.md": {Data: []byte("transcript")},
|
||||
}
|
||||
fsys, err := ModulePromptFS("module.test", fstest.MapFS{
|
||||
"assets/prompts/module.test.yaml": {Data: []byte("id: module.test")},
|
||||
"assets/prompts/task.md": {Data: []byte("task")},
|
||||
"assets/prompts/prompt.yaml": {Data: []byte("id: module.test")},
|
||||
"assets/prompts/instructions.md": {Data: []byte("instructions")},
|
||||
}, []ModulePromptFile{
|
||||
{Name: "module.test.yaml", Path: "assets/prompts/module.test.yaml"},
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "prompt.yaml", Path: "assets/prompts/prompt.yaml"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
},
|
||||
SharedPromptFile{Name: "system.md", FS: sharedFS, Path: "shared/system.md"},
|
||||
SharedPromptFile{Name: "reference.md", FS: sharedFS, Path: "shared/reference.md"},
|
||||
@@ -29,8 +29,8 @@ func TestModulePromptFSCombinesModuleAndSharedPrompts(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := map[string]string{
|
||||
"assets/prompts/module.test/module.test.yaml": "id: module.test",
|
||||
"assets/prompts/module.test/task.md": "task",
|
||||
"assets/prompts/module.test/prompt.yaml": "id: module.test",
|
||||
"assets/prompts/module.test/instructions.md": "instructions",
|
||||
"assets/prompts/module.test/sharedassets/system.md": "system",
|
||||
"assets/prompts/module.test/sharedassets/reference.md": "reference",
|
||||
"assets/prompts/module.test/sharedassets/transcript.md": "transcript",
|
||||
@@ -63,18 +63,18 @@ func TestModulePromptFSCombinesModuleAndSharedPrompts(t *testing.T) {
|
||||
|
||||
func TestModulePromptFSRejectsMissingModuleFile(t *testing.T) {
|
||||
_, err := ModulePromptFS("module.test", fstest.MapFS{}, []ModulePromptFile{
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "read module prompt asset assets/prompts/task.md") {
|
||||
if err == nil || !strings.Contains(err.Error(), "read module prompt asset assets/prompts/instructions.md") {
|
||||
t.Fatalf("ModulePromptFS() error = %v, want missing module asset context", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestModulePromptFSRejectsMissingSharedFile(t *testing.T) {
|
||||
_, err := ModulePromptFS("module.test", fstest.MapFS{
|
||||
"assets/prompts/task.md": {Data: []byte("task")},
|
||||
"assets/prompts/instructions.md": {Data: []byte("instructions")},
|
||||
}, []ModulePromptFile{
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
}, SharedPromptFile{Name: "system.md", FS: fstest.MapFS{}, Path: "shared/system.md"})
|
||||
if err == nil || !strings.Contains(err.Error(), "read shared prompt asset shared/system.md") {
|
||||
t.Fatalf("ModulePromptFS() error = %v, want missing shared asset context", err)
|
||||
@@ -83,9 +83,9 @@ func TestModulePromptFSRejectsMissingSharedFile(t *testing.T) {
|
||||
|
||||
func TestModulePromptFSRejectsNestedVirtualFileName(t *testing.T) {
|
||||
_, err := ModulePromptFS("module.test", fstest.MapFS{
|
||||
"assets/prompts/task.md": {Data: []byte("task")},
|
||||
"assets/prompts/instructions.md": {Data: []byte("instructions")},
|
||||
}, []ModulePromptFile{
|
||||
{Name: "nested/task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "nested/instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "must not contain path separators") {
|
||||
t.Fatalf("ModulePromptFS() error = %v, want nested file name error", err)
|
||||
@@ -94,9 +94,9 @@ func TestModulePromptFSRejectsNestedVirtualFileName(t *testing.T) {
|
||||
|
||||
func TestModulePromptFSRejectsNestedSharedFileName(t *testing.T) {
|
||||
_, err := ModulePromptFS("module.test", fstest.MapFS{
|
||||
"assets/prompts/task.md": {Data: []byte("task")},
|
||||
"assets/prompts/instructions.md": {Data: []byte("instructions")},
|
||||
}, []ModulePromptFile{
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
}, SharedPromptFile{Name: "nested/system.md", FS: fstest.MapFS{}, Path: "shared/system.md"})
|
||||
if err == nil || !strings.Contains(err.Error(), "shared prompt file name") || !strings.Contains(err.Error(), "must not contain path separators") {
|
||||
t.Fatalf("ModulePromptFS() error = %v, want nested shared file name error", err)
|
||||
|
||||
@@ -25,9 +25,6 @@ func TestPromptAssetsPrepareTranscriptWithInstructionOrdering(t *testing.T) {
|
||||
if prepared.OutputContract.SchemaPath != "dnd_scenes_llm.v1.json" {
|
||||
t.Fatalf("scene output schema path = %q, want private LLM schema", prepared.OutputContract.SchemaPath)
|
||||
}
|
||||
if len(prepared.Messages) < 4 {
|
||||
t.Fatalf("prepared messages = %#v, want system, references, instructions, and transcript", prepared.Messages)
|
||||
}
|
||||
if prepared.Messages[0].Role != "system" || prepared.Messages[1].Role != "user" {
|
||||
t.Fatalf("initial prompt roles = %#v, want system followed by campaign references", prepared.Messages[:2])
|
||||
}
|
||||
|
||||
@@ -62,9 +62,6 @@ func TestPromptAssetsPrepareRequiredInputs(t *testing.T) {
|
||||
if prepared.PromptID != PromptID || prepared.OutputContract.SchemaPath != "dnd_combat_turns_llm.v1.json" {
|
||||
t.Fatalf("prepared prompt = %#v, want combat prompt identity and schema", prepared)
|
||||
}
|
||||
if len(prepared.Messages) < 6 {
|
||||
t.Fatalf("prepared messages = %#v, want shared context, NPC grounding, and instructions", prepared.Messages)
|
||||
}
|
||||
referenceIndex := -1
|
||||
transcriptIndex := -1
|
||||
npcIndex := -1
|
||||
|
||||
@@ -41,7 +41,7 @@ func TestRegisterPromptAssetsAndPrepareEnemyEventPrompt(t *testing.T) {
|
||||
groundingIndices = append(groundingIndices, index)
|
||||
}
|
||||
}
|
||||
instructionIndex := renderedMessageIndex(t, prepared.Messages, "Extract Dungeons & Dragons enemy events")
|
||||
instructionIndex := len(prepared.Messages) - 1
|
||||
for _, index := range groundingIndices {
|
||||
if instructionIndex <= index {
|
||||
t.Fatalf("instruction index = %d, want after grounding index %d", instructionIndex, index)
|
||||
|
||||
@@ -3,7 +3,6 @@ package itemevents
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -43,9 +42,6 @@ func TestPromptAssetsPrepareItemEventPrompt(t *testing.T) {
|
||||
if prepared.PromptID != PromptID || prepared.OutputContract.SchemaPath != "dnd_item_events_llm.v1.json" {
|
||||
t.Fatalf("prepared prompt = %#v", prepared)
|
||||
}
|
||||
if len(prepared.Messages) < 5 {
|
||||
t.Fatalf("prepared messages = %#v, want shared policy, references, transcript, and instructions", prepared.Messages)
|
||||
}
|
||||
referenceIndex := -1
|
||||
transcriptIndex := -1
|
||||
for index, message := range prepared.Messages {
|
||||
@@ -91,16 +87,3 @@ func TestPromptAssetsDoNotLeakIntoMetadata(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPromptManifestReusesOnlySharedAssets(t *testing.T) {
|
||||
want := []string{
|
||||
"common-dnd-system.md",
|
||||
"common-dnd-extraction-evidence.md",
|
||||
"common-dnd-identity.md",
|
||||
"common-dnd-references.md",
|
||||
"common-dnd-transcript-chunk.md",
|
||||
}
|
||||
if !reflect.DeepEqual(promptAssetManifest.SharedFiles, want) {
|
||||
t.Fatalf("shared assets = %#v, want %#v", promptAssetManifest.SharedFiles, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package locations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -12,11 +11,6 @@ import (
|
||||
)
|
||||
|
||||
func TestRegisterPromptAssetsPreparesLocationPrompt(t *testing.T) {
|
||||
for _, name := range []string{"common-dnd-system.md", "common-dnd-identity.md", "common-dnd-references.md", "common-dnd-transcript-chunk.md", "common-dnd-extraction-evidence.md"} {
|
||||
if !slices.Contains(promptAssetManifest.SharedFiles, name) {
|
||||
t.Fatalf("shared prompt assets = %#v, missing %q", promptAssetManifest.SharedFiles, name)
|
||||
}
|
||||
}
|
||||
registry := llm.NewAssetRegistry()
|
||||
if err := RegisterPromptAssets(registry); err != nil {
|
||||
t.Fatalf("RegisterPromptAssets() error = %v", err)
|
||||
@@ -39,9 +33,6 @@ func TestRegisterPromptAssetsPreparesLocationPrompt(t *testing.T) {
|
||||
if prepared.OutputContract.SchemaPath != "dnd_locations_llm.v1.json" {
|
||||
t.Fatalf("output contract = %#v", prepared.OutputContract)
|
||||
}
|
||||
if len(prepared.Messages) < 5 {
|
||||
t.Fatalf("prepared messages = %#v, want shared policy, references, transcript, and instructions", prepared.Messages)
|
||||
}
|
||||
referenceIndex := -1
|
||||
transcriptIndex := -1
|
||||
for index, message := range prepared.Messages {
|
||||
|
||||
@@ -51,9 +51,6 @@ func TestRegisterPromptAssetsAndPrepareInteractionPrompt(t *testing.T) {
|
||||
if prepared.PromptID != PromptID || prepared.OutputContract.SchemaPath != "dnd_npc_interactions_llm.v1.json" {
|
||||
t.Fatalf("prepared prompt = %#v", prepared)
|
||||
}
|
||||
if len(prepared.Messages) < 6 {
|
||||
t.Fatalf("prepared messages = %#v, want shared context, NPC grounding, and instructions", prepared.Messages)
|
||||
}
|
||||
referenceIndex := -1
|
||||
transcriptIndex := -1
|
||||
npcIndex := -1
|
||||
|
||||
@@ -42,9 +42,6 @@ func TestRegisterPromptAssetsAndPrepareNPCPrompt(t *testing.T) {
|
||||
if prepared.PromptID != PromptID || prepared.OutputContract.SchemaPath != "dnd_npcs_llm.v1.json" {
|
||||
t.Fatalf("prepared prompt = %#v, want NPC prompt identity and wiring", prepared)
|
||||
}
|
||||
if len(prepared.Messages) < 5 {
|
||||
t.Fatalf("prepared messages = %#v, want shared policy, references, transcript, and instructions", prepared.Messages)
|
||||
}
|
||||
referenceIndex := -1
|
||||
transcriptIndex := -1
|
||||
for index, message := range prepared.Messages {
|
||||
|
||||
@@ -42,9 +42,6 @@ func TestRegisterPromptAssetsPreparesSceneDescriptionPrompt(t *testing.T) {
|
||||
if prepared.PromptID != PromptID || prepared.OutputContract.SchemaPath != "dnd_scene_descriptions_llm.v1.json" {
|
||||
t.Fatalf("prepared prompt = %#v, want scene-description prompt identity and schema wiring", prepared)
|
||||
}
|
||||
if len(prepared.Messages) < 5 {
|
||||
t.Fatalf("prepared messages = %#v, want shared policy, references, transcript, and instructions", prepared.Messages)
|
||||
}
|
||||
referenceIndex := -1
|
||||
transcriptIndex := -1
|
||||
for index, message := range prepared.Messages {
|
||||
|
||||
@@ -21,9 +21,6 @@ func TestPromptAssetsPrepareSpellPrompt(t *testing.T) {
|
||||
if prepared.OutputContract.SchemaPath != "dnd_spells_llm.v1.json" {
|
||||
t.Fatalf("schema path = %q, want LLM-only schema", prepared.OutputContract.SchemaPath)
|
||||
}
|
||||
if len(prepared.Messages) < 7 {
|
||||
t.Fatalf("prepared messages = %#v, want shared context, grounded inputs, and instructions", prepared.Messages)
|
||||
}
|
||||
indices := map[string]int{
|
||||
"spell-player": -1,
|
||||
"spell-transcript": -1,
|
||||
|
||||
@@ -12,18 +12,6 @@ import (
|
||||
)
|
||||
|
||||
func TestRegisterPromptAssetsPreparesLocationNormalizationPrompt(t *testing.T) {
|
||||
hasInstructions := false
|
||||
for _, file := range promptAssetManifest.ModuleFiles {
|
||||
if file.Name == "task.md" {
|
||||
t.Fatalf("module prompt files = %#v, want no retired task asset", promptAssetManifest.ModuleFiles)
|
||||
}
|
||||
if file.Name == "instructions.md" {
|
||||
hasInstructions = true
|
||||
}
|
||||
}
|
||||
if !hasInstructions {
|
||||
t.Fatalf("module prompt files = %#v, want instructions asset", promptAssetManifest.ModuleFiles)
|
||||
}
|
||||
registry := llm.NewAssetRegistry()
|
||||
if err := entityreconcile.RegisterSchemaAssets(registry); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -44,7 +32,7 @@ func TestRegisterPromptAssetsPreparesLocationNormalizationPrompt(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if prepared.OutputContract.SchemaPath != "dnd_entity_reconcile_llm.v1.json" || len(prepared.Messages) < 5 {
|
||||
if prepared.OutputContract.SchemaPath != "dnd_entity_reconcile_llm.v1.json" {
|
||||
t.Fatalf("prepared prompt = %#v", prepared)
|
||||
}
|
||||
for _, index := range []int{2, 4} {
|
||||
|
||||
@@ -2,7 +2,6 @@ package npcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -13,21 +12,6 @@ import (
|
||||
)
|
||||
|
||||
func TestRegisterPromptAssetsPreparesNormalizationPrompt(t *testing.T) {
|
||||
if want := []string{"common-dnd-system.md", "common-dnd-entity-reconciliation.md", "common-dnd-transcript-windows.md"}; !reflect.DeepEqual(promptAssetManifest.SharedFiles, want) {
|
||||
t.Fatalf("shared prompt assets = %#v, want %#v", promptAssetManifest.SharedFiles, want)
|
||||
}
|
||||
hasInstructions := false
|
||||
for _, file := range promptAssetManifest.ModuleFiles {
|
||||
if file.Name == "task.md" {
|
||||
t.Fatalf("module prompt files = %#v, want no retired task asset", promptAssetManifest.ModuleFiles)
|
||||
}
|
||||
if file.Name == "instructions.md" {
|
||||
hasInstructions = true
|
||||
}
|
||||
}
|
||||
if !hasInstructions {
|
||||
t.Fatalf("module prompt files = %#v, want instructions asset", promptAssetManifest.ModuleFiles)
|
||||
}
|
||||
if promptHash, err := promptAssetMetadata(); err != nil || promptHash == "" {
|
||||
t.Fatalf("promptAssetMetadata() = %q, %v; want prompt fingerprint", promptHash, err)
|
||||
}
|
||||
@@ -62,9 +46,6 @@ func TestRegisterPromptAssetsPreparesNormalizationPrompt(t *testing.T) {
|
||||
if prepared.PromptID != PromptID || prepared.OutputContract.SchemaPath != "dnd_entity_reconcile_llm.v1.json" {
|
||||
t.Fatalf("prepared prompt = %#v, want normalization prompt identity and schema", prepared)
|
||||
}
|
||||
if len(prepared.Messages) < 5 {
|
||||
t.Fatalf("prepared messages = %#v, want system, instructions, reconciliation policy, candidates, and transcript windows", prepared.Messages)
|
||||
}
|
||||
if prepared.Messages[0].Role != "system" {
|
||||
t.Fatalf("initial message role = %q, want system", prepared.Messages[0].Role)
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ func TestPromptAssetManifestPromptFS(t *testing.T) {
|
||||
manifest := PromptAssetManifest{
|
||||
ModuleDir: "dnd.test",
|
||||
ModuleFiles: []promptfs.ModulePromptFile{
|
||||
{Name: "dnd.test.yaml", Path: "assets/prompts/dnd.test.yaml"},
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "prompt.yaml", Path: "assets/prompts/prompt.yaml"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
},
|
||||
SharedFiles: []string{
|
||||
"common-dnd-system.md",
|
||||
@@ -27,16 +27,16 @@ func TestPromptAssetManifestPromptFS(t *testing.T) {
|
||||
}
|
||||
|
||||
fsys, err := manifest.PromptFS(fstest.MapFS{
|
||||
"assets/prompts/dnd.test.yaml": {Data: []byte("id: dnd.test")},
|
||||
"assets/prompts/task.md": {Data: []byte("task")},
|
||||
"assets/prompts/prompt.yaml": {Data: []byte("id: dnd.test")},
|
||||
"assets/prompts/instructions.md": {Data: []byte("instructions")},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("PromptFS() error = %v, want nil", err)
|
||||
}
|
||||
|
||||
wantModule := map[string]string{
|
||||
"assets/prompts/dnd.test/dnd.test.yaml": "id: dnd.test",
|
||||
"assets/prompts/dnd.test/task.md": "task",
|
||||
"assets/prompts/dnd.test/prompt.yaml": "id: dnd.test",
|
||||
"assets/prompts/dnd.test/instructions.md": "instructions",
|
||||
}
|
||||
for path, wantContent := range wantModule {
|
||||
content, err := fs.ReadFile(fsys, path)
|
||||
@@ -88,11 +88,11 @@ func TestPromptAssetManifestRejectsInvalidSharedNames(t *testing.T) {
|
||||
_, err := (PromptAssetManifest{
|
||||
ModuleDir: "dnd.test",
|
||||
ModuleFiles: []promptfs.ModulePromptFile{
|
||||
{Name: "dnd.test.yaml", Path: "assets/prompts/dnd.test.yaml"},
|
||||
{Name: "prompt.yaml", Path: "assets/prompts/prompt.yaml"},
|
||||
},
|
||||
SharedFiles: test.sharedFiles,
|
||||
}).PromptFS(fstest.MapFS{
|
||||
"assets/prompts/dnd.test.yaml": {Data: []byte("id: dnd.test")},
|
||||
"assets/prompts/prompt.yaml": {Data: []byte("id: dnd.test")},
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), test.wantError) {
|
||||
t.Fatalf("PromptFS() error = %v, want %q", err, test.wantError)
|
||||
@@ -105,10 +105,10 @@ func TestPromptAssetManifestRejectsMissingModuleFile(t *testing.T) {
|
||||
_, err := (PromptAssetManifest{
|
||||
ModuleDir: "dnd.test",
|
||||
ModuleFiles: []promptfs.ModulePromptFile{
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
},
|
||||
}).PromptFS(fstest.MapFS{})
|
||||
if err == nil || !strings.Contains(err.Error(), "read module prompt asset assets/prompts/task.md") {
|
||||
if err == nil || !strings.Contains(err.Error(), "read module prompt asset assets/prompts/instructions.md") {
|
||||
t.Fatalf("PromptFS() error = %v, want missing module asset context", err)
|
||||
}
|
||||
}
|
||||
@@ -129,11 +129,11 @@ func TestPromptAssetManifestRejectsMissingSharedFile(t *testing.T) {
|
||||
_, err := (PromptAssetManifest{
|
||||
ModuleDir: "dnd.test",
|
||||
ModuleFiles: []promptfs.ModulePromptFile{
|
||||
{Name: "dnd.test.yaml", Path: "assets/prompts/dnd.test.yaml"},
|
||||
{Name: "prompt.yaml", Path: "assets/prompts/prompt.yaml"},
|
||||
},
|
||||
SharedFiles: []string{name},
|
||||
}).PromptFS(fstest.MapFS{
|
||||
"assets/prompts/dnd.test.yaml": {Data: []byte("id: dnd.test")},
|
||||
"assets/prompts/prompt.yaml": {Data: []byte("id: dnd.test")},
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "read shared prompt asset "+path) {
|
||||
t.Fatalf("PromptFS() error = %v, want missing shared asset context", err)
|
||||
@@ -142,14 +142,14 @@ func TestPromptAssetManifestRejectsMissingSharedFile(t *testing.T) {
|
||||
|
||||
func TestPromptAssetManifestHashMatchesManifestParts(t *testing.T) {
|
||||
moduleFS := fstest.MapFS{
|
||||
"assets/prompts/dnd.test.yaml": {Data: []byte("id: dnd.test")},
|
||||
"assets/prompts/task.md": {Data: []byte("task")},
|
||||
"assets/prompts/prompt.yaml": {Data: []byte("id: dnd.test")},
|
||||
"assets/prompts/instructions.md": {Data: []byte("instructions")},
|
||||
}
|
||||
manifest := PromptAssetManifest{
|
||||
ModuleDir: "dnd.test",
|
||||
ModuleFiles: []promptfs.ModulePromptFile{
|
||||
{Name: "dnd.test.yaml", Path: "assets/prompts/dnd.test.yaml"},
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "prompt.yaml", Path: "assets/prompts/prompt.yaml"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
},
|
||||
SharedFiles: []string{
|
||||
"common-dnd-transcript-chunk.md",
|
||||
@@ -166,8 +166,8 @@ func TestPromptAssetManifestHashMatchesManifestParts(t *testing.T) {
|
||||
t.Fatalf("sharedAssetFS() error = %v, want nil", err)
|
||||
}
|
||||
want, err := llm.HashAssets([]llm.AssetHashPart{
|
||||
{FS: moduleFS, Path: "assets/prompts/dnd.test.yaml"},
|
||||
{FS: moduleFS, Path: "assets/prompts/task.md"},
|
||||
{FS: moduleFS, Path: "assets/prompts/prompt.yaml"},
|
||||
{FS: moduleFS, Path: "assets/prompts/instructions.md"},
|
||||
{FS: sharedFS, Path: "prompts/common-dnd-transcript-chunk.md"},
|
||||
{FS: sharedFS, Path: "prompts/common-dnd-system.md"},
|
||||
})
|
||||
@@ -178,8 +178,8 @@ func TestPromptAssetManifestHashMatchesManifestParts(t *testing.T) {
|
||||
t.Fatalf("Hash() = %q, want independently assembled manifest hash %q", got, want)
|
||||
}
|
||||
withUnused, err := llm.HashAssets([]llm.AssetHashPart{
|
||||
{FS: moduleFS, Path: "assets/prompts/dnd.test.yaml"},
|
||||
{FS: moduleFS, Path: "assets/prompts/task.md"},
|
||||
{FS: moduleFS, Path: "assets/prompts/prompt.yaml"},
|
||||
{FS: moduleFS, Path: "assets/prompts/instructions.md"},
|
||||
{FS: sharedFS, Path: "prompts/common-dnd-transcript-chunk.md"},
|
||||
{FS: sharedFS, Path: "prompts/common-dnd-system.md"},
|
||||
{FS: sharedFS, Path: "prompts/common-dnd-npcs.md"},
|
||||
|
||||
@@ -61,8 +61,8 @@ func TestRunnerProcessesSeriatimInputWithDNDSpellsExtractor(t *testing.T) {
|
||||
t.Fatalf("len(NormalizeOutputs) = %d, want 1", len(output.NormalizeOutputs))
|
||||
}
|
||||
serializedOutput := output.NormalizeOutputs[0]
|
||||
if serializedOutput.LaneID != "spells" || serializedOutput.Artifact.Schema.ID != spells.ResponseSchemaID || serializedOutput.Artifact.Schema.Version != spells.SchemaVersion {
|
||||
t.Fatalf("serialized output envelope = %#v, want dnd spells schema on spells lane", serializedOutput)
|
||||
if serializedOutput.LaneID != "spells" || serializedOutput.Artifact.Schema.ID != spellcodec.SchemaID || serializedOutput.Artifact.Schema.Version != spellcodec.SchemaVersion {
|
||||
t.Fatalf("serialized output envelope = %#v, want durable spell artifact schema on spells lane", serializedOutput)
|
||||
}
|
||||
response := decodeRunnerSpellResponse(t, serializedOutput.Artifact.Content)
|
||||
if len(response.SpellCasts) != 2 {
|
||||
|
||||
Reference in New Issue
Block a user