androidengineers.Book a session

Bounded story context

Bounded story context

exerciseSelf-paced

Saved history is larger than active model context

Story.scenes contains accepted chapters; draft is separate. storyPrompt selects a contiguous suffix of recent accepted scenes within 4,500 characters of scene text plus action. It then adds instructions, title, atmosphere and the new direction. Therefore 4,500 is not the full prompt length or an exact token budget. Image tokens, instructions and output allowance still occupy the model context.

The loop breaks when the next recent scene does not fit. It does not skip that scene to fish for smaller older ones. This preserves a contiguous suffix, but a single oversized newest scene can exclude all earlier history. Discarded drafts must never reappear through context selection.

Exercise: limit scene count as well as characters

Open data/Story.kt and add a parameter to storyPrompt without using it yet:

fun storyPrompt(story: Story, action: String, night: Boolean,
                maxScenes: Int = 6): String {
    // Keep the existing body for the red phase.
}

The comment above describes an edit; do not replace the existing function body with it. Add these tests inside StoryPolicyTest:

@Test
fun contextLimitsAcceptedSceneCount() {
    val story = Story(title = "Keys", genre = "Fantasy", scenes = listOf(
        Scene("OLDER_MARKER", "Walk"),
        Scene("RECENT_MARKER", "Open"),
    ))
    val prompt = storyPrompt(story, "Continue", false, maxScenes = 1)
    assertFalse(prompt.contains("OLDER_MARKER"))
    assertTrue(prompt.contains("RECENT_MARKER"))
    assertTrue(prompt.contains("1 older scenes omitted"))
}

@Test
fun contextRejectsNonPositiveSceneLimit() {
    assertThrows(IllegalArgumentException::class.java) {
        storyPrompt(Story(title = "Keys", genre = "Fantasy"),
                    "Continue", false, maxScenes = 0)
    }
}

Run the focused suite. Both assertions about the new policy must fail during the red phase; a compiler error is not the expected failure.

./gradlew :app:testDebugUnitTest --tests '*StoryPolicyTest'

Implement the green phase

Add require(maxScenes > 0) after the existing input require. Insert if (selected.size >= maxScenes) break as the first statement inside the loop over story.scenes.asReversed(). Keep the existing character-budget check, prepend order and omitted-count calculation unchanged. Run the new tests and the full unit suite. Existing callers keep compiling because the new parameter has a default.

Explain the result

With maxScenes 1, only RECENT_MARKER survives and one older scene is reported omitted. Neither the count nor character bound should mutate saved history. This extension reduces active context; it does not erase chapters or summarize them. Add your own test where a newest scene exceeds the character budget to preserve the contiguous-suffix behavior. Token counting and summary generation remain separate future work.

Roadmap · Hands-on codelab · Pinned source

YOUR LEARNING JOURNEY

0 of 13 available lessons completed

Progress saved in this browser. No account needed.
Bounded story context | Gemma on Android with PocketStories — Preview | Android Engineers