Define D&D prompt transcript scopes

This commit is contained in:
2026-08-05 14:33:00 +00:00
parent bad5db3ef3
commit 257bca0dc2
39 changed files with 87 additions and 59 deletions

View File

@@ -27,7 +27,7 @@ messages:
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-chunk.md
cache_control:
type: ephemeral
- role: user

View File

@@ -33,7 +33,7 @@ messages:
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-chunk.md
cache_control:
type: ephemeral
- role: user

View File

@@ -24,7 +24,7 @@ messages:
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-chunk.md
cache_control:
type: ephemeral
- role: user

View File

@@ -27,7 +27,7 @@ messages:
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-chunk.md
cache_control:
type: ephemeral
- role: user

View File

@@ -24,7 +24,7 @@ messages:
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-chunk.md
cache_control:
type: ephemeral
- role: user

View File

@@ -20,7 +20,7 @@ messages:
- role: user
content_file: ./candidates.md
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-windows.md
cache_control:
type: ephemeral
output:

View File

@@ -27,7 +27,7 @@ messages:
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-chunk.md
cache_control:
type: ephemeral
- role: user

View File

@@ -24,7 +24,7 @@ messages:
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-chunk.md
cache_control:
type: ephemeral
- role: user

View File

@@ -20,7 +20,7 @@ messages:
- role: user
content_file: ./candidates.md
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-windows.md
cache_control:
type: ephemeral
output:

View File

@@ -24,7 +24,7 @@ messages:
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-chunk.md
cache_control:
type: ephemeral
- role: user

View File

@@ -26,7 +26,7 @@ messages:
- role: user
content_file: ./instructions.md
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-full.md
cache_control:
type: ephemeral
output:

View File

@@ -1,14 +1,7 @@
Transcript units are the only evidence for extracted events and factual claims.
Campaign and registry references may disambiguate names, aliases, speakers, or
other identities, but they do not establish events, participation, effects, or
source evidence.
Every reported factual claim must be supported by cited transcript units. Use
integer `start_unit_id` and `end_unit_id` values from the transcript. Omit
`source_id`; Notarius assigns the current source identity.
When supporting evidence is non-contiguous, use multiple narrow ranges rather
than a broad range that bridges unrelated conversation.
Return exactly one JSON object and no explanatory text. Output only the
configured JSON object and fields defined by its response schema.

View File

@@ -1,6 +1,7 @@
You work with Dungeons & Dragons gameplay transcripts.
You process Dungeons & Dragons gameplay transcripts.
Use only the provided transcript and reference material. Source text may contain
transcription errors, repeated lines, incomplete sentences, and misheard proper
nouns. Reference material, when present, is supporting context only and must not
be treated as a source of extracted events by itself.
Rely only on the supplied inputs. They may contain transcription errors,
repeated lines, incomplete sentences, and misheard proper nouns.
Return exactly one JSON object that conforms to the configured response schema,
with no explanatory prose.

View File

@@ -0,0 +1,5 @@
One extraction chunk from a Dungeons & Dragons gameplay transcript is provided
below. Report and infer only what is within this chunk. Its unit IDs retain
their source-wide meaning.
{{ input "transcript" }}

View File

@@ -0,0 +1,4 @@
The complete ordered transcript of this Dungeons & Dragons gameplay session is
provided below. It may contain multiple scenes.
{{ input "transcript" }}

View File

@@ -0,0 +1,6 @@
Selected Dungeons & Dragons gameplay transcript evidence windows are provided
below. They may be incomplete, non-contiguous, or overlapping. Use them to
evaluate candidate identity, but do not treat absence outside these windows as
evidence.
{{ input "transcript" }}

View File

@@ -1,3 +0,0 @@
A transcript of a Dungeons & Dragons gameplay session is provided below.
{{ input "transcript" }}

View File

@@ -30,7 +30,7 @@ messages:
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
content_file: ./sharedassets/common-dnd-transcript-chunk.md
cache_control:
type: ephemeral
- role: user

View File

@@ -159,20 +159,20 @@ func TestProductionCatalogCoversMaintainedConfigurations(t *testing.T) {
"dnd.scenes/instructions.md",
"dnd.scenes/sharedassets/common-dnd-references.md",
"dnd.scenes/sharedassets/common-dnd-system.md",
"dnd.scenes/sharedassets/common-dnd-transcript.md",
"dnd.scenes/sharedassets/common-dnd-transcript-full.md",
"dnd.scenes/task.md",
"dnd.spells/dnd.spells.yaml",
"dnd.spells/catalog.md",
"dnd.spells/instructions.md",
"dnd.spells/sharedassets/common-dnd-references.md",
"dnd.spells/sharedassets/common-dnd-system.md",
"dnd.spells/sharedassets/common-dnd-transcript.md",
"dnd.spells/sharedassets/common-dnd-transcript-chunk.md",
"dnd.spells/task.md",
"dnd.combat_turns/dnd.combat_turns.yaml",
"dnd.combat_turns/instructions.md",
"dnd.combat_turns/sharedassets/common-dnd-references.md",
"dnd.combat_turns/sharedassets/common-dnd-system.md",
"dnd.combat_turns/sharedassets/common-dnd-transcript.md",
"dnd.combat_turns/sharedassets/common-dnd-transcript-chunk.md",
"dnd.combat_turns/task.md",
"dnd.item_events/dnd.item_events.yaml",
"dnd.item_events/instructions.md",
@@ -180,7 +180,7 @@ func TestProductionCatalogCoversMaintainedConfigurations(t *testing.T) {
"dnd.item_events/sharedassets/common-dnd-identity.md",
"dnd.item_events/sharedassets/common-dnd-references.md",
"dnd.item_events/sharedassets/common-dnd-system.md",
"dnd.item_events/sharedassets/common-dnd-transcript.md",
"dnd.item_events/sharedassets/common-dnd-transcript-chunk.md",
"dnd.item_events/task.md",
"dnd.enemy_events/dnd.enemy_events.yaml",
"dnd.enemy_events/grounding.md",

View File

@@ -22,7 +22,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
},
SharedFiles: []string{
"common-dnd-system.md",
"common-dnd-transcript.md",
"common-dnd-transcript-full.md",
"common-dnd-references.md",
},
}

View File

@@ -3,6 +3,7 @@ package scenes
import (
"context"
"encoding/json"
"slices"
"strings"
"testing"
"time"
@@ -12,6 +13,9 @@ import (
)
func TestPromptAssetsPrepareTranscriptAndTaskMessages(t *testing.T) {
if !slices.Contains(promptAssetManifest.SharedFiles, "common-dnd-transcript-full.md") {
t.Fatalf("shared prompt assets = %#v, want complete-session transcript scope", promptAssetManifest.SharedFiles)
}
transcript := []byte(`{"sentinel":"scene-transcript"}`)
prepared := prepareScenesPrompt(t, transcript, "scene-players", "scene-party", "scene-glossary")

View File

@@ -24,7 +24,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
"common-dnd-system.md",
"common-dnd-extraction-evidence.md",
"common-dnd-identity.md",
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
"common-dnd-references.md",
"common-dnd-npcs.md",
},

View File

@@ -25,7 +25,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
"common-dnd-system.md",
"common-dnd-extraction-evidence.md",
"common-dnd-identity.md",
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
"common-dnd-references.md",
"common-dnd-npcs.md",
},

View File

@@ -25,7 +25,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
"common-dnd-extraction-evidence.md",
"common-dnd-identity.md",
"common-dnd-references.md",
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
},
}

View File

@@ -68,7 +68,7 @@ func TestPromptManifestReusesOnlySharedAssets(t *testing.T) {
"common-dnd-extraction-evidence.md",
"common-dnd-identity.md",
"common-dnd-references.md",
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
}
if !reflect.DeepEqual(promptAssetManifest.SharedFiles, want) {
t.Fatalf("shared assets = %#v, want %#v", promptAssetManifest.SharedFiles, want)

View File

@@ -25,7 +25,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
"common-dnd-system.md",
"common-dnd-extraction-evidence.md",
"common-dnd-identity.md",
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
"common-dnd-references.md",
},
}

View File

@@ -24,7 +24,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
"common-dnd-system.md",
"common-dnd-extraction-evidence.md",
"common-dnd-identity.md",
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
"common-dnd-references.md",
},
}

View File

@@ -12,7 +12,7 @@ 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.md", "common-dnd-extraction-evidence.md"} {
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)
}

View File

@@ -24,7 +24,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
"common-dnd-system.md",
"common-dnd-extraction-evidence.md",
"common-dnd-identity.md",
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
"common-dnd-references.md",
"common-dnd-npcs.md",
},

View File

@@ -24,7 +24,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
"common-dnd-system.md",
"common-dnd-extraction-evidence.md",
"common-dnd-identity.md",
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
"common-dnd-references.md",
},
}

View File

@@ -24,7 +24,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
"common-dnd-system.md",
"common-dnd-identity.md",
"common-dnd-references.md",
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
},
}

View File

@@ -25,7 +25,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
"common-dnd-system.md",
"common-dnd-extraction-evidence.md",
"common-dnd-identity.md",
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
"common-dnd-references.md",
"common-dnd-npcs.md",
},

View File

@@ -20,7 +20,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
{Name: "task.md", Path: "prompts/task.md"},
{Name: "candidates.md", Path: "prompts/candidates.md"},
},
SharedFiles: []string{"common-dnd-system.md", "common-dnd-entity-reconciliation.md", "common-dnd-transcript.md"},
SharedFiles: []string{"common-dnd-system.md", "common-dnd-entity-reconciliation.md", "common-dnd-transcript-windows.md"},
}
func moduleAssetFS() (fs.FS, error) {

View File

@@ -23,7 +23,7 @@ var promptAssetManifest = shared.PromptAssetManifest{
SharedFiles: []string{
"common-dnd-system.md",
"common-dnd-entity-reconciliation.md",
"common-dnd-transcript.md",
"common-dnd-transcript-windows.md",
},
}

View File

@@ -13,7 +13,7 @@ import (
)
func TestRegisterPromptAssetsPreparesNormalizationPrompt(t *testing.T) {
if want := []string{"common-dnd-system.md", "common-dnd-entity-reconciliation.md", "common-dnd-transcript.md"}; !reflect.DeepEqual(promptAssetManifest.SharedFiles, want) {
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)
}
if promptHash, err := promptAssetMetadata(); err != nil || promptHash == "" {

View File

@@ -11,6 +11,8 @@ import (
combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
enemyeventextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/enemyevents"
itemeventextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/itemevents"
locationoccurrenceextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/locationoccurrences"
locationextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/locations"
interactionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcinteractions"
npcextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcs"
scenedescriptionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/scenedescriptions"
@@ -46,6 +48,7 @@ func TestExtractionPromptsShareRenderedPrefix(t *testing.T) {
inputSentinels []string
}{
{name: "npcs", promptID: npcextract.PromptID, promptVersion: npcextract.SchemaVersion, inputs: commonInputs},
{name: "locations", promptID: locationextract.PromptID, promptVersion: locationextract.SchemaVersion, inputs: commonInputs},
{name: "item events", promptID: itemeventextract.PromptID, promptVersion: itemeventextract.SchemaVersion, inputs: commonInputs},
{name: "scene descriptions", promptID: scenedescriptionextract.PromptID, promptVersion: scenedescriptionextract.SchemaVersion, inputs: commonInputs},
{
@@ -77,6 +80,15 @@ func TestExtractionPromptsShareRenderedPrefix(t *testing.T) {
}),
inputSentinels: []string{npcSentinel},
},
{
name: "location occurrences",
promptID: locationoccurrenceextract.PromptID,
promptVersion: locationoccurrenceextract.SchemaVersion,
inputs: withPromptInputs(commonInputs, map[string]promptkit.ArtifactRef{
"locations": promptkit.Inline(`{"sentinel":"location-registry-sentinel"}`),
}),
inputSentinels: []string{"location-registry-sentinel"},
},
{
name: "spells",
promptID: spellextract.PromptID,

View File

@@ -300,31 +300,31 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
"dnd.scenes/instructions.md",
"dnd.scenes/sharedassets/common-dnd-references.md",
"dnd.scenes/sharedassets/common-dnd-system.md",
"dnd.scenes/sharedassets/common-dnd-transcript.md",
"dnd.scenes/sharedassets/common-dnd-transcript-full.md",
"dnd.scenes/task.md",
"dnd.spells/dnd.spells.yaml",
"dnd.spells/instructions.md",
"dnd.spells/sharedassets/common-dnd-references.md",
"dnd.spells/sharedassets/common-dnd-system.md",
"dnd.spells/sharedassets/common-dnd-transcript.md",
"dnd.spells/sharedassets/common-dnd-transcript-chunk.md",
"dnd.spells/task.md",
"dnd.npcs/dnd.npcs.yaml",
"dnd.npcs/instructions.md",
"dnd.npcs/sharedassets/common-dnd-references.md",
"dnd.npcs/sharedassets/common-dnd-system.md",
"dnd.npcs/sharedassets/common-dnd-transcript.md",
"dnd.npcs/sharedassets/common-dnd-transcript-chunk.md",
"dnd.npcs/task.md",
"dnd.npcs.normalize/candidates.md",
"dnd.npcs.normalize/dnd.npcs.normalize.yaml",
"dnd.npcs.normalize/sharedassets/common-dnd-entity-reconciliation.md",
"dnd.npcs.normalize/sharedassets/common-dnd-system.md",
"dnd.npcs.normalize/sharedassets/common-dnd-transcript.md",
"dnd.npcs.normalize/sharedassets/common-dnd-transcript-windows.md",
"dnd.npcs.normalize/task.md",
"dnd.combat_turns/dnd.combat_turns.yaml",
"dnd.combat_turns/instructions.md",
"dnd.combat_turns/sharedassets/common-dnd-references.md",
"dnd.combat_turns/sharedassets/common-dnd-system.md",
"dnd.combat_turns/sharedassets/common-dnd-transcript.md",
"dnd.combat_turns/sharedassets/common-dnd-transcript-chunk.md",
"dnd.combat_turns/task.md",
"dnd.enemy_events/dnd.enemy_events.yaml",
"dnd.enemy_events/grounding.md",
@@ -336,7 +336,7 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
"dnd.item_events/sharedassets/common-dnd-identity.md",
"dnd.item_events/sharedassets/common-dnd-references.md",
"dnd.item_events/sharedassets/common-dnd-system.md",
"dnd.item_events/sharedassets/common-dnd-transcript.md",
"dnd.item_events/sharedassets/common-dnd-transcript-chunk.md",
"dnd.item_events/task.md",
"dnd.npc_interactions/dnd.npc_interactions.yaml",
"dnd.npc_interactions/instructions.md",
@@ -347,7 +347,7 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
"dnd.scene_descriptions/sharedassets/common-dnd-identity.md",
"dnd.scene_descriptions/sharedassets/common-dnd-references.md",
"dnd.scene_descriptions/sharedassets/common-dnd-system.md",
"dnd.scene_descriptions/sharedassets/common-dnd-transcript.md",
"dnd.scene_descriptions/sharedassets/common-dnd-transcript-chunk.md",
"dnd.scene_descriptions/task.md",
})
assertAssetNamesContain(t, assets.SchemaFS, []string{

View File

@@ -23,7 +23,9 @@ var sharedPromptPaths = map[string]string{
"common-dnd-system.md": "prompts/common-dnd-system.md",
"common-dnd-extraction-evidence.md": "prompts/common-dnd-extraction-evidence.md",
"common-dnd-identity.md": "prompts/common-dnd-identity.md",
"common-dnd-transcript.md": "prompts/common-dnd-transcript.md",
"common-dnd-transcript-full.md": "prompts/common-dnd-transcript-full.md",
"common-dnd-transcript-chunk.md": "prompts/common-dnd-transcript-chunk.md",
"common-dnd-transcript-windows.md": "prompts/common-dnd-transcript-windows.md",
"common-dnd-references.md": "prompts/common-dnd-references.md",
"common-dnd-npcs.md": "prompts/common-dnd-npcs.md",
"common-dnd-entity-reconciliation.md": "prompts/common-dnd-entity-reconciliation.md",

View File

@@ -20,7 +20,9 @@ func TestPromptAssetManifestPromptFS(t *testing.T) {
},
SharedFiles: []string{
"common-dnd-system.md",
"common-dnd-transcript.md",
"common-dnd-transcript-full.md",
"common-dnd-transcript-chunk.md",
"common-dnd-transcript-windows.md",
},
}
@@ -47,7 +49,9 @@ func TestPromptAssetManifestPromptFS(t *testing.T) {
}
for _, path := range []string{
"assets/prompts/dnd.test/sharedassets/common-dnd-system.md",
"assets/prompts/dnd.test/sharedassets/common-dnd-transcript.md",
"assets/prompts/dnd.test/sharedassets/common-dnd-transcript-full.md",
"assets/prompts/dnd.test/sharedassets/common-dnd-transcript-chunk.md",
"assets/prompts/dnd.test/sharedassets/common-dnd-transcript-windows.md",
} {
content, err := fs.ReadFile(fsys, path)
if err != nil {
@@ -148,7 +152,7 @@ func TestPromptAssetManifestHashMatchesManifestParts(t *testing.T) {
{Name: "task.md", Path: "assets/prompts/task.md"},
},
SharedFiles: []string{
"common-dnd-transcript.md",
"common-dnd-transcript-chunk.md",
"common-dnd-system.md",
},
}
@@ -164,7 +168,7 @@ func TestPromptAssetManifestHashMatchesManifestParts(t *testing.T) {
want, err := llm.HashAssets([]llm.AssetHashPart{
{FS: moduleFS, Path: "assets/prompts/dnd.test.yaml"},
{FS: moduleFS, Path: "assets/prompts/task.md"},
{FS: sharedFS, Path: "prompts/common-dnd-transcript.md"},
{FS: sharedFS, Path: "prompts/common-dnd-transcript-chunk.md"},
{FS: sharedFS, Path: "prompts/common-dnd-system.md"},
})
if err != nil {
@@ -176,7 +180,7 @@ func TestPromptAssetManifestHashMatchesManifestParts(t *testing.T) {
withUnused, err := llm.HashAssets([]llm.AssetHashPart{
{FS: moduleFS, Path: "assets/prompts/dnd.test.yaml"},
{FS: moduleFS, Path: "assets/prompts/task.md"},
{FS: sharedFS, Path: "prompts/common-dnd-transcript.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"},
})