Skip to learning content
Learning StudioCourses and practice
Experiences

Product · Stop, retry, context

Actions and Context

Editing, regenerating, stopping, and retrying all change the conversation graph. After any of them, you need to rebuild the model context within a fixed token budget.

A conversation spine branches into stopped, retried, and edited paths, while a bounded frame admits paired message tiles and leaves stale or oversized tiles outside.
History branches; each request stays boundedStop, retry, and edit preserve different branches, while the next model request projects only valid paired messages that fit the context window.
Evidence & limits
What the further reading establishes
You can store conversation state directly and carry it from one model request to the next instead of trying to reconstruct it from the UI.
What this lab runs
The three action flows keep cancelled output, create new attempt and request ids, show what an edit invalidates, and rebuild the exact request as you change the token budget.
What it does not prove
The token counts are fixed estimates, not results from the selected model's production tokenizer.

Dataset

Branching Conversation

Source
Course-authored synthetic scenario
License
Not separately licensed
Size
3 action flows · 29 budgets (14–42)

Further reading

  • Conversation state

    Primary · OpenAI API documentation · Current

    Explains how to carry a conversation across separate model requests.

  • AbortController

    Guide · MDN Web Docs · Current

    Covers the browser API used to stop fetches, streams, and generation work.

  • Queueing a Series of State Updates

    Guide · React · Current

    Explains the queued state updates behind retry, edit, and streaming actions.

Lesson progressRestoring progress…

  1. CodeRestoring
  2. ExperimentRestoring
  3. CheckRestoring

Summary

How branches work. Stop keeps the partial assistant message and marks it cancelled. Retry or regenerate starts a new assistant attempt from the same user message. Editing a user message starts a new branch and marks everything that depended on the old version invalid without deleting it.

Building the request. The system instructions and current user prompt always go into the request. Completed history can only come along in full user-assistant pairs. Pick the newest pairs first, then send them in time order so truncation never leaves half a turn behind.

Staying in budget. If a newer completed pair is too big, keep looking for older pairs that fit. The token count is the exact total for the records you picked. If the required system instructions already exceed the budget, keep them selected; overflow is reported, and the caller shouldn't send that request as-is.

One prefix, three actions, one request boundaryStopping keeps a cancelled partial attempt. Retry creates a new attempt and request from the same user message. Edit starts a new user branch and invalidates the old follow-up. When you build the next request, keep the required inputs, consider complete historical pairs from newest to oldest, and send the selected pairs in time order.
Required systems1 · 6 tokensActive userm-u3 · “Give one implementation detail.”
Stopm-a3 · a-31 · r-31cancelled · partial “Set future logits” retainedRetry / regeneratem-a4 · a-32 · r-32same parent m-u3 · new queued attemptEdit promptm-u3-e1 → m-a5 · a-33 · r-33m-a3 retained but invalid on edited branch
Request assembly · budget 2621 / 26 used
  1. Requireds1 + active m-u36 + 6 = 12
  2. Newest pairm-u2 + m-a220 tokens · skip
  3. Older pairm-u1 + m-a19 tokens · include

Final request, in time orders1 → m-u1 → m-a1 → m-u321 / 26 tokens · no half-finished turn

The required prompt is too largeThe system instructions stay selected, and overflow: true blocks the request instead of pretending it fits.

Tracking each attempt. For every attempt, save stable message, parent-user, attempt, and request ids. Also save the model id, prompt version, sampling policy, included message ids, and final status. That gives you what you need to explain or replay two different outputs.

Knowledge check

Under this lesson's context rules, what needs its own reserved space apart from complete history turns?

Implementation

product/chat-actions.py
0 of 2 exercises verifiedOpen coding workspace →

Build the exact request from the required system instructions, the current user prompt, and the newest complete history pairs that fit.

Signature
def select_context(options):
Inputs
options {system: messages, history: messages, activeUser: message, budget: int}
Returns
{selected: list[message], used: int, overflow: bool}
Rule
always include system + active user; then add newest adjacent complete user/assistant pairs that fit
Example
budget 14 with turns u1/a1 and u2/a2 → select system, u2, a2, active user
Context selection progressive practice rounds
Restoring saved code…
Reference solution

Approach Build the exact request from the required system instructions, the current user prompt, and the newest complete history pairs that fit.

def select_context(options):    system = options["system"]    history = options["history"]    active_user = options["activeUser"]    budget = options["budget"]     required_system = [        message for message in system if message.get("role") == "system"    ]    turns = []    index = 0    while index < len(history) - 1:        user = history[index]        assistant = history[index + 1]        is_complete_turn = (            user.get("role") == "user"            and user.get("status") == "complete"            and assistant.get("role") == "assistant"            and assistant.get("status") == "complete"        )        if is_complete_turn:            turns.append([user, assistant])            index += 2        else:            index += 1     selected_turns = []    used = sum(message["tokens"] for message in required_system) + active_user["tokens"]    overflow = used > budget    if not overflow:        for turn in reversed(turns):            turn_tokens = sum(message["tokens"] for message in turn)            if used + turn_tokens <= budget:                selected_turns.insert(0, turn)                used += turn_tokens     selected_history = [        message for turn in selected_turns for message in turn    ]    return {        "selected": required_system + selected_history + [active_user],        "used": used,        "overflow": overflow,    }

Build token-limited context selection and regeneration branches in Python before you work with a full conversation graph.

Saved results

Results created after your saved code passes its checks

The replay is course data. The validation result is tied to the code you saved and checked.

Loading…