Fix remaining code-review findings (15 bugs; #11 skipped as AID-compatible)
Backend: - provider: fall back to parsing a plain JSON body when a server ignores stream=true (was: silent empty turn); error if response has no text (#5) - memorybank: clamp cursors after undo/retry shrinks the action list, and translate summary_cursor (list position) to an Action.index boundary before comparing with Memory.source_end (#7) - memorybank: pinned memories now count toward the top_k budget (#8) - memorybank: cosine() returns 0.0 on dimension mismatch; changing the embedding model clears stored vectors so they re-embed (#9) - scripting: MAX_STORY_CARDS cap now counts cards inserted during the hook, so a script can't add unbounded cards in one turn (#10) - settings: /test tolerates non-dict JSON from /models (#13) - scenarios: import accepts worldInformation as a story-card source (#14) Frontend: - per-key debounce timers in PlotPanel and ScenarioEditor — editing two things within 600ms no longer drops the first save (#15, #16) - Continue button no longer discards typed input (#17) - failed retry resyncs actions from the server instead of leaving the removed action missing (#18) - Settings save/test surface errors instead of hanging on Testing… (#19) - InsightsPanel ignores stale responses from superseded requests (#20) - placeholder scan includes story-card trigger keys (#21) addStoryCard returning the 0-based index (falsy for the first card) matches real AI Dungeon per the scripting guidebook — kept, documented (#11). Statuses updated in CODE_REVIEW_FINDINGS.md; stale entries for previously fixed items (#1-4, #6, #12) corrected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KFsGHju9szibJJa2YJcdbg
This commit is contained in:
co-authored by
Claude Fable 5
parent
3ee653a631
commit
253b533d3b
@@ -130,7 +130,13 @@ def import_scenario(bundle: dict = Body(...), db: Session = Depends(get_db)):
|
||||
db.add(scenario)
|
||||
db.flush()
|
||||
|
||||
cards = bundle.get("storyCards") or bundle.get("worldInfo") or []
|
||||
# AI Dungeon exports have used all three names for the same list.
|
||||
cards = (
|
||||
bundle.get("storyCards")
|
||||
or bundle.get("worldInfo")
|
||||
or bundle.get("worldInformation")
|
||||
or []
|
||||
)
|
||||
for card in cards:
|
||||
if not isinstance(card, dict):
|
||||
continue
|
||||
|
||||
@@ -25,8 +25,17 @@ def read_settings(db: Session = Depends(get_db)):
|
||||
@router.put("", response_model=schemas.SettingsOut)
|
||||
def update_settings(payload: schemas.SettingsUpdate, db: Session = Depends(get_db)):
|
||||
settings = get_settings(db)
|
||||
for field, value in payload.model_dump(exclude_unset=True).items():
|
||||
fields = payload.model_dump(exclude_unset=True)
|
||||
embedding_model_changed = (
|
||||
"embedding_model" in fields
|
||||
and fields["embedding_model"] != settings.embedding_model
|
||||
)
|
||||
for field, value in fields.items():
|
||||
setattr(settings, field, value)
|
||||
if embedding_model_changed:
|
||||
# Vectors from the old model have a different dimensionality/space;
|
||||
# clear them so the post-turn task re-embeds with the new model.
|
||||
db.query(models.Memory).update({"embedding": None})
|
||||
db.commit()
|
||||
return settings
|
||||
|
||||
@@ -52,6 +61,6 @@ async def test_connection(db: Session = Depends(get_db)):
|
||||
try:
|
||||
data = resp.json()
|
||||
models_available = [m.get("id", "?") for m in data.get("data", [])]
|
||||
except ValueError:
|
||||
pass
|
||||
except (ValueError, AttributeError, TypeError):
|
||||
pass # non-JSON or unexpected shape — connectivity is still confirmed
|
||||
return {"ok": True, "models": models_available}
|
||||
|
||||
Reference in New Issue
Block a user