scientify 2.1.0 → 3.0.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.
Files changed (138) hide show
  1. package/dist/index.d.ts.map +1 -1
  2. package/dist/index.js +1 -76
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/cli/research.d.ts.map +1 -1
  5. package/dist/src/cli/research.js +6 -23
  6. package/dist/src/cli/research.js.map +1 -1
  7. package/dist/src/commands/metabolism-status.d.ts.map +1 -1
  8. package/dist/src/commands/metabolism-status.js +5 -25
  9. package/dist/src/commands/metabolism-status.js.map +1 -1
  10. package/dist/src/commands.d.ts +8 -8
  11. package/dist/src/commands.d.ts.map +1 -1
  12. package/dist/src/commands.js +91 -262
  13. package/dist/src/commands.js.map +1 -1
  14. package/dist/src/templates/bootstrap.d.ts.map +1 -1
  15. package/dist/src/templates/bootstrap.js +45 -59
  16. package/dist/src/templates/bootstrap.js.map +1 -1
  17. package/dist/src/types.d.ts +2 -10
  18. package/dist/src/types.d.ts.map +1 -1
  19. package/openclaw.plugin.json +3 -16
  20. package/package.json +2 -3
  21. package/skills/idea-generation/SKILL.md +20 -44
  22. package/skills/idea-generation/references/code-mapping.md +3 -3
  23. package/skills/idea-generation/references/idea-template.md +1 -1
  24. package/skills/idea-generation/references/reading-long-papers.md +3 -3
  25. package/skills/metabolism/SKILL.md +80 -36
  26. package/skills/paper-download/SKILL.md +61 -0
  27. package/skills/research-collect/SKILL.md +41 -111
  28. package/skills/research-experiment/SKILL.md +11 -12
  29. package/skills/research-implement/SKILL.md +10 -11
  30. package/skills/research-pipeline/SKILL.md +23 -31
  31. package/skills/research-plan/SKILL.md +7 -11
  32. package/skills/research-review/SKILL.md +21 -22
  33. package/skills/research-survey/SKILL.md +11 -25
  34. package/skills/write-review-paper/SKILL.md +12 -12
  35. package/skills/write-review-paper/references/note-template.md +1 -1
  36. package/skills/write-review-paper/references/survey-template.md +1 -1
  37. package/dist/src/hooks/research-mode.d.ts +0 -22
  38. package/dist/src/hooks/research-mode.d.ts.map +0 -1
  39. package/dist/src/hooks/research-mode.js +0 -35
  40. package/dist/src/hooks/research-mode.js.map +0 -1
  41. package/dist/src/hooks/scientify-cron-autofill.d.ts +0 -15
  42. package/dist/src/hooks/scientify-cron-autofill.d.ts.map +0 -1
  43. package/dist/src/hooks/scientify-cron-autofill.js +0 -156
  44. package/dist/src/hooks/scientify-cron-autofill.js.map +0 -1
  45. package/dist/src/hooks/scientify-signature.d.ts +0 -21
  46. package/dist/src/hooks/scientify-signature.d.ts.map +0 -1
  47. package/dist/src/hooks/scientify-signature.js +0 -150
  48. package/dist/src/hooks/scientify-signature.js.map +0 -1
  49. package/dist/src/knowledge-state/project.d.ts +0 -13
  50. package/dist/src/knowledge-state/project.d.ts.map +0 -1
  51. package/dist/src/knowledge-state/project.js +0 -88
  52. package/dist/src/knowledge-state/project.js.map +0 -1
  53. package/dist/src/knowledge-state/render.d.ts +0 -63
  54. package/dist/src/knowledge-state/render.d.ts.map +0 -1
  55. package/dist/src/knowledge-state/render.js +0 -368
  56. package/dist/src/knowledge-state/render.js.map +0 -1
  57. package/dist/src/knowledge-state/store.d.ts +0 -19
  58. package/dist/src/knowledge-state/store.d.ts.map +0 -1
  59. package/dist/src/knowledge-state/store.js +0 -978
  60. package/dist/src/knowledge-state/store.js.map +0 -1
  61. package/dist/src/knowledge-state/types.d.ts +0 -182
  62. package/dist/src/knowledge-state/types.d.ts.map +0 -1
  63. package/dist/src/knowledge-state/types.js +0 -2
  64. package/dist/src/knowledge-state/types.js.map +0 -1
  65. package/dist/src/literature/subscription-state.d.ts +0 -112
  66. package/dist/src/literature/subscription-state.d.ts.map +0 -1
  67. package/dist/src/literature/subscription-state.js +0 -696
  68. package/dist/src/literature/subscription-state.js.map +0 -1
  69. package/dist/src/research-subscriptions/constants.d.ts +0 -16
  70. package/dist/src/research-subscriptions/constants.d.ts.map +0 -1
  71. package/dist/src/research-subscriptions/constants.js +0 -59
  72. package/dist/src/research-subscriptions/constants.js.map +0 -1
  73. package/dist/src/research-subscriptions/cron-client.d.ts +0 -8
  74. package/dist/src/research-subscriptions/cron-client.d.ts.map +0 -1
  75. package/dist/src/research-subscriptions/cron-client.js +0 -81
  76. package/dist/src/research-subscriptions/cron-client.js.map +0 -1
  77. package/dist/src/research-subscriptions/delivery.d.ts +0 -10
  78. package/dist/src/research-subscriptions/delivery.d.ts.map +0 -1
  79. package/dist/src/research-subscriptions/delivery.js +0 -82
  80. package/dist/src/research-subscriptions/delivery.js.map +0 -1
  81. package/dist/src/research-subscriptions/handlers.d.ts +0 -6
  82. package/dist/src/research-subscriptions/handlers.d.ts.map +0 -1
  83. package/dist/src/research-subscriptions/handlers.js +0 -204
  84. package/dist/src/research-subscriptions/handlers.js.map +0 -1
  85. package/dist/src/research-subscriptions/parse.d.ts +0 -11
  86. package/dist/src/research-subscriptions/parse.d.ts.map +0 -1
  87. package/dist/src/research-subscriptions/parse.js +0 -492
  88. package/dist/src/research-subscriptions/parse.js.map +0 -1
  89. package/dist/src/research-subscriptions/prompt.d.ts +0 -5
  90. package/dist/src/research-subscriptions/prompt.d.ts.map +0 -1
  91. package/dist/src/research-subscriptions/prompt.js +0 -347
  92. package/dist/src/research-subscriptions/prompt.js.map +0 -1
  93. package/dist/src/research-subscriptions/types.d.ts +0 -66
  94. package/dist/src/research-subscriptions/types.d.ts.map +0 -1
  95. package/dist/src/research-subscriptions/types.js +0 -2
  96. package/dist/src/research-subscriptions/types.js.map +0 -1
  97. package/dist/src/research-subscriptions.d.ts +0 -2
  98. package/dist/src/research-subscriptions.d.ts.map +0 -1
  99. package/dist/src/research-subscriptions.js +0 -2
  100. package/dist/src/research-subscriptions.js.map +0 -1
  101. package/dist/src/services/auto-updater.d.ts +0 -15
  102. package/dist/src/services/auto-updater.d.ts.map +0 -1
  103. package/dist/src/services/auto-updater.js +0 -188
  104. package/dist/src/services/auto-updater.js.map +0 -1
  105. package/dist/src/tools/arxiv-download.d.ts +0 -24
  106. package/dist/src/tools/arxiv-download.d.ts.map +0 -1
  107. package/dist/src/tools/arxiv-download.js +0 -177
  108. package/dist/src/tools/arxiv-download.js.map +0 -1
  109. package/dist/src/tools/github-search-tool.d.ts +0 -25
  110. package/dist/src/tools/github-search-tool.d.ts.map +0 -1
  111. package/dist/src/tools/github-search-tool.js +0 -114
  112. package/dist/src/tools/github-search-tool.js.map +0 -1
  113. package/dist/src/tools/openreview-lookup.d.ts +0 -31
  114. package/dist/src/tools/openreview-lookup.d.ts.map +0 -1
  115. package/dist/src/tools/openreview-lookup.js +0 -414
  116. package/dist/src/tools/openreview-lookup.js.map +0 -1
  117. package/dist/src/tools/paper-browser.d.ts +0 -23
  118. package/dist/src/tools/paper-browser.d.ts.map +0 -1
  119. package/dist/src/tools/paper-browser.js +0 -121
  120. package/dist/src/tools/paper-browser.js.map +0 -1
  121. package/dist/src/tools/scientify-cron.d.ts +0 -63
  122. package/dist/src/tools/scientify-cron.d.ts.map +0 -1
  123. package/dist/src/tools/scientify-cron.js +0 -265
  124. package/dist/src/tools/scientify-cron.js.map +0 -1
  125. package/dist/src/tools/scientify-literature-state.d.ts +0 -303
  126. package/dist/src/tools/scientify-literature-state.d.ts.map +0 -1
  127. package/dist/src/tools/scientify-literature-state.js +0 -957
  128. package/dist/src/tools/scientify-literature-state.js.map +0 -1
  129. package/dist/src/tools/unpaywall-download.d.ts +0 -21
  130. package/dist/src/tools/unpaywall-download.d.ts.map +0 -1
  131. package/dist/src/tools/unpaywall-download.js +0 -169
  132. package/dist/src/tools/unpaywall-download.js.map +0 -1
  133. package/dist/src/tools/workspace.d.ts +0 -32
  134. package/dist/src/tools/workspace.d.ts.map +0 -1
  135. package/dist/src/tools/workspace.js +0 -69
  136. package/dist/src/tools/workspace.js.map +0 -1
  137. package/skills/metabolism-init/SKILL.md +0 -80
  138. package/skills/research-subscription/SKILL.md +0 -119
@@ -1,957 +0,0 @@
1
- import { Type } from "@sinclair/typebox";
2
- import { getIncrementalStateStatus, prepareIncrementalState, recordIncrementalPush, recordUserFeedback, } from "../literature/subscription-state.js";
3
- import { Result } from "./result.js";
4
- const PreferencesSchema = Type.Optional(Type.Object({
5
- max_papers: Type.Optional(Type.Number({
6
- description: "Maximum number of papers to push each run (1-20).",
7
- })),
8
- recency_days: Type.Optional(Type.Number({
9
- description: "Optional recency preference in days for candidate retrieval.",
10
- })),
11
- sources: Type.Optional(Type.Array(Type.String({
12
- description: "Preferred search sources, for example: arxiv, openalex.",
13
- }))),
14
- }));
15
- const PaperSchema = Type.Object({
16
- id: Type.Optional(Type.String({ description: "Stable paper id, such as arxiv:2501.12345 or doi:10.xxxx/..." })),
17
- title: Type.Optional(Type.String({ description: "Paper title." })),
18
- url: Type.Optional(Type.String({ description: "Source URL for traceability." })),
19
- score: Type.Optional(Type.Number({
20
- description: "Optional internal ranking score for backend logging (for example 0-100).",
21
- })),
22
- reason: Type.Optional(Type.String({
23
- description: "Optional internal ranking rationale for backend logging.",
24
- })),
25
- });
26
- const KnowledgePaperSchema = Type.Object({
27
- id: Type.Optional(Type.String({ description: "Optional stable paper id." })),
28
- title: Type.Optional(Type.String({ description: "Paper title." })),
29
- url: Type.Optional(Type.String({ description: "Paper source URL." })),
30
- source: Type.Optional(Type.String({ description: "Paper source name/domain." })),
31
- published_at: Type.Optional(Type.String({ description: "Published time in ISO string." })),
32
- score: Type.Optional(Type.Number({ description: "Optional score used in ranking." })),
33
- reason: Type.Optional(Type.String({ description: "Optional rationale for selecting this paper." })),
34
- summary: Type.Optional(Type.String({ description: "Optional short summary text." })),
35
- evidence_ids: Type.Optional(Type.Array(Type.String({ description: "Optional evidence IDs for this paper." }))),
36
- full_text_read: Type.Optional(Type.Boolean({ description: "Whether this paper was read from full text." })),
37
- read_status: Type.Optional(Type.String({
38
- description: "Read status: fulltext | partial | metadata | unread.",
39
- })),
40
- full_text_source: Type.Optional(Type.String({ description: "Where full text came from (e.g. arxiv_pdf)." })),
41
- full_text_ref: Type.Optional(Type.String({ description: "Reference to full text location/path/URL." })),
42
- unread_reason: Type.Optional(Type.String({ description: "Why full-text reading was not completed." })),
43
- key_evidence_spans: Type.Optional(Type.Array(Type.String({ description: "Short evidence excerpts/anchors from full text." }))),
44
- domain: Type.Optional(Type.String({ description: "Primary research domain." })),
45
- subdomains: Type.Optional(Type.Array(Type.String({ description: "Sub-research domains." }))),
46
- cross_domain_links: Type.Optional(Type.Array(Type.String({ description: "Cross-domain links/intersections." }))),
47
- research_goal: Type.Optional(Type.String({ description: "Core research goal/question of this paper." })),
48
- approach: Type.Optional(Type.String({ description: "What the paper does under that goal." })),
49
- methodology_design: Type.Optional(Type.String({ description: "Method/experiment design summary." })),
50
- key_contributions: Type.Optional(Type.Array(Type.String({ description: "Main contributions of this paper." }))),
51
- practical_insights: Type.Optional(Type.Array(Type.String({ description: "Practical takeaways or reusable experience." }))),
52
- must_understand_points: Type.Optional(Type.Array(Type.String({ description: "Critical points that must be understood after reading." }))),
53
- limitations: Type.Optional(Type.Array(Type.String({ description: "Known limitations." }))),
54
- evidence_anchors: Type.Optional(Type.Array(Type.Object({
55
- section: Type.Optional(Type.String({ description: "Section title or identifier." })),
56
- locator: Type.Optional(Type.String({ description: "Fine-grained locator, e.g. Eq.3/Table2/Page4." })),
57
- claim: Type.String({ description: "Claim supported by this anchor." }),
58
- quote: Type.Optional(Type.String({ description: "Short quote/excerpt supporting the claim." })),
59
- }))),
60
- });
61
- const ExplorationTraceSchema = Type.Object({
62
- query: Type.String({ description: "Exploration query text." }),
63
- reason: Type.Optional(Type.String({ description: "Why this exploration query was chosen." })),
64
- source: Type.Optional(Type.String({ description: "Source used for this exploration step (e.g. arxiv/openalex)." })),
65
- candidates: Type.Optional(Type.Number({ description: "Candidate count before filtering." })),
66
- filtered_to: Type.Optional(Type.Number({ description: "Candidate count after filtering." })),
67
- filtered_out_reasons: Type.Optional(Type.Array(Type.String({ description: "Optional filtering reasons for dropped candidates." }))),
68
- result_count: Type.Optional(Type.Number({ description: "Optional result count from this query." })),
69
- });
70
- const KnowledgeChangeSchema = Type.Object({
71
- type: Type.String({ description: "One of NEW|CONFIRM|REVISE|BRIDGE." }),
72
- statement: Type.String({ description: "Change statement." }),
73
- evidence_ids: Type.Optional(Type.Array(Type.String({ description: "Evidence IDs for this change." }))),
74
- topic: Type.Optional(Type.String({ description: "Optional topic affected by this change." })),
75
- });
76
- const KnowledgeUpdateSchema = Type.Object({
77
- topic: Type.String({ description: "Topic name for this update." }),
78
- op: Type.String({ description: "Update operation: append|revise|confirm|bridge." }),
79
- content: Type.String({ description: "Update content text." }),
80
- confidence: Type.Optional(Type.String({ description: "Optional confidence: low|medium|high." })),
81
- evidence_ids: Type.Optional(Type.Array(Type.String({ description: "Evidence IDs for this update." }))),
82
- });
83
- const KnowledgeHypothesisSchema = Type.Object({
84
- id: Type.Optional(Type.String({ description: "Optional hypothesis ID." })),
85
- statement: Type.String({ description: "Hypothesis statement." }),
86
- trigger: Type.String({ description: "Trigger type: GAP|BRIDGE|TREND|CONTRADICTION." }),
87
- dependency_path: Type.Optional(Type.Array(Type.String({ description: "Dependency path steps." }))),
88
- novelty: Type.Optional(Type.Number({ description: "Optional novelty score." })),
89
- feasibility: Type.Optional(Type.Number({ description: "Optional feasibility score." })),
90
- impact: Type.Optional(Type.Number({ description: "Optional impact score." })),
91
- evidence_ids: Type.Optional(Type.Array(Type.String({ description: "Evidence IDs for this hypothesis." }))),
92
- validation_status: Type.Optional(Type.String({
93
- description: "Optional validation status: unchecked | supporting | conflicting | openreview_related | openreview_not_found.",
94
- })),
95
- validation_notes: Type.Optional(Type.String({ description: "Optional validation notes." })),
96
- validation_evidence: Type.Optional(Type.Array(Type.String({ description: "Optional validation evidence links/ids." }))),
97
- });
98
- const KnowledgeRunLogSchema = Type.Object({
99
- model: Type.Optional(Type.String({ description: "Optional model name." })),
100
- duration_ms: Type.Optional(Type.Number({ description: "Optional run duration in ms." })),
101
- error: Type.Optional(Type.String({ description: "Optional run error text." })),
102
- degraded: Type.Optional(Type.Boolean({ description: "Whether this run used degraded behavior." })),
103
- notes: Type.Optional(Type.String({ description: "Optional extra notes." })),
104
- temp_full_text_dir: Type.Optional(Type.String({ description: "Temporary local directory for full-text files." })),
105
- temp_files_downloaded: Type.Optional(Type.Number({ description: "Number of temporary full-text files downloaded." })),
106
- temp_cleanup_status: Type.Optional(Type.String({
107
- description: "Temporary full-text cleanup status: done | partial | failed | not_needed.",
108
- })),
109
- temp_cleanup_note: Type.Optional(Type.String({ description: "Optional cleanup note/error." })),
110
- full_text_attempted: Type.Optional(Type.Number({ description: "Number of papers attempted for full-text read." })),
111
- full_text_completed: Type.Optional(Type.Number({ description: "Number of papers successfully full-text read." })),
112
- });
113
- const KnowledgeStateSchema = Type.Optional(Type.Object({
114
- core_papers: Type.Optional(Type.Array(KnowledgePaperSchema)),
115
- exploration_papers: Type.Optional(Type.Array(KnowledgePaperSchema)),
116
- exploration_trace: Type.Optional(Type.Array(ExplorationTraceSchema)),
117
- knowledge_changes: Type.Optional(Type.Array(KnowledgeChangeSchema)),
118
- knowledge_updates: Type.Optional(Type.Array(KnowledgeUpdateSchema)),
119
- hypotheses: Type.Optional(Type.Array(KnowledgeHypothesisSchema)),
120
- run_log: Type.Optional(KnowledgeRunLogSchema),
121
- }));
122
- export const ScientifyLiteratureStateToolSchema = Type.Object({
123
- action: Type.String({
124
- description: 'Action: "prepare" | "record" | "feedback" | "status". `status` returns recent papers plus knowledge_state summary for follow-up traceability.',
125
- }),
126
- scope: Type.String({
127
- description: "Scope key used to isolate user/channel state.",
128
- }),
129
- topic: Type.String({
130
- description: "Research topic text.",
131
- }),
132
- project_id: Type.Optional(Type.String({
133
- description: "Optional project id to pin knowledge_state writes.",
134
- })),
135
- preferences: PreferencesSchema,
136
- papers: Type.Optional(Type.Array(PaperSchema, {
137
- description: "Papers to mark as pushed when action=record.",
138
- })),
139
- status: Type.Optional(Type.String({
140
- description: "Run status for action=record, for example: ok, empty, error.",
141
- })),
142
- run_id: Type.Optional(Type.String({
143
- description: "Optional cron run/session id for traceability.",
144
- })),
145
- note: Type.Optional(Type.String({
146
- description: "Optional note for this record.",
147
- })),
148
- signal: Type.Optional(Type.String({
149
- description: 'Feedback signal for action=feedback: "read" | "skip" | "star".',
150
- })),
151
- paper: Type.Optional(Type.Object({
152
- id: Type.Optional(Type.String({ description: "Optional paper id for feedback context." })),
153
- title: Type.Optional(Type.String({ description: "Optional paper title for feedback context." })),
154
- url: Type.Optional(Type.String({ description: "Optional paper URL for feedback context." })),
155
- })),
156
- source: Type.Optional(Type.String({
157
- description: "Optional source hint for feedback (e.g. arxiv/openalex/domain).",
158
- })),
159
- tags: Type.Optional(Type.Array(Type.String({
160
- description: "Optional feedback tags, e.g. [\"physics simulation\", \"agent\"].",
161
- }))),
162
- knowledge_state: KnowledgeStateSchema,
163
- });
164
- function readStringParam(params, key) {
165
- const value = params[key];
166
- if (typeof value !== "string")
167
- return undefined;
168
- const trimmed = value.trim();
169
- return trimmed.length > 0 ? trimmed : undefined;
170
- }
171
- function readPreferences(params) {
172
- const raw = params.preferences;
173
- if (!raw || typeof raw !== "object" || Array.isArray(raw))
174
- return undefined;
175
- const record = raw;
176
- const maxRaw = record.max_papers;
177
- const recencyRaw = record.recency_days;
178
- const sourcesRaw = record.sources;
179
- const maxPapers = typeof maxRaw === "number" && Number.isFinite(maxRaw) ? maxRaw : undefined;
180
- const recencyDays = typeof recencyRaw === "number" && Number.isFinite(recencyRaw) ? recencyRaw : undefined;
181
- const sources = Array.isArray(sourcesRaw) && sourcesRaw.length > 0
182
- ? sourcesRaw
183
- .filter((item) => typeof item === "string")
184
- .map((item) => item.trim())
185
- .filter((item) => item.length > 0)
186
- : undefined;
187
- if (maxPapers === undefined && recencyDays === undefined && (!sources || sources.length === 0)) {
188
- return undefined;
189
- }
190
- return {
191
- ...(maxPapers !== undefined ? { maxPapers } : {}),
192
- ...(recencyDays !== undefined ? { recencyDays } : {}),
193
- ...(sources && sources.length > 0 ? { sources } : {}),
194
- };
195
- }
196
- function readPapers(params) {
197
- const raw = params.papers;
198
- if (!Array.isArray(raw))
199
- return [];
200
- const papers = [];
201
- for (const item of raw) {
202
- if (!item || typeof item !== "object" || Array.isArray(item))
203
- continue;
204
- const record = item;
205
- const id = typeof record.id === "string" ? record.id.trim() : undefined;
206
- const title = typeof record.title === "string" ? record.title.trim() : undefined;
207
- const url = typeof record.url === "string" ? record.url.trim() : undefined;
208
- const score = typeof record.score === "number" && Number.isFinite(record.score)
209
- ? record.score
210
- : undefined;
211
- const reason = typeof record.reason === "string" ? record.reason.trim() : undefined;
212
- papers.push({
213
- ...(id ? { id } : {}),
214
- ...(title ? { title } : {}),
215
- ...(url ? { url } : {}),
216
- ...(score !== undefined ? { score } : {}),
217
- ...(reason ? { reason } : {}),
218
- });
219
- }
220
- return papers;
221
- }
222
- function readFeedbackSignal(params) {
223
- const raw = readStringParam(params, "signal")?.toLowerCase();
224
- if (raw === "read" || raw === "skip" || raw === "star")
225
- return raw;
226
- return undefined;
227
- }
228
- function readFeedbackPaper(params) {
229
- const raw = params.paper;
230
- if (!raw || typeof raw !== "object" || Array.isArray(raw))
231
- return undefined;
232
- const record = raw;
233
- const id = typeof record.id === "string" ? record.id.trim() : undefined;
234
- const title = typeof record.title === "string" ? record.title.trim() : undefined;
235
- const url = typeof record.url === "string" ? record.url.trim() : undefined;
236
- if (!id && !title && !url)
237
- return undefined;
238
- return {
239
- ...(id ? { id } : {}),
240
- ...(title ? { title } : {}),
241
- ...(url ? { url } : {}),
242
- };
243
- }
244
- function readStringList(params, key) {
245
- const raw = params[key];
246
- if (!Array.isArray(raw))
247
- return undefined;
248
- const values = raw
249
- .filter((item) => typeof item === "string")
250
- .map((item) => item.trim())
251
- .filter((item) => item.length > 0);
252
- return values.length > 0 ? values : undefined;
253
- }
254
- function readKnowledgePapers(raw) {
255
- if (!Array.isArray(raw))
256
- return [];
257
- const papers = [];
258
- for (const item of raw) {
259
- if (!item || typeof item !== "object" || Array.isArray(item))
260
- continue;
261
- const record = item;
262
- const id = typeof record.id === "string" ? record.id.trim() : undefined;
263
- const title = typeof record.title === "string" ? record.title.trim() : undefined;
264
- const url = typeof record.url === "string" ? record.url.trim() : undefined;
265
- const source = typeof record.source === "string" ? record.source.trim() : undefined;
266
- const publishedAt = typeof record.published_at === "string"
267
- ? record.published_at.trim()
268
- : typeof record.publishedAt === "string"
269
- ? record.publishedAt.trim()
270
- : undefined;
271
- const score = typeof record.score === "number" && Number.isFinite(record.score) ? record.score : undefined;
272
- const reason = typeof record.reason === "string" ? record.reason.trim() : undefined;
273
- const summary = typeof record.summary === "string" ? record.summary.trim() : undefined;
274
- const evidenceRaw = record.evidence_ids ?? record.evidenceIds;
275
- const evidenceIds = Array.isArray(evidenceRaw)
276
- ? evidenceRaw
277
- .filter((v) => typeof v === "string")
278
- .map((v) => v.trim())
279
- .filter((v) => v.length > 0)
280
- : undefined;
281
- const fullTextReadRaw = record.full_text_read ?? record.fullTextRead;
282
- const fullTextRead = typeof fullTextReadRaw === "boolean" ? fullTextReadRaw : undefined;
283
- const readStatusRaw = typeof (record.read_status ?? record.readStatus) === "string"
284
- ? String(record.read_status ?? record.readStatus).trim().toLowerCase()
285
- : undefined;
286
- const readStatus = readStatusRaw && ["fulltext", "partial", "metadata", "unread"].includes(readStatusRaw)
287
- ? readStatusRaw
288
- : undefined;
289
- const fullTextSource = typeof (record.full_text_source ?? record.fullTextSource) === "string"
290
- ? String(record.full_text_source ?? record.fullTextSource).trim()
291
- : undefined;
292
- const fullTextRef = typeof (record.full_text_ref ?? record.fullTextRef) === "string"
293
- ? String(record.full_text_ref ?? record.fullTextRef).trim()
294
- : undefined;
295
- const unreadReason = typeof (record.unread_reason ?? record.unreadReason) === "string"
296
- ? String(record.unread_reason ?? record.unreadReason).trim()
297
- : undefined;
298
- const keyEvidenceSpansRaw = record.key_evidence_spans ?? record.keyEvidenceSpans;
299
- const keyEvidenceSpans = Array.isArray(keyEvidenceSpansRaw)
300
- ? keyEvidenceSpansRaw
301
- .filter((v) => typeof v === "string")
302
- .map((v) => v.trim())
303
- .filter((v) => v.length > 0)
304
- : undefined;
305
- const domain = typeof record.domain === "string" ? record.domain.trim() : undefined;
306
- const subdomainsRaw = record.subdomains;
307
- const subdomains = Array.isArray(subdomainsRaw)
308
- ? subdomainsRaw
309
- .filter((v) => typeof v === "string")
310
- .map((v) => v.trim())
311
- .filter((v) => v.length > 0)
312
- : undefined;
313
- const crossDomainLinksRaw = record.cross_domain_links ?? record.crossDomainLinks;
314
- const crossDomainLinks = Array.isArray(crossDomainLinksRaw)
315
- ? crossDomainLinksRaw
316
- .filter((v) => typeof v === "string")
317
- .map((v) => v.trim())
318
- .filter((v) => v.length > 0)
319
- : undefined;
320
- const researchGoal = typeof (record.research_goal ?? record.researchGoal) === "string"
321
- ? String(record.research_goal ?? record.researchGoal).trim()
322
- : undefined;
323
- const approach = typeof record.approach === "string" ? record.approach.trim() : undefined;
324
- const methodologyDesign = typeof (record.methodology_design ?? record.methodologyDesign) === "string"
325
- ? String(record.methodology_design ?? record.methodologyDesign).trim()
326
- : undefined;
327
- const keyContributionsRaw = record.key_contributions ?? record.keyContributions;
328
- const keyContributions = Array.isArray(keyContributionsRaw)
329
- ? keyContributionsRaw
330
- .filter((v) => typeof v === "string")
331
- .map((v) => v.trim())
332
- .filter((v) => v.length > 0)
333
- : undefined;
334
- const practicalInsightsRaw = record.practical_insights ?? record.practicalInsights;
335
- const practicalInsights = Array.isArray(practicalInsightsRaw)
336
- ? practicalInsightsRaw
337
- .filter((v) => typeof v === "string")
338
- .map((v) => v.trim())
339
- .filter((v) => v.length > 0)
340
- : undefined;
341
- const mustUnderstandPointsRaw = record.must_understand_points ?? record.mustUnderstandPoints;
342
- const mustUnderstandPoints = Array.isArray(mustUnderstandPointsRaw)
343
- ? mustUnderstandPointsRaw
344
- .filter((v) => typeof v === "string")
345
- .map((v) => v.trim())
346
- .filter((v) => v.length > 0)
347
- : undefined;
348
- const limitationsRaw = record.limitations;
349
- const limitations = Array.isArray(limitationsRaw)
350
- ? limitationsRaw
351
- .filter((v) => typeof v === "string")
352
- .map((v) => v.trim())
353
- .filter((v) => v.length > 0)
354
- : undefined;
355
- const evidenceAnchorsRaw = record.evidence_anchors ?? record.evidenceAnchors;
356
- const evidenceAnchors = Array.isArray(evidenceAnchorsRaw)
357
- ? evidenceAnchorsRaw
358
- .filter((v) => !!v && typeof v === "object" && !Array.isArray(v))
359
- .map((anchor) => {
360
- const section = typeof anchor.section === "string" ? anchor.section.trim() : undefined;
361
- const locator = typeof anchor.locator === "string" ? anchor.locator.trim() : undefined;
362
- const claim = typeof anchor.claim === "string" ? anchor.claim.trim() : "";
363
- const quote = typeof anchor.quote === "string" ? anchor.quote.trim() : undefined;
364
- if (!claim)
365
- return undefined;
366
- return {
367
- ...(section ? { section } : {}),
368
- ...(locator ? { locator } : {}),
369
- claim,
370
- ...(quote ? { quote } : {}),
371
- };
372
- })
373
- .filter((v) => Boolean(v))
374
- : undefined;
375
- if (!id &&
376
- !title &&
377
- !url &&
378
- !summary &&
379
- !reason &&
380
- !domain &&
381
- !researchGoal &&
382
- !approach &&
383
- !methodologyDesign &&
384
- (!keyContributions || keyContributions.length === 0) &&
385
- (!practicalInsights || practicalInsights.length === 0) &&
386
- (!mustUnderstandPoints || mustUnderstandPoints.length === 0) &&
387
- (!limitations || limitations.length === 0)) {
388
- continue;
389
- }
390
- papers.push({
391
- ...(id ? { id } : {}),
392
- ...(title ? { title } : {}),
393
- ...(url ? { url } : {}),
394
- ...(source ? { source } : {}),
395
- ...(publishedAt ? { publishedAt } : {}),
396
- ...(score !== undefined ? { score } : {}),
397
- ...(reason ? { reason } : {}),
398
- ...(summary ? { summary } : {}),
399
- ...(evidenceIds && evidenceIds.length > 0 ? { evidenceIds } : {}),
400
- ...(typeof fullTextRead === "boolean" ? { fullTextRead } : {}),
401
- ...(readStatus ? { readStatus } : {}),
402
- ...(fullTextSource ? { fullTextSource } : {}),
403
- ...(fullTextRef ? { fullTextRef } : {}),
404
- ...(unreadReason ? { unreadReason } : {}),
405
- ...(keyEvidenceSpans && keyEvidenceSpans.length > 0 ? { keyEvidenceSpans } : {}),
406
- ...(domain ? { domain } : {}),
407
- ...(subdomains && subdomains.length > 0 ? { subdomains } : {}),
408
- ...(crossDomainLinks && crossDomainLinks.length > 0 ? { crossDomainLinks } : {}),
409
- ...(researchGoal ? { researchGoal } : {}),
410
- ...(approach ? { approach } : {}),
411
- ...(methodologyDesign ? { methodologyDesign } : {}),
412
- ...(keyContributions && keyContributions.length > 0 ? { keyContributions } : {}),
413
- ...(practicalInsights && practicalInsights.length > 0 ? { practicalInsights } : {}),
414
- ...(mustUnderstandPoints && mustUnderstandPoints.length > 0 ? { mustUnderstandPoints } : {}),
415
- ...(limitations && limitations.length > 0 ? { limitations } : {}),
416
- ...(evidenceAnchors && evidenceAnchors.length > 0 ? { evidenceAnchors } : {}),
417
- });
418
- }
419
- return papers;
420
- }
421
- function readKnowledgeStatePayload(params) {
422
- const raw = params.knowledge_state;
423
- if (!raw || typeof raw !== "object" || Array.isArray(raw))
424
- return undefined;
425
- const record = raw;
426
- const corePapers = readKnowledgePapers(record.core_papers ?? record.corePapers);
427
- const explorationPapers = readKnowledgePapers(record.exploration_papers ?? record.explorationPapers);
428
- const explorationTraceRaw = record.exploration_trace ?? record.explorationTrace;
429
- const explorationTrace = Array.isArray(explorationTraceRaw)
430
- ? explorationTraceRaw
431
- .filter((item) => !!item && typeof item === "object" && !Array.isArray(item))
432
- .map((item) => {
433
- const query = typeof item.query === "string" ? item.query.trim() : "";
434
- if (!query)
435
- return undefined;
436
- const reason = typeof item.reason === "string" ? item.reason.trim() : undefined;
437
- const source = typeof item.source === "string" ? item.source.trim() : undefined;
438
- const candidatesRaw = item.candidates;
439
- const candidates = typeof candidatesRaw === "number" && Number.isFinite(candidatesRaw) ? candidatesRaw : undefined;
440
- const filteredToRaw = item.filtered_to ?? item.filteredTo;
441
- const filteredTo = typeof filteredToRaw === "number" && Number.isFinite(filteredToRaw) ? filteredToRaw : undefined;
442
- const filteredOutRaw = item.filtered_out_reasons ?? item.filteredOutReasons;
443
- const filteredOutReasons = Array.isArray(filteredOutRaw)
444
- ? filteredOutRaw
445
- .filter((v) => typeof v === "string")
446
- .map((v) => v.trim())
447
- .filter((v) => v.length > 0)
448
- : undefined;
449
- const resultCountRaw = item.result_count ?? item.resultCount;
450
- const resultCount = typeof resultCountRaw === "number" && Number.isFinite(resultCountRaw)
451
- ? resultCountRaw
452
- : undefined;
453
- return {
454
- query,
455
- ...(reason ? { reason } : {}),
456
- ...(source ? { source } : {}),
457
- ...(typeof candidates === "number" ? { candidates } : {}),
458
- ...(typeof filteredTo === "number" ? { filteredTo } : {}),
459
- ...(filteredOutReasons && filteredOutReasons.length > 0 ? { filteredOutReasons } : {}),
460
- ...(typeof resultCount === "number" ? { resultCount } : {}),
461
- };
462
- })
463
- .filter((item) => Boolean(item))
464
- : [];
465
- const knowledgeChangesRaw = record.knowledge_changes ?? record.knowledgeChanges;
466
- const knowledgeChanges = [];
467
- if (Array.isArray(knowledgeChangesRaw)) {
468
- for (const item of knowledgeChangesRaw) {
469
- if (!item || typeof item !== "object" || Array.isArray(item))
470
- continue;
471
- const row = item;
472
- const rawType = typeof row.type === "string" ? row.type.trim().toUpperCase() : "NEW";
473
- const type = ["NEW", "CONFIRM", "REVISE", "BRIDGE"].includes(rawType)
474
- ? rawType
475
- : "NEW";
476
- const statement = typeof row.statement === "string" ? row.statement.trim() : "";
477
- if (!statement)
478
- continue;
479
- const evidenceRaw = row.evidence_ids ?? row.evidenceIds;
480
- const evidenceIds = Array.isArray(evidenceRaw)
481
- ? evidenceRaw
482
- .filter((v) => typeof v === "string")
483
- .map((v) => v.trim())
484
- .filter((v) => v.length > 0)
485
- : undefined;
486
- const topic = typeof row.topic === "string" ? row.topic.trim() : undefined;
487
- knowledgeChanges.push({
488
- type,
489
- statement,
490
- ...(evidenceIds && evidenceIds.length > 0 ? { evidenceIds } : {}),
491
- ...(topic ? { topic } : {}),
492
- });
493
- }
494
- }
495
- const knowledgeUpdatesRaw = record.knowledge_updates ?? record.knowledgeUpdates;
496
- const knowledgeUpdates = [];
497
- if (Array.isArray(knowledgeUpdatesRaw)) {
498
- for (const item of knowledgeUpdatesRaw) {
499
- if (!item || typeof item !== "object" || Array.isArray(item))
500
- continue;
501
- const row = item;
502
- const topic = typeof row.topic === "string" ? row.topic.trim() : "";
503
- const rawOp = typeof row.op === "string" ? row.op.trim().toLowerCase() : "append";
504
- const op = ["append", "revise", "confirm", "bridge"].includes(rawOp)
505
- ? rawOp
506
- : "append";
507
- const content = typeof row.content === "string" ? row.content.trim() : "";
508
- if (!topic || !content)
509
- continue;
510
- const rawConfidence = typeof row.confidence === "string" ? row.confidence.trim().toLowerCase() : undefined;
511
- const confidence = rawConfidence && ["low", "medium", "high"].includes(rawConfidence)
512
- ? rawConfidence
513
- : undefined;
514
- const evidenceRaw = row.evidence_ids ?? row.evidenceIds;
515
- const evidenceIds = Array.isArray(evidenceRaw)
516
- ? evidenceRaw
517
- .filter((v) => typeof v === "string")
518
- .map((v) => v.trim())
519
- .filter((v) => v.length > 0)
520
- : undefined;
521
- knowledgeUpdates.push({
522
- topic,
523
- op,
524
- content,
525
- ...(confidence ? { confidence } : {}),
526
- ...(evidenceIds && evidenceIds.length > 0 ? { evidenceIds } : {}),
527
- });
528
- }
529
- }
530
- const hypothesesRaw = record.hypotheses;
531
- const hypotheses = [];
532
- if (Array.isArray(hypothesesRaw)) {
533
- for (const item of hypothesesRaw) {
534
- if (!item || typeof item !== "object" || Array.isArray(item))
535
- continue;
536
- const row = item;
537
- const id = typeof row.id === "string" ? row.id.trim() : undefined;
538
- const statement = typeof row.statement === "string" ? row.statement.trim() : "";
539
- const rawTrigger = typeof row.trigger === "string" ? row.trigger.trim().toUpperCase() : "TREND";
540
- const trigger = ["GAP", "BRIDGE", "TREND", "CONTRADICTION"].includes(rawTrigger)
541
- ? rawTrigger
542
- : "TREND";
543
- if (!statement)
544
- continue;
545
- const dependencyRaw = row.dependency_path ?? row.dependencyPath;
546
- const dependencyPath = Array.isArray(dependencyRaw)
547
- ? dependencyRaw
548
- .filter((v) => typeof v === "string")
549
- .map((v) => v.trim())
550
- .filter((v) => v.length > 0)
551
- : undefined;
552
- const evidenceRaw = row.evidence_ids ?? row.evidenceIds;
553
- const evidenceIds = Array.isArray(evidenceRaw)
554
- ? evidenceRaw
555
- .filter((v) => typeof v === "string")
556
- .map((v) => v.trim())
557
- .filter((v) => v.length > 0)
558
- : undefined;
559
- const validationStatusRaw = typeof (row.validation_status ?? row.validationStatus) === "string"
560
- ? String(row.validation_status ?? row.validationStatus).trim().toLowerCase()
561
- : undefined;
562
- const validationStatus = validationStatusRaw &&
563
- ["unchecked", "supporting", "conflicting", "openreview_related", "openreview_not_found"].includes(validationStatusRaw)
564
- ? validationStatusRaw
565
- : undefined;
566
- const validationNotes = typeof (row.validation_notes ?? row.validationNotes) === "string"
567
- ? String(row.validation_notes ?? row.validationNotes).trim()
568
- : undefined;
569
- const validationEvidenceRaw = row.validation_evidence ?? row.validationEvidence;
570
- const validationEvidence = Array.isArray(validationEvidenceRaw)
571
- ? validationEvidenceRaw
572
- .filter((v) => typeof v === "string")
573
- .map((v) => v.trim())
574
- .filter((v) => v.length > 0)
575
- : undefined;
576
- const novelty = typeof row.novelty === "number" && Number.isFinite(row.novelty) ? row.novelty : undefined;
577
- const feasibility = typeof row.feasibility === "number" && Number.isFinite(row.feasibility) ? row.feasibility : undefined;
578
- const impact = typeof row.impact === "number" && Number.isFinite(row.impact) ? row.impact : undefined;
579
- hypotheses.push({
580
- ...(id ? { id } : {}),
581
- statement,
582
- trigger,
583
- ...(dependencyPath && dependencyPath.length > 0 ? { dependencyPath } : {}),
584
- ...(evidenceIds && evidenceIds.length > 0 ? { evidenceIds } : {}),
585
- ...(validationStatus ? { validationStatus } : {}),
586
- ...(validationNotes ? { validationNotes } : {}),
587
- ...(validationEvidence && validationEvidence.length > 0 ? { validationEvidence } : {}),
588
- ...(novelty !== undefined ? { novelty } : {}),
589
- ...(feasibility !== undefined ? { feasibility } : {}),
590
- ...(impact !== undefined ? { impact } : {}),
591
- });
592
- }
593
- }
594
- const runLogRaw = record.run_log ?? record.runLog;
595
- const runLog = runLogRaw && typeof runLogRaw === "object" && !Array.isArray(runLogRaw)
596
- ? (() => {
597
- const runLogRecord = runLogRaw;
598
- const model = typeof runLogRecord.model === "string" ? runLogRecord.model.trim() : undefined;
599
- const durationMsRaw = runLogRecord.duration_ms ?? runLogRecord.durationMs;
600
- const durationMs = typeof durationMsRaw === "number" && Number.isFinite(durationMsRaw) ? durationMsRaw : undefined;
601
- const error = typeof runLogRecord.error === "string" ? runLogRecord.error.trim() : undefined;
602
- const degraded = runLogRecord.degraded === true;
603
- const notes = typeof runLogRecord.notes === "string" ? runLogRecord.notes.trim() : undefined;
604
- const tempFullTextDir = typeof (runLogRecord.temp_full_text_dir ?? runLogRecord.tempFullTextDir) === "string"
605
- ? String(runLogRecord.temp_full_text_dir ?? runLogRecord.tempFullTextDir).trim()
606
- : undefined;
607
- const tempFilesDownloadedRaw = runLogRecord.temp_files_downloaded ?? runLogRecord.tempFilesDownloaded;
608
- const tempFilesDownloaded = typeof tempFilesDownloadedRaw === "number" && Number.isFinite(tempFilesDownloadedRaw)
609
- ? tempFilesDownloadedRaw
610
- : undefined;
611
- const tempCleanupStatusRaw = typeof (runLogRecord.temp_cleanup_status ?? runLogRecord.tempCleanupStatus) === "string"
612
- ? String(runLogRecord.temp_cleanup_status ?? runLogRecord.tempCleanupStatus).trim().toLowerCase()
613
- : undefined;
614
- const tempCleanupStatus = tempCleanupStatusRaw && ["done", "partial", "failed", "not_needed"].includes(tempCleanupStatusRaw)
615
- ? tempCleanupStatusRaw
616
- : undefined;
617
- const tempCleanupNote = typeof (runLogRecord.temp_cleanup_note ?? runLogRecord.tempCleanupNote) === "string"
618
- ? String(runLogRecord.temp_cleanup_note ?? runLogRecord.tempCleanupNote).trim()
619
- : undefined;
620
- const fullTextAttemptedRaw = runLogRecord.full_text_attempted ?? runLogRecord.fullTextAttempted;
621
- const fullTextAttempted = typeof fullTextAttemptedRaw === "number" && Number.isFinite(fullTextAttemptedRaw)
622
- ? fullTextAttemptedRaw
623
- : undefined;
624
- const fullTextCompletedRaw = runLogRecord.full_text_completed ?? runLogRecord.fullTextCompleted;
625
- const fullTextCompleted = typeof fullTextCompletedRaw === "number" && Number.isFinite(fullTextCompletedRaw)
626
- ? fullTextCompletedRaw
627
- : undefined;
628
- if (!model &&
629
- durationMs === undefined &&
630
- !error &&
631
- !degraded &&
632
- !notes &&
633
- !tempFullTextDir &&
634
- tempFilesDownloaded === undefined &&
635
- !tempCleanupStatus &&
636
- !tempCleanupNote &&
637
- fullTextAttempted === undefined &&
638
- fullTextCompleted === undefined) {
639
- return undefined;
640
- }
641
- return {
642
- ...(model ? { model } : {}),
643
- ...(durationMs !== undefined ? { durationMs } : {}),
644
- ...(error ? { error } : {}),
645
- ...(degraded ? { degraded } : {}),
646
- ...(notes ? { notes } : {}),
647
- ...(tempFullTextDir ? { tempFullTextDir } : {}),
648
- ...(tempFilesDownloaded !== undefined ? { tempFilesDownloaded } : {}),
649
- ...(tempCleanupStatus ? { tempCleanupStatus } : {}),
650
- ...(tempCleanupNote ? { tempCleanupNote } : {}),
651
- ...(fullTextAttempted !== undefined ? { fullTextAttempted } : {}),
652
- ...(fullTextCompleted !== undefined ? { fullTextCompleted } : {}),
653
- };
654
- })()
655
- : undefined;
656
- const hasAny = corePapers.length > 0 ||
657
- explorationPapers.length > 0 ||
658
- explorationTrace.length > 0 ||
659
- knowledgeChanges.length > 0 ||
660
- knowledgeUpdates.length > 0 ||
661
- hypotheses.length > 0 ||
662
- Boolean(runLog);
663
- if (!hasAny)
664
- return undefined;
665
- return {
666
- ...(corePapers.length > 0 ? { corePapers } : {}),
667
- ...(explorationPapers.length > 0 ? { explorationPapers } : {}),
668
- ...(explorationTrace.length > 0 ? { explorationTrace } : {}),
669
- ...(knowledgeChanges.length > 0 ? { knowledgeChanges } : {}),
670
- ...(knowledgeUpdates.length > 0 ? { knowledgeUpdates } : {}),
671
- ...(hypotheses.length > 0 ? { hypotheses } : {}),
672
- ...(runLog ? { runLog } : {}),
673
- };
674
- }
675
- function serializeKnowledgePaper(paper) {
676
- return {
677
- id: paper.id ?? null,
678
- title: paper.title ?? null,
679
- url: paper.url ?? null,
680
- source: paper.source ?? null,
681
- published_at: paper.publishedAt ?? null,
682
- score: paper.score ?? null,
683
- reason: paper.reason ?? null,
684
- summary: paper.summary ?? null,
685
- evidence_ids: paper.evidenceIds ?? [],
686
- full_text_read: paper.fullTextRead ?? null,
687
- read_status: paper.readStatus ?? null,
688
- full_text_source: paper.fullTextSource ?? null,
689
- full_text_ref: paper.fullTextRef ?? null,
690
- unread_reason: paper.unreadReason ?? null,
691
- key_evidence_spans: paper.keyEvidenceSpans ?? [],
692
- domain: paper.domain ?? null,
693
- subdomains: paper.subdomains ?? [],
694
- cross_domain_links: paper.crossDomainLinks ?? [],
695
- research_goal: paper.researchGoal ?? null,
696
- approach: paper.approach ?? null,
697
- methodology_design: paper.methodologyDesign ?? null,
698
- key_contributions: paper.keyContributions ?? [],
699
- practical_insights: paper.practicalInsights ?? [],
700
- must_understand_points: paper.mustUnderstandPoints ?? [],
701
- limitations: paper.limitations ?? [],
702
- evidence_anchors: (paper.evidenceAnchors ?? []).map((anchor) => ({
703
- section: anchor.section ?? null,
704
- locator: anchor.locator ?? null,
705
- claim: anchor.claim,
706
- quote: anchor.quote ?? null,
707
- })),
708
- };
709
- }
710
- export function createScientifyLiteratureStateTool() {
711
- return {
712
- label: "Scientify Literature State",
713
- name: "scientify_literature_state",
714
- description: "Manage incremental research state for subscriptions: prepare dedupe context, record pushed papers plus knowledge_state artifacts, persist lightweight feedback memory, and query status.",
715
- parameters: ScientifyLiteratureStateToolSchema,
716
- execute: async (_toolCallId, rawArgs) => {
717
- const params = (rawArgs ?? {});
718
- const action = (readStringParam(params, "action") ?? "").toLowerCase();
719
- const scope = readStringParam(params, "scope");
720
- const topic = readStringParam(params, "topic");
721
- const projectId = readStringParam(params, "project_id");
722
- const preferences = readPreferences(params);
723
- if (!scope || !topic) {
724
- return Result.err("invalid_params", "Both `scope` and `topic` are required.");
725
- }
726
- try {
727
- if (action === "prepare") {
728
- const prepared = await prepareIncrementalState({ scope, topic, preferences });
729
- return Result.ok({
730
- action,
731
- scope: prepared.scope,
732
- topic: prepared.topic,
733
- topic_key: prepared.topicKey,
734
- preferences: {
735
- max_papers: prepared.preferences.maxPapers,
736
- recency_days: prepared.preferences.recencyDays,
737
- sources: prepared.preferences.sources,
738
- },
739
- memory_hints: {
740
- preferred_keywords: prepared.memoryHints.preferredKeywords,
741
- avoided_keywords: prepared.memoryHints.avoidedKeywords,
742
- preferred_sources: prepared.memoryHints.preferredSources,
743
- avoided_sources: prepared.memoryHints.avoidedSources,
744
- feedback_counts: prepared.memoryHints.feedbackCounts,
745
- last_feedback_at_ms: prepared.memoryHints.lastFeedbackAtMs ?? null,
746
- },
747
- exclude_paper_ids: prepared.excludePaperIds,
748
- known_paper_count: prepared.knownPaperCount,
749
- last_pushed_at_ms: prepared.lastPushedAtMs ?? null,
750
- });
751
- }
752
- if (action === "record") {
753
- const papers = readPapers(params);
754
- const status = readStringParam(params, "status");
755
- const runId = readStringParam(params, "run_id");
756
- const note = readStringParam(params, "note");
757
- const knowledgeState = readKnowledgeStatePayload(params);
758
- const recorded = await recordIncrementalPush({
759
- scope,
760
- topic,
761
- preferences,
762
- status,
763
- runId,
764
- note,
765
- papers,
766
- ...(projectId ? { projectId } : {}),
767
- ...(knowledgeState ? { knowledgeState } : {}),
768
- });
769
- return Result.ok({
770
- action,
771
- scope: recorded.scope,
772
- topic: recorded.topic,
773
- topic_key: recorded.topicKey,
774
- preferences: {
775
- max_papers: recorded.preferences.maxPapers,
776
- recency_days: recorded.preferences.recencyDays,
777
- sources: recorded.preferences.sources,
778
- },
779
- memory_hints: {
780
- preferred_keywords: recorded.memoryHints.preferredKeywords,
781
- avoided_keywords: recorded.memoryHints.avoidedKeywords,
782
- preferred_sources: recorded.memoryHints.preferredSources,
783
- avoided_sources: recorded.memoryHints.avoidedSources,
784
- feedback_counts: recorded.memoryHints.feedbackCounts,
785
- last_feedback_at_ms: recorded.memoryHints.lastFeedbackAtMs ?? null,
786
- },
787
- recorded_papers: recorded.recordedPapers,
788
- total_known_papers: recorded.totalKnownPapers,
789
- pushed_at_ms: recorded.pushedAtMs,
790
- project_id: recorded.projectId ?? null,
791
- knowledge_state_summary: recorded.knowledgeStateSummary
792
- ? {
793
- project_id: recorded.knowledgeStateSummary.projectId,
794
- stream_key: recorded.knowledgeStateSummary.streamKey,
795
- total_runs: recorded.knowledgeStateSummary.totalRuns,
796
- total_hypotheses: recorded.knowledgeStateSummary.totalHypotheses,
797
- knowledge_topics_count: recorded.knowledgeStateSummary.knowledgeTopicsCount,
798
- paper_notes_count: recorded.knowledgeStateSummary.paperNotesCount,
799
- recent_full_text_read_count: recorded.knowledgeStateSummary.recentFullTextReadCount,
800
- recent_not_full_text_read_count: recorded.knowledgeStateSummary.recentNotFullTextReadCount,
801
- quality_gate: {
802
- passed: recorded.knowledgeStateSummary.qualityGate.passed,
803
- full_text_coverage_pct: recorded.knowledgeStateSummary.qualityGate.fullTextCoveragePct,
804
- evidence_binding_rate_pct: recorded.knowledgeStateSummary.qualityGate.evidenceBindingRatePct,
805
- citation_error_rate_pct: recorded.knowledgeStateSummary.qualityGate.citationErrorRatePct,
806
- reasons: recorded.knowledgeStateSummary.qualityGate.reasons,
807
- },
808
- unread_core_paper_ids: recorded.knowledgeStateSummary.unreadCorePaperIds,
809
- last_run_at_ms: recorded.knowledgeStateSummary.lastRunAtMs ?? null,
810
- last_status: recorded.knowledgeStateSummary.lastStatus ?? null,
811
- recent_papers: recorded.knowledgeStateSummary.recentPapers.map(serializeKnowledgePaper),
812
- }
813
- : null,
814
- });
815
- }
816
- if (action === "feedback") {
817
- const signal = readFeedbackSignal(params);
818
- if (!signal) {
819
- return Result.err("invalid_params", 'Action "feedback" requires `signal` as one of: read, skip, star.');
820
- }
821
- const runId = readStringParam(params, "run_id");
822
- const note = readStringParam(params, "note");
823
- const source = readStringParam(params, "source");
824
- const tags = readStringList(params, "tags");
825
- const paper = readFeedbackPaper(params);
826
- const feedback = await recordUserFeedback({
827
- scope,
828
- topic,
829
- preferences,
830
- feedback: {
831
- signal,
832
- ...(paper ? { paper } : {}),
833
- ...(source ? { source } : {}),
834
- ...(tags ? { tags } : {}),
835
- ...(note ? { note } : {}),
836
- ...(runId ? { runId } : {}),
837
- },
838
- });
839
- return Result.ok({
840
- action,
841
- scope: feedback.scope,
842
- topic: feedback.topic,
843
- topic_key: feedback.topicKey,
844
- signal: feedback.signal,
845
- preferences: {
846
- max_papers: feedback.preferences.maxPapers,
847
- recency_days: feedback.preferences.recencyDays,
848
- sources: feedback.preferences.sources,
849
- },
850
- memory_hints: {
851
- preferred_keywords: feedback.memoryHints.preferredKeywords,
852
- avoided_keywords: feedback.memoryHints.avoidedKeywords,
853
- preferred_sources: feedback.memoryHints.preferredSources,
854
- avoided_sources: feedback.memoryHints.avoidedSources,
855
- feedback_counts: feedback.memoryHints.feedbackCounts,
856
- last_feedback_at_ms: feedback.memoryHints.lastFeedbackAtMs ?? null,
857
- },
858
- updated_at_ms: feedback.updatedAtMs,
859
- });
860
- }
861
- if (action === "status") {
862
- const status = await getIncrementalStateStatus({
863
- scope,
864
- topic,
865
- ...(projectId ? { projectId } : {}),
866
- });
867
- return Result.ok({
868
- action,
869
- scope: status.scope,
870
- topic: status.topic,
871
- topic_key: status.topicKey,
872
- preferences: {
873
- max_papers: status.preferences.maxPapers,
874
- recency_days: status.preferences.recencyDays,
875
- sources: status.preferences.sources,
876
- },
877
- memory_hints: {
878
- preferred_keywords: status.memoryHints.preferredKeywords,
879
- avoided_keywords: status.memoryHints.avoidedKeywords,
880
- preferred_sources: status.memoryHints.preferredSources,
881
- avoided_sources: status.memoryHints.avoidedSources,
882
- feedback_counts: status.memoryHints.feedbackCounts,
883
- last_feedback_at_ms: status.memoryHints.lastFeedbackAtMs ?? null,
884
- },
885
- exclude_paper_ids: status.excludePaperIds,
886
- known_paper_count: status.knownPaperCount,
887
- total_runs: status.totalRuns,
888
- last_status: status.lastStatus ?? null,
889
- last_pushed_at_ms: status.lastPushedAtMs ?? null,
890
- knowledge_state_summary: status.knowledgeStateSummary
891
- ? {
892
- project_id: status.knowledgeStateSummary.projectId,
893
- stream_key: status.knowledgeStateSummary.streamKey,
894
- total_runs: status.knowledgeStateSummary.totalRuns,
895
- total_hypotheses: status.knowledgeStateSummary.totalHypotheses,
896
- knowledge_topics_count: status.knowledgeStateSummary.knowledgeTopicsCount,
897
- paper_notes_count: status.knowledgeStateSummary.paperNotesCount,
898
- recent_full_text_read_count: status.knowledgeStateSummary.recentFullTextReadCount,
899
- recent_not_full_text_read_count: status.knowledgeStateSummary.recentNotFullTextReadCount,
900
- quality_gate: {
901
- passed: status.knowledgeStateSummary.qualityGate.passed,
902
- full_text_coverage_pct: status.knowledgeStateSummary.qualityGate.fullTextCoveragePct,
903
- evidence_binding_rate_pct: status.knowledgeStateSummary.qualityGate.evidenceBindingRatePct,
904
- citation_error_rate_pct: status.knowledgeStateSummary.qualityGate.citationErrorRatePct,
905
- reasons: status.knowledgeStateSummary.qualityGate.reasons,
906
- },
907
- unread_core_paper_ids: status.knowledgeStateSummary.unreadCorePaperIds,
908
- last_run_at_ms: status.knowledgeStateSummary.lastRunAtMs ?? null,
909
- last_status: status.knowledgeStateSummary.lastStatus ?? null,
910
- recent_papers: status.knowledgeStateSummary.recentPapers.map(serializeKnowledgePaper),
911
- }
912
- : null,
913
- recent_hypotheses: status.recentHypotheses.map((item) => ({
914
- id: item.id,
915
- statement: item.statement,
916
- trigger: item.trigger,
917
- created_at_ms: item.createdAtMs,
918
- file: item.file,
919
- })),
920
- recent_change_stats: status.recentChangeStats.map((item) => ({
921
- day: item.day,
922
- run_id: item.runId,
923
- new_count: item.newCount,
924
- confirm_count: item.confirmCount,
925
- revise_count: item.reviseCount,
926
- bridge_count: item.bridgeCount,
927
- })),
928
- last_exploration_trace: status.lastExplorationTrace.map((item) => ({
929
- query: item.query,
930
- reason: item.reason ?? null,
931
- source: item.source ?? null,
932
- candidates: item.candidates ?? null,
933
- filtered_to: item.filteredTo ?? null,
934
- filtered_out_reasons: item.filteredOutReasons ?? [],
935
- result_count: item.resultCount ?? null,
936
- })),
937
- recent_papers: status.recentPapers.map((paper) => ({
938
- id: paper.id,
939
- title: paper.title ?? null,
940
- url: paper.url ?? null,
941
- last_score: paper.lastScore ?? null,
942
- last_reason: paper.lastReason ?? null,
943
- first_pushed_at_ms: paper.firstPushedAtMs,
944
- last_pushed_at_ms: paper.lastPushedAtMs,
945
- push_count: paper.pushCount,
946
- })),
947
- });
948
- }
949
- return Result.err("invalid_params", 'Invalid action. Use one of: "prepare", "record", "feedback", "status".');
950
- }
951
- catch (error) {
952
- return Result.err("runtime_error", `scientify_literature_state failed: ${error instanceof Error ? error.message : String(error)}`);
953
- }
954
- },
955
- };
956
- }
957
- //# sourceMappingURL=scientify-literature-state.js.map