Commit graph

82 commits

Author SHA1 Message Date
Damien Elmes
365b243e04 Update to Rust 1.85
Edition update to follow later
2025-02-21 10:42:42 +07:00
Jarrett Ye
93351bfb50 Feat/support load balance and easy days in rescheduling (#3815)
* Feat/support load balance and easy days in rescheduling

* ./ninja fix:minilints

* apply clippy

* reuse calculate_easy_days_modifiers()

* consider LoadBalancerEnabled

* move calculate_easy_days_modifiers out of struct

* improve naming & add comments

* apply clippy

* reschedule if easy days settings are changed

* Minor simplification

* refactor to share code between load balancer and rescheduler

* intervals_and_params -> intervals_and_weights

* find_best_interval -> select_weighted_interval

* cargo clippy

* add warning about easyDaysChanged

* compare arrays directly

* Don't show warning if fsrs+rescehdule is already enabled

---------

Co-authored-by: Damien Elmes <gpg@ankiweb.net>
Co-authored-by: Jake Probst <jake.probst@gmail.com>
2025-02-18 13:44:00 +07:00
Jarrett Ye
8f8db1b350 Fix/re-optimize FSRS if short-term param is weird (#3742)
* Fix/re-optimize FSRS if short-term param is weird

* Reset progress when another run is required (dae)

* only count the same-day steps

* Fix flicker when optimizing again (dae)
2025-01-26 10:42:17 +11:00
Damien Elmes
0a9990ed77 Rename remaining 'weights' references to 'params' 2024-10-21 18:13:23 +10:00
Damien Elmes
74330c5b34 Use separate field to store FSRS params
Will allow the user to keep using old params with older clients
2024-10-21 18:13:23 +10:00
Damien Elmes
6146dcc390 Revert "When updating all FSRS parameters at once, exclude suspended cards"
https://forums.ankiweb.net/t/memory-state-of-suspended-cards/50460/6

This reverts commit 69f8d9713f.
2024-10-12 22:09:05 +10:00
Jarrett Ye
dea7bf8e36 Feat/Easy Days (#3442)
* Feat/Easy Days

* format

* add easy_days_percentages to deck_config

* configure Easy Days via table

* remove unused code

* add translatable strings & add default of easy days

* don't check easy_days_percentages when deserialize

* pass test::all_reserved_fields_are_removed

* consider next_day_at when interval_to_weekday

* remove y-axis-title created in last simulation

* EstimatedTotalKnowledge should be integer

* Reorder deck option sections (dae)

- Move FSRS to bottom left, to move it closer to the top, and so
the left and right columns appear roughly balanced when FSRS is
enabled.
- Move Easy Days above Advanced

* Don't crash if wrong number of days (dae)

* Use lower field number (dae)

Repeated fields are more compactly stored in the first 15 fields.
2024-10-11 19:47:44 +10:00
Damien Elmes
83108a3775 Remove redundant is_finite() check 2024-09-11 02:54:00 +07:00
Jarrett Ye
8d22175471 graduate card when user presses again or hard and has 0 learning steps (#3367)
* graduate card when user press hard and has 0 learning steps

* fix error: useless conversion to the same type

* do the same thing to again

* fix expected `Option<u32>`, found integer

* ./ninja format

* Update to FSRS-rs v1.2.0

* if else -> match

* Weight length check has been moved into FSRS (dae)

* Don't mention the number of FSRS parameters (dae)

It has changed, and may change again.
2024-08-29 22:20:11 +07:00
Jarrett Ye
0a37d366f6 Feat/FSRS-5 (#3298)
* Feat/FSRS-5

* adapt the SimulatorConfig of FSRS-5

* update parameters from FSRS-4.5

* udpate to FSRS-rs v1.1.0

* ./ninja fix:minilints

* pass ci

* update cargo-deny to 0.14.24

* udpate to FSRS-rs v1.1.1

* update to fsrs-rs v1.1.2
2024-07-21 21:02:24 +07:00
Jarrett Ye
64f2eb9f17 Fix/exclude suspended cards when optimize all presets (#3198) 2024-05-15 13:12:52 +01:00
Loudwig
bf809d5e1f Feature Show Reminder before answer (#3064) (#3119)
* Feature Question Action Show Reminder (#3064)

Added a option in the deck config that allow the user to choose in
Autoupdate mode between showing a reminder or revealing the card.
Also added my name to the contributors

* Update ftl/core/deck-config.ftl
2024-04-13 08:39:50 +01:00
Jarrett Ye
63d7d92fb4 rename sm2 retention to historical retention (#3101)
* rename sm2 retention to historical retention

* ninja format

* keep sm2_retention in DeckConfSchema11

* update wording

* Update schema11.rs
2024-03-29 09:34:26 +00:00
Damien Elmes
69f8d9713f When updating all FSRS parameters at once, exclude suspended cards 2024-03-20 12:56:36 +07:00
Damien Elmes
1883549d32 Shift FSRS optimization into top level; shown optimize all tip after 30 days 2024-03-17 17:46:26 +07:00
Jarrett Ye
fec80175d9 alert when the resp.weights is empty (#3061)
* alert when the resp.weights is empty

* format
2024-03-09 10:26:59 +00:00
Jarrett Ye
0362727bd9 update fsrs to 0.4.4 (#3045)
* update fsrs to 0.4.4

* fix bypassed_learning_is_handled
2024-03-03 14:30:34 +07:00
Luc Mcgrady
291342ea2c FSRS - Ignore revlogs before date while optimizing (#2922)
* Added: Date input button

* Added: ignoreDate to config

* Added: Backend

* Optimize function passes value

* Fix: Spelling

* Moved: filter logic from revlog_for_srs to update_memory_state

* fmt

* Copyright header

* ./check

* Fix: Test

* Renamed: Ignore_date -> Ignore_before_date

* Neaten parameters

* evaluate weights

* ./check

* Optimize all presets

* Added: Label localizations

* Removed globe label

* Added: Tooltip

* Changed error type

* fmt

* Moved filter to own function

* missing function call replacement

* Fix: Typo

* Apply suggestions from code review

Co-authored-by: Damien Elmes <dae@users.noreply.github.com>

* timestamp * 1000 -> timestamp_millis

* ignoreBefore -> ignore_before

* clarified ignore_before variables

* i64 -> TimestampMillis

* Un-traitified remove_revlogs_before

* Added: ms == 0 guard

* Added: Ignore_before affects scheduling

* Moved filter to fsrs_items_for_training

* removed filter from revlog_for_srs

* Tuple -> UpdateMemoryStateEntry

* Removed unused function

* Removed superfluous _ms from variables

* cid -> id

* Different ignore method

* Added: Unit test

* cid -> id

* Test: Exact ms edge case

* ./check

* Fix: re-learns could be before ignore date in cards without learning steps

* getignoreRevlogsBeforeMs -> getIgnoreRevlogsBeforeMs

* Removed pub(crate)

* Clarified unit test

* last_learn_entry -> first_of_last_learn_entries

* @user1823's method

* IOS fix

* ./check

* Fix: width defined twice
2024-02-22 11:01:10 +07:00
Abdo
739e0196e9 Keep previous FSRS parameters if they get worse when optimizing (#2996)
* Update to fsrs-rs 0.3.0

* Keep previous FSRS parameters if they get worse when optimizing
2024-02-11 16:26:04 +10:00
Abdo
c183b758bd Default to 'Bury Card' action consistently (#2950) 2024-01-19 15:49:16 +10:00
Damien Elmes
701e0b7e60 Fix error generating parameters when a parameter is 0 2023-12-12 12:33:32 +10:00
Damien Elmes
7d8ca4f86d Catch NaNs in FSRS weights
Users pasting in weights from the old scheduler were leaving the outer
square brackets in, causing the first and last numbers to be parsed as
NaN.
2023-12-04 16:19:22 +10:00
Damien Elmes
910d864ee7 Update to Rust 1.74, and update most Rust deps
hyper has been held back, as neither reqwest nor axum support 1.0 yet
2023-11-27 13:34:42 +10:00
Damien Elmes
aea95ee9ae Switch FSRS reschedule to a global option; don't persist
A global is easier to use in conjunction with the 'optimize all' action.
The value is no longer persisted, as doing so makes it too easy for users
to generate a lot of revlog entries when playing with different FSRS
weights/retention settings, such as in https://forums.ankiweb.net/t/possible-syncing-limitation-by-fsrs-manual-scheduling-data-accumulation/37610
2023-11-27 11:24:31 +10:00
Damien Elmes
1021502377 Add option to calculate all weights at once 2023-11-27 11:24:31 +10:00
Abdo
7c2007ccad Persist FSRS weights search in preset (#2827) 2023-11-14 11:47:08 +10:00
RumovZ
134793835f Allow applying limits of inactive parents (#2824)
* Allow applying limits of inactive parents

* Tweak label/help text (dae)
2023-11-13 14:30:19 +10:00
Abdo
cb9d5218f7 Add auto-advance options to deck preset (#2765)
* Move stop-timer-on-answer strings to correct section

* Add auto-advance options to deck preset

* Implement answer actions

* Fix error when last card is answered before timeout

* Fix deserialization of answerAction

* Add answerAction to reserved key list

* Fix inverted boolean

* Add option to wait for audio to finish

* Add auto-advance toggle

* Add shortcut

* Disable auto-advance when main window state changes

* Start auto-advance timer after option is toggled

* Disable auto-advance when main window loses focus

* Use existing translations

* Add Answer Hard and Show Reminder
2023-11-13 10:41:51 +10:00
Damien Elmes
3c31386c1f Change color of info box depending on retention; increase limit to 0.99
Closes #2803
2023-11-07 13:05:43 +10:00
Damien Elmes
dbfbd356f1 Fix sm2_retention getting reset on downgrade/sync 2023-10-28 14:45:24 +10:00
Abdo
10966394fd Remove v1/v2 support from the backend (#2727)
* Remove v1/v2 support from deck list

* Remove v1/v2 support from most routines and show error

* Remove scheduler_version from preferences

* Fix formatting

* Remove v1/v2 conditionals from Python code

* Fix legacy importer

* Remove legacy hooks

* Add missing scheduler checks

* Remove V2 logic from deck options screen

* Remove the review_did_undo hook

* Restore ability to open old options with shift (dae)
2023-10-14 10:50:59 +10:00
Damien Elmes
ec8990dc11 Use sm2 retention when deriving memory state
Closes #2702
2023-10-13 10:37:35 +10:00
Damien Elmes
6394a449bc Fix 'Expression tree is too large' when user has many decks
+ Allow 'did:' searches to match multiple decks at once
2023-10-09 18:39:18 +10:00
Damien Elmes
49fcbe8f8f Support rescheduling on weight/retention change 2023-10-01 15:20:58 +10:00
Damien Elmes
6b0bc2ce71 Display the default weights as a placeholder 2023-09-30 16:10:23 +10:00
Abdo
97bd06dc49 Implement "stop timer on answer" as a preset option (#2686)
* Implement "stop timer on answer" as a preset option

* Hide timer setting on AnkiMobile (dae)
2023-09-27 16:10:14 +10:00
Damien Elmes
3a6dd627d7 Allow desired retention to be set to 0.7
https://github.com/open-spaced-repetition/fsrs-rs/issues/79#issuecomment-1733779005
2023-09-26 13:03:49 +10:00
Damien Elmes
3d59a0eebe Store desired retention in card data
If we want to be able to factor the desired retention into a sort based
on relative overdueness, having the values accessible on the card makes
things easier.
2023-09-23 15:42:42 +10:00
Damien Elmes
0f899efea7 Convert FSRS to a global option
Allowing some decks to be FSRS and some SM-2 will lead to confusing
behavior when sorting on SM-2 or FSRS-specific fields, or when moving
cards between decks.
2023-09-23 14:41:55 +10:00
Damien Elmes
02a823c846 Clear memory state when user disables FSRS 2023-09-17 11:50:38 +10:00
Damien Elmes
41bcb20f1e Integrate FSRS into Anki (#2654)
* Pack FSRS data into card.data

* Update FSRS card data when preset or weights change

+ Show FSRS stats in card stats

* Show a warning when there's a limited review history

* Add some translations; tweak UI

* Fix default requested retention

* Add browser columns, fix calculation of R

* Property searches

eg prop:d>0.1

* Integrate FSRS into reviewer

* Warn about long learning steps

* Hide minimum interval when FSRS is on

* Don't apply interval multiplier to FSRS intervals

* Expose memory state to Python

* Don't set memory state on new cards

* Port Jarret's new tests; add some helpers to make tests more compact

https://github.com/open-spaced-repetition/fsrs-rs/pull/64

* Fix learning cards not being given memory state

* Require update to v3 scheduler

* Don't exclude single learning step when calculating memory state

* Use relearning step when learning steps unavailable

* Update docstring

* fix single_card_revlog_to_items (#2656)

* not need check the review_kind for unique_dates

* add email address to CONTRIBUTORS

* fix last first learn & keep early review

* cargo fmt

* cargo clippy --fix

* Add Jarrett to about screen

* Fix fsrs_memory_state being initialized to default in get_card()

* Set initial memory state on graduate

* Update to latest FSRS

* Fix experiment.log being empty

* Fix broken colpkg imports

Introduced by "Update FSRS card data when preset or weights change"

* Update memory state during (re)learning; use FSRS for graduating intervals

* Reset memory state when cards are manually rescheduled as new

* Add difficulty graph; hide eases when FSRS enabled

* Add retrievability graph

* Derive memory_state from revlog when it's missing and shouldn't be

---------

Co-authored-by: Jarrett Ye <jarrett.ye@outlook.com>
2023-09-16 16:09:26 +10:00
Damien Elmes
fff60936bc Integrate the FSRS optimizer (#2633)
* Support searching for deck configs by name

* Integrate FSRS optimizer into Anki

* Hack in a rough implementation of evaluate_weights()

* Interrupt calculation if user closes dialog

* Fix interrupted error check

* log_loss/rmse

* Update to latest fsrs commit; add progress info to weight evaluation

* Fix progress not appearing when pretrain takes a while

* Update to latest commit
2023-09-05 18:45:05 +10:00
Damien Elmes
c78180b590 Fix clippy issues in Rust 1.72 2023-08-25 07:56:38 +10:00
Damien Elmes
ed8c04b0da Take another approach to dealing with conflicting flattened keys
The approach in #2542 unfortunately introduced a regression, as whilst
it ensured that duplicate keys are removed when downgrading, it no longer
prevented the duplicates from being removed when converting to a legacy
Schema11 object. This resulted in things like backend.get_notetype_legacy()
returning duplicate keys, and could break syncing:

https://forums.ankiweb.net/t/windows-desktop-sync-error/33128

As syncing and schema11 object usage is quite common compared to downgrading,
the extra Value deserialization seemed a bit expensive, so I've switched
back to explicitly removing the problem keys. To ensure we don't forget to
add new keys in the future, I've added some new tests that should alert us
whenever a newly-added key is missing from the reserved list.
2023-08-15 11:25:53 +10:00
Damien Elmes
5623523a16 deckconfig.proto -> deck_config.proto
Makes it consistent with our other proto files, and matches the service
name.
2023-07-03 13:44:54 +10:00
Damien Elmes
d2089bc00e Refactor service generation (#2552)
* Automatically elide empty inputs and outputs to backend methods

* Refactor service generation

Despite the fact that the majority of our Protobuf service methods require
an open collection, they were not accessible with just a Collection
object. To access the methods (e.g. because we haven't gotten around to
exposing the correct API in Collection yet), you had to wrap the collection
in a Backend object, and pay a mutex-acquisition cost for each call, even
if you have exclusive access to the object.

This commit migrates the majority of service methods to the Collection, so
they can now be used directly, and improves the ergonomics a bit at the
same time.

The approach taken:

- The service generation now happens in rslib instead of anki_proto, which
avoids the need for trait constraints and associated types.
- Service methods are assumed to be collection-based by default. Instead of
implementing the service on Backend, we now implement it on Collection, which
means our methods no longer need to use self.with_col(...).
- We automatically generate methods in Backend which use self.with_col() to
delegate to the Collection method.
- For methods that are only appropriate for the backend, we add a flag in
the .proto file. The codegen uses this flag to write the method into a
BackendFooService instead of FooService, which the backend implements.
- The flag can also allows us to define separate implementations for collection
and backend, so we can e.g. skip the collection mutex in the i18n service
while also providing the service on a collection.
2023-06-19 15:33:40 +10:00
Damien Elmes
632c95c177 Move generated protobuf into anki_proto
Due to the orphan rule, this meant removing our usages of impl ProtoStruct,
or converting them to a trait when they were used commonly.

rslib now directly references anki_proto and anki_i18n, instead of
'pub use'-ing them, and we can put the generated files back in OUT_DIR.
2023-06-12 15:47:51 +10:00
RumovZ
43b11a6e18 Automate schema 11 other duplicates clearing (#2542)
* Skip linting target folder

Contains build files not passing the copyright header check.

* Implicitly clear duplicate keys when serializing

Fixes `originalStockKind` not being cleared from `other`, as it had
mistakenly been added to the field list for `NoteFieldSchema11`.
2023-06-12 11:14:14 +10:00
Damien Elmes
1d4619139b Bump Rust version 2023-03-31 14:11:33 +10:00
RumovZ
8c86e742be Fix invalid ids on db check (#2445)
* Move open_test_collection into Collection test impl

* Fix invalid ids when checking database

* Report fixed invalid ids

* Improve message when trying to export invalid ids

Also move ImportError due to namespace conflicts with snafu macro.

* Take a human name in DeckAdder::new

* Mention timestamps in the db check message (dae)

Will help to correlate the fix with the message shown when importing/
exporting.
2023-03-19 10:58:35 +10:00