scientify 1.9.0 → 1.10.1

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.
Files changed (63) hide show
  1. package/README.md +29 -0
  2. package/README.zh.md +29 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +29 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/src/hooks/research-mode.d.ts.map +1 -1
  7. package/dist/src/hooks/research-mode.js +6 -0
  8. package/dist/src/hooks/research-mode.js.map +1 -1
  9. package/dist/src/hooks/scientify-cron-autofill.d.ts +15 -0
  10. package/dist/src/hooks/scientify-cron-autofill.d.ts.map +1 -0
  11. package/dist/src/hooks/scientify-cron-autofill.js +156 -0
  12. package/dist/src/hooks/scientify-cron-autofill.js.map +1 -0
  13. package/dist/src/hooks/scientify-signature.d.ts.map +1 -1
  14. package/dist/src/hooks/scientify-signature.js +4 -1
  15. package/dist/src/hooks/scientify-signature.js.map +1 -1
  16. package/dist/src/literature/subscription-state.d.ts +90 -0
  17. package/dist/src/literature/subscription-state.d.ts.map +1 -0
  18. package/dist/src/literature/subscription-state.js +521 -0
  19. package/dist/src/literature/subscription-state.js.map +1 -0
  20. package/dist/src/research-subscriptions/constants.d.ts +16 -0
  21. package/dist/src/research-subscriptions/constants.d.ts.map +1 -0
  22. package/dist/src/research-subscriptions/constants.js +59 -0
  23. package/dist/src/research-subscriptions/constants.js.map +1 -0
  24. package/dist/src/research-subscriptions/cron-client.d.ts +8 -0
  25. package/dist/src/research-subscriptions/cron-client.d.ts.map +1 -0
  26. package/dist/src/research-subscriptions/cron-client.js +81 -0
  27. package/dist/src/research-subscriptions/cron-client.js.map +1 -0
  28. package/dist/src/research-subscriptions/delivery.d.ts +10 -0
  29. package/dist/src/research-subscriptions/delivery.d.ts.map +1 -0
  30. package/dist/src/research-subscriptions/delivery.js +82 -0
  31. package/dist/src/research-subscriptions/delivery.js.map +1 -0
  32. package/dist/src/research-subscriptions/handlers.d.ts +6 -0
  33. package/dist/src/research-subscriptions/handlers.d.ts.map +1 -0
  34. package/dist/src/research-subscriptions/handlers.js +200 -0
  35. package/dist/src/research-subscriptions/handlers.js.map +1 -0
  36. package/dist/src/research-subscriptions/parse.d.ts +11 -0
  37. package/dist/src/research-subscriptions/parse.d.ts.map +1 -0
  38. package/dist/src/research-subscriptions/parse.js +478 -0
  39. package/dist/src/research-subscriptions/parse.js.map +1 -0
  40. package/dist/src/research-subscriptions/prompt.d.ts +5 -0
  41. package/dist/src/research-subscriptions/prompt.d.ts.map +1 -0
  42. package/dist/src/research-subscriptions/prompt.js +161 -0
  43. package/dist/src/research-subscriptions/prompt.js.map +1 -0
  44. package/dist/src/research-subscriptions/types.d.ts +65 -0
  45. package/dist/src/research-subscriptions/types.d.ts.map +1 -0
  46. package/dist/src/research-subscriptions/types.js +2 -0
  47. package/dist/src/research-subscriptions/types.js.map +1 -0
  48. package/dist/src/research-subscriptions.d.ts +2 -0
  49. package/dist/src/research-subscriptions.d.ts.map +1 -0
  50. package/dist/src/research-subscriptions.js +2 -0
  51. package/dist/src/research-subscriptions.js.map +1 -0
  52. package/dist/src/tools/scientify-cron.d.ts +62 -0
  53. package/dist/src/tools/scientify-cron.d.ts.map +1 -0
  54. package/dist/src/tools/scientify-cron.js +224 -0
  55. package/dist/src/tools/scientify-cron.js.map +1 -0
  56. package/dist/src/tools/scientify-literature-state.d.ts +70 -0
  57. package/dist/src/tools/scientify-literature-state.d.ts.map +1 -0
  58. package/dist/src/tools/scientify-literature-state.js +312 -0
  59. package/dist/src/tools/scientify-literature-state.js.map +1 -0
  60. package/openclaw.plugin.json +2 -1
  61. package/package.json +1 -1
  62. package/skills/_shared/workspace-spec.md +13 -0
  63. package/skills/research-subscription/SKILL.md +102 -0
@@ -0,0 +1,478 @@
1
+ import { DEFAULT_CANDIDATE_POOL, DEFAULT_SCORE_WEIGHTS, DEFAULT_TIME, DEFAULT_TZ, MAX_CANDIDATE_POOL, MIN_CANDIDATE_POOL, SCORE_WEIGHT_KEYS, WEEKDAY_MAP, } from "./constants.js";
2
+ function tokenizeArgs(raw) {
3
+ const tokens = [];
4
+ let current = "";
5
+ let quote = null;
6
+ let escaped = false;
7
+ for (let i = 0; i < raw.length; i++) {
8
+ const ch = raw[i];
9
+ if (escaped) {
10
+ current += ch;
11
+ escaped = false;
12
+ continue;
13
+ }
14
+ if (quote) {
15
+ if (ch === "\\") {
16
+ const next = raw[i + 1];
17
+ if (next === quote || next === "\\") {
18
+ escaped = true;
19
+ continue;
20
+ }
21
+ }
22
+ if (ch === quote) {
23
+ quote = null;
24
+ }
25
+ else {
26
+ current += ch;
27
+ }
28
+ continue;
29
+ }
30
+ if (ch === '"' || ch === "'") {
31
+ quote = ch;
32
+ continue;
33
+ }
34
+ if (/\s/.test(ch)) {
35
+ if (current.length > 0) {
36
+ tokens.push(current);
37
+ current = "";
38
+ }
39
+ continue;
40
+ }
41
+ current += ch;
42
+ }
43
+ if (current.length > 0) {
44
+ tokens.push(current);
45
+ }
46
+ return tokens;
47
+ }
48
+ function parseTime(raw) {
49
+ const m = raw.match(/^([01]?\d|2[0-3]):([0-5]\d)$/);
50
+ if (!m)
51
+ return null;
52
+ return { hour: Number(m[1]), minute: Number(m[2]) };
53
+ }
54
+ function isValidTimezone(raw) {
55
+ try {
56
+ new Intl.DateTimeFormat("en-US", { timeZone: raw });
57
+ return true;
58
+ }
59
+ catch {
60
+ return false;
61
+ }
62
+ }
63
+ function validateEveryDuration(raw) {
64
+ return /^\d+[smhdw]$/i.test(raw);
65
+ }
66
+ export function isDurationLike(raw) {
67
+ return /^\+?\d+[smhdw]$/i.test(raw);
68
+ }
69
+ function validateCronExpr(raw) {
70
+ const fields = raw.trim().split(/\s+/);
71
+ return fields.length === 5 || fields.length === 6;
72
+ }
73
+ function isScoreWeightKey(raw) {
74
+ return SCORE_WEIGHT_KEYS.includes(raw);
75
+ }
76
+ function parseScoreWeights(raw) {
77
+ const value = raw.trim();
78
+ if (!value) {
79
+ return {
80
+ error: "Error: `--score-weights` expects a value, e.g. `--score-weights relevance:40,novelty:20,authority:30,actionability:10`.",
81
+ };
82
+ }
83
+ const parts = value
84
+ .split(",")
85
+ .map((item) => item.trim())
86
+ .filter((item) => item.length > 0);
87
+ if (parts.length === 0) {
88
+ return {
89
+ error: "Error: `--score-weights` expects a non-empty value, e.g. `--score-weights 40,20,30,10`.",
90
+ };
91
+ }
92
+ const parsed = {};
93
+ const hasNamedWeights = parts.some((item) => item.includes(":") || item.includes("="));
94
+ if (hasNamedWeights) {
95
+ for (const part of parts) {
96
+ const match = part.match(/^([a-z_]+)\s*[:=]\s*(-?\d+(?:\.\d+)?)$/i);
97
+ if (!match) {
98
+ return {
99
+ error: "Error: invalid `--score-weights` entry. Use `key:value` pairs, e.g. `relevance:40,novelty:20,authority:30,actionability:10`.",
100
+ };
101
+ }
102
+ const key = match[1].toLowerCase();
103
+ if (!isScoreWeightKey(key)) {
104
+ return {
105
+ error: "Error: unknown score weight key. Allowed keys: relevance, novelty, authority, actionability.",
106
+ };
107
+ }
108
+ const num = Number(match[2]);
109
+ if (!Number.isFinite(num) || num < 0 || num > 100) {
110
+ return {
111
+ error: `Error: score weight \`${key}\` must be between 0 and 100.`,
112
+ };
113
+ }
114
+ parsed[key] = num;
115
+ }
116
+ }
117
+ else {
118
+ if (parts.length !== 4) {
119
+ return {
120
+ error: "Error: positional `--score-weights` needs exactly 4 numbers: relevance,novelty,authority,actionability.",
121
+ };
122
+ }
123
+ const nums = parts.map((part) => Number(part));
124
+ if (nums.some((num) => !Number.isFinite(num) || num < 0 || num > 100)) {
125
+ return {
126
+ error: "Error: each positional score weight must be between 0 and 100.",
127
+ };
128
+ }
129
+ parsed.relevance = nums[0];
130
+ parsed.novelty = nums[1];
131
+ parsed.authority = nums[2];
132
+ parsed.actionability = nums[3];
133
+ }
134
+ const merged = {
135
+ relevance: parsed.relevance ?? DEFAULT_SCORE_WEIGHTS.relevance,
136
+ novelty: parsed.novelty ?? DEFAULT_SCORE_WEIGHTS.novelty,
137
+ authority: parsed.authority ?? DEFAULT_SCORE_WEIGHTS.authority,
138
+ actionability: parsed.actionability ?? DEFAULT_SCORE_WEIGHTS.actionability,
139
+ };
140
+ const sum = merged.relevance + merged.novelty + merged.authority + merged.actionability;
141
+ if (sum <= 0) {
142
+ return {
143
+ error: "Error: score weights must sum to a positive value.",
144
+ };
145
+ }
146
+ return merged;
147
+ }
148
+ export function resolveCandidatePool(candidatePool, maxPapers) {
149
+ const base = candidatePool ?? Math.max(DEFAULT_CANDIDATE_POOL, maxPapers);
150
+ const normalized = Math.floor(base);
151
+ return Math.max(maxPapers, Math.min(MAX_CANDIDATE_POOL, Math.max(MIN_CANDIDATE_POOL, normalized)));
152
+ }
153
+ export function formatScoreWeights(weights) {
154
+ const sum = weights.relevance + weights.novelty + weights.authority + weights.actionability;
155
+ const ratio = (value) => {
156
+ const pct = (value / sum) * 100;
157
+ const text = pct.toFixed(1);
158
+ return text.endsWith(".0") ? `${text.slice(0, -2)}%` : `${text}%`;
159
+ };
160
+ return `relevance ${ratio(weights.relevance)}, novelty ${ratio(weights.novelty)}, authority ${ratio(weights.authority)}, actionability ${ratio(weights.actionability)}`;
161
+ }
162
+ function parseTimeAndTz(tokens, startIndex) {
163
+ let time = DEFAULT_TIME;
164
+ let tz = DEFAULT_TZ;
165
+ const first = tokens[startIndex];
166
+ const second = tokens[startIndex + 1];
167
+ if (!first) {
168
+ return { time, tz };
169
+ }
170
+ if (parseTime(first)) {
171
+ time = first;
172
+ if (second) {
173
+ if (!isValidTimezone(second)) {
174
+ return {
175
+ error: `Error: invalid timezone \`${second}\`. Use an IANA timezone like \`Asia/Shanghai\`.`,
176
+ };
177
+ }
178
+ tz = second;
179
+ }
180
+ return { time, tz };
181
+ }
182
+ if (!isValidTimezone(first)) {
183
+ return {
184
+ error: `Error: invalid time format \`${first}\`. Use \`HH:MM\` (24-hour) or a timezone value.`,
185
+ };
186
+ }
187
+ tz = first;
188
+ return { time, tz };
189
+ }
190
+ export function parseScheduleArgs(tokens) {
191
+ if (tokens.length === 0) {
192
+ const parsed = parseTime(DEFAULT_TIME);
193
+ const expr = `${parsed.minute} ${parsed.hour} * * *`;
194
+ return { kind: "cron", expr, tz: DEFAULT_TZ, display: `daily ${DEFAULT_TIME} (${DEFAULT_TZ})` };
195
+ }
196
+ const mode = tokens[0]?.toLowerCase();
197
+ if (mode === "daily" || mode === "day") {
198
+ const parsed = parseTimeAndTz(tokens, 1);
199
+ if ("error" in parsed)
200
+ return parsed;
201
+ const time = parseTime(parsed.time);
202
+ return {
203
+ kind: "cron",
204
+ expr: `${time.minute} ${time.hour} * * *`,
205
+ tz: parsed.tz,
206
+ display: `daily ${parsed.time} (${parsed.tz})`,
207
+ };
208
+ }
209
+ if (mode === "weekly" || mode === "week") {
210
+ const dayToken = (tokens[1] ?? "").toLowerCase();
211
+ const dow = WEEKDAY_MAP[dayToken];
212
+ if (dow === undefined) {
213
+ return {
214
+ error: "Error: weekly mode requires a weekday, for example \`mon\`, \`tue\`, or \`sun\`.",
215
+ };
216
+ }
217
+ const parsed = parseTimeAndTz(tokens, 2);
218
+ if ("error" in parsed)
219
+ return parsed;
220
+ const time = parseTime(parsed.time);
221
+ return {
222
+ kind: "cron",
223
+ expr: `${time.minute} ${time.hour} * * ${dow}`,
224
+ tz: parsed.tz,
225
+ display: `weekly ${tokens[1]} ${parsed.time} (${parsed.tz})`,
226
+ };
227
+ }
228
+ if (mode === "every") {
229
+ const duration = tokens[1];
230
+ if (!duration || !validateEveryDuration(duration)) {
231
+ return {
232
+ error: "Error: every mode needs an interval, for example \`every 6h\` or \`every 30m\`.",
233
+ };
234
+ }
235
+ return {
236
+ kind: "every",
237
+ duration,
238
+ display: `every ${duration}`,
239
+ };
240
+ }
241
+ if (mode === "at" || mode === "once") {
242
+ const when = tokens[1];
243
+ if (!when) {
244
+ return {
245
+ error: "Error: at mode needs a time value, for example \`at 2m\` or \`at 2026-03-04T08:00:00+08:00\`.",
246
+ };
247
+ }
248
+ if (isDurationLike(when)) {
249
+ return {
250
+ kind: "at",
251
+ when: when.startsWith("+") ? when.slice(1) : when,
252
+ display: `at ${when}`,
253
+ };
254
+ }
255
+ const date = new Date(when);
256
+ if (Number.isNaN(date.getTime())) {
257
+ return {
258
+ error: "Error: invalid at time format. Use a duration like \`2m\` or an ISO datetime like \`2026-03-04T08:00:00+08:00\`.",
259
+ };
260
+ }
261
+ return {
262
+ kind: "at",
263
+ when,
264
+ display: `at ${when}`,
265
+ };
266
+ }
267
+ if (mode === "cron") {
268
+ let expr = "";
269
+ let tz = DEFAULT_TZ;
270
+ if (tokens[1]?.includes(" ")) {
271
+ expr = tokens[1];
272
+ tz = tokens[2] ?? DEFAULT_TZ;
273
+ if (tokens.length > 3) {
274
+ return {
275
+ error: "Error: invalid cron mode format. Use either `cron \"<expr>\" [TZ]` or split fields (`cron 0 9 * * * [TZ]`).",
276
+ };
277
+ }
278
+ }
279
+ else {
280
+ const valueCount = tokens.length - 1;
281
+ if (valueCount < 5 || valueCount > 7) {
282
+ return {
283
+ error: "Error: invalid cron mode format. Example: `cron \"0 9 * * *\" Asia/Shanghai`, `cron 0 9 * * * Asia/Shanghai`, or `cron 0 0 9 * * * Asia/Shanghai`.",
284
+ };
285
+ }
286
+ if (valueCount === 7) {
287
+ expr = tokens.slice(1, 7).join(" ").trim();
288
+ tz = tokens[7] ?? DEFAULT_TZ;
289
+ }
290
+ else if (valueCount === 6) {
291
+ const maybeTz = tokens[6];
292
+ if (maybeTz && isValidTimezone(maybeTz)) {
293
+ expr = tokens.slice(1, 6).join(" ").trim();
294
+ tz = maybeTz;
295
+ }
296
+ else {
297
+ expr = tokens.slice(1, 7).join(" ").trim();
298
+ tz = DEFAULT_TZ;
299
+ }
300
+ }
301
+ else {
302
+ expr = tokens.slice(1, 6).join(" ").trim();
303
+ tz = DEFAULT_TZ;
304
+ }
305
+ }
306
+ if (!validateCronExpr(expr)) {
307
+ return {
308
+ error: "Error: invalid cron mode format. Example: \`cron \"0 9 * * *\" Asia/Shanghai\` or \`cron 0 9 * * * Asia/Shanghai\`.",
309
+ };
310
+ }
311
+ if (!isValidTimezone(tz)) {
312
+ return {
313
+ error: `Error: invalid timezone \`${tz}\`. Use an IANA timezone like \`Asia/Shanghai\`.`,
314
+ };
315
+ }
316
+ return {
317
+ kind: "cron",
318
+ expr,
319
+ tz,
320
+ display: `cron ${expr} (${tz})`,
321
+ };
322
+ }
323
+ return {
324
+ error: "Error: usage is \`/research-subscribe daily [HH:MM] [TZ]\`, \`/research-subscribe weekly <day> [HH:MM] [TZ]\`, \`/research-subscribe every <duration>\`, \`/research-subscribe at <2m|ISO>\`, or \`/research-subscribe cron \"<expr>\" [TZ]\`.",
325
+ };
326
+ }
327
+ export function parseSubscribeOptions(rawArgs) {
328
+ const tokens = tokenizeArgs((rawArgs ?? "").trim());
329
+ const scheduleTokens = [];
330
+ let channelOverride;
331
+ let toOverride;
332
+ let topic;
333
+ let message;
334
+ let maxPapers;
335
+ let recencyDays;
336
+ let sources;
337
+ let candidatePool;
338
+ let scoreWeights;
339
+ let noDeliver = false;
340
+ for (let i = 0; i < tokens.length; i++) {
341
+ const token = tokens[i];
342
+ if (token === "--channel") {
343
+ const value = tokens[i + 1];
344
+ if (!value) {
345
+ return { error: "Error: \`--channel\` expects a value, e.g. \`--channel feishu\`." };
346
+ }
347
+ channelOverride = value.toLowerCase();
348
+ i++;
349
+ continue;
350
+ }
351
+ if (token === "--to") {
352
+ const value = tokens[i + 1];
353
+ if (!value) {
354
+ return { error: "Error: \`--to\` expects a value, e.g. \`--to user_or_chat_id\`." };
355
+ }
356
+ toOverride = value;
357
+ i++;
358
+ continue;
359
+ }
360
+ if (token === "--no-deliver") {
361
+ noDeliver = true;
362
+ continue;
363
+ }
364
+ if (token === "--topic") {
365
+ const value = tokens[i + 1];
366
+ if (!value) {
367
+ return { error: "Error: \`--topic\` expects a value, e.g. \`--topic \"multimodal LLM safety\"\`." };
368
+ }
369
+ topic = value;
370
+ i++;
371
+ continue;
372
+ }
373
+ if (token === "--message") {
374
+ const value = tokens[i + 1];
375
+ if (!value) {
376
+ return { error: "Error: `--message` expects a value, e.g. `--message \"Time to drink water.\"`." };
377
+ }
378
+ message = value;
379
+ i++;
380
+ continue;
381
+ }
382
+ if (token === "--max-papers") {
383
+ const value = tokens[i + 1];
384
+ if (!value) {
385
+ return { error: "Error: `--max-papers` expects an integer value, e.g. `--max-papers 3`." };
386
+ }
387
+ const num = Number.parseInt(value, 10);
388
+ if (!Number.isFinite(num) || num < 1 || num > 20) {
389
+ return { error: "Error: `--max-papers` must be an integer between 1 and 20." };
390
+ }
391
+ maxPapers = num;
392
+ i++;
393
+ continue;
394
+ }
395
+ if (token === "--recency-days") {
396
+ const value = tokens[i + 1];
397
+ if (!value) {
398
+ return { error: "Error: `--recency-days` expects an integer value, e.g. `--recency-days 30`." };
399
+ }
400
+ const num = Number.parseInt(value, 10);
401
+ if (!Number.isFinite(num) || num < 1 || num > 3650) {
402
+ return { error: "Error: `--recency-days` must be an integer between 1 and 3650." };
403
+ }
404
+ recencyDays = num;
405
+ i++;
406
+ continue;
407
+ }
408
+ if (token === "--sources") {
409
+ const value = tokens[i + 1];
410
+ if (!value) {
411
+ return { error: "Error: `--sources` expects a CSV value, e.g. `--sources arxiv,openalex`." };
412
+ }
413
+ const parsed = value
414
+ .split(",")
415
+ .map((item) => item.trim().toLowerCase())
416
+ .filter((item) => item.length > 0);
417
+ if (parsed.length === 0) {
418
+ return { error: "Error: `--sources` must include at least one source." };
419
+ }
420
+ sources = [...new Set(parsed)];
421
+ i++;
422
+ continue;
423
+ }
424
+ if (token === "--candidate-pool") {
425
+ const value = tokens[i + 1];
426
+ if (!value) {
427
+ return { error: "Error: `--candidate-pool` expects an integer value, e.g. `--candidate-pool 12`." };
428
+ }
429
+ const num = Number.parseInt(value, 10);
430
+ if (!Number.isFinite(num) || num < MIN_CANDIDATE_POOL || num > MAX_CANDIDATE_POOL) {
431
+ return {
432
+ error: `Error: \`--candidate-pool\` must be an integer between ${MIN_CANDIDATE_POOL} and ${MAX_CANDIDATE_POOL}.`,
433
+ };
434
+ }
435
+ candidatePool = num;
436
+ i++;
437
+ continue;
438
+ }
439
+ if (token === "--score-weights") {
440
+ const value = tokens[i + 1];
441
+ if (!value) {
442
+ return {
443
+ error: "Error: `--score-weights` expects a value, e.g. `--score-weights relevance:40,novelty:20,authority:30,actionability:10`.",
444
+ };
445
+ }
446
+ const parsed = parseScoreWeights(value);
447
+ if ("error" in parsed) {
448
+ return parsed;
449
+ }
450
+ scoreWeights = parsed;
451
+ i++;
452
+ continue;
453
+ }
454
+ if (token.startsWith("--")) {
455
+ return { error: `Error: unknown argument \`${token}\`.` };
456
+ }
457
+ scheduleTokens.push(token);
458
+ }
459
+ if (candidatePool !== undefined && maxPapers !== undefined && candidatePool < maxPapers) {
460
+ return {
461
+ error: "Error: `--candidate-pool` must be greater than or equal to `--max-papers`.",
462
+ };
463
+ }
464
+ return {
465
+ scheduleTokens,
466
+ channelOverride,
467
+ toOverride,
468
+ noDeliver,
469
+ topic,
470
+ message,
471
+ ...(maxPapers !== undefined ? { maxPapers } : {}),
472
+ ...(recencyDays !== undefined ? { recencyDays } : {}),
473
+ ...(sources && sources.length > 0 ? { sources } : {}),
474
+ ...(candidatePool !== undefined ? { candidatePool } : {}),
475
+ ...(scoreWeights ? { scoreWeights } : {}),
476
+ };
477
+ }
478
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/research-subscriptions/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { ScheduleSpec, SubscriptionOptions } from "./types.js";
2
+ export declare function buildScheduledTaskMessage(options: Pick<SubscriptionOptions, "topic" | "message" | "maxPapers" | "recencyDays" | "sources" | "candidatePool" | "scoreWeights">, scheduleKind: ScheduleSpec["kind"], scopeKey: string): string;
3
+ export declare function formatUsage(): string;
4
+ export declare function withSignature(text: string): string;
5
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/research-subscriptions/prompt.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAiCpE,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,IAAI,CACX,mBAAmB,EACnB,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,eAAe,GAAG,cAAc,CACjG,EACD,YAAY,EAAE,YAAY,CAAC,MAAM,CAAC,EAClC,QAAQ,EAAE,MAAM,GACf,MAAM,CA8GR;AAED,wBAAgB,WAAW,IAAI,MAAM,CAqBpC;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD"}
@@ -0,0 +1,161 @@
1
+ import { DEFAULT_CRON_PROMPT, DEFAULT_SCORE_WEIGHTS, REMINDER_HINT_RE, RESEARCH_HINT_RE, SCIENTIFY_SIGNATURE_FOOTER, } from "./constants.js";
2
+ import { formatScoreWeights, resolveCandidatePool } from "./parse.js";
3
+ function normalizeReminderText(raw) {
4
+ let text = raw.trim();
5
+ text = text.replace(/^(please\s+)?remind\s+(me|us|you)\s+(to\s+)?/i, "");
6
+ text = text.replace(/^remember\s+to\s+/i, "");
7
+ text = text.replace(/^(请)?(提醒我|提醒你|提醒|记得)(一下|一声)?[::,\s]*/u, "");
8
+ const normalized = text.trim();
9
+ return normalized.length > 0 ? normalized : raw.trim();
10
+ }
11
+ function inferReminderMessageFromTopic(topic) {
12
+ const trimmed = topic?.trim();
13
+ if (!trimmed)
14
+ return undefined;
15
+ if (!REMINDER_HINT_RE.test(trimmed))
16
+ return undefined;
17
+ if (RESEARCH_HINT_RE.test(trimmed))
18
+ return undefined;
19
+ return normalizeReminderText(trimmed);
20
+ }
21
+ function buildPreferencePayload(options) {
22
+ const maxPapers = options.maxPapers ?? 3;
23
+ const normalizedSources = options.sources?.map((item) => item.trim().toLowerCase()).filter(Boolean);
24
+ return {
25
+ max_papers: Math.max(1, Math.min(20, Math.floor(maxPapers))),
26
+ ...(options.recencyDays ? { recency_days: options.recencyDays } : {}),
27
+ ...(normalizedSources && normalizedSources.length > 0 ? { sources: [...new Set(normalizedSources)] } : {}),
28
+ };
29
+ }
30
+ export function buildScheduledTaskMessage(options, scheduleKind, scopeKey) {
31
+ const customMessage = options.message?.trim();
32
+ if (customMessage) {
33
+ return [
34
+ "Scheduled reminder task.",
35
+ `Please send this reminder now: \"${customMessage}\"`,
36
+ "Keep the reminder concise and do not run a research workflow unless explicitly requested.",
37
+ ].join("\n");
38
+ }
39
+ const reminderFromTopic = inferReminderMessageFromTopic(options.topic);
40
+ if (reminderFromTopic) {
41
+ return [
42
+ "Scheduled reminder task.",
43
+ `Please send this reminder now: \"${reminderFromTopic}\"`,
44
+ "Keep the reminder concise and do not run a research workflow unless explicitly requested.",
45
+ ].join("\n");
46
+ }
47
+ const trimmedTopic = options.topic?.trim();
48
+ if (!trimmedTopic) {
49
+ return DEFAULT_CRON_PROMPT;
50
+ }
51
+ const preferences = buildPreferencePayload(options);
52
+ const candidatePool = resolveCandidatePool(options.candidatePool, preferences.max_papers);
53
+ const scoreWeights = options.scoreWeights ?? DEFAULT_SCORE_WEIGHTS;
54
+ const scoreWeightsText = formatScoreWeights(scoreWeights);
55
+ const preparePayload = JSON.stringify({
56
+ action: "prepare",
57
+ scope: scopeKey,
58
+ topic: trimmedTopic,
59
+ preferences,
60
+ });
61
+ const recordPaperTemplate = [
62
+ {
63
+ id: "arxiv:2501.12345",
64
+ title: "Paper title",
65
+ url: "https://arxiv.org/abs/2501.12345",
66
+ score: 92,
67
+ reason: "High topical relevance and strong authority.",
68
+ },
69
+ {
70
+ id: "doi:10.1000/xyz123",
71
+ title: "Paper title 2",
72
+ url: "https://doi.org/10.1000/xyz123",
73
+ score: 88,
74
+ reason: "Novel method with clear practical impact.",
75
+ },
76
+ ];
77
+ const recordTemplate = JSON.stringify({
78
+ action: "record",
79
+ scope: scopeKey,
80
+ topic: trimmedTopic,
81
+ status: "ok",
82
+ papers: recordPaperTemplate,
83
+ });
84
+ const recordFallbackTemplate = JSON.stringify({
85
+ action: "record",
86
+ scope: scopeKey,
87
+ topic: trimmedTopic,
88
+ status: "fallback_representative",
89
+ papers: recordPaperTemplate,
90
+ note: "No unseen papers this cycle; delivered best representative papers instead.",
91
+ });
92
+ const recordEmptyTemplate = JSON.stringify({
93
+ action: "record",
94
+ scope: scopeKey,
95
+ topic: trimmedTopic,
96
+ status: "empty",
97
+ papers: [],
98
+ note: "No suitable paper found in incremental pass and fallback representative pass.",
99
+ });
100
+ if (scheduleKind === "at") {
101
+ return [
102
+ `/research-pipeline Run a focused literature study on \"${trimmedTopic}\" and return up to ${preferences.max_papers} high-value representative papers.`,
103
+ "",
104
+ "Mandatory workflow:",
105
+ `1) Call tool \`scientify_literature_state\` with: ${preparePayload}`,
106
+ "2) Read `memory_hints` from prepare result. Treat preferred keywords/sources as positive ranking priors, and avoided ones as negative priors.",
107
+ `3) Build a candidate pool of around ${candidatePool} papers when possible, matching returned preferences (sources/recency).`,
108
+ `4) Score each candidate with weighted dimensions (${scoreWeightsText}). Each dimension is 0-100, then compute weighted average score.`,
109
+ `5) Apply memory prior adjustment to the score (up-rank preferred keyword/source matches; down-rank avoided matches).`,
110
+ `6) Select top ${preferences.max_papers} papers, then call \`scientify_literature_state\` to persist selected papers (include score/reason) using this JSON shape: ${recordTemplate}`,
111
+ "7) In user-facing output, do not display score/reason unless explicitly requested. Show only conclusions and source links.",
112
+ "8) If nothing suitable is found, still call record with empty papers using:",
113
+ `${recordEmptyTemplate}`,
114
+ "Then respond: `No new literature found.`",
115
+ ].join("\n");
116
+ }
117
+ return [
118
+ `/research-pipeline Run an incremental literature check focused on \"${trimmedTopic}\".`,
119
+ "",
120
+ "Mandatory workflow:",
121
+ `1) Call tool \`scientify_literature_state\` with: ${preparePayload}`,
122
+ "2) Read `memory_hints` from prepare result. Use them as quiet personalization priors in ranking (not user-facing).",
123
+ "3) Treat `exclude_paper_ids` as hard dedupe constraints. Do not push papers whose IDs are already in that list.",
124
+ `4) Incremental pass: build a candidate pool of around ${candidatePool} unseen papers when possible, following preferences (sources/recency).`,
125
+ `5) Score each candidate with weighted dimensions (${scoreWeightsText}). Each dimension is 0-100, then compute weighted average score.`,
126
+ "6) Apply memory prior adjustment to the score (up-rank preferred keyword/source matches; down-rank avoided matches).",
127
+ `7) Select at most ${preferences.max_papers} top-ranked unseen papers. If selected > 0, call \`scientify_literature_state\` with status \`ok\` using: ${recordTemplate}`,
128
+ "8) If incremental selection is empty, run one fallback representative pass (ignore `exclude_paper_ids` once) and select best representative papers.",
129
+ `9) If fallback returns papers, call \`scientify_literature_state\` with status \`fallback_representative\` using: ${recordFallbackTemplate}`,
130
+ "10) In user-facing output, do not expose score/reason unless explicitly requested.",
131
+ "11) If both incremental and fallback passes are empty, call record with empty papers using:",
132
+ `${recordEmptyTemplate}`,
133
+ "Then reply exactly: `No new literature found.`",
134
+ ].join("\n");
135
+ }
136
+ export function formatUsage() {
137
+ return [
138
+ "## Scientify Scheduled Subscription",
139
+ "",
140
+ "Examples:",
141
+ "- `/research-subscribe`",
142
+ "- `/research-subscribe daily 09:00 Asia/Shanghai`",
143
+ "- `/research-subscribe weekly mon 09:30 Asia/Shanghai`",
144
+ "- `/research-subscribe every 6h`",
145
+ "- `/research-subscribe at 2m`",
146
+ "- `/research-subscribe at 2026-03-04T08:00:00+08:00`",
147
+ "- `/research-subscribe cron \"0 9 * * 1\" Asia/Shanghai`",
148
+ "- `/research-subscribe daily 09:00 --channel feishu --to ou_xxx`",
149
+ "- `/research-subscribe every 2h --channel telegram --to 12345678`",
150
+ "- `/research-subscribe at 2m --channel webui`",
151
+ "- `/research-subscribe daily 08:00 --topic \"LLM alignment\"`",
152
+ "- `/research-subscribe daily 08:00 --topic \"LLM alignment\" --max-papers 5 --sources arxiv,openalex`",
153
+ "- `/research-subscribe daily 08:00 --topic \"LLM alignment\" --candidate-pool 12 --score-weights relevance:45,novelty:20,authority:25,actionability:10`",
154
+ "- `/research-subscribe at 1m --message \"Time to drink coffee.\"`",
155
+ "- `/research-subscribe daily 09:00 --no-deliver`",
156
+ ].join("\n");
157
+ }
158
+ export function withSignature(text) {
159
+ return `${text}\n${SCIENTIFY_SIGNATURE_FOOTER}`;
160
+ }
161
+ //# sourceMappingURL=prompt.js.map