gencode-ai 0.1.0 → 0.1.1
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 +8 -90
- package/dist/agent/agent.d.ts +1 -1
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +8 -2
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/types.d.ts +9 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/cli/components/AllModelsSelector.d.ts +11 -0
- package/dist/cli/components/AllModelsSelector.d.ts.map +1 -0
- package/dist/cli/components/AllModelsSelector.js +153 -0
- package/dist/cli/components/AllModelsSelector.js.map +1 -0
- package/dist/cli/components/App.d.ts.map +1 -1
- package/dist/cli/components/App.js +59 -25
- package/dist/cli/components/App.js.map +1 -1
- package/dist/cli/components/CommandSuggestions.d.ts.map +1 -1
- package/dist/cli/components/CommandSuggestions.js +1 -0
- package/dist/cli/components/CommandSuggestions.js.map +1 -1
- package/dist/cli/components/Messages.d.ts +15 -1
- package/dist/cli/components/Messages.d.ts.map +1 -1
- package/dist/cli/components/Messages.js +41 -15
- package/dist/cli/components/Messages.js.map +1 -1
- package/dist/cli/components/ModelSelector.d.ts +7 -7
- package/dist/cli/components/ModelSelector.d.ts.map +1 -1
- package/dist/cli/components/ModelSelector.js +116 -33
- package/dist/cli/components/ModelSelector.js.map +1 -1
- package/dist/cli/components/ProviderManager.d.ts +8 -0
- package/dist/cli/components/ProviderManager.d.ts.map +1 -0
- package/dist/cli/components/ProviderManager.js +280 -0
- package/dist/cli/components/ProviderManager.js.map +1 -0
- package/dist/cli/components/markdown.d.ts +9 -0
- package/dist/cli/components/markdown.d.ts.map +1 -0
- package/dist/cli/components/markdown.js +129 -0
- package/dist/cli/components/markdown.js.map +1 -0
- package/dist/cli/components/theme.d.ts +5 -0
- package/dist/cli/components/theme.d.ts.map +1 -1
- package/dist/cli/components/theme.js +7 -0
- package/dist/cli/components/theme.js.map +1 -1
- package/dist/cli/index.js +19 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +3 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +2 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/providers-config.d.ts +28 -0
- package/dist/config/providers-config.d.ts.map +1 -0
- package/dist/config/providers-config.js +79 -0
- package/dist/config/providers-config.js.map +1 -0
- package/dist/config/types.d.ts +31 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +1 -0
- package/dist/config/types.js.map +1 -1
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +14 -3
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/index.d.ts +5 -3
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +13 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/registry.d.ts +66 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +158 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/search/brave.d.ts +14 -0
- package/dist/providers/search/brave.d.ts.map +1 -0
- package/dist/providers/search/brave.js +87 -0
- package/dist/providers/search/brave.js.map +1 -0
- package/dist/providers/search/exa.d.ts +12 -0
- package/dist/providers/search/exa.d.ts.map +1 -0
- package/dist/providers/search/exa.js +158 -0
- package/dist/providers/search/exa.js.map +1 -0
- package/dist/providers/search/index.d.ts +31 -0
- package/dist/providers/search/index.d.ts.map +1 -0
- package/dist/providers/search/index.js +75 -0
- package/dist/providers/search/index.js.map +1 -0
- package/dist/providers/search/serper.d.ts +14 -0
- package/dist/providers/search/serper.d.ts.map +1 -0
- package/dist/providers/search/serper.js +87 -0
- package/dist/providers/search/serper.js.map +1 -0
- package/dist/providers/search/types.d.ts +21 -0
- package/dist/providers/search/types.d.ts.map +1 -0
- package/dist/providers/search/types.js +5 -0
- package/dist/providers/search/types.js.map +1 -0
- package/dist/providers/store.d.ts +104 -0
- package/dist/providers/store.d.ts.map +1 -0
- package/dist/providers/store.js +171 -0
- package/dist/providers/store.js.map +1 -0
- package/dist/providers/types.d.ts +7 -1
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/vertex-ai.d.ts +33 -0
- package/dist/providers/vertex-ai.d.ts.map +1 -0
- package/dist/providers/vertex-ai.js +407 -0
- package/dist/providers/vertex-ai.js.map +1 -0
- package/dist/tools/builtin/webfetch.d.ts +20 -0
- package/dist/tools/builtin/webfetch.d.ts.map +1 -0
- package/dist/tools/builtin/webfetch.js +231 -0
- package/dist/tools/builtin/webfetch.js.map +1 -0
- package/dist/tools/builtin/websearch.d.ts +17 -0
- package/dist/tools/builtin/websearch.d.ts.map +1 -0
- package/dist/tools/builtin/websearch.js +101 -0
- package/dist/tools/builtin/websearch.js.map +1 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +24 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/types.d.ts +19 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js +8 -0
- package/dist/tools/types.js.map +1 -1
- package/dist/tools/utils/ssrf.d.ts +18 -0
- package/dist/tools/utils/ssrf.d.ts.map +1 -0
- package/dist/tools/utils/ssrf.js +70 -0
- package/dist/tools/utils/ssrf.js.map +1 -0
- package/docs/README.md +5 -4
- package/docs/proposals/0001-web-fetch-tool.md +32 -2
- package/docs/proposals/0002-web-search-tool.md +59 -2
- package/docs/proposals/0041-configuration-system.md +556 -0
- package/docs/proposals/README.md +3 -2
- package/docs/providers.md +220 -0
- package/package.json +7 -2
- package/src/agent/agent.ts +9 -2
- package/src/agent/types.ts +9 -1
- package/src/cli/components/App.tsx +72 -23
- package/src/cli/components/CommandSuggestions.tsx +1 -0
- package/src/cli/components/Messages.tsx +117 -29
- package/src/cli/components/ModelSelector.tsx +169 -52
- package/src/cli/components/ProviderManager.tsx +534 -0
- package/src/cli/components/markdown.ts +157 -0
- package/src/cli/components/theme.ts +7 -0
- package/src/cli/index.tsx +22 -7
- package/src/config/index.ts +3 -2
- package/src/config/providers-config.ts +85 -0
- package/src/config/types.ts +35 -1
- package/src/providers/gemini.ts +20 -4
- package/src/providers/index.ts +18 -3
- package/src/providers/registry.ts +198 -0
- package/src/providers/search/brave.ts +132 -0
- package/src/providers/search/exa.ts +217 -0
- package/src/providers/search/index.ts +79 -0
- package/src/providers/search/serper.ts +133 -0
- package/src/providers/search/types.ts +24 -0
- package/src/providers/store.ts +216 -0
- package/src/providers/types.ts +9 -1
- package/src/providers/vertex-ai.ts +594 -0
- package/src/tools/builtin/webfetch.ts +264 -0
- package/src/tools/builtin/websearch.ts +117 -0
- package/src/tools/index.ts +24 -2
- package/src/tools/types.ts +20 -0
- package/src/tools/utils/ssrf.ts +79 -0
- package/CLAUDE.md +0 -70
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brave Search Provider
|
|
3
|
+
*
|
|
4
|
+
* Uses Brave Search API (same as Claude Code).
|
|
5
|
+
* Requires BRAVE_API_KEY environment variable.
|
|
6
|
+
*/
|
|
7
|
+
const API_CONFIG = {
|
|
8
|
+
BASE_URL: 'https://api.search.brave.com',
|
|
9
|
+
ENDPOINT: '/res/v1/web/search',
|
|
10
|
+
DEFAULT_NUM_RESULTS: 10,
|
|
11
|
+
DEFAULT_TIMEOUT: 10000,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Filter results by allowed/blocked domains
|
|
15
|
+
*/
|
|
16
|
+
function filterByDomain(results, options) {
|
|
17
|
+
if (!options?.allowedDomains?.length && !options?.blockedDomains?.length) {
|
|
18
|
+
return results;
|
|
19
|
+
}
|
|
20
|
+
return results.filter((result) => {
|
|
21
|
+
try {
|
|
22
|
+
const domain = new URL(result.url).hostname;
|
|
23
|
+
if (options.allowedDomains?.length) {
|
|
24
|
+
return options.allowedDomains.some((allowed) => domain === allowed || domain.endsWith('.' + allowed));
|
|
25
|
+
}
|
|
26
|
+
if (options.blockedDomains?.length) {
|
|
27
|
+
return !options.blockedDomains.some((blocked) => domain === blocked || domain.endsWith('.' + blocked));
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export class BraveProvider {
|
|
37
|
+
name = 'brave';
|
|
38
|
+
apiKey;
|
|
39
|
+
constructor(apiKey) {
|
|
40
|
+
this.apiKey = apiKey ?? process.env.BRAVE_API_KEY ?? '';
|
|
41
|
+
if (!this.apiKey) {
|
|
42
|
+
throw new Error('BRAVE_API_KEY environment variable is required for Brave provider');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async search(query, options) {
|
|
46
|
+
const params = new URLSearchParams({
|
|
47
|
+
q: query,
|
|
48
|
+
count: String(options?.numResults ?? API_CONFIG.DEFAULT_NUM_RESULTS),
|
|
49
|
+
});
|
|
50
|
+
const controller = new AbortController();
|
|
51
|
+
const timeoutId = setTimeout(() => controller.abort(), options?.timeout ?? API_CONFIG.DEFAULT_TIMEOUT);
|
|
52
|
+
try {
|
|
53
|
+
const signals = options?.abortSignal
|
|
54
|
+
? [controller.signal, options.abortSignal]
|
|
55
|
+
: [controller.signal];
|
|
56
|
+
const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINT}?${params.toString()}`, {
|
|
57
|
+
method: 'GET',
|
|
58
|
+
headers: {
|
|
59
|
+
Accept: 'application/json',
|
|
60
|
+
'Accept-Encoding': 'gzip',
|
|
61
|
+
'X-Subscription-Token': this.apiKey,
|
|
62
|
+
},
|
|
63
|
+
signal: AbortSignal.any(signals),
|
|
64
|
+
});
|
|
65
|
+
clearTimeout(timeoutId);
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const errorText = await response.text();
|
|
68
|
+
throw new Error(`Brave search error (${response.status}): ${errorText}`);
|
|
69
|
+
}
|
|
70
|
+
const data = (await response.json());
|
|
71
|
+
const results = (data.web?.results || []).map((item) => ({
|
|
72
|
+
title: item.title,
|
|
73
|
+
url: item.url,
|
|
74
|
+
snippet: item.description,
|
|
75
|
+
}));
|
|
76
|
+
return filterByDomain(results, options);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
clearTimeout(timeoutId);
|
|
80
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
81
|
+
throw new Error('Search request timed out');
|
|
82
|
+
}
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=brave.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brave.js","sourceRoot":"","sources":["../../../src/providers/search/brave.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exa AI Search Provider
|
|
3
|
+
*
|
|
4
|
+
* Uses Exa's public MCP endpoint (no API key required).
|
|
5
|
+
* Based on OpenCode's implementation pattern.
|
|
6
|
+
*/
|
|
7
|
+
import type { SearchProvider, SearchResult, SearchOptions } from './types.js';
|
|
8
|
+
export declare class ExaProvider implements SearchProvider {
|
|
9
|
+
readonly name: "exa";
|
|
10
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=exa.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exa.d.ts","sourceRoot":"","sources":["../../../src/providers/search/exa.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAuI9E,qBAAa,WAAY,YAAW,cAAc;IAChD,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAEzB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAuE9E"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exa AI Search Provider
|
|
3
|
+
*
|
|
4
|
+
* Uses Exa's public MCP endpoint (no API key required).
|
|
5
|
+
* Based on OpenCode's implementation pattern.
|
|
6
|
+
*/
|
|
7
|
+
const API_CONFIG = {
|
|
8
|
+
BASE_URL: 'https://mcp.exa.ai',
|
|
9
|
+
ENDPOINT: '/mcp',
|
|
10
|
+
DEFAULT_NUM_RESULTS: 8,
|
|
11
|
+
DEFAULT_TIMEOUT: 25000,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Parse Exa's response text into structured search results
|
|
15
|
+
*
|
|
16
|
+
* Exa returns results in this format:
|
|
17
|
+
* Title: ...
|
|
18
|
+
* URL: ...
|
|
19
|
+
* Text: ...
|
|
20
|
+
*/
|
|
21
|
+
function parseExaResults(text) {
|
|
22
|
+
const results = [];
|
|
23
|
+
const lines = text.split('\n');
|
|
24
|
+
let currentResult = {};
|
|
25
|
+
let collectingText = false;
|
|
26
|
+
let textBuffer = [];
|
|
27
|
+
for (const line of lines) {
|
|
28
|
+
const trimmed = line.trim();
|
|
29
|
+
// Check for "Title: ..." line
|
|
30
|
+
if (trimmed.startsWith('Title:')) {
|
|
31
|
+
// Save previous result if exists
|
|
32
|
+
if (currentResult.title && currentResult.url) {
|
|
33
|
+
results.push({
|
|
34
|
+
title: currentResult.title,
|
|
35
|
+
url: currentResult.url,
|
|
36
|
+
snippet: textBuffer.join(' ').trim().substring(0, 300),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
currentResult = { title: trimmed.substring(6).trim() };
|
|
40
|
+
collectingText = false;
|
|
41
|
+
textBuffer = [];
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
// Check for "URL: ..." line
|
|
45
|
+
if (trimmed.startsWith('URL:')) {
|
|
46
|
+
currentResult.url = trimmed.substring(4).trim();
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
// Check for "Text: ..." line - start of snippet
|
|
50
|
+
if (trimmed.startsWith('Text:')) {
|
|
51
|
+
collectingText = true;
|
|
52
|
+
const initialText = trimmed.substring(5).trim();
|
|
53
|
+
if (initialText) {
|
|
54
|
+
textBuffer.push(initialText);
|
|
55
|
+
}
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// Collect text lines until next Title
|
|
59
|
+
if (collectingText && trimmed && !trimmed.startsWith('Title:')) {
|
|
60
|
+
textBuffer.push(trimmed);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Add the last result
|
|
64
|
+
if (currentResult.title && currentResult.url) {
|
|
65
|
+
results.push({
|
|
66
|
+
title: currentResult.title,
|
|
67
|
+
url: currentResult.url,
|
|
68
|
+
snippet: textBuffer.join(' ').trim().substring(0, 300),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return results;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Filter results by allowed/blocked domains
|
|
75
|
+
*/
|
|
76
|
+
function filterByDomain(results, options) {
|
|
77
|
+
if (!options?.allowedDomains?.length && !options?.blockedDomains?.length) {
|
|
78
|
+
return results;
|
|
79
|
+
}
|
|
80
|
+
return results.filter((result) => {
|
|
81
|
+
try {
|
|
82
|
+
const domain = new URL(result.url).hostname;
|
|
83
|
+
if (options.allowedDomains?.length) {
|
|
84
|
+
return options.allowedDomains.some((allowed) => domain === allowed || domain.endsWith('.' + allowed));
|
|
85
|
+
}
|
|
86
|
+
if (options.blockedDomains?.length) {
|
|
87
|
+
return !options.blockedDomains.some((blocked) => domain === blocked || domain.endsWith('.' + blocked));
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
export class ExaProvider {
|
|
97
|
+
name = 'exa';
|
|
98
|
+
async search(query, options) {
|
|
99
|
+
const searchRequest = {
|
|
100
|
+
jsonrpc: '2.0',
|
|
101
|
+
id: 1,
|
|
102
|
+
method: 'tools/call',
|
|
103
|
+
params: {
|
|
104
|
+
name: 'web_search_exa',
|
|
105
|
+
arguments: {
|
|
106
|
+
query,
|
|
107
|
+
type: 'auto',
|
|
108
|
+
numResults: options?.numResults ?? API_CONFIG.DEFAULT_NUM_RESULTS,
|
|
109
|
+
livecrawl: 'fallback',
|
|
110
|
+
contextMaxCharacters: 10000,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
const controller = new AbortController();
|
|
115
|
+
const timeoutId = setTimeout(() => controller.abort(), options?.timeout ?? API_CONFIG.DEFAULT_TIMEOUT);
|
|
116
|
+
try {
|
|
117
|
+
const signals = options?.abortSignal
|
|
118
|
+
? [controller.signal, options.abortSignal]
|
|
119
|
+
: [controller.signal];
|
|
120
|
+
const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINT}`, {
|
|
121
|
+
method: 'POST',
|
|
122
|
+
headers: {
|
|
123
|
+
Accept: 'application/json, text/event-stream',
|
|
124
|
+
'Content-Type': 'application/json',
|
|
125
|
+
},
|
|
126
|
+
body: JSON.stringify(searchRequest),
|
|
127
|
+
signal: AbortSignal.any(signals),
|
|
128
|
+
});
|
|
129
|
+
clearTimeout(timeoutId);
|
|
130
|
+
if (!response.ok) {
|
|
131
|
+
const errorText = await response.text();
|
|
132
|
+
throw new Error(`Exa search error (${response.status}): ${errorText}`);
|
|
133
|
+
}
|
|
134
|
+
const responseText = await response.text();
|
|
135
|
+
// Parse SSE response
|
|
136
|
+
const lines = responseText.split('\n');
|
|
137
|
+
for (const line of lines) {
|
|
138
|
+
if (line.startsWith('data: ')) {
|
|
139
|
+
const data = JSON.parse(line.substring(6));
|
|
140
|
+
if (data.result?.content?.length > 0) {
|
|
141
|
+
const text = data.result.content[0].text;
|
|
142
|
+
const results = parseExaResults(text);
|
|
143
|
+
return filterByDomain(results, options);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
clearTimeout(timeoutId);
|
|
151
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
152
|
+
throw new Error('Search request timed out');
|
|
153
|
+
}
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=exa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exa.js","sourceRoot":"","sources":["../../../src/providers/search/exa.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Providers - Factory and exports
|
|
3
|
+
*/
|
|
4
|
+
export * from './types.js';
|
|
5
|
+
export { ExaProvider } from './exa.js';
|
|
6
|
+
export { SerperProvider } from './serper.js';
|
|
7
|
+
export { BraveProvider } from './brave.js';
|
|
8
|
+
import type { SearchProvider, SearchProviderName } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Create a search provider instance
|
|
11
|
+
*
|
|
12
|
+
* Priority:
|
|
13
|
+
* 1. Explicit name parameter
|
|
14
|
+
* 2. Configured in provider store
|
|
15
|
+
* 3. Detected from environment variables
|
|
16
|
+
* 4. Default: Exa (no key required)
|
|
17
|
+
*/
|
|
18
|
+
export declare function createSearchProvider(name?: SearchProviderName): SearchProvider;
|
|
19
|
+
/**
|
|
20
|
+
* Get the name of the current search provider
|
|
21
|
+
*/
|
|
22
|
+
export declare function getCurrentSearchProviderName(): SearchProviderName;
|
|
23
|
+
/**
|
|
24
|
+
* Check if a search provider is available (has required API keys)
|
|
25
|
+
*/
|
|
26
|
+
export declare function isSearchProviderAvailable(name: SearchProviderName): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Get all available search providers
|
|
29
|
+
*/
|
|
30
|
+
export declare function getAvailableSearchProviders(): SearchProviderName[];
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/search/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAerE;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,kBAAkB,GAAG,cAAc,CAY9E;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,kBAAkB,CAEjE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAW3E;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,kBAAkB,EAAE,CAKlE"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Providers - Factory and exports
|
|
3
|
+
*/
|
|
4
|
+
export * from './types.js';
|
|
5
|
+
export { ExaProvider } from './exa.js';
|
|
6
|
+
export { SerperProvider } from './serper.js';
|
|
7
|
+
export { BraveProvider } from './brave.js';
|
|
8
|
+
import { ExaProvider } from './exa.js';
|
|
9
|
+
import { SerperProvider } from './serper.js';
|
|
10
|
+
import { BraveProvider } from './brave.js';
|
|
11
|
+
import { getProviderStore } from '../store.js';
|
|
12
|
+
/**
|
|
13
|
+
* Detect search provider from environment variables
|
|
14
|
+
*/
|
|
15
|
+
function detectFromEnv() {
|
|
16
|
+
if (process.env.SERPER_API_KEY)
|
|
17
|
+
return 'serper';
|
|
18
|
+
if (process.env.BRAVE_API_KEY)
|
|
19
|
+
return 'brave';
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a search provider instance
|
|
24
|
+
*
|
|
25
|
+
* Priority:
|
|
26
|
+
* 1. Explicit name parameter
|
|
27
|
+
* 2. Configured in provider store
|
|
28
|
+
* 3. Detected from environment variables
|
|
29
|
+
* 4. Default: Exa (no key required)
|
|
30
|
+
*/
|
|
31
|
+
export function createSearchProvider(name) {
|
|
32
|
+
const providerName = name ?? getProviderStore().getSearchProvider() ?? detectFromEnv() ?? 'exa';
|
|
33
|
+
switch (providerName) {
|
|
34
|
+
case 'serper':
|
|
35
|
+
return new SerperProvider();
|
|
36
|
+
case 'brave':
|
|
37
|
+
return new BraveProvider();
|
|
38
|
+
case 'exa':
|
|
39
|
+
default:
|
|
40
|
+
return new ExaProvider();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get the name of the current search provider
|
|
45
|
+
*/
|
|
46
|
+
export function getCurrentSearchProviderName() {
|
|
47
|
+
return getProviderStore().getSearchProvider() ?? detectFromEnv() ?? 'exa';
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if a search provider is available (has required API keys)
|
|
51
|
+
*/
|
|
52
|
+
export function isSearchProviderAvailable(name) {
|
|
53
|
+
switch (name) {
|
|
54
|
+
case 'exa':
|
|
55
|
+
return true; // Always available
|
|
56
|
+
case 'serper':
|
|
57
|
+
return !!process.env.SERPER_API_KEY;
|
|
58
|
+
case 'brave':
|
|
59
|
+
return !!process.env.BRAVE_API_KEY;
|
|
60
|
+
default:
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get all available search providers
|
|
66
|
+
*/
|
|
67
|
+
export function getAvailableSearchProviders() {
|
|
68
|
+
const providers = ['exa']; // Always available
|
|
69
|
+
if (process.env.SERPER_API_KEY)
|
|
70
|
+
providers.push('serper');
|
|
71
|
+
if (process.env.BRAVE_API_KEY)
|
|
72
|
+
providers.push('brave');
|
|
73
|
+
return providers;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/search/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,SAAS,aAAa;IACpB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,QAAQ,CAAC;IAChD,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa;QAAE,OAAO,OAAO,CAAC;IAC9C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAyB;IAC5D,MAAM,YAAY,GAAG,IAAI,IAAI,gBAAgB,EAAE,CAAC,iBAAiB,EAAE,IAAI,aAAa,EAAE,IAAI,KAAK,CAAC;IAEhG,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,EAAE,CAAC;QAC9B,KAAK,OAAO;YACV,OAAO,IAAI,aAAa,EAAE,CAAC;QAC7B,KAAK,KAAK,CAAC;QACX;YACE,OAAO,IAAI,WAAW,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO,gBAAgB,EAAE,CAAC,iBAAiB,EAAE,IAAI,aAAa,EAAE,IAAI,KAAK,CAAC;AAC5E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAwB;IAChE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK;YACR,OAAO,IAAI,CAAC,CAAC,mBAAmB;QAClC,KAAK,QAAQ;YACX,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QACtC,KAAK,OAAO;YACV,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACrC;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B;IACzC,MAAM,SAAS,GAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB;IACpE,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa;QAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serper.dev Search Provider
|
|
3
|
+
*
|
|
4
|
+
* Uses Google Search via Serper.dev API.
|
|
5
|
+
* Requires SERPER_API_KEY environment variable.
|
|
6
|
+
*/
|
|
7
|
+
import type { SearchProvider, SearchResult, SearchOptions } from './types.js';
|
|
8
|
+
export declare class SerperProvider implements SearchProvider {
|
|
9
|
+
readonly name: "serper";
|
|
10
|
+
private apiKey;
|
|
11
|
+
constructor(apiKey?: string);
|
|
12
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=serper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serper.d.ts","sourceRoot":"","sources":["../../../src/providers/search/serper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA6D9E,qBAAa,cAAe,YAAW,cAAc;IACnD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,CAAC,EAAE,MAAM;IAOrB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAqD9E"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serper.dev Search Provider
|
|
3
|
+
*
|
|
4
|
+
* Uses Google Search via Serper.dev API.
|
|
5
|
+
* Requires SERPER_API_KEY environment variable.
|
|
6
|
+
*/
|
|
7
|
+
const API_CONFIG = {
|
|
8
|
+
BASE_URL: 'https://google.serper.dev',
|
|
9
|
+
ENDPOINT: '/search',
|
|
10
|
+
DEFAULT_NUM_RESULTS: 10,
|
|
11
|
+
DEFAULT_TIMEOUT: 10000,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Filter results by allowed/blocked domains
|
|
15
|
+
*/
|
|
16
|
+
function filterByDomain(results, options) {
|
|
17
|
+
if (!options?.allowedDomains?.length && !options?.blockedDomains?.length) {
|
|
18
|
+
return results;
|
|
19
|
+
}
|
|
20
|
+
return results.filter((result) => {
|
|
21
|
+
try {
|
|
22
|
+
const domain = new URL(result.url).hostname;
|
|
23
|
+
if (options.allowedDomains?.length) {
|
|
24
|
+
return options.allowedDomains.some((allowed) => domain === allowed || domain.endsWith('.' + allowed));
|
|
25
|
+
}
|
|
26
|
+
if (options.blockedDomains?.length) {
|
|
27
|
+
return !options.blockedDomains.some((blocked) => domain === blocked || domain.endsWith('.' + blocked));
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export class SerperProvider {
|
|
37
|
+
name = 'serper';
|
|
38
|
+
apiKey;
|
|
39
|
+
constructor(apiKey) {
|
|
40
|
+
this.apiKey = apiKey ?? process.env.SERPER_API_KEY ?? '';
|
|
41
|
+
if (!this.apiKey) {
|
|
42
|
+
throw new Error('SERPER_API_KEY environment variable is required for Serper provider');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async search(query, options) {
|
|
46
|
+
const searchRequest = {
|
|
47
|
+
q: query,
|
|
48
|
+
num: options?.numResults ?? API_CONFIG.DEFAULT_NUM_RESULTS,
|
|
49
|
+
};
|
|
50
|
+
const controller = new AbortController();
|
|
51
|
+
const timeoutId = setTimeout(() => controller.abort(), options?.timeout ?? API_CONFIG.DEFAULT_TIMEOUT);
|
|
52
|
+
try {
|
|
53
|
+
const signals = options?.abortSignal
|
|
54
|
+
? [controller.signal, options.abortSignal]
|
|
55
|
+
: [controller.signal];
|
|
56
|
+
const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINT}`, {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
headers: {
|
|
59
|
+
'X-API-KEY': this.apiKey,
|
|
60
|
+
'Content-Type': 'application/json',
|
|
61
|
+
},
|
|
62
|
+
body: JSON.stringify(searchRequest),
|
|
63
|
+
signal: AbortSignal.any(signals),
|
|
64
|
+
});
|
|
65
|
+
clearTimeout(timeoutId);
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const errorText = await response.text();
|
|
68
|
+
throw new Error(`Serper search error (${response.status}): ${errorText}`);
|
|
69
|
+
}
|
|
70
|
+
const data = await response.json();
|
|
71
|
+
const results = (data.organic || []).map((item) => ({
|
|
72
|
+
title: item.title,
|
|
73
|
+
url: item.link,
|
|
74
|
+
snippet: item.snippet,
|
|
75
|
+
}));
|
|
76
|
+
return filterByDomain(results, options);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
clearTimeout(timeoutId);
|
|
80
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
81
|
+
throw new Error('Search request timed out');
|
|
82
|
+
}
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=serper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serper.js","sourceRoot":"","sources":["../../../src/providers/search/serper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Provider Types
|
|
3
|
+
*/
|
|
4
|
+
export type SearchProviderName = 'exa' | 'serper' | 'brave';
|
|
5
|
+
export interface SearchResult {
|
|
6
|
+
title: string;
|
|
7
|
+
url: string;
|
|
8
|
+
snippet: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SearchOptions {
|
|
11
|
+
numResults?: number;
|
|
12
|
+
allowedDomains?: string[];
|
|
13
|
+
blockedDomains?: string[];
|
|
14
|
+
timeout?: number;
|
|
15
|
+
abortSignal?: AbortSignal;
|
|
16
|
+
}
|
|
17
|
+
export interface SearchProvider {
|
|
18
|
+
readonly name: SearchProviderName;
|
|
19
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/search/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CACzE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/providers/search/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Store - Manages provider connections and model cache
|
|
3
|
+
*
|
|
4
|
+
* Storage location: ~/.gencode/providers.json
|
|
5
|
+
*/
|
|
6
|
+
import type { ProviderName } from './index.js';
|
|
7
|
+
import type { SearchProviderName } from './search/types.js';
|
|
8
|
+
export interface ModelInfo {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ProviderConnection {
|
|
13
|
+
method: string;
|
|
14
|
+
connectedAt: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ModelCache {
|
|
17
|
+
cachedAt: string;
|
|
18
|
+
list: ModelInfo[];
|
|
19
|
+
}
|
|
20
|
+
export interface ProvidersConfig {
|
|
21
|
+
connections: Record<string, ProviderConnection>;
|
|
22
|
+
models: Record<string, ModelCache>;
|
|
23
|
+
searchProvider?: SearchProviderName;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Provider Store - manages connection state and model cache
|
|
27
|
+
*/
|
|
28
|
+
export declare class ProviderStore {
|
|
29
|
+
private config;
|
|
30
|
+
constructor();
|
|
31
|
+
/**
|
|
32
|
+
* Load configuration from disk
|
|
33
|
+
*/
|
|
34
|
+
private load;
|
|
35
|
+
/**
|
|
36
|
+
* Save configuration to disk
|
|
37
|
+
*/
|
|
38
|
+
private save;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a provider is connected
|
|
41
|
+
*/
|
|
42
|
+
isConnected(providerId: ProviderName): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Get connection info for a provider
|
|
45
|
+
*/
|
|
46
|
+
getConnection(providerId: ProviderName): ProviderConnection | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Get all connected provider IDs
|
|
49
|
+
*/
|
|
50
|
+
getConnectedProviders(): ProviderName[];
|
|
51
|
+
/**
|
|
52
|
+
* Connect a provider
|
|
53
|
+
*/
|
|
54
|
+
connect(providerId: ProviderName, method: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Disconnect a provider
|
|
57
|
+
*/
|
|
58
|
+
disconnect(providerId: ProviderName): void;
|
|
59
|
+
/**
|
|
60
|
+
* Get cached models for a provider
|
|
61
|
+
*/
|
|
62
|
+
getModels(providerId: ProviderName): ModelInfo[];
|
|
63
|
+
/**
|
|
64
|
+
* Get all cached models grouped by provider
|
|
65
|
+
*/
|
|
66
|
+
getAllModels(): Record<ProviderName, ModelInfo[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Cache models for a provider
|
|
69
|
+
*/
|
|
70
|
+
cacheModels(providerId: ProviderName, models: ModelInfo[]): void;
|
|
71
|
+
/**
|
|
72
|
+
* Get cache timestamp for a provider
|
|
73
|
+
*/
|
|
74
|
+
getCacheTime(providerId: ProviderName): Date | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Check if model cache is stale (older than 24 hours)
|
|
77
|
+
*/
|
|
78
|
+
isCacheStale(providerId: ProviderName): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Get total model count across all connected providers
|
|
81
|
+
*/
|
|
82
|
+
getTotalModelCount(): number;
|
|
83
|
+
/**
|
|
84
|
+
* Get model count for a specific provider
|
|
85
|
+
*/
|
|
86
|
+
getModelCount(providerId: ProviderName): number;
|
|
87
|
+
/**
|
|
88
|
+
* Get the configured search provider
|
|
89
|
+
*/
|
|
90
|
+
getSearchProvider(): SearchProviderName | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* Set the search provider
|
|
93
|
+
*/
|
|
94
|
+
setSearchProvider(id: SearchProviderName): void;
|
|
95
|
+
/**
|
|
96
|
+
* Clear the search provider (use default)
|
|
97
|
+
*/
|
|
98
|
+
clearSearchProvider(): void;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get the singleton provider store instance
|
|
102
|
+
*/
|
|
103
|
+
export declare function getProviderStore(): ProviderStore;
|
|
104
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/providers/store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAChD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACrC;AAKD;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAkB;;IAMhC;;OAEG;IACH,OAAO,CAAC,IAAI;IAYZ;;OAEG;IACH,OAAO,CAAC,IAAI;IAWZ;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,YAAY,GAAG,OAAO;IAI9C;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,YAAY,GAAG,kBAAkB,GAAG,SAAS;IAIvE;;OAEG;IACH,qBAAqB,IAAI,YAAY,EAAE;IAIvC;;OAEG;IACH,OAAO,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQvD;;OAEG;IACH,UAAU,CAAC,UAAU,EAAE,YAAY,GAAG,IAAI;IAM1C;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,YAAY,GAAG,SAAS,EAAE;IAIhD;;OAEG;IACH,YAAY,IAAI,MAAM,CAAC,YAAY,EAAE,SAAS,EAAE,CAAC;IAQjD;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI;IAQhE;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS;IAKxD;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,YAAY,GAAG,OAAO;IAO/C;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAO5B;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,YAAY,GAAG,MAAM;IAI/C;;OAEG;IACH,iBAAiB,IAAI,kBAAkB,GAAG,SAAS;IAInD;;OAEG;IACH,iBAAiB,CAAC,EAAE,EAAE,kBAAkB,GAAG,IAAI;IAK/C;;OAEG;IACH,mBAAmB,IAAI,IAAI;CAI5B;AAKD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD"}
|