Centralize item and enemy event assets
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
package enemyevents
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed assets/schemas/dnd_enemy_events_llm.v1.json assets/prompts/*.yaml assets/prompts/*.md
|
||||
var embeddedAssets embed.FS
|
||||
@@ -1,55 +0,0 @@
|
||||
id: dnd.enemy_events
|
||||
version: "v1"
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: players
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: party
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: npcs
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: combat_turns
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: npc_interactions
|
||||
required: true
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-npcs.md
|
||||
- role: user
|
||||
content_file: ./grounding.md
|
||||
- role: user
|
||||
content_file: ./task.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_enemy_events_llm.v1.json
|
||||
repair_attempts: 0
|
||||
@@ -1,12 +0,0 @@
|
||||
Compact combat grounding is supplied below. It can guide attention and
|
||||
disambiguation, but it is not evidence. Do not derive an event, subject,
|
||||
outcome, or source range from either list. The current transcript alone must
|
||||
directly establish every returned event.
|
||||
|
||||
Combat-turn grounding:
|
||||
|
||||
{{ input "combat_turns" }}
|
||||
|
||||
Named combat-opponent grounding:
|
||||
|
||||
{{ input "npc_interactions" }}
|
||||
@@ -1,14 +0,0 @@
|
||||
Exclude party members, allies, neutral observers, mentioned-but-absent enemies,
|
||||
hazards, traps, environmental effects, uncertain allegiance, table talk,
|
||||
planning, hypotheses, recaps outside this passage, and downstream inference.
|
||||
|
||||
Do not infer an engagement or outcome from initiative, turn absence, damage,
|
||||
defeat, movement, a scene ending, combat-opponent grounding, or any auxiliary
|
||||
artifact. Auxiliary inputs can guide attention but cannot prove or supply an
|
||||
event. Cite only narrow current-transcript ranges that establish each event.
|
||||
|
||||
Return the `events` array even when no enemy event is established. Every event
|
||||
must contain only `name`, `kind`, and `source_refs`. Use exactly one kind:
|
||||
`engaged`, `killed`, `fled`, `captured`, or `incapacitated`. Each source range
|
||||
uses integer `start_unit_id` and `end_unit_id`; omit `source_id` because
|
||||
Notarius assigns the current source identity.
|
||||
@@ -1,20 +0,0 @@
|
||||
Extract Dungeons & Dragons enemy events from the supplied combat transcript.
|
||||
|
||||
Return an `engaged` event only when the transcript directly establishes that a
|
||||
subject is actively opposing the party in combat. Return `killed`, `fled`,
|
||||
`captured`, or `incapacitated` only when the transcript explicitly establishes
|
||||
that outcome. An outcome may share evidence with an engagement, and a later
|
||||
engagement or outcome for the same subject remains a separate observation.
|
||||
Emit at most one engagement for the same subject in this combat scene.
|
||||
|
||||
For `killed`, direct death or killing is required. For `fled`, the subject must
|
||||
explicitly escape, retreat, or leave combat to avoid continued engagement. For
|
||||
`captured`, the subject must be explicitly taken prisoner or secured under the
|
||||
party's control. For `incapacitated`, the subject must be explicitly unable to
|
||||
continue acting without being established as killed or captured.
|
||||
|
||||
Use a normalized NPC registry spelling when the transcript identifies that
|
||||
named NPC. A hostile creature without a registry entry is allowed. For unnamed
|
||||
individuals or groups, use only the narrowest transcript-grounded label, such
|
||||
as `Orcs`, `One orc`, or `Remaining orcs`; never invent member names, IDs, or
|
||||
quantities.
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.enemy_events.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["events"],
|
||||
"properties": {
|
||||
"events": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["name", "kind", "source_refs"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"kind": {"type": "string"},
|
||||
"source_refs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["start_unit_id", "end_unit_id"],
|
||||
"properties": {
|
||||
"start_unit_id": {"type": "integer"},
|
||||
"end_unit_id": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,10 @@ package enemyevents
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"sync"
|
||||
|
||||
rootassets "gitea.maximumdirect.net/eric/notarius/assets"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/promptfs"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||
@@ -14,10 +16,10 @@ const promptAssetRoot = "assets/prompts"
|
||||
var promptAssetManifest = shared.PromptAssetManifest{
|
||||
ModuleDir: "dnd.enemy_events",
|
||||
ModuleFiles: []promptfs.ModulePromptFile{
|
||||
{Name: "dnd.enemy_events.yaml", Path: "assets/prompts/dnd.enemy_events.yaml"},
|
||||
{Name: "grounding.md", Path: "assets/prompts/grounding.md"},
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
{Name: "dnd.enemy_events.yaml", Path: "prompts/dnd.enemy_events.yaml"},
|
||||
{Name: "grounding.md", Path: "prompts/grounding.md"},
|
||||
{Name: "task.md", Path: "prompts/task.md"},
|
||||
{Name: "instructions.md", Path: "prompts/instructions.md"},
|
||||
},
|
||||
SharedFiles: []string{
|
||||
"common-dnd-system.md",
|
||||
@@ -29,20 +31,41 @@ var promptAssetManifest = shared.PromptAssetManifest{
|
||||
},
|
||||
}
|
||||
|
||||
func moduleAssetFS() (fs.FS, error) {
|
||||
assets, err := fs.Sub(rootassets.FS(), "dnd/enemy-events")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("scope enemy-event assets: %w", err)
|
||||
}
|
||||
return assets, nil
|
||||
}
|
||||
|
||||
func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
||||
promptFS, err := promptAssetManifest.PromptFS(embeddedAssets)
|
||||
assets, err := moduleAssetFS()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
promptFS, err := promptAssetManifest.PromptFS(assets)
|
||||
if err != nil {
|
||||
return fmt.Errorf("prepare enemy-event prompt assets: %w", err)
|
||||
}
|
||||
if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil {
|
||||
return err
|
||||
}
|
||||
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
||||
schemas, err := fs.Sub(assets, "schemas")
|
||||
if err != nil {
|
||||
return fmt.Errorf("scope enemy-event schemas: %w", err)
|
||||
}
|
||||
return registry.RegisterSchemaFS(schemas, ".")
|
||||
}
|
||||
|
||||
func promptAssetMetadata() (string, error) {
|
||||
promptAssetHashOnce.Do(func() {
|
||||
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets)
|
||||
assets, err := moduleAssetFS()
|
||||
if err != nil {
|
||||
promptAssetHashErr = err
|
||||
return
|
||||
}
|
||||
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(assets)
|
||||
})
|
||||
return promptAssetHash, promptAssetHashErr
|
||||
}
|
||||
|
||||
@@ -11,11 +11,15 @@ const (
|
||||
)
|
||||
|
||||
func loadResponseSchema() (llm.ResponseSchema, error) {
|
||||
return llm.LoadResponseSchema(embeddedAssets, llm.ResponseSchemaDefinition{
|
||||
assets, err := moduleAssetFS()
|
||||
if err != nil {
|
||||
return llm.ResponseSchema{}, err
|
||||
}
|
||||
return llm.LoadResponseSchema(assets, llm.ResponseSchemaDefinition{
|
||||
Key: ResponseSchemaKey,
|
||||
ID: ResponseSchemaID,
|
||||
Version: SchemaVersion,
|
||||
Name: ResponseSchemaName,
|
||||
AssetPath: "assets/schemas/dnd_enemy_events_llm.v1.json",
|
||||
AssetPath: "schemas/dnd_enemy_events_llm.v1.json",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
package itemevents
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed assets/schemas/dnd_item_events_llm.v1.json assets/prompts/*.yaml assets/prompts/*.md
|
||||
var embeddedAssets embed.FS
|
||||
@@ -1,42 +0,0 @@
|
||||
id: dnd.item_events
|
||||
version: "v1"
|
||||
default_profile: dnd-extraction
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: application/json
|
||||
- name: players
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: party
|
||||
required: false
|
||||
content_type: text/plain
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/plain
|
||||
messages:
|
||||
- role: system
|
||||
content_file: ./sharedassets/common-dnd-system.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-identity.md
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-references.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-transcript.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
- role: user
|
||||
content_file: ./sharedassets/common-dnd-extraction-evidence.md
|
||||
- role: user
|
||||
content_file: ./task.md
|
||||
- role: user
|
||||
content_file: ./instructions.md
|
||||
cache_control:
|
||||
type: ephemeral
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: dnd_item_events_llm.v1.json
|
||||
repair_attempts: 0
|
||||
@@ -1,26 +0,0 @@
|
||||
Return one event only when the transcript establishes a meaningful item or
|
||||
currency occurrence. Use a concise observed item name and preserve the stated
|
||||
currency denomination. Set `quantity` to the explicitly stated integer, or to
|
||||
`null` when the transcript does not state one.
|
||||
|
||||
Use `discovered` when the party learns of or encounters an item without
|
||||
establishing possession. Use `acquired` when the party or a party member gains
|
||||
possession. Use `lost` when party possession ends through a gift, sale, payment,
|
||||
theft, abandonment, or destruction not caused by intended use. Use `consumed`
|
||||
when intended use depletes an expendable item. Monetary spending, purchases, and
|
||||
payments are always `lost`, not `consumed`. Classify currency as `consumed` only
|
||||
when the transcript explicitly describes it being physically destroyed or
|
||||
expended as a non-payment component. Use `transferred` only when possession
|
||||
moves between two distinct named party members.
|
||||
|
||||
Return both `from` and `to` for every event, using `null` when a holder does not
|
||||
apply. For `discovered`, set both holders to `null`. For `acquired`, set `from`
|
||||
to `null` and provide `to`; for `lost` and `consumed`, provide `from` and set
|
||||
`to` to `null`; and for `transferred`, provide both holders. Use `party` only
|
||||
for collective or unresolved party possession, never for either side of a
|
||||
transfer. Do not emit a transfer for a gift, sale, or payment outside the party.
|
||||
|
||||
Ordinary non-depleting use is not an event. Do not infer acquisition from a
|
||||
discovery, or discovery from an acquisition: emit both only when each is
|
||||
independently established. Every event needs at least one narrow transcript
|
||||
range. Return no lore, inventory totals, aliases, or unstated holder details.
|
||||
@@ -1,7 +0,0 @@
|
||||
Extract meaningful Dungeons & Dragons item and currency events established by
|
||||
the transcript. Record only discoveries and changes in party possession, with
|
||||
the transcript ranges that support each event.
|
||||
|
||||
This is an event history, not an inventory or ledger. Do not calculate balances,
|
||||
resolve item identity across records, or infer ownership that the transcript
|
||||
does not establish.
|
||||
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "notarius.dnd.item_events.llm",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["events"],
|
||||
"properties": {
|
||||
"events": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["name", "kind", "quantity", "from", "to", "source_refs"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"kind": {"type": "string"},
|
||||
"quantity": {"type": ["integer", "null"]},
|
||||
"from": {"type": ["string", "null"]},
|
||||
"to": {"type": ["string", "null"]},
|
||||
"source_refs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["start_segment", "end_segment"],
|
||||
"properties": {
|
||||
"start_segment": {"type": "integer"},
|
||||
"end_segment": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,10 @@ package itemevents
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"sync"
|
||||
|
||||
rootassets "gitea.maximumdirect.net/eric/notarius/assets"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/promptfs"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||
@@ -14,9 +16,9 @@ const promptAssetRoot = "assets/prompts"
|
||||
var promptAssetManifest = shared.PromptAssetManifest{
|
||||
ModuleDir: "dnd.item_events",
|
||||
ModuleFiles: []promptfs.ModulePromptFile{
|
||||
{Name: "dnd.item_events.yaml", Path: "assets/prompts/dnd.item_events.yaml"},
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
{Name: "dnd.item_events.yaml", Path: "prompts/dnd.item_events.yaml"},
|
||||
{Name: "task.md", Path: "prompts/task.md"},
|
||||
{Name: "instructions.md", Path: "prompts/instructions.md"},
|
||||
},
|
||||
SharedFiles: []string{
|
||||
"common-dnd-system.md",
|
||||
@@ -27,20 +29,41 @@ var promptAssetManifest = shared.PromptAssetManifest{
|
||||
},
|
||||
}
|
||||
|
||||
func moduleAssetFS() (fs.FS, error) {
|
||||
assets, err := fs.Sub(rootassets.FS(), "dnd/item-events")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("scope item-event assets: %w", err)
|
||||
}
|
||||
return assets, nil
|
||||
}
|
||||
|
||||
func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
||||
promptFS, err := promptAssetManifest.PromptFS(embeddedAssets)
|
||||
assets, err := moduleAssetFS()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
promptFS, err := promptAssetManifest.PromptFS(assets)
|
||||
if err != nil {
|
||||
return fmt.Errorf("prepare item event prompt assets: %w", err)
|
||||
}
|
||||
if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil {
|
||||
return err
|
||||
}
|
||||
return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas")
|
||||
schemas, err := fs.Sub(assets, "schemas")
|
||||
if err != nil {
|
||||
return fmt.Errorf("scope item-event schemas: %w", err)
|
||||
}
|
||||
return registry.RegisterSchemaFS(schemas, ".")
|
||||
}
|
||||
|
||||
func promptAssetMetadata() (string, error) {
|
||||
promptAssetHashOnce.Do(func() {
|
||||
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets)
|
||||
assets, err := moduleAssetFS()
|
||||
if err != nil {
|
||||
promptAssetHashErr = err
|
||||
return
|
||||
}
|
||||
promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(assets)
|
||||
})
|
||||
return promptAssetHash, promptAssetHashErr
|
||||
}
|
||||
|
||||
@@ -11,11 +11,15 @@ const (
|
||||
)
|
||||
|
||||
func loadResponseSchema() (llm.ResponseSchema, error) {
|
||||
return llm.LoadResponseSchema(embeddedAssets, llm.ResponseSchemaDefinition{
|
||||
assets, err := moduleAssetFS()
|
||||
if err != nil {
|
||||
return llm.ResponseSchema{}, err
|
||||
}
|
||||
return llm.LoadResponseSchema(assets, llm.ResponseSchemaDefinition{
|
||||
Key: ResponseSchemaKey,
|
||||
ID: ResponseSchemaID,
|
||||
Version: SchemaVersion,
|
||||
Name: ResponseSchemaName,
|
||||
AssetPath: "assets/schemas/dnd_item_events_llm.v1.json",
|
||||
AssetPath: "schemas/dnd_item_events_llm.v1.json",
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user