@auxiora/research 1.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.
- package/LICENSE +191 -0
- package/dist/brave-search.d.ts +15 -0
- package/dist/brave-search.d.ts.map +1 -0
- package/dist/brave-search.js +106 -0
- package/dist/brave-search.js.map +1 -0
- package/dist/citation.d.ts +12 -0
- package/dist/citation.d.ts.map +1 -0
- package/dist/citation.js +64 -0
- package/dist/citation.js.map +1 -0
- package/dist/credibility.d.ts +7 -0
- package/dist/credibility.d.ts.map +1 -0
- package/dist/credibility.js +57 -0
- package/dist/credibility.js.map +1 -0
- package/dist/engine.d.ts +24 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +204 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge-graph.d.ts +22 -0
- package/dist/knowledge-graph.d.ts.map +1 -0
- package/dist/knowledge-graph.js +74 -0
- package/dist/knowledge-graph.js.map +1 -0
- package/dist/types.d.ts +75 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +27 -0
- package/src/brave-search.ts +130 -0
- package/src/citation.ts +80 -0
- package/src/credibility.ts +65 -0
- package/src/engine.ts +244 -0
- package/src/index.ts +18 -0
- package/src/knowledge-graph.ts +87 -0
- package/src/types.ts +78 -0
- package/tests/citation.test.ts +72 -0
- package/tests/credibility.test.ts +53 -0
- package/tests/engine.test.ts +104 -0
- package/tests/knowledge-graph.test.ts +68 -0
- package/tsconfig.json +12 -0
- package/tsconfig.tsbuildinfo +1 -0
package/dist/engine.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
import { BraveSearchClient } from './brave-search.js';
|
|
3
|
+
import { CredibilityScorer } from './credibility.js';
|
|
4
|
+
import { CitationTracker } from './citation.js';
|
|
5
|
+
export class ResearchEngine {
|
|
6
|
+
config;
|
|
7
|
+
braveClient;
|
|
8
|
+
provider;
|
|
9
|
+
credibilityScorer = new CredibilityScorer();
|
|
10
|
+
constructor(config) {
|
|
11
|
+
const apiKey = config?.braveApiKey ?? process.env.AUXIORA_RESEARCH_BRAVE_API_KEY;
|
|
12
|
+
if (!apiKey) {
|
|
13
|
+
throw new Error('Research engine requires a Brave Search API key (braveApiKey or AUXIORA_RESEARCH_BRAVE_API_KEY)');
|
|
14
|
+
}
|
|
15
|
+
this.config = {
|
|
16
|
+
maxConcurrentSources: config?.maxConcurrentSources ?? 5,
|
|
17
|
+
defaultDepth: config?.defaultDepth ?? 'standard',
|
|
18
|
+
searchTimeout: config?.searchTimeout ?? 10_000,
|
|
19
|
+
fetchTimeout: config?.fetchTimeout ?? 15_000,
|
|
20
|
+
};
|
|
21
|
+
this.braveClient = new BraveSearchClient({
|
|
22
|
+
apiKey,
|
|
23
|
+
searchTimeout: this.config.searchTimeout,
|
|
24
|
+
fetchTimeout: this.config.fetchTimeout,
|
|
25
|
+
});
|
|
26
|
+
this.provider = config?.provider;
|
|
27
|
+
}
|
|
28
|
+
async research(query) {
|
|
29
|
+
const startTime = Date.now();
|
|
30
|
+
const depth = query.depth ?? this.config.defaultDepth;
|
|
31
|
+
const maxSources = query.maxSources ?? this.getMaxSources(depth);
|
|
32
|
+
const searchQueries = this.planResearch(query.topic, depth, query.focusAreas);
|
|
33
|
+
const tracker = new CitationTracker();
|
|
34
|
+
const findings = [];
|
|
35
|
+
// Execute searches in parallel, limited to maxSources total results
|
|
36
|
+
const searchPromises = searchQueries.map((q) => this.braveClient.search(q, 3));
|
|
37
|
+
const searchResults = await Promise.all(searchPromises);
|
|
38
|
+
// Flatten and deduplicate by URL, cap at maxSources
|
|
39
|
+
const seenUrls = new Set();
|
|
40
|
+
const uniqueResults = [];
|
|
41
|
+
for (let i = 0; i < searchResults.length; i++) {
|
|
42
|
+
for (const result of searchResults[i]) {
|
|
43
|
+
if (!seenUrls.has(result.url) && uniqueResults.length < maxSources) {
|
|
44
|
+
seenUrls.add(result.url);
|
|
45
|
+
uniqueResults.push({
|
|
46
|
+
query: searchQueries[i],
|
|
47
|
+
url: result.url,
|
|
48
|
+
title: result.title,
|
|
49
|
+
snippet: result.description,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Fetch pages in parallel
|
|
55
|
+
const fetchPromises = uniqueResults.map((r) => this.braveClient.fetchPage(r.url));
|
|
56
|
+
const pageContents = await Promise.all(fetchPromises);
|
|
57
|
+
// Process each result
|
|
58
|
+
for (let i = 0; i < uniqueResults.length; i++) {
|
|
59
|
+
const r = uniqueResults[i];
|
|
60
|
+
const credibility = this.credibilityScorer.score(r.url, {
|
|
61
|
+
isHttps: r.url.startsWith('https'),
|
|
62
|
+
});
|
|
63
|
+
const source = tracker.addSource(r.url, r.title, credibility);
|
|
64
|
+
const content = pageContents[i];
|
|
65
|
+
if (this.provider && content) {
|
|
66
|
+
// AI-powered extraction
|
|
67
|
+
const extracted = await this.extractFindings(r.query, content, r.title);
|
|
68
|
+
for (const text of extracted) {
|
|
69
|
+
tracker.addFinding(text, source.id, credibility, 'general');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// Fallback: use search snippet + first paragraph from fetched content
|
|
74
|
+
let text = r.snippet;
|
|
75
|
+
if (content) {
|
|
76
|
+
const firstParagraph = content.split('\n\n').find((p) => p.trim().length > 50);
|
|
77
|
+
if (firstParagraph) {
|
|
78
|
+
text += ' ' + firstParagraph.trim();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
tracker.addFinding(text, source.id, credibility, 'general');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const allFindings = tracker.getFindings();
|
|
85
|
+
const deduplicated = this.deduplicateFindings(allFindings);
|
|
86
|
+
const sources = tracker.getSources();
|
|
87
|
+
// Synthesize summary
|
|
88
|
+
let executiveSummary;
|
|
89
|
+
if (this.provider && deduplicated.length > 0) {
|
|
90
|
+
executiveSummary = await this.synthesizeWithAI(query.topic, deduplicated, sources);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
executiveSummary = this.synthesize(deduplicated);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
id: nanoid(),
|
|
97
|
+
query,
|
|
98
|
+
findings: deduplicated,
|
|
99
|
+
executiveSummary,
|
|
100
|
+
sources,
|
|
101
|
+
confidence: Math.min(deduplicated.length / maxSources, 1),
|
|
102
|
+
generatedAt: Date.now(),
|
|
103
|
+
durationMs: Date.now() - startTime,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
planResearch(topic, depth, focusAreas) {
|
|
107
|
+
let queries;
|
|
108
|
+
switch (depth) {
|
|
109
|
+
case 'quick':
|
|
110
|
+
queries = [topic];
|
|
111
|
+
break;
|
|
112
|
+
case 'standard':
|
|
113
|
+
queries = [topic, `${topic} overview`, `${topic} analysis`];
|
|
114
|
+
break;
|
|
115
|
+
case 'deep':
|
|
116
|
+
queries = [
|
|
117
|
+
topic,
|
|
118
|
+
`${topic} overview`,
|
|
119
|
+
`${topic} analysis`,
|
|
120
|
+
`${topic} comparison`,
|
|
121
|
+
`${topic} best practices`,
|
|
122
|
+
`${topic} research papers`,
|
|
123
|
+
];
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
if (focusAreas?.length) {
|
|
127
|
+
for (const area of focusAreas) {
|
|
128
|
+
queries.push(`${topic} ${area}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return queries;
|
|
132
|
+
}
|
|
133
|
+
synthesize(findings) {
|
|
134
|
+
const sourceIds = new Set(findings.map((f) => f.sourceId));
|
|
135
|
+
const topFindings = findings
|
|
136
|
+
.sort((a, b) => b.relevance - a.relevance)
|
|
137
|
+
.slice(0, 3)
|
|
138
|
+
.map((f) => f.content);
|
|
139
|
+
return `Based on ${findings.length} findings from ${sourceIds.size} sources: ${topFindings.join('. ')}`;
|
|
140
|
+
}
|
|
141
|
+
deduplicateFindings(findings) {
|
|
142
|
+
const seen = new Set();
|
|
143
|
+
return findings.filter((f) => {
|
|
144
|
+
if (seen.has(f.content)) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
seen.add(f.content);
|
|
148
|
+
return true;
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
async extractFindings(query, content, title) {
|
|
152
|
+
if (!this.provider)
|
|
153
|
+
return [];
|
|
154
|
+
try {
|
|
155
|
+
const result = await this.provider.complete([{ role: 'user', content: `Extract key findings from this source about "${query}".\n\nSource: ${title}\n\nContent:\n${content.slice(0, 8000)}` }], {
|
|
156
|
+
systemPrompt: 'You are a research assistant. Extract 2-4 distinct factual findings from the source. Return each finding on a separate line, prefixed with "- ". Be concise and factual.',
|
|
157
|
+
maxTokens: 500,
|
|
158
|
+
temperature: 0.1,
|
|
159
|
+
});
|
|
160
|
+
return result.content
|
|
161
|
+
.split('\n')
|
|
162
|
+
.filter((line) => line.startsWith('- '))
|
|
163
|
+
.map((line) => line.slice(2).trim())
|
|
164
|
+
.filter((line) => line.length > 10);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async synthesizeWithAI(topic, findings, sources) {
|
|
171
|
+
if (!this.provider)
|
|
172
|
+
return this.synthesize(findings);
|
|
173
|
+
try {
|
|
174
|
+
const findingsText = findings
|
|
175
|
+
.sort((a, b) => b.relevance - a.relevance)
|
|
176
|
+
.slice(0, 10)
|
|
177
|
+
.map((f, i) => `${i + 1}. ${f.content}`)
|
|
178
|
+
.join('\n');
|
|
179
|
+
const sourcesText = sources
|
|
180
|
+
.map((s) => `- ${s.title} (${s.domain}, credibility: ${s.credibilityScore.toFixed(2)})`)
|
|
181
|
+
.join('\n');
|
|
182
|
+
const result = await this.provider.complete([{ role: 'user', content: `Synthesize these research findings about "${topic}" into a concise executive summary.\n\nFindings:\n${findingsText}\n\nSources:\n${sourcesText}` }], {
|
|
183
|
+
systemPrompt: 'You are a research analyst. Write a concise executive summary (2-4 paragraphs) synthesizing the findings. Mention source credibility where relevant. Be factual and balanced.',
|
|
184
|
+
maxTokens: 800,
|
|
185
|
+
temperature: 0.3,
|
|
186
|
+
});
|
|
187
|
+
return result.content;
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return this.synthesize(findings);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
getMaxSources(depth) {
|
|
194
|
+
switch (depth) {
|
|
195
|
+
case 'quick':
|
|
196
|
+
return 3;
|
|
197
|
+
case 'standard':
|
|
198
|
+
return 5;
|
|
199
|
+
case 'deep':
|
|
200
|
+
return 10;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { ResearchDepth, ResearchQuery, ResearchResult, Finding, Source, CredibilityFactors, KnowledgeEntity, KnowledgeRelation, ResearchProvider, BraveWebResult, BraveSearchResponse, } from './types.js';
|
|
2
|
+
export { ResearchEngine, type ResearchEngineConfig } from './engine.js';
|
|
3
|
+
export { BraveSearchClient, type BraveSearchOptions } from './brave-search.js';
|
|
4
|
+
export { CredibilityScorer } from './credibility.js';
|
|
5
|
+
export { CitationTracker } from './citation.js';
|
|
6
|
+
export { KnowledgeGraph } from './knowledge-graph.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,OAAO,EACP,MAAM,EACN,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ResearchEngine } from './engine.js';
|
|
2
|
+
export { BraveSearchClient } from './brave-search.js';
|
|
3
|
+
export { CredibilityScorer } from './credibility.js';
|
|
4
|
+
export { CitationTracker } from './citation.js';
|
|
5
|
+
export { KnowledgeGraph } from './knowledge-graph.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,cAAc,EAA6B,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAA2B,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { KnowledgeEntity, KnowledgeRelation } from './types.js';
|
|
2
|
+
export declare class KnowledgeGraph {
|
|
3
|
+
private entities;
|
|
4
|
+
private relations;
|
|
5
|
+
addEntity(name: string, type: string, properties?: Record<string, string>): KnowledgeEntity;
|
|
6
|
+
getEntity(id: string): KnowledgeEntity | undefined;
|
|
7
|
+
findByName(name: string): KnowledgeEntity | undefined;
|
|
8
|
+
findByType(type: string): KnowledgeEntity[];
|
|
9
|
+
addRelation(fromId: string, toId: string, relation: string): void;
|
|
10
|
+
getRelated(entityId: string): Array<{
|
|
11
|
+
entity: KnowledgeEntity;
|
|
12
|
+
relation: string;
|
|
13
|
+
direction: 'from' | 'to';
|
|
14
|
+
}>;
|
|
15
|
+
removeEntity(id: string): boolean;
|
|
16
|
+
toJSON(): {
|
|
17
|
+
entities: KnowledgeEntity[];
|
|
18
|
+
relations: KnowledgeRelation[];
|
|
19
|
+
};
|
|
20
|
+
clear(): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=knowledge-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-graph.d.ts","sourceRoot":"","sources":["../src/knowledge-graph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAErE,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,SAAS,CAA2B;IAE5C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,eAAe;IAY3F,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIlD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IASrD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE;IAU3C,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIjE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAqB5G,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQjC,MAAM,IAAI;QAAE,QAAQ,EAAE,eAAe,EAAE,CAAC;QAAC,SAAS,EAAE,iBAAiB,EAAE,CAAA;KAAE;IAOzE,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
export class KnowledgeGraph {
|
|
3
|
+
entities = new Map();
|
|
4
|
+
relations = [];
|
|
5
|
+
addEntity(name, type, properties) {
|
|
6
|
+
const entity = {
|
|
7
|
+
id: nanoid(),
|
|
8
|
+
name,
|
|
9
|
+
type,
|
|
10
|
+
properties: properties ?? {},
|
|
11
|
+
};
|
|
12
|
+
this.entities.set(entity.id, entity);
|
|
13
|
+
return entity;
|
|
14
|
+
}
|
|
15
|
+
getEntity(id) {
|
|
16
|
+
return this.entities.get(id);
|
|
17
|
+
}
|
|
18
|
+
findByName(name) {
|
|
19
|
+
for (const entity of this.entities.values()) {
|
|
20
|
+
if (entity.name === name) {
|
|
21
|
+
return entity;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
findByType(type) {
|
|
27
|
+
const result = [];
|
|
28
|
+
for (const entity of this.entities.values()) {
|
|
29
|
+
if (entity.type === type) {
|
|
30
|
+
result.push(entity);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
addRelation(fromId, toId, relation) {
|
|
36
|
+
this.relations.push({ fromId, toId, relation });
|
|
37
|
+
}
|
|
38
|
+
getRelated(entityId) {
|
|
39
|
+
const result = [];
|
|
40
|
+
for (const rel of this.relations) {
|
|
41
|
+
if (rel.fromId === entityId) {
|
|
42
|
+
const entity = this.entities.get(rel.toId);
|
|
43
|
+
if (entity) {
|
|
44
|
+
result.push({ entity, relation: rel.relation, direction: 'from' });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (rel.toId === entityId) {
|
|
48
|
+
const entity = this.entities.get(rel.fromId);
|
|
49
|
+
if (entity) {
|
|
50
|
+
result.push({ entity, relation: rel.relation, direction: 'to' });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
removeEntity(id) {
|
|
57
|
+
const deleted = this.entities.delete(id);
|
|
58
|
+
if (deleted) {
|
|
59
|
+
this.relations = this.relations.filter((r) => r.fromId !== id && r.toId !== id);
|
|
60
|
+
}
|
|
61
|
+
return deleted;
|
|
62
|
+
}
|
|
63
|
+
toJSON() {
|
|
64
|
+
return {
|
|
65
|
+
entities: Array.from(this.entities.values()),
|
|
66
|
+
relations: [...this.relations],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
clear() {
|
|
70
|
+
this.entities.clear();
|
|
71
|
+
this.relations = [];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=knowledge-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-graph.js","sourceRoot":"","sources":["../src/knowledge-graph.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export type ResearchDepth = 'quick' | 'standard' | 'deep';
|
|
2
|
+
export interface ResearchQuery {
|
|
3
|
+
topic: string;
|
|
4
|
+
depth: ResearchDepth;
|
|
5
|
+
maxSources?: number;
|
|
6
|
+
focusAreas?: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface ResearchResult {
|
|
9
|
+
id: string;
|
|
10
|
+
query: ResearchQuery;
|
|
11
|
+
findings: Finding[];
|
|
12
|
+
executiveSummary: string;
|
|
13
|
+
sources: Source[];
|
|
14
|
+
confidence: number;
|
|
15
|
+
generatedAt: number;
|
|
16
|
+
durationMs: number;
|
|
17
|
+
}
|
|
18
|
+
export interface Finding {
|
|
19
|
+
id: string;
|
|
20
|
+
content: string;
|
|
21
|
+
sourceId: string;
|
|
22
|
+
relevance: number;
|
|
23
|
+
category: string;
|
|
24
|
+
}
|
|
25
|
+
export interface Source {
|
|
26
|
+
id: string;
|
|
27
|
+
url: string;
|
|
28
|
+
title: string;
|
|
29
|
+
domain: string;
|
|
30
|
+
accessedAt: number;
|
|
31
|
+
credibilityScore: number;
|
|
32
|
+
}
|
|
33
|
+
export interface CredibilityFactors {
|
|
34
|
+
domainReputation: number;
|
|
35
|
+
hasAuthor: boolean;
|
|
36
|
+
hasDate: boolean;
|
|
37
|
+
isHttps: boolean;
|
|
38
|
+
crossReferenced: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface KnowledgeEntity {
|
|
41
|
+
id: string;
|
|
42
|
+
name: string;
|
|
43
|
+
type: string;
|
|
44
|
+
properties: Record<string, string>;
|
|
45
|
+
}
|
|
46
|
+
export interface KnowledgeRelation {
|
|
47
|
+
fromId: string;
|
|
48
|
+
toId: string;
|
|
49
|
+
relation: string;
|
|
50
|
+
}
|
|
51
|
+
/** Minimal provider interface — avoids hard dep on @auxiora/providers */
|
|
52
|
+
export interface ResearchProvider {
|
|
53
|
+
complete(messages: {
|
|
54
|
+
role: 'user' | 'assistant' | 'system';
|
|
55
|
+
content: string;
|
|
56
|
+
}[], options?: {
|
|
57
|
+
systemPrompt?: string;
|
|
58
|
+
maxTokens?: number;
|
|
59
|
+
temperature?: number;
|
|
60
|
+
}): Promise<{
|
|
61
|
+
content: string;
|
|
62
|
+
}>;
|
|
63
|
+
}
|
|
64
|
+
export interface BraveWebResult {
|
|
65
|
+
title: string;
|
|
66
|
+
url: string;
|
|
67
|
+
description: string;
|
|
68
|
+
extra_snippets?: string[];
|
|
69
|
+
}
|
|
70
|
+
export interface BraveSearchResponse {
|
|
71
|
+
web?: {
|
|
72
|
+
results: BraveWebResult[];
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;AAE1D,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CACN,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,EACtE,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5E,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE;QACJ,OAAO,EAAE,cAAc,EAAE,CAAC;KAC3B,CAAC;CACH"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@auxiora/research",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Deep multi-source research agent with citation tracking and knowledge graph",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"nanoid": "^5.1.2",
|
|
16
|
+
"@auxiora/audit": "1.0.0",
|
|
17
|
+
"@auxiora/logger": "1.0.0"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=22.0.0"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"clean": "rm -rf dist",
|
|
25
|
+
"typecheck": "tsc --noEmit"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { BraveSearchResponse, BraveWebResult } from './types.js';
|
|
2
|
+
|
|
3
|
+
const BRAVE_SEARCH_URL = 'https://api.search.brave.com/res/v1/web/search';
|
|
4
|
+
const USER_AGENT = 'Auxiora/1.0 (Research Engine)';
|
|
5
|
+
|
|
6
|
+
export interface BraveSearchOptions {
|
|
7
|
+
apiKey: string;
|
|
8
|
+
searchTimeout?: number;
|
|
9
|
+
fetchTimeout?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class BraveSearchClient {
|
|
13
|
+
private readonly apiKey: string;
|
|
14
|
+
private readonly searchTimeout: number;
|
|
15
|
+
private readonly fetchTimeout: number;
|
|
16
|
+
|
|
17
|
+
constructor(options: BraveSearchOptions) {
|
|
18
|
+
this.apiKey = options.apiKey;
|
|
19
|
+
this.searchTimeout = options.searchTimeout ?? 10_000;
|
|
20
|
+
this.fetchTimeout = options.fetchTimeout ?? 15_000;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async search(query: string, count = 5): Promise<BraveWebResult[]> {
|
|
24
|
+
const url = new URL(BRAVE_SEARCH_URL);
|
|
25
|
+
url.searchParams.set('q', query);
|
|
26
|
+
url.searchParams.set('count', String(count));
|
|
27
|
+
|
|
28
|
+
const controller = new AbortController();
|
|
29
|
+
const timer = setTimeout(() => controller.abort(), this.searchTimeout);
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const response = await fetch(url.toString(), {
|
|
33
|
+
headers: {
|
|
34
|
+
'Accept': 'application/json',
|
|
35
|
+
'X-Subscription-Token': this.apiKey,
|
|
36
|
+
'User-Agent': USER_AGENT,
|
|
37
|
+
},
|
|
38
|
+
signal: controller.signal,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new Error(`Brave Search API error: ${response.status} ${response.statusText}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const data = (await response.json()) as BraveSearchResponse;
|
|
46
|
+
return (data.web?.results ?? []).map((r) => ({
|
|
47
|
+
...r,
|
|
48
|
+
description: stripHtml(r.description),
|
|
49
|
+
extra_snippets: r.extra_snippets?.map(stripHtml),
|
|
50
|
+
}));
|
|
51
|
+
} finally {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async fetchPage(url: string): Promise<string> {
|
|
57
|
+
const controller = new AbortController();
|
|
58
|
+
const timer = setTimeout(() => controller.abort(), this.fetchTimeout);
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const response = await fetch(url, {
|
|
62
|
+
headers: { 'User-Agent': USER_AGENT },
|
|
63
|
+
signal: controller.signal,
|
|
64
|
+
redirect: 'follow',
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
return '';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
72
|
+
if (!contentType.includes('text/html') && !contentType.includes('text/plain')) {
|
|
73
|
+
return '';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const html = await response.text();
|
|
77
|
+
const maxLength = 15_000;
|
|
78
|
+
return htmlToMarkdown(html).slice(0, maxLength);
|
|
79
|
+
} catch {
|
|
80
|
+
return '';
|
|
81
|
+
} finally {
|
|
82
|
+
clearTimeout(timer);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Strip HTML tags and decode entities from short text (e.g. Brave snippets). */
|
|
88
|
+
function stripHtml(text: string): string {
|
|
89
|
+
return text
|
|
90
|
+
.replace(/<[^>]+>/g, '')
|
|
91
|
+
.replace(/ /g, ' ')
|
|
92
|
+
.replace(/&/g, '&')
|
|
93
|
+
.replace(/</g, '<')
|
|
94
|
+
.replace(/>/g, '>')
|
|
95
|
+
.replace(/"/g, '"')
|
|
96
|
+
.replace(/'/g, "'")
|
|
97
|
+
.trim();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Simple HTML to markdown conversion.
|
|
102
|
+
* Local copy to avoid circular dependency with @auxiora/tools.
|
|
103
|
+
*/
|
|
104
|
+
function htmlToMarkdown(html: string): string {
|
|
105
|
+
let text = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
|
|
106
|
+
text = text.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '');
|
|
107
|
+
|
|
108
|
+
text = text.replace(/<h1[^>]*>(.*?)<\/h1>/gi, '\n# $1\n');
|
|
109
|
+
text = text.replace(/<h2[^>]*>(.*?)<\/h2>/gi, '\n## $1\n');
|
|
110
|
+
text = text.replace(/<h3[^>]*>(.*?)<\/h3>/gi, '\n### $1\n');
|
|
111
|
+
|
|
112
|
+
text = text.replace(/<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/gi, '[$2]($1)');
|
|
113
|
+
text = text.replace(/<li[^>]*>(.*?)<\/li>/gi, '- $1\n');
|
|
114
|
+
text = text.replace(/<p[^>]*>(.*?)<\/p>/gi, '$1\n\n');
|
|
115
|
+
text = text.replace(/<br\s*\/?>/gi, '\n');
|
|
116
|
+
|
|
117
|
+
text = text.replace(/<[^>]+>/g, '');
|
|
118
|
+
|
|
119
|
+
text = text.replace(/ /g, ' ');
|
|
120
|
+
text = text.replace(/&/g, '&');
|
|
121
|
+
text = text.replace(/</g, '<');
|
|
122
|
+
text = text.replace(/>/g, '>');
|
|
123
|
+
text = text.replace(/"/g, '"');
|
|
124
|
+
text = text.replace(/'/g, "'");
|
|
125
|
+
|
|
126
|
+
text = text.replace(/\n{3,}/g, '\n\n');
|
|
127
|
+
text = text.replace(/[ \t]{2,}/g, ' ');
|
|
128
|
+
|
|
129
|
+
return text.trim();
|
|
130
|
+
}
|