@nahisaho/katashiro-collector 0.2.2 → 0.2.4
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/dist/browser/ActionExecutor.d.ts +85 -0
- package/dist/browser/ActionExecutor.d.ts.map +1 -0
- package/dist/browser/ActionExecutor.js +171 -0
- package/dist/browser/ActionExecutor.js.map +1 -0
- package/dist/browser/BrowserAutomation.d.ts +147 -0
- package/dist/browser/BrowserAutomation.d.ts.map +1 -0
- package/dist/browser/BrowserAutomation.js +463 -0
- package/dist/browser/BrowserAutomation.js.map +1 -0
- package/dist/browser/ContentExtractor.d.ts +54 -0
- package/dist/browser/ContentExtractor.d.ts.map +1 -0
- package/dist/browser/ContentExtractor.js +159 -0
- package/dist/browser/ContentExtractor.js.map +1 -0
- package/dist/browser/SessionManager.d.ts +67 -0
- package/dist/browser/SessionManager.d.ts.map +1 -0
- package/dist/browser/SessionManager.js +173 -0
- package/dist/browser/SessionManager.js.map +1 -0
- package/dist/browser/index.d.ts +17 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +17 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/types.d.ts +361 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +23 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/document/DocumentParser.d.ts +91 -0
- package/dist/document/DocumentParser.d.ts.map +1 -0
- package/dist/document/DocumentParser.js +234 -0
- package/dist/document/DocumentParser.js.map +1 -0
- package/dist/document/index.d.ts +11 -0
- package/dist/document/index.d.ts.map +1 -0
- package/dist/document/index.js +10 -0
- package/dist/document/index.js.map +1 -0
- package/dist/document/parsers/DOCXParser.d.ts +63 -0
- package/dist/document/parsers/DOCXParser.d.ts.map +1 -0
- package/dist/document/parsers/DOCXParser.js +362 -0
- package/dist/document/parsers/DOCXParser.js.map +1 -0
- package/dist/document/parsers/PDFParser.d.ts +60 -0
- package/dist/document/parsers/PDFParser.d.ts.map +1 -0
- package/dist/document/parsers/PDFParser.js +338 -0
- package/dist/document/parsers/PDFParser.js.map +1 -0
- package/dist/document/parsers/XLSXParser.d.ts +55 -0
- package/dist/document/parsers/XLSXParser.d.ts.map +1 -0
- package/dist/document/parsers/XLSXParser.js +314 -0
- package/dist/document/parsers/XLSXParser.js.map +1 -0
- package/dist/document/parsers/index.d.ts +10 -0
- package/dist/document/parsers/index.d.ts.map +1 -0
- package/dist/document/parsers/index.js +10 -0
- package/dist/document/parsers/index.js.map +1 -0
- package/dist/document/types.d.ts +251 -0
- package/dist/document/types.d.ts.map +1 -0
- package/dist/document/types.js +13 -0
- package/dist/document/types.js.map +1 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -2
- package/dist/index.js.map +1 -1
- package/dist/research/CoverageAnalyzer.d.ts +50 -0
- package/dist/research/CoverageAnalyzer.d.ts.map +1 -0
- package/dist/research/CoverageAnalyzer.js +169 -0
- package/dist/research/CoverageAnalyzer.js.map +1 -0
- package/dist/research/QueryPlanner.d.ts +57 -0
- package/dist/research/QueryPlanner.d.ts.map +1 -0
- package/dist/research/QueryPlanner.js +102 -0
- package/dist/research/QueryPlanner.js.map +1 -0
- package/dist/research/ResultAggregator.d.ts +39 -0
- package/dist/research/ResultAggregator.d.ts.map +1 -0
- package/dist/research/ResultAggregator.js +85 -0
- package/dist/research/ResultAggregator.js.map +1 -0
- package/dist/research/WideResearchEngine.d.ts +110 -0
- package/dist/research/WideResearchEngine.d.ts.map +1 -0
- package/dist/research/WideResearchEngine.js +330 -0
- package/dist/research/WideResearchEngine.js.map +1 -0
- package/dist/research/agents/AcademicSearchAgent.d.ts +57 -0
- package/dist/research/agents/AcademicSearchAgent.d.ts.map +1 -0
- package/dist/research/agents/AcademicSearchAgent.js +180 -0
- package/dist/research/agents/AcademicSearchAgent.js.map +1 -0
- package/dist/research/agents/EncyclopediaAgent.d.ts +49 -0
- package/dist/research/agents/EncyclopediaAgent.d.ts.map +1 -0
- package/dist/research/agents/EncyclopediaAgent.js +153 -0
- package/dist/research/agents/EncyclopediaAgent.js.map +1 -0
- package/dist/research/agents/NewsSearchAgent.d.ts +38 -0
- package/dist/research/agents/NewsSearchAgent.d.ts.map +1 -0
- package/dist/research/agents/NewsSearchAgent.js +146 -0
- package/dist/research/agents/NewsSearchAgent.js.map +1 -0
- package/dist/research/agents/WebSearchAgent.d.ts +45 -0
- package/dist/research/agents/WebSearchAgent.d.ts.map +1 -0
- package/dist/research/agents/WebSearchAgent.js +135 -0
- package/dist/research/agents/WebSearchAgent.js.map +1 -0
- package/dist/research/agents/index.d.ts +13 -0
- package/dist/research/agents/index.d.ts.map +1 -0
- package/dist/research/agents/index.js +12 -0
- package/dist/research/agents/index.js.map +1 -0
- package/dist/research/agents/types.d.ts +60 -0
- package/dist/research/agents/types.d.ts.map +1 -0
- package/dist/research/agents/types.js +9 -0
- package/dist/research/agents/types.js.map +1 -0
- package/dist/research/index.d.ts +16 -0
- package/dist/research/index.d.ts.map +1 -0
- package/dist/research/index.js +17 -0
- package/dist/research/index.js.map +1 -0
- package/dist/research/types.d.ts +206 -0
- package/dist/research/types.d.ts.map +1 -0
- package/dist/research/types.js +33 -0
- package/dist/research/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AcademicSearchAgent - 学術論文検索エージェント
|
|
3
|
+
*
|
|
4
|
+
* arXiv、CrossRef、Semantic Scholarなどの学術APIを使用。
|
|
5
|
+
* 現在はarXiv APIを実装。
|
|
6
|
+
*
|
|
7
|
+
* @requirement REQ-COLLECT-008
|
|
8
|
+
* @design DES-COLLECT-008
|
|
9
|
+
* @task TASK-002
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* 学術論文検索エージェント
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const agent = new AcademicSearchAgent();
|
|
17
|
+
* const result = await agent.search({
|
|
18
|
+
* query: 'machine learning',
|
|
19
|
+
* maxResults: 10,
|
|
20
|
+
* timeout: 30000,
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export class AcademicSearchAgent {
|
|
25
|
+
type = 'academic';
|
|
26
|
+
name = 'Academic Search (arXiv)';
|
|
27
|
+
arxivApiUrl = 'http://export.arxiv.org/api/query';
|
|
28
|
+
async search(query) {
|
|
29
|
+
const startTime = Date.now();
|
|
30
|
+
try {
|
|
31
|
+
const findings = await this.searchArxiv(query);
|
|
32
|
+
return {
|
|
33
|
+
findings,
|
|
34
|
+
status: findings.length > 0 ? 'success' : 'partial',
|
|
35
|
+
processingTime: Date.now() - startTime,
|
|
36
|
+
metadata: {
|
|
37
|
+
source: 'arxiv',
|
|
38
|
+
totalFound: findings.length,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return {
|
|
44
|
+
findings: [],
|
|
45
|
+
status: 'failed',
|
|
46
|
+
error: error.message,
|
|
47
|
+
processingTime: Date.now() - startTime,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async isAvailable() {
|
|
52
|
+
// arXiv APIは無料で利用可能
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* arXiv APIで検索
|
|
57
|
+
*/
|
|
58
|
+
async searchArxiv(query) {
|
|
59
|
+
const searchQuery = encodeURIComponent(query.query);
|
|
60
|
+
const url = `${this.arxivApiUrl}?search_query=all:${searchQuery}&start=0&max_results=${query.maxResults}`;
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
const timeoutId = setTimeout(() => controller.abort(), query.timeout);
|
|
63
|
+
try {
|
|
64
|
+
const response = await fetch(url, {
|
|
65
|
+
signal: controller.signal,
|
|
66
|
+
headers: {
|
|
67
|
+
Accept: 'application/atom+xml',
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
clearTimeout(timeoutId);
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
throw new Error(`arXiv API error: ${response.status}`);
|
|
73
|
+
}
|
|
74
|
+
const xmlText = await response.text();
|
|
75
|
+
return this.parseArxivResponse(xmlText, query.query);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
clearTimeout(timeoutId);
|
|
79
|
+
if (error.name === 'AbortError') {
|
|
80
|
+
throw new Error('arXiv API request timed out');
|
|
81
|
+
}
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* arXiv XMLレスポンスをパース
|
|
87
|
+
*/
|
|
88
|
+
parseArxivResponse(xml, originalQuery) {
|
|
89
|
+
const findings = [];
|
|
90
|
+
// シンプルなXMLパース(正規表現ベース)
|
|
91
|
+
const entryRegex = /<entry>([\s\S]*?)<\/entry>/g;
|
|
92
|
+
let entryMatch;
|
|
93
|
+
let index = 0;
|
|
94
|
+
while ((entryMatch = entryRegex.exec(xml)) !== null) {
|
|
95
|
+
const entry = entryMatch[1] ?? '';
|
|
96
|
+
const rawId = this.extractXmlTag(entry, 'id');
|
|
97
|
+
const rawTitle = this.extractXmlTag(entry, 'title');
|
|
98
|
+
const rawSummary = this.extractXmlTag(entry, 'summary');
|
|
99
|
+
const published = this.extractXmlTag(entry, 'published');
|
|
100
|
+
const authors = this.extractAuthors(entry);
|
|
101
|
+
// 必須フィールドがない場合はスキップ
|
|
102
|
+
if (!rawId || !rawTitle || !rawSummary) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const arxivIdValue = rawId;
|
|
106
|
+
const titleValue = rawTitle.replace(/\s+/g, ' ').trim();
|
|
107
|
+
const summaryValue = rawSummary.replace(/\s+/g, ' ').trim();
|
|
108
|
+
// arXiv IDからURLを生成
|
|
109
|
+
const arxivId = arxivIdValue.replace('http://arxiv.org/abs/', '');
|
|
110
|
+
const url = `https://arxiv.org/abs/${arxivId}`;
|
|
111
|
+
const pdfUrl = `https://arxiv.org/pdf/${arxivId}.pdf`;
|
|
112
|
+
findings.push({
|
|
113
|
+
id: `academic-${Date.now()}-${index}`,
|
|
114
|
+
title: titleValue,
|
|
115
|
+
summary: summaryValue.length > 500 ? summaryValue.substring(0, 500) + '...' : summaryValue,
|
|
116
|
+
url,
|
|
117
|
+
sourceType: 'academic',
|
|
118
|
+
sourceName: 'arXiv',
|
|
119
|
+
relevanceScore: this.calculateRelevance(titleValue, summaryValue, originalQuery),
|
|
120
|
+
credibilityScore: 0.85, // 学術論文は一般的に高信頼度
|
|
121
|
+
publishedAt: published ? new Date(published) : undefined,
|
|
122
|
+
author: authors,
|
|
123
|
+
metadata: {
|
|
124
|
+
arxivId,
|
|
125
|
+
pdfUrl,
|
|
126
|
+
category: this.extractCategory(entry),
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
index++;
|
|
130
|
+
}
|
|
131
|
+
return findings;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* XMLタグの内容を抽出
|
|
135
|
+
*/
|
|
136
|
+
extractXmlTag(xml, tag) {
|
|
137
|
+
const regex = new RegExp(`<${tag}[^>]*>([\\s\\S]*?)<\\/${tag}>`, 'i');
|
|
138
|
+
const match = regex.exec(xml);
|
|
139
|
+
return match ? match[1] : undefined;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 著者を抽出
|
|
143
|
+
*/
|
|
144
|
+
extractAuthors(entry) {
|
|
145
|
+
const authorRegex = /<author>[\s\S]*?<name>([^<]+)<\/name>[\s\S]*?<\/author>/g;
|
|
146
|
+
const authors = [];
|
|
147
|
+
let authorMatch;
|
|
148
|
+
while ((authorMatch = authorRegex.exec(entry)) !== null) {
|
|
149
|
+
if (authorMatch[1]) {
|
|
150
|
+
authors.push(authorMatch[1].trim());
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return authors.slice(0, 3).join(', ') + (authors.length > 3 ? ' et al.' : '');
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* カテゴリを抽出
|
|
157
|
+
*/
|
|
158
|
+
extractCategory(entry) {
|
|
159
|
+
const categoryRegex = /<arxiv:primary_category[^>]*term="([^"]+)"/;
|
|
160
|
+
const match = categoryRegex.exec(entry);
|
|
161
|
+
return match ? match[1] : undefined;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* 関連性スコアを計算
|
|
165
|
+
*/
|
|
166
|
+
calculateRelevance(title, summary, query) {
|
|
167
|
+
const queryLower = query.toLowerCase();
|
|
168
|
+
const titleLower = title.toLowerCase();
|
|
169
|
+
const summaryLower = summary.toLowerCase();
|
|
170
|
+
const titleMatch = titleLower.includes(queryLower) ? 0.35 : 0;
|
|
171
|
+
const summaryMatch = summaryLower.includes(queryLower) ? 0.25 : 0;
|
|
172
|
+
// 単語レベルのマッチング
|
|
173
|
+
const queryWords = queryLower.split(/\s+/).filter((w) => w.length > 3);
|
|
174
|
+
const wordMatchRate = queryWords.filter((w) => titleLower.includes(w) || summaryLower.includes(w)).length /
|
|
175
|
+
Math.max(queryWords.length, 1);
|
|
176
|
+
const baseScore = 0.3;
|
|
177
|
+
return Math.min(titleMatch + summaryMatch + wordMatchRate * 0.3 + baseScore, 1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=AcademicSearchAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AcademicSearchAgent.js","sourceRoot":"","sources":["../../../src/research/agents/AcademicSearchAgent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EncyclopediaAgent - 百科事典検索エージェント
|
|
3
|
+
*
|
|
4
|
+
* Wikipedia APIを使用して百科事典的な情報を検索する。
|
|
5
|
+
*
|
|
6
|
+
* @requirement REQ-COLLECT-008
|
|
7
|
+
* @design DES-COLLECT-008
|
|
8
|
+
* @task TASK-002
|
|
9
|
+
*/
|
|
10
|
+
import type { ISearchAgent, AgentSearchQuery, AgentSearchResult } from './types.js';
|
|
11
|
+
import type { SourceType } from '../types.js';
|
|
12
|
+
/**
|
|
13
|
+
* 百科事典検索エージェント(Wikipedia)
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const agent = new EncyclopediaAgent();
|
|
18
|
+
* const result = await agent.search({
|
|
19
|
+
* query: 'Artificial Intelligence',
|
|
20
|
+
* maxResults: 10,
|
|
21
|
+
* timeout: 30000,
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare class EncyclopediaAgent implements ISearchAgent {
|
|
26
|
+
readonly type: SourceType;
|
|
27
|
+
readonly name = "Encyclopedia (Wikipedia)";
|
|
28
|
+
private readonly wikipediaApiUrl;
|
|
29
|
+
private readonly defaultLanguage;
|
|
30
|
+
search(query: AgentSearchQuery): Promise<AgentSearchResult>;
|
|
31
|
+
isAvailable(): Promise<boolean>;
|
|
32
|
+
/**
|
|
33
|
+
* クエリの言語を検出
|
|
34
|
+
*/
|
|
35
|
+
private detectLanguage;
|
|
36
|
+
/**
|
|
37
|
+
* Wikipedia APIで検索
|
|
38
|
+
*/
|
|
39
|
+
private searchWikipedia;
|
|
40
|
+
/**
|
|
41
|
+
* Wikipediaレスポンスをパース
|
|
42
|
+
*/
|
|
43
|
+
private parseWikipediaResponse;
|
|
44
|
+
/**
|
|
45
|
+
* 関連性スコアを計算
|
|
46
|
+
*/
|
|
47
|
+
private calculateRelevance;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=EncyclopediaAgent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncyclopediaAgent.d.ts","sourceRoot":"","sources":["../../../src/research/agents/EncyclopediaAgent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,aAAa,CAAC;AAqBvD;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IACpD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAkB;IAC3C,QAAQ,CAAC,IAAI,8BAA8B;IAE3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAwC;IACxE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IAElC,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA4B3D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAIrC;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;YACW,eAAe;IA2C7B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiC9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAc3B"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EncyclopediaAgent - 百科事典検索エージェント
|
|
3
|
+
*
|
|
4
|
+
* Wikipedia APIを使用して百科事典的な情報を検索する。
|
|
5
|
+
*
|
|
6
|
+
* @requirement REQ-COLLECT-008
|
|
7
|
+
* @design DES-COLLECT-008
|
|
8
|
+
* @task TASK-002
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* 百科事典検索エージェント(Wikipedia)
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const agent = new EncyclopediaAgent();
|
|
16
|
+
* const result = await agent.search({
|
|
17
|
+
* query: 'Artificial Intelligence',
|
|
18
|
+
* maxResults: 10,
|
|
19
|
+
* timeout: 30000,
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export class EncyclopediaAgent {
|
|
24
|
+
type = 'encyclopedia';
|
|
25
|
+
name = 'Encyclopedia (Wikipedia)';
|
|
26
|
+
wikipediaApiUrl = 'https://en.wikipedia.org/w/api.php';
|
|
27
|
+
defaultLanguage = 'en';
|
|
28
|
+
async search(query) {
|
|
29
|
+
const startTime = Date.now();
|
|
30
|
+
try {
|
|
31
|
+
// 言語を決定
|
|
32
|
+
const lang = this.detectLanguage(query.query, query.languages);
|
|
33
|
+
const findings = await this.searchWikipedia(query, lang);
|
|
34
|
+
return {
|
|
35
|
+
findings,
|
|
36
|
+
status: findings.length > 0 ? 'success' : 'partial',
|
|
37
|
+
processingTime: Date.now() - startTime,
|
|
38
|
+
metadata: {
|
|
39
|
+
source: 'wikipedia',
|
|
40
|
+
language: lang,
|
|
41
|
+
totalFound: findings.length,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
return {
|
|
47
|
+
findings: [],
|
|
48
|
+
status: 'failed',
|
|
49
|
+
error: error.message,
|
|
50
|
+
processingTime: Date.now() - startTime,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async isAvailable() {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* クエリの言語を検出
|
|
59
|
+
*/
|
|
60
|
+
detectLanguage(query, languages) {
|
|
61
|
+
// 明示的に指定されている場合
|
|
62
|
+
if (languages && languages.length > 0 && languages[0] !== undefined) {
|
|
63
|
+
return languages[0];
|
|
64
|
+
}
|
|
65
|
+
// 日本語文字が含まれている場合
|
|
66
|
+
if (/[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]/.test(query)) {
|
|
67
|
+
return 'ja';
|
|
68
|
+
}
|
|
69
|
+
return this.defaultLanguage;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Wikipedia APIで検索
|
|
73
|
+
*/
|
|
74
|
+
async searchWikipedia(query, lang) {
|
|
75
|
+
const apiUrl = lang === 'en'
|
|
76
|
+
? this.wikipediaApiUrl
|
|
77
|
+
: `https://${lang}.wikipedia.org/w/api.php`;
|
|
78
|
+
const params = new URLSearchParams({
|
|
79
|
+
action: 'query',
|
|
80
|
+
list: 'search',
|
|
81
|
+
srsearch: query.query,
|
|
82
|
+
srlimit: String(query.maxResults),
|
|
83
|
+
format: 'json',
|
|
84
|
+
origin: '*',
|
|
85
|
+
});
|
|
86
|
+
const controller = new AbortController();
|
|
87
|
+
const timeoutId = setTimeout(() => controller.abort(), query.timeout);
|
|
88
|
+
try {
|
|
89
|
+
const response = await fetch(`${apiUrl}?${params}`, {
|
|
90
|
+
signal: controller.signal,
|
|
91
|
+
headers: {
|
|
92
|
+
Accept: 'application/json',
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
clearTimeout(timeoutId);
|
|
96
|
+
if (!response.ok) {
|
|
97
|
+
throw new Error(`Wikipedia API error: ${response.status}`);
|
|
98
|
+
}
|
|
99
|
+
const data = (await response.json());
|
|
100
|
+
return this.parseWikipediaResponse(data, query.query, lang);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
clearTimeout(timeoutId);
|
|
104
|
+
if (error.name === 'AbortError') {
|
|
105
|
+
throw new Error('Wikipedia API request timed out');
|
|
106
|
+
}
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Wikipediaレスポンスをパース
|
|
112
|
+
*/
|
|
113
|
+
parseWikipediaResponse(data, originalQuery, language) {
|
|
114
|
+
const results = data.query?.search || [];
|
|
115
|
+
return results.map((result, index) => {
|
|
116
|
+
// HTMLタグを除去
|
|
117
|
+
const cleanSnippet = result.snippet.replace(/<[^>]+>/g, '');
|
|
118
|
+
const url = `https://${language}.wikipedia.org/wiki/${encodeURIComponent(result.title.replace(/ /g, '_'))}`;
|
|
119
|
+
return {
|
|
120
|
+
id: `encyclopedia-${Date.now()}-${index}`,
|
|
121
|
+
title: result.title,
|
|
122
|
+
summary: cleanSnippet,
|
|
123
|
+
url,
|
|
124
|
+
sourceType: 'encyclopedia',
|
|
125
|
+
sourceName: `Wikipedia (${language})`,
|
|
126
|
+
relevanceScore: this.calculateRelevance(result.title, cleanSnippet, originalQuery),
|
|
127
|
+
credibilityScore: 0.8, // Wikipediaは編集可能だが一般的に信頼度高め
|
|
128
|
+
publishedAt: new Date(result.timestamp),
|
|
129
|
+
metadata: {
|
|
130
|
+
pageId: result.pageid,
|
|
131
|
+
wordCount: result.wordcount,
|
|
132
|
+
size: result.size,
|
|
133
|
+
language,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 関連性スコアを計算
|
|
140
|
+
*/
|
|
141
|
+
calculateRelevance(title, snippet, query) {
|
|
142
|
+
const queryLower = query.toLowerCase();
|
|
143
|
+
const titleLower = title.toLowerCase();
|
|
144
|
+
const snippetLower = snippet.toLowerCase();
|
|
145
|
+
// タイトル完全一致
|
|
146
|
+
const exactMatch = titleLower === queryLower ? 0.4 : 0;
|
|
147
|
+
const titleContains = titleLower.includes(queryLower) ? 0.25 : 0;
|
|
148
|
+
const snippetContains = snippetLower.includes(queryLower) ? 0.15 : 0;
|
|
149
|
+
const baseScore = 0.2;
|
|
150
|
+
return Math.min(exactMatch + titleContains + snippetContains + baseScore, 1);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=EncyclopediaAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncyclopediaAgent.js","sourceRoot":"","sources":["../../../src/research/agents/EncyclopediaAgent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NewsSearchAgent - ニュース検索エージェント
|
|
3
|
+
*
|
|
4
|
+
* Web検索を使用してニュースを検索する。
|
|
5
|
+
* NewsAPIなどの専用APIがある場合は、それを使用することを推奨。
|
|
6
|
+
*
|
|
7
|
+
* @requirement REQ-COLLECT-008
|
|
8
|
+
* @design DES-COLLECT-008
|
|
9
|
+
* @task TASK-002
|
|
10
|
+
*/
|
|
11
|
+
import type { ISearchAgent, AgentSearchQuery, AgentSearchResult } from './types.js';
|
|
12
|
+
import type { SourceType } from '../types.js';
|
|
13
|
+
/**
|
|
14
|
+
* ニュース検索エージェント
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const agent = new NewsSearchAgent();
|
|
19
|
+
* const result = await agent.search({
|
|
20
|
+
* query: 'AI regulation',
|
|
21
|
+
* maxResults: 10,
|
|
22
|
+
* timeout: 30000,
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare class NewsSearchAgent implements ISearchAgent {
|
|
27
|
+
readonly type: SourceType;
|
|
28
|
+
readonly name = "News Search";
|
|
29
|
+
private searchClient;
|
|
30
|
+
constructor();
|
|
31
|
+
search(query: AgentSearchQuery): Promise<AgentSearchResult>;
|
|
32
|
+
isAvailable(): Promise<boolean>;
|
|
33
|
+
private extractDomain;
|
|
34
|
+
private isNewsDomain;
|
|
35
|
+
private calculateRelevance;
|
|
36
|
+
private assessNewsCredibility;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=NewsSearchAgent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NewsSearchAgent.d.ts","sourceRoot":"","sources":["../../../src/research/agents/NewsSearchAgent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,aAAa,CAAC;AAwBvD;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,YAAW,YAAY;IAClD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAU;IACnC,QAAQ,CAAC,IAAI,iBAAiB;IAE9B,OAAO,CAAC,YAAY,CAAkB;;IAMhC,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA2D3D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAIrC,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,qBAAqB;CAkB9B"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NewsSearchAgent - ニュース検索エージェント
|
|
3
|
+
*
|
|
4
|
+
* Web検索を使用してニュースを検索する。
|
|
5
|
+
* NewsAPIなどの専用APIがある場合は、それを使用することを推奨。
|
|
6
|
+
*
|
|
7
|
+
* @requirement REQ-COLLECT-008
|
|
8
|
+
* @design DES-COLLECT-008
|
|
9
|
+
* @task TASK-002
|
|
10
|
+
*/
|
|
11
|
+
import { WebSearchClient } from '../../web-search/index.js';
|
|
12
|
+
/** ニュースドメインリスト */
|
|
13
|
+
const NEWS_DOMAINS = [
|
|
14
|
+
'reuters.com',
|
|
15
|
+
'bbc.com',
|
|
16
|
+
'bbc.co.uk',
|
|
17
|
+
'nytimes.com',
|
|
18
|
+
'theguardian.com',
|
|
19
|
+
'wsj.com',
|
|
20
|
+
'cnn.com',
|
|
21
|
+
'apnews.com',
|
|
22
|
+
'bloomberg.com',
|
|
23
|
+
'techcrunch.com',
|
|
24
|
+
'wired.com',
|
|
25
|
+
'theverge.com',
|
|
26
|
+
'arstechnica.com',
|
|
27
|
+
'nhk.or.jp',
|
|
28
|
+
'asahi.com',
|
|
29
|
+
'nikkei.com',
|
|
30
|
+
'yomiuri.co.jp',
|
|
31
|
+
'mainichi.jp',
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* ニュース検索エージェント
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const agent = new NewsSearchAgent();
|
|
39
|
+
* const result = await agent.search({
|
|
40
|
+
* query: 'AI regulation',
|
|
41
|
+
* maxResults: 10,
|
|
42
|
+
* timeout: 30000,
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export class NewsSearchAgent {
|
|
47
|
+
type = 'news';
|
|
48
|
+
name = 'News Search';
|
|
49
|
+
searchClient;
|
|
50
|
+
constructor() {
|
|
51
|
+
this.searchClient = new WebSearchClient();
|
|
52
|
+
}
|
|
53
|
+
async search(query) {
|
|
54
|
+
const startTime = Date.now();
|
|
55
|
+
try {
|
|
56
|
+
// "news" キーワードを追加してニュース寄りの結果を取得
|
|
57
|
+
const newsQuery = `${query.query} news`;
|
|
58
|
+
const results = await this.searchClient.search({
|
|
59
|
+
query: newsQuery,
|
|
60
|
+
maxResults: query.maxResults * 2, // フィルタリングのため多めに取得
|
|
61
|
+
});
|
|
62
|
+
// ニュースドメインのフィルタリングと優先
|
|
63
|
+
const findings = results
|
|
64
|
+
.map((result, index) => {
|
|
65
|
+
const domain = this.extractDomain(result.url);
|
|
66
|
+
const isNewsSite = this.isNewsDomain(domain);
|
|
67
|
+
return {
|
|
68
|
+
id: `news-${Date.now()}-${index}`,
|
|
69
|
+
title: result.title,
|
|
70
|
+
summary: result.snippet || '',
|
|
71
|
+
url: result.url,
|
|
72
|
+
sourceType: 'news',
|
|
73
|
+
sourceName: domain,
|
|
74
|
+
relevanceScore: this.calculateRelevance(result.title, result.snippet || '', query.query, isNewsSite),
|
|
75
|
+
credibilityScore: this.assessNewsCredibility(domain),
|
|
76
|
+
metadata: {
|
|
77
|
+
isVerifiedNews: isNewsSite,
|
|
78
|
+
originalPosition: index,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
})
|
|
82
|
+
.sort((a, b) => b.relevanceScore - a.relevanceScore)
|
|
83
|
+
.slice(0, query.maxResults);
|
|
84
|
+
return {
|
|
85
|
+
findings,
|
|
86
|
+
status: 'success',
|
|
87
|
+
processingTime: Date.now() - startTime,
|
|
88
|
+
metadata: {
|
|
89
|
+
newsSourcesFound: findings.filter((f) => f.metadata?.isVerifiedNews).length,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return {
|
|
95
|
+
findings: [],
|
|
96
|
+
status: 'failed',
|
|
97
|
+
error: error.message,
|
|
98
|
+
processingTime: Date.now() - startTime,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async isAvailable() {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
extractDomain(url) {
|
|
106
|
+
try {
|
|
107
|
+
return new URL(url).hostname;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return 'unknown';
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
isNewsDomain(domain) {
|
|
114
|
+
return NEWS_DOMAINS.some((nd) => domain.includes(nd));
|
|
115
|
+
}
|
|
116
|
+
calculateRelevance(title, snippet, query, isNewsSite) {
|
|
117
|
+
const queryLower = query.toLowerCase();
|
|
118
|
+
const titleLower = title.toLowerCase();
|
|
119
|
+
const snippetLower = snippet.toLowerCase();
|
|
120
|
+
const titleMatch = titleLower.includes(queryLower) ? 0.3 : 0;
|
|
121
|
+
const snippetMatch = snippetLower.includes(queryLower) ? 0.2 : 0;
|
|
122
|
+
const newsBonus = isNewsSite ? 0.2 : 0;
|
|
123
|
+
const baseScore = 0.3;
|
|
124
|
+
return Math.min(titleMatch + snippetMatch + newsBonus + baseScore, 1);
|
|
125
|
+
}
|
|
126
|
+
assessNewsCredibility(domain) {
|
|
127
|
+
// 信頼性の高いニュースソース
|
|
128
|
+
const tier1 = ['reuters.com', 'apnews.com', 'bbc.com', 'bbc.co.uk', 'nhk.or.jp'];
|
|
129
|
+
const tier2 = [
|
|
130
|
+
'nytimes.com',
|
|
131
|
+
'theguardian.com',
|
|
132
|
+
'wsj.com',
|
|
133
|
+
'bloomberg.com',
|
|
134
|
+
'nikkei.com',
|
|
135
|
+
];
|
|
136
|
+
const tier3 = NEWS_DOMAINS;
|
|
137
|
+
if (tier1.some((d) => domain.includes(d)))
|
|
138
|
+
return 0.95;
|
|
139
|
+
if (tier2.some((d) => domain.includes(d)))
|
|
140
|
+
return 0.85;
|
|
141
|
+
if (tier3.some((d) => domain.includes(d)))
|
|
142
|
+
return 0.75;
|
|
143
|
+
return 0.5;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=NewsSearchAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NewsSearchAgent.js","sourceRoot":"","sources":["../../../src/research/agents/NewsSearchAgent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSearchAgent - Web検索エージェント
|
|
3
|
+
*
|
|
4
|
+
* 既存のWebSearchClientを使用して一般Web検索を実行する。
|
|
5
|
+
*
|
|
6
|
+
* @requirement REQ-COLLECT-008
|
|
7
|
+
* @design DES-COLLECT-008
|
|
8
|
+
* @task TASK-002
|
|
9
|
+
*/
|
|
10
|
+
import type { ISearchAgent, AgentSearchQuery, AgentSearchResult } from './types.js';
|
|
11
|
+
import type { SourceType } from '../types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Web検索エージェント
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const agent = new WebSearchAgent();
|
|
18
|
+
* const result = await agent.search({
|
|
19
|
+
* query: 'TypeScript best practices',
|
|
20
|
+
* maxResults: 10,
|
|
21
|
+
* timeout: 30000,
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare class WebSearchAgent implements ISearchAgent {
|
|
26
|
+
readonly type: SourceType;
|
|
27
|
+
readonly name = "Web Search";
|
|
28
|
+
private searchClient;
|
|
29
|
+
constructor();
|
|
30
|
+
search(query: AgentSearchQuery): Promise<AgentSearchResult>;
|
|
31
|
+
isAvailable(): Promise<boolean>;
|
|
32
|
+
/**
|
|
33
|
+
* URLからドメイン名を抽出
|
|
34
|
+
*/
|
|
35
|
+
private extractDomain;
|
|
36
|
+
/**
|
|
37
|
+
* 関連性スコアを計算
|
|
38
|
+
*/
|
|
39
|
+
private calculateRelevance;
|
|
40
|
+
/**
|
|
41
|
+
* ドメインベースの信頼度スコアリング
|
|
42
|
+
*/
|
|
43
|
+
private assessCredibility;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=WebSearchAgent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSearchAgent.d.ts","sourceRoot":"","sources":["../../../src/research/agents/WebSearchAgent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvD;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAe,YAAW,YAAY;IACjD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAS;IAClC,QAAQ,CAAC,IAAI,gBAAgB;IAE7B,OAAO,CAAC,YAAY,CAAkB;;IAMhC,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAuC3D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAKrC;;OAEG;IACH,OAAO,CAAC,aAAa;IAQrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAiC1B"}
|