@anthusai/papyrus 5.24.0 → 5.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/amplify/plugins/reader-steering/config.js +12 -1
- package/amplify/plugins/reader-steering/config.ts +24 -4
- package/amplify/plugins/reader-steering/papyrus.plugin.js +1 -0
- package/amplify/plugins/reader-steering/papyrus.plugin.ts +1 -0
- package/lib/semantic-graph.ts +2 -0
- package/package.json +1 -1
- package/routes.manifest.json +1 -1
|
@@ -83,7 +83,13 @@ export function resolveReaderSteeringConfig(request) {
|
|
|
83
83
|
throw new Error(`reader-steering plugin dimensions cannot use the reserved names: ${reserved.join(", ")}`);
|
|
84
84
|
const limits = object(raw.limits, "limits", ["actionsPerHour", "newAccountHours", "newAccountDivisor"]);
|
|
85
85
|
const karma = object(raw.karma, "karma", ["upvoteWeight", "usedItWeight"]);
|
|
86
|
-
const ranking = object(raw.ranking, "ranking", [
|
|
86
|
+
const ranking = object(raw.ranking, "ranking", [
|
|
87
|
+
"halfLifeHours", "risingWindowHours", "readerMinimum", "editorWeight", "combination", "shrinkageK", "readerShareCap", "newAccountWeight", "risingMinimumAccountHours",
|
|
88
|
+
]);
|
|
89
|
+
const combination = ranking.combination === undefined ? "blend" : ranking.combination;
|
|
90
|
+
if (combination !== "blend" && combination !== "shrinkage")
|
|
91
|
+
throw new Error("reader-steering plugin ranking.combination must be blend or shrinkage");
|
|
92
|
+
const shrinking = combination === "shrinkage";
|
|
87
93
|
const snapshot = object(raw.snapshot, "snapshot", ["schedule", "intervalHours", "hypeMinimum"]);
|
|
88
94
|
const submissions = object(raw.submissions, "submissions", ["perDay", "similarHours", "kinds", "itemType", "section"]);
|
|
89
95
|
const moderation = object(raw.moderation, "moderation", ["mode", "preModeration", "reportsPerDay", "ai"]);
|
|
@@ -130,6 +136,11 @@ export function resolveReaderSteeringConfig(request) {
|
|
|
130
136
|
risingWindowHours: number(ranking.risingWindowHours, "ranking.risingWindowHours", 6, 1, 24 * 30),
|
|
131
137
|
readerMinimum: integer(ranking.readerMinimum, "ranking.readerMinimum", 5, 1, 10000),
|
|
132
138
|
editorWeight: number(ranking.editorWeight, "ranking.editorWeight", 0.5, 0, 1),
|
|
139
|
+
combination,
|
|
140
|
+
shrinkageK: number(ranking.shrinkageK, "ranking.shrinkageK", 20, 0.01, 10000),
|
|
141
|
+
readerShareCap: number(ranking.readerShareCap, "ranking.readerShareCap", 0.4, 0, 1),
|
|
142
|
+
newAccountWeight: number(ranking.newAccountWeight, "ranking.newAccountWeight", shrinking ? 1 / 3 : 1, 0, 1),
|
|
143
|
+
risingMinimumAccountHours: number(ranking.risingMinimumAccountHours, "ranking.risingMinimumAccountHours", shrinking ? 24 : 0, 0, 24 * 90),
|
|
133
144
|
},
|
|
134
145
|
snapshot: {
|
|
135
146
|
schedule: flag(snapshot.schedule, "snapshot.schedule"),
|
|
@@ -12,7 +12,7 @@ export const COMPUTE_ROLE_ARN = /^arn:aws:iam::[0-9]{12}:role\/[A-Za-z0-9+=,.@_/
|
|
|
12
12
|
export type ReaderSteeringConfig = {
|
|
13
13
|
/** The IAM role of the CMS app's server runtime (the `CmsComputeRoleArn` output of the app-shell stack): the only caller of reader-actions. */
|
|
14
14
|
computeRoleArn: string;
|
|
15
|
-
/** Rating dimensions of the publication,
|
|
15
|
+
/** Rating dimensions of the publication, named by the site (lowercase). `up` and `used-it` are always available. */
|
|
16
16
|
dimensions: string[];
|
|
17
17
|
limits: {
|
|
18
18
|
/** Votes and ratings one reader may make in a clock hour. */
|
|
@@ -31,8 +31,18 @@ export type ReaderSteeringConfig = {
|
|
|
31
31
|
risingWindowHours: number;
|
|
32
32
|
/** Reader ratings per item needed before the reader composite counts in Front. */
|
|
33
33
|
readerMinimum: number;
|
|
34
|
-
/** Weight of the editor composite in Front once readers have rated (the reader composite gets the rest). */
|
|
34
|
+
/** Weight of the editor composite in Front once readers have rated (the reader composite gets the rest). Used by `blend` only. */
|
|
35
35
|
editorWeight: number;
|
|
36
|
+
/** `blend`: editor composite, then a fixed-weight blend after `readerMinimum` ratings (the original rule). `shrinkage`: per dimension, the editor score is a prior worth `shrinkageK` ratings and the reader share is capped. */
|
|
37
|
+
combination: "blend" | "shrinkage";
|
|
38
|
+
/** Shrinkage: the editor score counts as this many reader ratings. */
|
|
39
|
+
shrinkageK: number;
|
|
40
|
+
/** Shrinkage: the reader mean never gets more than this share of the distance from the editor score. */
|
|
41
|
+
readerShareCap: number;
|
|
42
|
+
/** A rating from a profile younger than `limits.newAccountHours` counts for this fraction in the reader mean and count. Default 1/3 under `shrinkage`, 1 under `blend`. */
|
|
43
|
+
newAccountWeight: number;
|
|
44
|
+
/** Rising and the used-it reporter count only take profiles at least this many hours old; 0 takes all. Default 24 under `shrinkage`, 0 under `blend`. */
|
|
45
|
+
risingMinimumAccountHours: number;
|
|
36
46
|
};
|
|
37
47
|
snapshot: {
|
|
38
48
|
/** An EventBridge rule runs the snapshot every `intervalHours`. Off by default. */
|
|
@@ -84,7 +94,7 @@ export type ReaderSteeringConfig = {
|
|
|
84
94
|
};
|
|
85
95
|
/**
|
|
86
96
|
* The hype gap is `mean(plus dimensions) - mean(minus dimensions)`, computed for reader means and for editor scores.
|
|
87
|
-
* Absent means no hype gap is published.
|
|
97
|
+
* Absent means no hype gap is published. The site names the dimensions in each group.
|
|
88
98
|
*/
|
|
89
99
|
hypeGap?: { plus: string[]; minus: string[] };
|
|
90
100
|
/**
|
|
@@ -171,7 +181,12 @@ export function resolveReaderSteeringConfig(request: PluginRequest): ReaderSteer
|
|
|
171
181
|
if (reserved.length > 0) throw new Error(`reader-steering plugin dimensions cannot use the reserved names: ${reserved.join(", ")}`);
|
|
172
182
|
const limits = object(raw.limits, "limits", ["actionsPerHour", "newAccountHours", "newAccountDivisor"]);
|
|
173
183
|
const karma = object(raw.karma, "karma", ["upvoteWeight", "usedItWeight"]);
|
|
174
|
-
const ranking = object(raw.ranking, "ranking", [
|
|
184
|
+
const ranking = object(raw.ranking, "ranking", [
|
|
185
|
+
"halfLifeHours", "risingWindowHours", "readerMinimum", "editorWeight", "combination", "shrinkageK", "readerShareCap", "newAccountWeight", "risingMinimumAccountHours",
|
|
186
|
+
]);
|
|
187
|
+
const combination = ranking.combination === undefined ? "blend" : ranking.combination;
|
|
188
|
+
if (combination !== "blend" && combination !== "shrinkage") throw new Error("reader-steering plugin ranking.combination must be blend or shrinkage");
|
|
189
|
+
const shrinking = combination === "shrinkage";
|
|
175
190
|
const snapshot = object(raw.snapshot, "snapshot", ["schedule", "intervalHours", "hypeMinimum"]);
|
|
176
191
|
const submissions = object(raw.submissions, "submissions", ["perDay", "similarHours", "kinds", "itemType", "section"]);
|
|
177
192
|
const moderation = object(raw.moderation, "moderation", ["mode", "preModeration", "reportsPerDay", "ai"]);
|
|
@@ -216,6 +231,11 @@ export function resolveReaderSteeringConfig(request: PluginRequest): ReaderSteer
|
|
|
216
231
|
risingWindowHours: number(ranking.risingWindowHours, "ranking.risingWindowHours", 6, 1, 24 * 30),
|
|
217
232
|
readerMinimum: integer(ranking.readerMinimum, "ranking.readerMinimum", 5, 1, 10000),
|
|
218
233
|
editorWeight: number(ranking.editorWeight, "ranking.editorWeight", 0.5, 0, 1),
|
|
234
|
+
combination,
|
|
235
|
+
shrinkageK: number(ranking.shrinkageK, "ranking.shrinkageK", 20, 0.01, 10000),
|
|
236
|
+
readerShareCap: number(ranking.readerShareCap, "ranking.readerShareCap", 0.4, 0, 1),
|
|
237
|
+
newAccountWeight: number(ranking.newAccountWeight, "ranking.newAccountWeight", shrinking ? 1 / 3 : 1, 0, 1),
|
|
238
|
+
risingMinimumAccountHours: number(ranking.risingMinimumAccountHours, "ranking.risingMinimumAccountHours", shrinking ? 24 : 0, 0, 24 * 90),
|
|
219
239
|
},
|
|
220
240
|
snapshot: {
|
|
221
241
|
schedule: flag(snapshot.schedule, "snapshot.schedule"),
|
|
@@ -40,6 +40,7 @@ export function readerSnapshotSettings(config) {
|
|
|
40
40
|
submissions: config.submissions,
|
|
41
41
|
karma: config.karma,
|
|
42
42
|
ranking: config.ranking,
|
|
43
|
+
limits: { newAccountHours: config.limits.newAccountHours },
|
|
43
44
|
hypeMinimum: config.snapshot.hypeMinimum,
|
|
44
45
|
...(config.hypeGap ? { hypeGap: config.hypeGap } : {}),
|
|
45
46
|
retirementPoll: config.retirementPoll,
|
|
@@ -49,6 +49,7 @@ export function readerSnapshotSettings(config: ReaderSteeringConfig) {
|
|
|
49
49
|
submissions: config.submissions,
|
|
50
50
|
karma: config.karma,
|
|
51
51
|
ranking: config.ranking,
|
|
52
|
+
limits: { newAccountHours: config.limits.newAccountHours },
|
|
52
53
|
hypeMinimum: config.snapshot.hypeMinimum,
|
|
53
54
|
...(config.hypeGap ? { hypeGap: config.hypeGap } : {}),
|
|
54
55
|
retirementPoll: config.retirementPoll,
|
package/lib/semantic-graph.ts
CHANGED
|
@@ -57,6 +57,7 @@ export type SemanticPredicateId =
|
|
|
57
57
|
| "related_to"
|
|
58
58
|
| "broader_than"
|
|
59
59
|
| "narrower_than"
|
|
60
|
+
| "member_of"
|
|
60
61
|
| "supports"
|
|
61
62
|
| "contradicts";
|
|
62
63
|
|
|
@@ -96,6 +97,7 @@ export const SEMANTIC_PREDICATES: SemanticPredicateDefinition[] = [
|
|
|
96
97
|
{ id: "related_to", label: "related to", group: "generic", inverseLabel: "related from" },
|
|
97
98
|
{ id: "broader_than", label: "broader than", group: "ontology", inverseLabel: "narrower concept" },
|
|
98
99
|
{ id: "narrower_than", label: "narrower than", group: "ontology", inverseLabel: "broader concept" },
|
|
100
|
+
{ id: "member_of", label: "member of", group: "ontology", inverseLabel: "members" },
|
|
99
101
|
{ id: "supports", label: "supports", group: "evidence", inverseLabel: "supported by" },
|
|
100
102
|
{ id: "contradicts", label: "contradicts", group: "evidence", inverseLabel: "contradicted by" },
|
|
101
103
|
];
|
package/package.json
CHANGED
package/routes.manifest.json
CHANGED