Added prompts to determine the starting and ending segments of a D&D session transcript

This commit is contained in:
2026-05-16 21:06:41 -05:00
parent 7f76534af0
commit d87e90f93b
9 changed files with 229 additions and 29 deletions

View File

@@ -0,0 +1,6 @@
id: openrouter-opus
endpoint: https://openrouter.ai/api/v1
model: "~anthropic/claude-opus-latest"
reasoning_effort: high
timeout_seconds: 180
api_key_env: OPENROUTER_API_KEY

64
prompts/bounds.system.md Normal file
View File

@@ -0,0 +1,64 @@
You are a transcript boundary detector for a Dungeons & Dragons actual-play session.
Your task is to identify the contiguous range of transcript segments that covers the actual gameplay session, excluding pre-session setup chatter and post-session banter.
The transcript consists of speaker segments. Each segment has an `id`, a `speaker`, and text. Segment IDs are stable and should be used as the boundary markers.
Definitions:
Actual gameplay includes:
- the DM beginning the session recap or scene setup;
- the DM narrating the current in-world situation;
- players discussing in-character decisions, tactics, exploration, combat, travel, spellcasting, roleplay, or plans;
- rules discussion that occurs during gameplay and affects in-world decisions;
- end-of-session narration, cliffhanger setup, combat state, or next-session handoff.
Pre-session chatter includes:
- greetings, microphone checks, recording setup, waiting for players, food/drink talk, scheduling before play begins, casual conversation, jokes, or unrelated discussion before the DM begins the session.
Post-session banter includes:
- discussion after the DM has clearly ended play;
- scheduling the next session;
- post-session rules debate that does not change the in-world outcome;
- player commentary, jokes, debrief, technical discussion, or unrelated conversation after the gameplay endpoint.
Boundary rules:
- Identify one continuous inclusive range: `start_segment_id` through `end_segment_id`.
- The `start_segment_id` should be the first segment that is meaningfully part of the session: usually the DMs opening recap, scene-setting, or the first in-world/player decision after pre-session chatter.
- The `end_segment_id` should be the last segment that is meaningfully part of gameplay: usually the final in-world narration, final adjudicated action, combat state, cliffhanger, or “well pick up there next time” moment.
- If a segment contains both chatter and gameplay, include it if any meaningful gameplay occurs in that segment.
- Do not exclude mid-session breaks, jokes, or tangents if they occur between the start and end of gameplay. The goal is to remove only the pre-session prefix and post-session suffix.
- Do not skip the opening recap, planning, recovery, shopping, travel preparation, or rules adjudication merely because it is less dramatic than later combat. If it occurs after gameplay has begun and affects the sessions state, it belongs inside the range.
- When uncertain, choose a slightly wider range. It is better to include a small amount of chatter than to exclude actual gameplay.
- Players may provide spoken indications that the gameplay is beginning or ending. For example, speech such as "Are we ready to get started?" is a strong indication that gameplay is beginning. Likewise, speech such as "Should we end it here?" is a strong indication that gameplay is ending.
- Do not infer missing segment IDs. Only use IDs that appear in the transcript.
- Do not summarize the session.
Return only valid JSON. Do not include markdown, commentary, or prose outside the JSON object.
Use this JSON shape:
{
"start_segment_id": 0,
"end_segment_id": 0,
"confidence": "high",
"start_boundary_reason": "",
"end_boundary_reason": "",
"start_evidence": {
"segment_id": 0,
"speaker": "",
"text_excerpt": ""
},
"end_evidence": {
"segment_id": 0,
"speaker": "",
"text_excerpt": ""
},
"excluded_prefix_summary": "",
"excluded_suffix_summary": "",
"warnings": []
}
The `confidence` value must be one of: "high", "medium", or "low".
Keep evidence excerpts short. Quote only enough text to justify the boundary.

16
prompts/bounds.user.md Normal file
View File

@@ -0,0 +1,16 @@
Identify the inclusive segment ID range that covers the actual gameplay session in the transcript below.
Use the first gameplay segment as `start_segment_id`.
Use the final gameplay segment as `end_segment_id`.
Remember:
- Include the DMs opening recap or scene-setting if present.
- Include the final in-world narration, unresolved combat state, cliffhanger, or explicit handoff to next session.
- Exclude only pre-session chatter before gameplay begins and post-session banter after gameplay ends.
- Return only valid JSON using the required schema.
- Do not skip the opening recap, planning, recovery, shopping, travel preparation, or rules adjudication merely because it is less dramatic than later combat. If it occurs after gameplay has begun and affects the sessions state, it belongs inside the range.
Transcript:
<<<CURRENT_SESSION_TRANSCRIPT
{{input "transcript"}}
CURRENT_SESSION_TRANSCRIPT>>>

19
prompts/bounds.yml Normal file
View File

@@ -0,0 +1,19 @@
id: dnd.session_bounds
version: "1.0.0"
default_profile: local-gemma4
description: Review D&D session transcript and identify starting and ending segments for actual gameplay.
inputs:
- name: transcript
required: true
content_type: application/json
description: Structured recap source transcript
messages:
- role: system
content_file: ./bounds.system.md
- role: user
content_file: ./bounds.user.md
output:
format: json
validation_mode: json_schema
schema_path: bounds.schema.json
repair_attempts: 0

View File

@@ -13,9 +13,9 @@ inputs:
description: Optional glossary context
messages:
- role: system
content_file: ./session_recap.system.md
content_file: ./recap.system.md
- role: user
content_file: ./session_recap.user.md
content_file: ./recap.user.md
output:
format: markdown
validation_mode: basic

122
schemas/bounds.schema.json Normal file
View File

@@ -0,0 +1,122 @@
{
"schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"description": "Identifies the inclusive range of transcript segment IDs that covers the actual Dungeons & Dragons gameplay session, excluding pre-session chatter and post-session banter.",
"required": [
"trim_action",
"start_segment_id",
"end_segment_id",
"confidence",
"start_boundary_reason",
"end_boundary_reason",
"start_evidence",
"end_evidence",
"excluded_prefix_summary",
"excluded_suffix_summary",
"warnings"
],
"additionalProperties": false,
"properties": {
"trim_action": {
"type": "string",
"description": "Whether the transcript should be trimmed, appears to need no trimming, or is too ambiguous for confident trimming.",
"enum": [
"trim",
"no_trim_needed",
"uncertain"
]
},
"start_segment_id": {
"type": "integer",
"description": "The inclusive segment ID where actual gameplay begins. This should be the first meaningful gameplay segment, such as the DM's opening recap, scene-setting, or the first in-world decision.",
"minimum": 0
},
"end_segment_id": {
"type": "integer",
"description": "The inclusive segment ID where actual gameplay ends. This should be the final meaningful gameplay segment, such as final in-world narration, an adjudicated action, a cliffhanger, or a next-session handoff.",
"minimum": 0
},
"confidence": {
"type": "string",
"description": "Confidence in the selected boundaries.",
"enum": [
"high",
"medium",
"low"
]
},
"start_boundary_reason": {
"type": "string",
"description": "Brief explanation of why the selected start segment is the first gameplay segment."
},
"end_boundary_reason": {
"type": "string",
"description": "Brief explanation of why the selected end segment is the last gameplay segment."
},
"start_evidence": {
"type": "object",
"description": "Short evidence supporting the selected start boundary.",
"properties": {
"segment_id": {
"type": "integer",
"description": "The segment ID used as evidence for the start boundary.",
"minimum": 0
},
"speaker": {
"type": "string",
"description": "The speaker of the evidence segment."
},
"text_excerpt": {
"type": "string",
"description": "A short excerpt from the evidence segment showing why gameplay begins here."
}
},
"required": [
"segment_id",
"speaker",
"text_excerpt"
],
"additionalProperties": false
},
"end_evidence": {
"type": "object",
"description": "Short evidence supporting the selected end boundary.",
"properties": {
"segment_id": {
"type": "integer",
"description": "The segment ID used as evidence for the end boundary.",
"minimum": 0
},
"speaker": {
"type": "string",
"description": "The speaker of the evidence segment."
},
"text_excerpt": {
"type": "string",
"description": "A short excerpt from the evidence segment showing why gameplay ends here."
}
},
"required": [
"segment_id",
"speaker",
"text_excerpt"
],
"additionalProperties": false
},
"excluded_prefix_summary": {
"type": "string",
"description": "Brief summary of the material excluded before the start segment. Use an empty string if no prefix was excluded."
},
"excluded_suffix_summary": {
"type": "string",
"description": "Brief summary of the material excluded after the end segment. Use an empty string if no suffix was excluded."
},
"warnings": {
"type": "array",
"description": "Any caveats, ambiguities, or reasons the boundary selection may need human review.",
"items": {
"type": "string"
}
}
}
}

View File

@@ -1,27 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.local/structured_events.schema.json",
"type": "object",
"required": ["summary", "events"],
"properties": {
"summary": {
"type": "string",
"minLength": 1
},
"events": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["title", "type"],
"properties": {
"title": {"type": "string", "minLength": 1},
"type": {"type": "string", "enum": ["combat", "social", "travel", "discovery", "other"]},
"notes": {"type": "string"}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
}