feat: [api] Various changes to get the adventure possible choice feature working
This commit is contained in:
parent
e40574ae9d
commit
461473d379
4 changed files with 32 additions and 6 deletions
|
|
@ -144,6 +144,7 @@ class AdventureService:
|
|||
self,
|
||||
adventure_id: uuid.UUID,
|
||||
entry_id: uuid.UUID,
|
||||
user_id: uuid.UUID,
|
||||
) -> None:
|
||||
"""Full entry generation pipeline. Called from the worker queue.
|
||||
|
||||
|
|
@ -157,6 +158,7 @@ class AdventureService:
|
|||
assert adventure is not None, f"Adventure {adventure_id} not found"
|
||||
|
||||
all_entries = await self.entry_repo.list_for_adventure(adventure_id)
|
||||
all_decisions = [await self.decision_repo.get_for_entry_and_user(entry_id=uuid.UUID(e.id), user_id=user_id) for e in all_entries]
|
||||
current_entry = next(e for e in all_entries if e.id == str(entry_id))
|
||||
is_first_entry = current_entry.entry_index == 0
|
||||
is_final_entry = current_entry.entry_index + 1 == adventure.max_entry_count
|
||||
|
|
@ -184,6 +186,7 @@ class AdventureService:
|
|||
vibes=adventure.vibes,
|
||||
protagonist=adventure.protagonist,
|
||||
prior_entries=prior_entries,
|
||||
prior_decisions=all_decisions,
|
||||
)
|
||||
|
||||
raw_text, usage_dict = await self.anthropic_client.complete(
|
||||
|
|
@ -192,7 +195,7 @@ class AdventureService:
|
|||
max_tokens=2048,
|
||||
)
|
||||
|
||||
story_text, choices_parsed, gm_notes, story_so_far = parse_entry_response(raw_text)
|
||||
story_text, choices_parsed, gm_notes = parse_entry_response(raw_text)
|
||||
|
||||
await self.entry_repo.update_content(
|
||||
entry_id=entry_id,
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ def build_conversation_messages(
|
|||
vibes: list[str],
|
||||
protagonist: list[str],
|
||||
prior_entries: list[tuple[AdventureEntry, list[AdventureEntryPossibleChoice], str | None]],
|
||||
prior_decisions: list[AdventureEntryPossibleChoice | None],
|
||||
) -> list[dict]:
|
||||
"""Build the full messages array for an Anthropic API call.
|
||||
|
||||
|
|
@ -110,8 +111,22 @@ def build_conversation_messages(
|
|||
messages.append(
|
||||
{"role": "assistant", "content": reconstruct_assistant_message(entry, choices)}
|
||||
)
|
||||
if chosen_label is not None:
|
||||
messages.append({"role": "user", "content": chosen_label})
|
||||
|
||||
# Find the player's decision for this entry
|
||||
choice_ids = [c.id for c in choices]
|
||||
decision_for_entry = next(
|
||||
(d for d in prior_decisions if d and d.choice_id in choice_ids),
|
||||
None
|
||||
)
|
||||
|
||||
# If a decision exists, append the player's chosen option
|
||||
if decision_for_entry:
|
||||
chosen_option = next(
|
||||
(c for c in choices if c.id == decision_for_entry.choice_id),
|
||||
None
|
||||
)
|
||||
if chosen_option:
|
||||
messages.append({"role": "user", "content": chosen_option.label})
|
||||
return messages
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -120,10 +120,10 @@ def _make_service(db: AsyncSession) -> AdventureService:
|
|||
|
||||
|
||||
async def _run_entry_pipeline_task(
|
||||
adventure_id: uuid.UUID, entry_id: uuid.UUID
|
||||
adventure_id: uuid.UUID, entry_id: uuid.UUID, user_id: uuid.UUID
|
||||
) -> None:
|
||||
async with AsyncSessionLocal() as db:
|
||||
await _make_service(db).run_entry_pipeline(adventure_id, entry_id)
|
||||
await _make_service(db).run_entry_pipeline(adventure_id, entry_id, user_id)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -289,7 +289,7 @@ async def create_adventure(
|
|||
)
|
||||
await worker.enqueue(
|
||||
partial(
|
||||
_run_entry_pipeline_task, uuid.UUID(adventure.id), uuid.UUID(first_entry.id)
|
||||
_run_entry_pipeline_task, uuid.UUID(adventure.id), uuid.UUID(first_entry.id), user_id
|
||||
)
|
||||
)
|
||||
return _to_adventure_response(adventure)
|
||||
|
|
@ -375,6 +375,7 @@ async def record_decision(
|
|||
_run_entry_pipeline_task,
|
||||
uuid.UUID(next_entry.adventure_id),
|
||||
uuid.UUID(next_entry.id),
|
||||
user_id,
|
||||
)
|
||||
)
|
||||
return DecisionResponse(
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class AdventureChoiceItem(BaseModel):
|
|||
class AdventureEntryItem(BaseModel):
|
||||
id: str
|
||||
adventure_id: str
|
||||
possible_choices: list[AdventureChoiceItem] | None
|
||||
generated_from_choice_id: str | None
|
||||
status: str
|
||||
entry_index: int
|
||||
|
|
@ -81,6 +82,7 @@ async def get_adventure(
|
|||
|
||||
entries = await PostgresAdventureEntryRepository(db).list_for_adventure(adv_id)
|
||||
|
||||
choices_repo = PostgresAdventureEntryChoiceRepository(db)
|
||||
translation_repo = PostgresAdventureEntryTranslationRepository(db)
|
||||
audio_repo = PostgresAdventureEntryAudioRepository(db)
|
||||
|
||||
|
|
@ -93,10 +95,15 @@ async def get_adventure(
|
|||
target_language=adventure.source_language,
|
||||
)
|
||||
audio = await audio_repo.get_for_entry(entry_id=eid, component_type="story_text")
|
||||
choices = await choices_repo.list_for_entry(eid)
|
||||
entry_items.append(
|
||||
AdventureEntryItem(
|
||||
id=entry.id,
|
||||
adventure_id=entry.adventure_id,
|
||||
possible_choices=[
|
||||
AdventureChoiceItem(id=c.id, index=c.index, label=c.label, text=c.text)
|
||||
for c in choices ]
|
||||
if choices else None,
|
||||
generated_from_choice_id=entry.generated_from_choice_id,
|
||||
status=entry.status,
|
||||
entry_index=entry.entry_index,
|
||||
|
|
|
|||
Loading…
Reference in a new issue