Drop the eight legacy columns SP8 left behind
Migrations 66 to 73 drop `actions.index`, `variants`, `variant_index`, `variant_count`, `state_before`, and `world_state_before`, plus `adventures.memory_cursor` and `summary_cursor`. `index` is a keyword in SQLite, so migration 71 quotes it. Nothing outside the migrations read these. `models.py`, `schemas.py`, and `ACTION_LIST_COLUMNS` lose the same eight fields, `Adventure.actions` orders by `id`, and `attempts.renumber`, `context.history.max_action_index`, and `nodes.next_index` are deleted. Two changes keep the migration replayable on a `create_all` database: - `_split_variants_into_siblings` wrote through the live ORM table, so it stopped compiling once migration 66 removed five of its columns. It now writes through `_ACTIONS_AT_60`, a frozen `Table` with its own `MetaData`. - Five data passes read columns these migrations drop. Each now calls `_has_columns` and returns early when the columns are absent. `bootstrap` takes a `through` version so a migration test can stop at the schema it asserts on. 555 tests pass, up from 549. Eight of the new cases assert each column is gone after a real schema-45 database migrates all the way. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0198qDK3gmgSo7EtQ4GTPqqK
This commit is contained in:
committed by
Parth
co-authored by
Claude Opus 5
parent
e0bf2b61d9
commit
f1bebe18d0
@@ -23,7 +23,7 @@ from ...sse import SSE_HEADERS, sse, turn_error
|
||||
from ..settings import get_settings
|
||||
|
||||
from .deps import CurrentUser, current_adventure, router
|
||||
from .nodes import _move_to_after, next_depth, next_index
|
||||
from .nodes import _move_to_after, next_depth
|
||||
from .paging import annotate_takes
|
||||
|
||||
|
||||
@@ -275,11 +275,6 @@ async def _generate_turn(
|
||||
reasoning = "".join(reasoning_chunks).strip() or None
|
||||
ai_action = models.Action(
|
||||
adventure_id=adventure.id,
|
||||
# A sibling shares the turn's legacy index for the same reason it
|
||||
# shares its depth: it is the same turn. Two rows then hold one index,
|
||||
# which is safe, because `max_action_index` takes a maximum rather than
|
||||
# a count, and nothing else reads the column.
|
||||
index=retry_of.index if retry_of is not None else next_index(adventure),
|
||||
depth=ai_depth,
|
||||
type="ai",
|
||||
text=text,
|
||||
@@ -298,8 +293,10 @@ async def _generate_turn(
|
||||
# a turn landed on top of it. See `memorybank`.
|
||||
memorybank.forget_node(db, adventure, retry_of)
|
||||
cursors.rewind_all(adventure, retry_of.branch_id, ai_depth - 1)
|
||||
# Flush so the new attempt has an id. The session does not autoflush,
|
||||
# and attempts page in id order, so a read taken before this point puts
|
||||
# the newest attempt nowhere.
|
||||
db.flush()
|
||||
attempts.renumber(attempts.group(db, ai_action))
|
||||
else:
|
||||
tree.place_action(db, adventure, ai_action)
|
||||
db.add(ai_action)
|
||||
@@ -369,7 +366,6 @@ async def run_player_turn(
|
||||
return
|
||||
player_action = models.Action(
|
||||
adventure_id=adventure.id,
|
||||
index=next_index(adventure),
|
||||
depth=next_depth(adventure),
|
||||
type=payload.type,
|
||||
text=modified,
|
||||
@@ -384,8 +380,8 @@ async def run_player_turn(
|
||||
db.refresh(player_action)
|
||||
# The new action was added through its foreign key, so the loaded
|
||||
# `adventure.actions` collection is stale. Without this expire,
|
||||
# `build_context` and `next_index` for the AI action do not see the
|
||||
# player action that was just saved.
|
||||
# `build_context` for the AI action does not see the player action
|
||||
# that was just saved.
|
||||
db.expire(adventure, ["actions"])
|
||||
yield sse({"type": "player", "action": action_json(player_action, db)})
|
||||
if stop:
|
||||
|
||||
Reference in New Issue
Block a user