@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.
@@ -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", ["halfLifeHours", "risingWindowHours", "readerMinimum", "editorWeight"]);
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, such as `real` and `useful`. `up` and `used-it` are always available. */
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. Shipped sets plus = notable, novel and minus = real, useful.
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", ["halfLifeHours", "risingWindowHours", "readerMinimum", "editorWeight"]);
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,
@@ -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
@@ -433,7 +433,7 @@
433
433
  "optional": true
434
434
  }
435
435
  },
436
- "version": "5.24.0",
436
+ "version": "5.26.0",
437
437
  "dependencies": {
438
438
  "@aws-amplify/adapter-nextjs": "^1.7.3",
439
439
  "@aws-crypto/sha256-js": "5.2.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.24.0",
2
+ "version": "5.26.0",
3
3
  "routes": [
4
4
  {
5
5
  "file": "app/%5F_preview/[[...path]]/route.ts",