open-research 1.1.2 → 1.2.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.
@@ -1,94 +1,7 @@
1
- import {
2
- readJsonFile,
3
- writeJsonFile
4
- } from "./chunk-77Q5B5H7.js";
5
- import {
6
- getOpenResearchConfigFile
7
- } from "./chunk-4HCPHCC2.js";
8
1
  import {
9
2
  getProviderCatalog
10
3
  } from "./chunk-GVEVKDGV.js";
11
4
 
12
- // src/lib/config/store.ts
13
- import { z } from "zod";
14
- var themeValues = ["dark", "light"];
15
- var providerValues = ["openai", "gemini"];
16
- var openAIProviderConfigSchema = z.object({
17
- apiKey: z.string().optional()
18
- }).optional();
19
- var geminiProviderConfigSchema = z.object({
20
- apiKey: z.string().optional()
21
- }).optional();
22
- var openResearchConfigSchema = z.object({
23
- version: z.literal(1),
24
- defaults: z.object({
25
- model: z.string().min(1),
26
- reasoningEffort: z.enum(["low", "medium", "high", "xhigh"]),
27
- editPolicy: z.literal("mixed")
28
- }),
29
- theme: z.enum(themeValues).default("dark"),
30
- activeProvider: z.enum(providerValues).default("openai"),
31
- lastWorkspace: z.string().nullable(),
32
- providers: z.object({
33
- openai: openAIProviderConfigSchema,
34
- gemini: geminiProviderConfigSchema
35
- }).optional(),
36
- apiKeys: z.object({
37
- openai: z.string().optional(),
38
- semanticScholar: z.string().optional(),
39
- openAlex: z.string().optional(),
40
- brave: z.string().optional(),
41
- gemini: z.string().optional()
42
- }).optional()
43
- });
44
- var DEFAULT_OPEN_RESEARCH_CONFIG = {
45
- version: 1,
46
- defaults: {
47
- model: "gpt-5.4",
48
- reasoningEffort: "medium",
49
- editPolicy: "mixed"
50
- },
51
- theme: "dark",
52
- activeProvider: "openai",
53
- lastWorkspace: null,
54
- providers: {
55
- openai: {},
56
- gemini: {}
57
- },
58
- apiKeys: {}
59
- };
60
- function getConfiguredOpenAIApiKey(config) {
61
- return config?.providers?.openai?.apiKey || config?.apiKeys?.openai;
62
- }
63
- function getSemanticScholarApiKey(config) {
64
- return config?.apiKeys?.semanticScholar || process.env.SEMANTIC_SCHOLAR_API_KEY;
65
- }
66
- function getOpenAlexApiKey(config) {
67
- return config?.apiKeys?.openAlex || process.env.OPENALEX_API_KEY;
68
- }
69
- function getBraveApiKey(config) {
70
- return config?.apiKeys?.brave || process.env.BRAVE_API_KEY;
71
- }
72
- async function loadOpenResearchConfig(options) {
73
- const configFile = getOpenResearchConfigFile(options);
74
- const config = await readJsonFile(configFile, null);
75
- if (!config) {
76
- return null;
77
- }
78
- return openResearchConfigSchema.parse(config);
79
- }
80
- async function saveOpenResearchConfig(config, options) {
81
- await writeJsonFile(getOpenResearchConfigFile(options), config);
82
- }
83
- async function ensureOpenResearchConfig(options) {
84
- const existing = await loadOpenResearchConfig(options);
85
- if (existing) {
86
- return existing;
87
- }
88
- await writeJsonFile(getOpenResearchConfigFile(options), DEFAULT_OPEN_RESEARCH_CONFIG);
89
- return DEFAULT_OPEN_RESEARCH_CONFIG;
90
- }
91
-
92
5
  // src/lib/agent/tools/fetch-url.ts
93
6
  import { load as loadCheerio } from "cheerio";
94
7
  var MAX_RESPONSE_BYTES = 512 * 1024;
@@ -370,9 +283,7 @@ async function fetchAndParseContent(url) {
370
283
 
371
284
  // src/lib/search/extract.ts
372
285
  var MAX_CONTENT_CHARS = 12e3;
373
- var EXTRACTION_PROMPT = `You are a research extraction system. You receive source text and a research target.
374
-
375
- Analyze the source through the lens of the target and extract structured findings.
286
+ var EXTRACTION_PROMPT = `You are a research extraction system. You receive source text and a research target. Analyze the source through the lens of the target and extract structured findings.
376
287
 
377
288
  Research target: {TARGET}
378
289
  Source: "{TITLE}" ({URL})
@@ -383,7 +294,11 @@ Rules:
383
294
  - "related": Relevant context that neither supports nor contradicts \u2014 methodology, definitions, related phenomena, frameworks.
384
295
  - "summary": One paragraph synthesizing what this source contributes to understanding the target.
385
296
  - "relevanceScore": 0-10. 0 = unrelated. 5 = tangentially relevant. 10 = directly addresses the target.
386
- - If clearly unrelated (score < 2), set supports/contradicts/related to empty arrays.
297
+ - "evidenceType": Classify the source \u2014 meta-analysis, systematic-review, experiment, observational, review, opinion, dataset, or other.
298
+ - "methodologyNotes": One sentence on methodology. Include study design, duration, key methods. Write "N/A" if not applicable (e.g., opinion piece).
299
+ - "sampleInfo": Sample size and population if mentioned (e.g., "N=1,234 undergraduate students"). Null if not available.
300
+ - "confidence": Your confidence in this extraction \u2014 high (clear evidence, unambiguous), medium (evidence present but interpretation uncertain), low (tangential or ambiguous source).
301
+ - If clearly unrelated (score < 2), set supports/contradicts/related to empty arrays and evidenceType to "other".
387
302
  - Maximum 5 items per category. Prefer fewer precise items over many vague ones.
388
303
  - Include specific numbers, methods, or datasets when available.`;
389
304
  var EXTRACTION_SCHEMA = {
@@ -413,9 +328,27 @@ var EXTRACTION_SCHEMA = {
413
328
  relevanceScore: {
414
329
  type: "number",
415
330
  description: "0-10 relevance to target"
331
+ },
332
+ evidenceType: {
333
+ type: "string",
334
+ enum: ["meta-analysis", "systematic-review", "experiment", "observational", "review", "opinion", "dataset", "other"],
335
+ description: "Classification of evidence type"
336
+ },
337
+ methodologyNotes: {
338
+ type: "string",
339
+ description: "Brief methodology description or N/A"
340
+ },
341
+ sampleInfo: {
342
+ type: ["string", "null"],
343
+ description: "Sample size and population, or null if unavailable"
344
+ },
345
+ confidence: {
346
+ type: "string",
347
+ enum: ["high", "medium", "low"],
348
+ description: "Extraction confidence level"
416
349
  }
417
350
  },
418
- required: ["supports", "contradicts", "related", "summary", "relevanceScore"],
351
+ required: ["supports", "contradicts", "related", "summary", "relevanceScore", "evidenceType", "methodologyNotes", "sampleInfo", "confidence"],
419
352
  additionalProperties: false
420
353
  }
421
354
  };
@@ -436,6 +369,10 @@ async function extractWithTarget(input, provider) {
436
369
  const parsed = JSON.parse(response.content);
437
370
  if (typeof parsed.relevanceScore !== "number") return null;
438
371
  if (!Array.isArray(parsed.supports)) return null;
372
+ if (!parsed.evidenceType) parsed.evidenceType = "other";
373
+ if (!parsed.methodologyNotes) parsed.methodologyNotes = "N/A";
374
+ if (parsed.sampleInfo === void 0) parsed.sampleInfo = null;
375
+ if (!parsed.confidence) parsed.confidence = "medium";
439
376
  return parsed;
440
377
  } catch {
441
378
  return null;
@@ -464,8 +401,18 @@ function formatExtractionResults(sources) {
464
401
  for (let i = 0; i < sorted.length; i++) {
465
402
  const s = sorted[i];
466
403
  const providerLabel = s.provider ? ` [${s.provider}]` : "";
467
- parts.push(`${i + 1}. "${s.title}"${providerLabel} (relevance: ${s.extraction.relevanceScore}/10)`);
404
+ const intentLabel = s.queryIntent === "adversarial" ? " [adversarial]" : "";
405
+ const metaParts = [];
406
+ if (s.year) metaParts.push(String(s.year));
407
+ if (s.venue) metaParts.push(s.venue);
408
+ if (s.citationCount !== void 0 && s.citationCount > 0) metaParts.push(`${s.citationCount} citations`);
409
+ metaParts.push(s.extraction.evidenceType);
410
+ if (s.extraction.sampleInfo) metaParts.push(s.extraction.sampleInfo);
411
+ if (s.extraction.confidence !== "high") metaParts.push(`confidence: ${s.extraction.confidence}`);
412
+ const metaLine = metaParts.length > 0 ? ` ${metaParts.join(" | ")}` : "";
413
+ parts.push(`${i + 1}. "${s.title}"${providerLabel}${intentLabel} (relevance: ${s.extraction.relevanceScore}/10)`);
468
414
  parts.push(` ${s.url}`);
415
+ if (metaLine) parts.push(metaLine);
469
416
  if (s.extraction.supports.length > 0) {
470
417
  parts.push(` Supports:`);
471
418
  for (const item of s.extraction.supports) {
@@ -484,6 +431,9 @@ function formatExtractionResults(sources) {
484
431
  parts.push(` ~ ${item}`);
485
432
  }
486
433
  }
434
+ if (s.extraction.methodologyNotes && s.extraction.methodologyNotes !== "N/A") {
435
+ parts.push(` Methodology: ${s.extraction.methodologyNotes}`);
436
+ }
487
437
  parts.push(` Summary: ${s.extraction.summary}`);
488
438
  parts.push("");
489
439
  }
@@ -492,14 +442,6 @@ function formatExtractionResults(sources) {
492
442
 
493
443
  export {
494
444
  extractPdfText,
495
- themeValues,
496
- getConfiguredOpenAIApiKey,
497
- getSemanticScholarApiKey,
498
- getOpenAlexApiKey,
499
- getBraveApiKey,
500
- loadOpenResearchConfig,
501
- saveOpenResearchConfig,
502
- ensureOpenResearchConfig,
503
445
  USER_AGENT,
504
446
  executeFetchUrl,
505
447
  fetchAndParseContent,