change proto format

This commit is contained in:
Luc Mcgrady 2025-06-21 23:17:30 +01:00
parent 0e0e3b9238
commit 21ea2da76f
No known key found for this signature in database
GPG key ID: 4F3D7A0B17CC3D9C
5 changed files with 68 additions and 34 deletions

View file

@ -389,12 +389,6 @@ message FsrsReview {
uint32 delta_t = 2; uint32 delta_t = 2;
} }
enum CMRRTarget {
memorized = 0;
loss_aversion = 1;
stability = 2;
};
message SimulateFsrsReviewRequest { message SimulateFsrsReviewRequest {
repeated float params = 1; repeated float params = 1;
float desired_retention = 2; float desired_retention = 2;
@ -409,6 +403,19 @@ message SimulateFsrsReviewRequest {
deck_config.DeckConfig.Config.ReviewCardOrder review_order = 11; deck_config.DeckConfig.Config.ReviewCardOrder review_order = 11;
optional uint32 suspend_after_lapse_count = 12; optional uint32 suspend_after_lapse_count = 12;
// For CMRR // For CMRR
message CMRRTarget {
message Memorized {
float loss_aversion = 1;
};
message Stability {};
oneof kind {
Memorized memorized = 1;
Stability stability = 2;
};
};
optional CMRRTarget target = 13; optional CMRRTarget target = 13;
} }

View file

@ -1,4 +1,4 @@
use anki_proto::scheduler::CmrrTarget; use anki_proto::scheduler::simulate_fsrs_review_request::cmrr_target::Kind;
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use anki_proto::scheduler::SimulateFsrsReviewRequest; use anki_proto::scheduler::SimulateFsrsReviewRequest;
@ -25,18 +25,13 @@ impl Collection {
}; };
} }
let target_type = req let target_type = req.target.unwrap().kind;
.target
.map(TryInto::try_into)
.transpose()
.unwrap_or(None);
let days_to_simulate = req.days_to_simulate as f32; let days_to_simulate = req.days_to_simulate as f32;
let target = match target_type { let target = match target_type {
Some(CmrrTarget::Memorized) => None, Some(Kind::Memorized(_)) => None,
Some(CmrrTarget::LossAversion) => None, Some(Kind::Stability(_)) => {
Some(CmrrTarget::Stability) => {
wrap!(move |SimulationResult { wrap!(move |SimulationResult {
cards, cards,
cost_per_day, cost_per_day,
@ -60,10 +55,12 @@ impl Collection {
} }
let (mut config, cards) = self.simulate_request_to_config(&req)?; let (mut config, cards) = self.simulate_request_to_config(&req)?;
if target_type == Some(CmrrTarget::LossAversion) { if let Some(Kind::Memorized(settings)) = target_type {
config.relearning_step_transitions[0][0] *= 2.; let loss_aversion = settings.loss_aversion;
config.relearning_step_transitions[1][0] *= 2.;
config.relearning_step_transitions[2][0] *= 2.; config.relearning_step_transitions[0][0] *= loss_aversion;
config.relearning_step_transitions[1][0] *= loss_aversion;
config.relearning_step_transitions[2][0] *= loss_aversion;
} }
Ok(fsrs Ok(fsrs

View file

@ -8,8 +8,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
type ComputeParamsProgress, type ComputeParamsProgress,
} from "@generated/anki/collection_pb"; } from "@generated/anki/collection_pb";
import { import {
CMRRTarget,
SimulateFsrsReviewRequest, SimulateFsrsReviewRequest,
SimulateFsrsReviewRequest_CMRRTarget,
SimulateFsrsReviewRequest_CMRRTarget_Memorized,
} from "@generated/anki/scheduler_pb"; } from "@generated/anki/scheduler_pb";
import { import {
computeFsrsParams, computeFsrsParams,
@ -97,7 +98,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
newCardsIgnoreReviewLimit: $newCardsIgnoreReviewLimit, newCardsIgnoreReviewLimit: $newCardsIgnoreReviewLimit,
easyDaysPercentages: $config.easyDaysPercentages, easyDaysPercentages: $config.easyDaysPercentages,
reviewOrder: $config.reviewOrder, reviewOrder: $config.reviewOrder,
target: CMRRTarget.memorized, target: new SimulateFsrsReviewRequest_CMRRTarget({
kind: {
case: "memorized",
value: new SimulateFsrsReviewRequest_CMRRTarget_Memorized({
lossAversion: 1,
}),
},
}),
}); });
const DESIRED_RETENTION_LOW_THRESHOLD = 0.8; const DESIRED_RETENTION_LOW_THRESHOLD = 0.8;

View file

@ -19,7 +19,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { computeOptimalRetention, simulateFsrsReview } from "@generated/backend"; import { computeOptimalRetention, simulateFsrsReview } from "@generated/backend";
import { runWithBackendProgress } from "@tslib/progress"; import { runWithBackendProgress } from "@tslib/progress";
import { import {
CMRRTarget, SimulateFsrsReviewRequest_CMRRTarget_Memorized,
SimulateFsrsReviewRequest_CMRRTarget_Stability,
type ComputeOptimalRetentionResponse, type ComputeOptimalRetentionResponse,
type SimulateFsrsReviewRequest, type SimulateFsrsReviewRequest,
type SimulateFsrsReviewResponse, type SimulateFsrsReviewResponse,
@ -28,7 +29,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import SwitchRow from "$lib/components/SwitchRow.svelte"; import SwitchRow from "$lib/components/SwitchRow.svelte";
import GlobalLabel from "./GlobalLabel.svelte"; import GlobalLabel from "./GlobalLabel.svelte";
import SpinBoxFloatRow from "./SpinBoxFloatRow.svelte"; import SpinBoxFloatRow from "./SpinBoxFloatRow.svelte";
import { CMRRTargetChoices, reviewOrderChoices } from "./choices"; import {
DEFAULT_CMRR_TARGET,
CMRRTargetChoices,
reviewOrderChoices,
} from "./choices";
import EnumSelectorRow from "$lib/components/EnumSelectorRow.svelte"; import EnumSelectorRow from "$lib/components/EnumSelectorRow.svelte";
import { DeckConfig_Config_LeechAction } from "@generated/anki/deck_config_pb"; import { DeckConfig_Config_LeechAction } from "@generated/anki/deck_config_pb";
import EasyDaysInput from "./EasyDaysInput.svelte"; import EasyDaysInput from "./EasyDaysInput.svelte";
@ -43,6 +48,26 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let openHelpModal: (key: string) => void; export let openHelpModal: (key: string) => void;
export let onPresetChange: () => void; export let onPresetChange: () => void;
let cmrrTargetType = DEFAULT_CMRR_TARGET;
$: if (simulateFsrsRequest?.target) {
switch (cmrrTargetType) {
case "memorized":
simulateFsrsRequest.target.kind = {
case: "memorized",
value: new SimulateFsrsReviewRequest_CMRRTarget_Memorized({
lossAversion: 1,
}),
};
break;
case "stability":
simulateFsrsRequest.target.kind = {
case: "stability",
value: new SimulateFsrsReviewRequest_CMRRTarget_Stability({}),
};
break;
}
}
const config = state.currentConfig; const config = state.currentConfig;
let simulateSubgraph: SimulateSubgraph = SimulateSubgraph.count; let simulateSubgraph: SimulateSubgraph = SimulateSubgraph.count;
let tableData: TableDatum[] = []; let tableData: TableDatum[] = [];
@ -416,8 +441,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<Item> <Item>
<EnumSelectorRow <EnumSelectorRow
choices={CMRRTargetChoices()} choices={CMRRTargetChoices()}
bind:value={simulateFsrsRequest.target} bind:value={cmrrTargetType}
defaultValue={CMRRTarget.memorized} defaultValue={DEFAULT_CMRR_TARGET}
> >
<SettingTitle> <SettingTitle>
{"Target: "} {"Target: "}

View file

@ -11,7 +11,6 @@ import {
DeckConfig_Config_ReviewCardOrder, DeckConfig_Config_ReviewCardOrder,
DeckConfig_Config_ReviewMix, DeckConfig_Config_ReviewMix,
} from "@generated/anki/deck_config_pb"; } from "@generated/anki/deck_config_pb";
import { CMRRTarget } from "@generated/anki/scheduler_pb";
import * as tr from "@generated/ftl"; import * as tr from "@generated/ftl";
import type { Choice } from "$lib/components/EnumSelector.svelte"; import type { Choice } from "$lib/components/EnumSelector.svelte";
@ -200,21 +199,19 @@ export function questionActionChoices(): Choice<DeckConfig_Config_QuestionAction
]; ];
} }
export function CMRRTargetChoices(): Choice<CMRRTarget>[] { export const DEFAULT_CMRR_TARGET = "memorized";
export function CMRRTargetChoices(): Choice<string>[] {
return [ return [
{ {
label: "Memorized (Default)", label: "Memorized (Default)",
value: CMRRTarget.memorized, value: "memorized",
},
{
label: "Memorized (Double cost)",
values: CMRRTarget.loss_aversion,
}, },
{ {
label: "Stability (Experimental)", label: "Stability (Experimental)",
value: CMRRTarget.stability, value: "stability",
}, },
]; ] as const;
} }
function difficultyOrders(fsrs: boolean): Choice<DeckConfig_Config_ReviewCardOrder>[] { function difficultyOrders(fsrs: boolean): Choice<DeckConfig_Config_ReviewCardOrder>[] {