scientify 1.10.3 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -6
- package/README.zh.md +22 -8
- package/dist/src/commands.d.ts.map +1 -1
- package/dist/src/commands.js +63 -0
- package/dist/src/commands.js.map +1 -1
- package/dist/src/hooks/research-mode.d.ts.map +1 -1
- package/dist/src/hooks/research-mode.js +6 -1
- package/dist/src/hooks/research-mode.js.map +1 -1
- package/dist/src/knowledge-state/project.d.ts +13 -0
- package/dist/src/knowledge-state/project.d.ts.map +1 -0
- package/dist/src/knowledge-state/project.js +88 -0
- package/dist/src/knowledge-state/project.js.map +1 -0
- package/dist/src/knowledge-state/render.d.ts +63 -0
- package/dist/src/knowledge-state/render.d.ts.map +1 -0
- package/dist/src/knowledge-state/render.js +368 -0
- package/dist/src/knowledge-state/render.js.map +1 -0
- package/dist/src/knowledge-state/store.d.ts +19 -0
- package/dist/src/knowledge-state/store.d.ts.map +1 -0
- package/dist/src/knowledge-state/store.js +978 -0
- package/dist/src/knowledge-state/store.js.map +1 -0
- package/dist/src/knowledge-state/types.d.ts +182 -0
- package/dist/src/knowledge-state/types.d.ts.map +1 -0
- package/dist/src/knowledge-state/types.js +2 -0
- package/dist/src/knowledge-state/types.js.map +1 -0
- package/dist/src/literature/subscription-state.d.ts +11 -0
- package/dist/src/literature/subscription-state.d.ts.map +1 -1
- package/dist/src/literature/subscription-state.js +38 -2
- package/dist/src/literature/subscription-state.js.map +1 -1
- package/dist/src/research-subscriptions/handlers.d.ts.map +1 -1
- package/dist/src/research-subscriptions/handlers.js +1 -0
- package/dist/src/research-subscriptions/handlers.js.map +1 -1
- package/dist/src/research-subscriptions/parse.d.ts.map +1 -1
- package/dist/src/research-subscriptions/parse.js +14 -0
- package/dist/src/research-subscriptions/parse.js.map +1 -1
- package/dist/src/research-subscriptions/prompt.d.ts +1 -1
- package/dist/src/research-subscriptions/prompt.d.ts.map +1 -1
- package/dist/src/research-subscriptions/prompt.js +178 -23
- package/dist/src/research-subscriptions/prompt.js.map +1 -1
- package/dist/src/research-subscriptions/types.d.ts +1 -0
- package/dist/src/research-subscriptions/types.d.ts.map +1 -1
- package/dist/src/tools/scientify-cron.d.ts +2 -0
- package/dist/src/tools/scientify-cron.d.ts.map +1 -1
- package/dist/src/tools/scientify-cron.js +7 -0
- package/dist/src/tools/scientify-cron.js.map +1 -1
- package/dist/src/tools/scientify-literature-state.d.ts +234 -0
- package/dist/src/tools/scientify-literature-state.d.ts.map +1 -1
- package/dist/src/tools/scientify-literature-state.js +638 -3
- package/dist/src/tools/scientify-literature-state.js.map +1 -1
- package/package.json +1 -1
- package/skills/_shared/workspace-spec.md +15 -3
- package/skills/research-subscription/SKILL.md +18 -3
|
@@ -23,9 +23,105 @@ const PaperSchema = Type.Object({
|
|
|
23
23
|
description: "Optional internal ranking rationale for backend logging.",
|
|
24
24
|
})),
|
|
25
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
|
+
}));
|
|
26
122
|
export const ScientifyLiteratureStateToolSchema = Type.Object({
|
|
27
123
|
action: Type.String({
|
|
28
|
-
description: 'Action: "prepare" | "record" | "feedback" | "status". `status`
|
|
124
|
+
description: 'Action: "prepare" | "record" | "feedback" | "status". `status` returns recent papers plus knowledge_state summary for follow-up traceability.',
|
|
29
125
|
}),
|
|
30
126
|
scope: Type.String({
|
|
31
127
|
description: "Scope key used to isolate user/channel state.",
|
|
@@ -33,6 +129,9 @@ export const ScientifyLiteratureStateToolSchema = Type.Object({
|
|
|
33
129
|
topic: Type.String({
|
|
34
130
|
description: "Research topic text.",
|
|
35
131
|
}),
|
|
132
|
+
project_id: Type.Optional(Type.String({
|
|
133
|
+
description: "Optional project id to pin knowledge_state writes.",
|
|
134
|
+
})),
|
|
36
135
|
preferences: PreferencesSchema,
|
|
37
136
|
papers: Type.Optional(Type.Array(PaperSchema, {
|
|
38
137
|
description: "Papers to mark as pushed when action=record.",
|
|
@@ -60,6 +159,7 @@ export const ScientifyLiteratureStateToolSchema = Type.Object({
|
|
|
60
159
|
tags: Type.Optional(Type.Array(Type.String({
|
|
61
160
|
description: "Optional feedback tags, e.g. [\"physics simulation\", \"agent\"].",
|
|
62
161
|
}))),
|
|
162
|
+
knowledge_state: KnowledgeStateSchema,
|
|
63
163
|
});
|
|
64
164
|
function readStringParam(params, key) {
|
|
65
165
|
const value = params[key];
|
|
@@ -151,17 +251,474 @@ function readStringList(params, key) {
|
|
|
151
251
|
.filter((item) => item.length > 0);
|
|
152
252
|
return values.length > 0 ? values : undefined;
|
|
153
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
|
+
}
|
|
154
710
|
export function createScientifyLiteratureStateTool() {
|
|
155
711
|
return {
|
|
156
712
|
label: "Scientify Literature State",
|
|
157
713
|
name: "scientify_literature_state",
|
|
158
|
-
description: "Manage incremental
|
|
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.",
|
|
159
715
|
parameters: ScientifyLiteratureStateToolSchema,
|
|
160
716
|
execute: async (_toolCallId, rawArgs) => {
|
|
161
717
|
const params = (rawArgs ?? {});
|
|
162
718
|
const action = (readStringParam(params, "action") ?? "").toLowerCase();
|
|
163
719
|
const scope = readStringParam(params, "scope");
|
|
164
720
|
const topic = readStringParam(params, "topic");
|
|
721
|
+
const projectId = readStringParam(params, "project_id");
|
|
165
722
|
const preferences = readPreferences(params);
|
|
166
723
|
if (!scope || !topic) {
|
|
167
724
|
return Result.err("invalid_params", "Both `scope` and `topic` are required.");
|
|
@@ -197,6 +754,7 @@ export function createScientifyLiteratureStateTool() {
|
|
|
197
754
|
const status = readStringParam(params, "status");
|
|
198
755
|
const runId = readStringParam(params, "run_id");
|
|
199
756
|
const note = readStringParam(params, "note");
|
|
757
|
+
const knowledgeState = readKnowledgeStatePayload(params);
|
|
200
758
|
const recorded = await recordIncrementalPush({
|
|
201
759
|
scope,
|
|
202
760
|
topic,
|
|
@@ -205,6 +763,8 @@ export function createScientifyLiteratureStateTool() {
|
|
|
205
763
|
runId,
|
|
206
764
|
note,
|
|
207
765
|
papers,
|
|
766
|
+
...(projectId ? { projectId } : {}),
|
|
767
|
+
...(knowledgeState ? { knowledgeState } : {}),
|
|
208
768
|
});
|
|
209
769
|
return Result.ok({
|
|
210
770
|
action,
|
|
@@ -227,6 +787,30 @@ export function createScientifyLiteratureStateTool() {
|
|
|
227
787
|
recorded_papers: recorded.recordedPapers,
|
|
228
788
|
total_known_papers: recorded.totalKnownPapers,
|
|
229
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,
|
|
230
814
|
});
|
|
231
815
|
}
|
|
232
816
|
if (action === "feedback") {
|
|
@@ -275,7 +859,11 @@ export function createScientifyLiteratureStateTool() {
|
|
|
275
859
|
});
|
|
276
860
|
}
|
|
277
861
|
if (action === "status") {
|
|
278
|
-
const status = await getIncrementalStateStatus({
|
|
862
|
+
const status = await getIncrementalStateStatus({
|
|
863
|
+
scope,
|
|
864
|
+
topic,
|
|
865
|
+
...(projectId ? { projectId } : {}),
|
|
866
|
+
});
|
|
279
867
|
return Result.ok({
|
|
280
868
|
action,
|
|
281
869
|
scope: status.scope,
|
|
@@ -299,6 +887,53 @@ export function createScientifyLiteratureStateTool() {
|
|
|
299
887
|
total_runs: status.totalRuns,
|
|
300
888
|
last_status: status.lastStatus ?? null,
|
|
301
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
|
+
})),
|
|
302
937
|
recent_papers: status.recentPapers.map((paper) => ({
|
|
303
938
|
id: paper.id,
|
|
304
939
|
title: paper.title ?? null,
|