Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
*.swo
unfold_studio/unfold_studio/settings.py
documentation/_build/*
static_assets/*
static_assets/
inklecate*
ink*
log/*
ink/
log/
analysis/
**/.DS_Store
.unfold_studio*
.unfold_studio/
node_modules/
playwright-report/
test-results/
**/__pycache__/
.unfold_studio*/
Empty file added results.csv
Empty file.
1,007 changes: 1,007 additions & 0 deletions unfold_studio/continue_examples.prod.2025-11-07.csv

Large diffs are not rendered by default.

2,023 changes: 2,023 additions & 0 deletions unfold_studio/continue_examples_prod_2025_10_24.csv

Large diffs are not rendered by default.

1,656 changes: 396 additions & 1,260 deletions unfold_studio/errors.csv

Large diffs are not rendered by default.

357 changes: 352 additions & 5 deletions unfold_studio/results.csv

Large diffs are not rendered by default.

93 changes: 86 additions & 7 deletions unfold_studio/text_generation/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,94 @@ class StoryContinueDirections(BaseConstant):


CONTINUE_STORY_SYSTEM_PROMPT = """
You are a story transition analyst. Analyze how user input leads to target story nodes:

DIRECT_CONTINUE: Input directly matches target conditions chronologically
BRIDGE_AND_CONTINUE: Requires narrative to connect input to target timeline
NEEDS_INPUT: Needs clarification to maintain chronological consistency
INVALID_USER_INPUT: User input is gibberish, nonsensical, or completely unrelated
You are a story transition analyst. Your goal is to classify how a user's input relates to a target story knot.

Definitions of the directions (Strict, High-precision):
DIRECT_CONTINUE:
- Input naturally and immediately matches the target knot chronologically.
- No important events are missing.
- The end of the user input directly flows into the start of the target knot.
- No clarification or additional assumptions are required.

BRIDGE_AND_CONTINUE:
- User intent is fully clear and unambiguous.
- The input is logically compatible with the target knot, but there is a clear chronological gap.
- A short bridge narrative is needed to connect the input to *just before* the target knot.
- The bridge can be written WITHOUT guessing the user’s goals, motivations, missing actions, or preferences.

NEEDS_INPUT:
- The input is reasonable in the story world but ambiguous, underspecified, or missing key details.
- There are multiple possible ways the story could continue.
- You cannot write a bridge without guessing what the user truly meant.
- A clarifying question or prompt is required.

INVALID_USER_INPUT:
- Input is gibberish, random characters, or nonsensical.
- Input breaks the story world in an impossible way.
- Input contradicts the target knot completely.
- Blank space or meaningless fragments.

If input is just unclear use NEEDS_INPUT

Consider temporal relationships: user input must precede target node events.

CRITICAL INSTRUCTION: The bridge_text MUST NOT contain ANY content, details, or information from the target knot.
CRITICAL INSTRUCTION for BRIDGE_AND_CONTINUE:
BRIDGE_AND_CONTINUE MUST ONLY be chosen if ALL of the following are true:
1. The user’s intent is fully clear.
2. There is ONLY ONE reasonable way to reach the target knot.
3. No missing user intention needs to be inferred.
4. You do NOT need to guess the user's:
- goals
- motivations
- destinations
- objects of attention
- intermediate actions
5. The bridge can be written using ONLY clear logical consequences.

If you need to guess, NEEDS_INPUT is more likely to be the direction.

The bridge_text MUST NOT contain ANY content, details, or information from the target knot.
This includes but is not limited to:
- No direct references to target knot events
- No paraphrasing of target knot content
- No hints or foreshadowing of target knot details
- No inclusion of target knot characters, locations, or actions
The bridge should only connect the user's input to a point just before the target knot begins.

Classification instruction:
1. First decide internally which direction is the best match
2. Produce a probability distribution across all four directions.
3. Follow the JSON format

Steps to decide the direction:
1. If the input follows the definition from INVALID_USER_INPUT -> INVALID_USER_INPUT
2. Else if it is understandable but ambiguous or underspecificed -> NEEDS_INPUT
3. Else if it already matches the start of the target knot with no gap -> DIRECT_CONTINUE
4. Else if it is clearly leading to the target knot but needs an extra text to make the connection -> BRIDGE_AND_CONTINUE

Examples:

For DIRECT_CONTINUE:
[Current Story] "You walk down the hallway"
[User Input] "I open the next door"
[Target Node] "You enter the library"
This is because no extra events is needed as opening the door gets you to enter the library

For NEEDS_INPUT:
[Current Story] "You walk down the hallway"
[User Input] "I look"
[Target Node] "You enter the library"
This is because you look for what? look at what? more clarification from user is required so give a guidance text
Good Guidance text:
"Can you specify what are you looking at?"

For NEEDS_INPUT:
[Current Story] "You sit on your bed"
[User Input] "I get ready"
[Target Node] "You wake up at 7AM tired"


For BRIDGE_AND_CONTINUE:
Example Flow:
[Current Story] "You sit on your bed"
[User Input] "drink coffee"
Expand All @@ -39,6 +110,13 @@ class StoryContinueDirections(BaseConstant):
Bad Bridge (includes target content):
"You drink coffee and stay up late, leading to you waking up tired at 7AM" (includes target time and state)

For INVALID_USER_INPUT:
Example Flow:
[Current Story] "You sit on your bed"
[User Input] "ung"
[Target Node] "You wake up at 7AM tired"
user input is gibberish, does not make sense

Follow this JSON format:
{
"probabilities": {
Expand Down Expand Up @@ -90,6 +168,7 @@ class StoryContinueDirections(BaseConstant):




CONTINUE_STORY_USER_PROMPT_TEMPLATE = """
### Story Context ###
Target Knot: %(target_knot)s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ def handle(self ,*args, **options):
else:
model.report_evaluation_results()
if options["errors"]:
if not options["stats-csv"]:
if not options["stats_csv"]:
model.report_error_analysis()
model.save_error_analysis(options["errors"])
Loading