genesis-ai-cli 14.6.3 → 14.6.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/src/agents/explorer.d.ts +2 -0
- package/dist/src/agents/explorer.js +129 -37
- package/dist/src/economy/live/payment-verifier.js +3 -1
- package/dist/src/llm/advanced-router.d.ts +7 -0
- package/dist/src/llm/advanced-router.js +32 -0
- package/dist/src/llm/index.js +21 -0
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ import { MessageBus } from './message-bus.js';
|
|
|
9
9
|
import { Message, MessageType, ExplorationResult, ExplorationSource } from './types.js';
|
|
10
10
|
export declare class ExplorerAgent extends BaseAgent {
|
|
11
11
|
private explorationHistory;
|
|
12
|
+
private mcp;
|
|
12
13
|
constructor(bus?: MessageBus);
|
|
13
14
|
protected getMessageTypes(): MessageType[];
|
|
14
15
|
process(message: Message): Promise<Message | null>;
|
|
@@ -16,6 +17,7 @@ export declare class ExplorerAgent extends BaseAgent {
|
|
|
16
17
|
private handleCommand;
|
|
17
18
|
explore(query: string, sources?: ExplorationSource['type'][], depth?: 'shallow' | 'medium' | 'deep'): Promise<ExplorationResult>;
|
|
18
19
|
private searchSource;
|
|
20
|
+
private computeRelevance;
|
|
19
21
|
private createFinding;
|
|
20
22
|
private getDefaultSources;
|
|
21
23
|
private calculateNovelty;
|
|
@@ -10,12 +10,15 @@ exports.ExplorerAgent = void 0;
|
|
|
10
10
|
exports.createExplorerAgent = createExplorerAgent;
|
|
11
11
|
const base_agent_js_1 = require("./base-agent.js");
|
|
12
12
|
const message_bus_js_1 = require("./message-bus.js");
|
|
13
|
+
const index_js_1 = require("../mcp/index.js");
|
|
13
14
|
// ============================================================================
|
|
14
15
|
// Explorer Agent
|
|
15
16
|
// ============================================================================
|
|
16
17
|
class ExplorerAgent extends base_agent_js_1.BaseAgent {
|
|
17
18
|
// Track exploration history for novelty detection
|
|
18
19
|
explorationHistory = new Set();
|
|
20
|
+
// MCP client for real searches
|
|
21
|
+
mcp = (0, index_js_1.getMCPClient)();
|
|
19
22
|
constructor(bus = message_bus_js_1.messageBus) {
|
|
20
23
|
super({ type: 'explorer' }, bus);
|
|
21
24
|
}
|
|
@@ -110,48 +113,137 @@ class ExplorerAgent extends base_agent_js_1.BaseAgent {
|
|
|
110
113
|
// Source-Specific Search
|
|
111
114
|
// ============================================================================
|
|
112
115
|
async searchSource(source, query) {
|
|
113
|
-
// In production, these would call actual MCP servers
|
|
114
|
-
// For now, we return simulated results based on source type
|
|
115
116
|
const findings = [];
|
|
116
117
|
const metadata = {};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
118
|
+
try {
|
|
119
|
+
switch (source) {
|
|
120
|
+
case 'arxiv': {
|
|
121
|
+
const result = await this.mcp.call('arxiv', 'search_arxiv', {
|
|
122
|
+
query,
|
|
123
|
+
max_results: 5,
|
|
124
|
+
});
|
|
125
|
+
if (result?.data) {
|
|
126
|
+
const papers = Array.isArray(result.data) ? result.data :
|
|
127
|
+
(result.data.papers || []);
|
|
128
|
+
for (const paper of papers.slice(0, 5)) {
|
|
129
|
+
findings.push(this.createFinding(`[arxiv] ${paper.title || 'Paper'}: ${(paper.summary || paper.abstract || '').slice(0, 200)}...`, source, this.computeRelevance(query, paper.title, paper.summary), true));
|
|
130
|
+
}
|
|
131
|
+
metadata.paperCount = papers.length;
|
|
132
|
+
}
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case 'semantic-scholar': {
|
|
136
|
+
const result = await this.mcp.call('semantic-scholar', 'search_semantic_scholar', {
|
|
137
|
+
query,
|
|
138
|
+
limit: 5,
|
|
139
|
+
});
|
|
140
|
+
if (result?.data) {
|
|
141
|
+
const papers = Array.isArray(result.data) ? result.data :
|
|
142
|
+
(result.data.papers || []);
|
|
143
|
+
for (const paper of papers.slice(0, 5)) {
|
|
144
|
+
const citations = paper.citationCount || 0;
|
|
145
|
+
findings.push(this.createFinding(`[semantic-scholar] ${paper.title || 'Paper'} (${citations} citations): ${(paper.abstract || '').slice(0, 200)}...`, source, citations > 100 ? 0.9 : citations > 10 ? 0.7 : 0.5, true));
|
|
146
|
+
}
|
|
147
|
+
metadata.citationDepth = 2;
|
|
148
|
+
}
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
case 'brave': {
|
|
152
|
+
const result = await this.mcp.call('brave-search', 'brave_web_search', {
|
|
153
|
+
query,
|
|
154
|
+
count: 5,
|
|
155
|
+
});
|
|
156
|
+
if (result?.data) {
|
|
157
|
+
const results = result.data.web?.results || result.data.results || [];
|
|
158
|
+
for (const item of results.slice(0, 5)) {
|
|
159
|
+
findings.push(this.createFinding(`[brave] ${item.title || 'Result'}: ${(item.description || item.snippet || '').slice(0, 200)}...`, source, 0.7, false));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
case 'gemini': {
|
|
165
|
+
const result = await this.mcp.call('gemini', 'web_search', {
|
|
166
|
+
query,
|
|
167
|
+
});
|
|
168
|
+
if (result?.data) {
|
|
169
|
+
const content = typeof result.data === 'string' ? result.data :
|
|
170
|
+
JSON.stringify(result.data).slice(0, 500);
|
|
171
|
+
findings.push(this.createFinding(`[gemini] ${content.slice(0, 300)}...`, source, 0.75, false));
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case 'exa': {
|
|
176
|
+
const result = await this.mcp.call('exa', 'web_search_exa', {
|
|
177
|
+
query,
|
|
178
|
+
numResults: 5,
|
|
179
|
+
});
|
|
180
|
+
if (result?.data) {
|
|
181
|
+
const results = result.data.results || [];
|
|
182
|
+
for (const item of results.slice(0, 5)) {
|
|
183
|
+
findings.push(this.createFinding(`[exa] ${item.title || 'Result'}: ${(item.text || item.snippet || '').slice(0, 200)}...`, source, 0.8, true));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
case 'firecrawl': {
|
|
189
|
+
const result = await this.mcp.call('firecrawl', 'firecrawl_search', {
|
|
190
|
+
query,
|
|
191
|
+
limit: 5,
|
|
192
|
+
});
|
|
193
|
+
if (result?.data) {
|
|
194
|
+
const results = result.data.results || result.data || [];
|
|
195
|
+
const items = Array.isArray(results) ? results : [results];
|
|
196
|
+
for (const item of items.slice(0, 5)) {
|
|
197
|
+
findings.push(this.createFinding(`[firecrawl] ${item.title || item.url || 'Result'}: ${(item.content || item.description || '').slice(0, 200)}...`, source, 0.65, false));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
case 'context7': {
|
|
203
|
+
// context7 requires library resolution first
|
|
204
|
+
const libResult = await this.mcp.call('context7', 'resolve-library-id', {
|
|
205
|
+
libraryName: query.split(' ')[0], // Use first word as library name
|
|
206
|
+
});
|
|
207
|
+
if (libResult?.data?.libraryId) {
|
|
208
|
+
const docsResult = await this.mcp.call('context7', 'query-docs', {
|
|
209
|
+
libraryId: libResult.data.libraryId,
|
|
210
|
+
query,
|
|
211
|
+
});
|
|
212
|
+
if (docsResult?.data) {
|
|
213
|
+
findings.push(this.createFinding(`[context7] ${typeof docsResult.data === 'string' ? docsResult.data.slice(0, 300) : JSON.stringify(docsResult.data).slice(0, 300)}...`, source, 0.9, true));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case 'wolfram': {
|
|
219
|
+
const result = await this.mcp.call('wolfram', 'wolfram_query', {
|
|
220
|
+
input: query,
|
|
221
|
+
});
|
|
222
|
+
if (result?.data) {
|
|
223
|
+
const content = typeof result.data === 'string' ? result.data :
|
|
224
|
+
JSON.stringify(result.data).slice(0, 500);
|
|
225
|
+
findings.push(this.createFinding(`[wolfram] ${content.slice(0, 300)}...`, source, 0.95, true));
|
|
226
|
+
}
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
this.log(`MCP call to ${source} failed: ${error}`);
|
|
233
|
+
// Return empty findings on error - graceful degradation
|
|
152
234
|
}
|
|
153
235
|
return { findings, metadata };
|
|
154
236
|
}
|
|
237
|
+
computeRelevance(query, title, summary) {
|
|
238
|
+
const queryTerms = query.toLowerCase().split(/\s+/);
|
|
239
|
+
const text = `${title || ''} ${summary || ''}`.toLowerCase();
|
|
240
|
+
let matches = 0;
|
|
241
|
+
for (const term of queryTerms) {
|
|
242
|
+
if (text.includes(term))
|
|
243
|
+
matches++;
|
|
244
|
+
}
|
|
245
|
+
return queryTerms.length > 0 ? Math.min(0.95, 0.5 + (matches / queryTerms.length) * 0.45) : 0.5;
|
|
246
|
+
}
|
|
155
247
|
createFinding(content, sourceType, importance, isNovel) {
|
|
156
248
|
return {
|
|
157
249
|
content,
|
|
@@ -79,6 +79,8 @@ export declare class AdvancedRouter {
|
|
|
79
79
|
private stats;
|
|
80
80
|
private metaLearning;
|
|
81
81
|
private providerHealth;
|
|
82
|
+
private rateLimiters;
|
|
83
|
+
private static readonly TOKEN_REFILL_INTERVAL;
|
|
82
84
|
constructor(config?: {
|
|
83
85
|
costOptimize: boolean;
|
|
84
86
|
speedOptimize: boolean;
|
|
@@ -87,6 +89,11 @@ export declare class AdvancedRouter {
|
|
|
87
89
|
enableMetaLearning: boolean;
|
|
88
90
|
});
|
|
89
91
|
private checkProviderHealth;
|
|
92
|
+
/**
|
|
93
|
+
* Enforce rate limiting using token bucket algorithm.
|
|
94
|
+
* Waits if tokens are exhausted, preventing 429 errors.
|
|
95
|
+
*/
|
|
96
|
+
private enforceRateLimit;
|
|
90
97
|
private getAvailableProviders;
|
|
91
98
|
route(prompt: string, forceTaskType?: TaskType): Promise<AdvancedRoutingDecision>;
|
|
92
99
|
private selectCheapest;
|
|
@@ -408,6 +408,9 @@ class AdvancedRouter {
|
|
|
408
408
|
};
|
|
409
409
|
metaLearning = [];
|
|
410
410
|
providerHealth = new Map();
|
|
411
|
+
// Rate limiting with token bucket
|
|
412
|
+
rateLimiters = new Map();
|
|
413
|
+
static TOKEN_REFILL_INTERVAL = 60000; // 1 minute
|
|
411
414
|
constructor(config = {
|
|
412
415
|
costOptimize: true,
|
|
413
416
|
speedOptimize: true,
|
|
@@ -458,6 +461,33 @@ class AdvancedRouter {
|
|
|
458
461
|
this.providerHealth.set(provider, { available, lastCheck: now });
|
|
459
462
|
return available;
|
|
460
463
|
}
|
|
464
|
+
/**
|
|
465
|
+
* Enforce rate limiting using token bucket algorithm.
|
|
466
|
+
* Waits if tokens are exhausted, preventing 429 errors.
|
|
467
|
+
*/
|
|
468
|
+
async enforceRateLimit(provider) {
|
|
469
|
+
const config = exports.PROVIDER_REGISTRY[provider];
|
|
470
|
+
const rateLimit = config.rateLimit || 60; // Default 60 RPM
|
|
471
|
+
let bucket = this.rateLimiters.get(provider);
|
|
472
|
+
const now = Date.now();
|
|
473
|
+
if (!bucket) {
|
|
474
|
+
bucket = { tokens: rateLimit, lastRefill: now };
|
|
475
|
+
this.rateLimiters.set(provider, bucket);
|
|
476
|
+
}
|
|
477
|
+
// Refill tokens based on time elapsed
|
|
478
|
+
const elapsed = now - bucket.lastRefill;
|
|
479
|
+
const refillAmount = (elapsed / AdvancedRouter.TOKEN_REFILL_INTERVAL) * rateLimit;
|
|
480
|
+
bucket.tokens = Math.min(rateLimit, bucket.tokens + refillAmount);
|
|
481
|
+
bucket.lastRefill = now;
|
|
482
|
+
// Wait if no tokens available
|
|
483
|
+
if (bucket.tokens < 1) {
|
|
484
|
+
const waitMs = Math.ceil((1 - bucket.tokens) * (AdvancedRouter.TOKEN_REFILL_INTERVAL / rateLimit));
|
|
485
|
+
console.log(`[AdvancedRouter] Rate limit reached for ${provider}, waiting ${waitMs}ms`);
|
|
486
|
+
await new Promise(r => setTimeout(r, waitMs));
|
|
487
|
+
bucket.tokens = 1; // Reset after wait
|
|
488
|
+
}
|
|
489
|
+
bucket.tokens--;
|
|
490
|
+
}
|
|
461
491
|
async getAvailableProviders() {
|
|
462
492
|
const checks = await Promise.all(Object.keys(exports.PROVIDER_REGISTRY).map(async (p) => ({
|
|
463
493
|
provider: p,
|
|
@@ -611,6 +641,8 @@ class AdvancedRouter {
|
|
|
611
641
|
// Provider Calls
|
|
612
642
|
// ==========================================================================
|
|
613
643
|
async callProvider(provider, model, prompt, systemPrompt) {
|
|
644
|
+
// Enforce rate limiting before making the call
|
|
645
|
+
await this.enforceRateLimit(provider);
|
|
614
646
|
const startTime = Date.now();
|
|
615
647
|
const config = exports.PROVIDER_REGISTRY[provider];
|
|
616
648
|
switch (provider) {
|
package/dist/src/llm/index.js
CHANGED
|
@@ -634,6 +634,13 @@ class LLMBridge {
|
|
|
634
634
|
}
|
|
635
635
|
finally {
|
|
636
636
|
reader.releaseLock();
|
|
637
|
+
// Properly clean up the stream to prevent connection leaks
|
|
638
|
+
try {
|
|
639
|
+
await response.body?.cancel();
|
|
640
|
+
}
|
|
641
|
+
catch {
|
|
642
|
+
// Ignore cancel errors - stream may already be closed
|
|
643
|
+
}
|
|
637
644
|
}
|
|
638
645
|
// Add to history
|
|
639
646
|
this.conversationHistory.push({ role: 'assistant', content: fullContent });
|
|
@@ -759,6 +766,13 @@ class LLMBridge {
|
|
|
759
766
|
}
|
|
760
767
|
finally {
|
|
761
768
|
reader.releaseLock();
|
|
769
|
+
// Properly clean up the stream to prevent connection leaks
|
|
770
|
+
try {
|
|
771
|
+
await response.body?.cancel();
|
|
772
|
+
}
|
|
773
|
+
catch {
|
|
774
|
+
// Ignore cancel errors - stream may already be closed
|
|
775
|
+
}
|
|
762
776
|
}
|
|
763
777
|
// Add to history
|
|
764
778
|
this.conversationHistory.push({ role: 'assistant', content: fullContent });
|
|
@@ -842,6 +856,13 @@ class LLMBridge {
|
|
|
842
856
|
}
|
|
843
857
|
finally {
|
|
844
858
|
reader.releaseLock();
|
|
859
|
+
// Properly clean up the stream to prevent connection leaks
|
|
860
|
+
try {
|
|
861
|
+
await response.body?.cancel();
|
|
862
|
+
}
|
|
863
|
+
catch {
|
|
864
|
+
// Ignore cancel errors - stream may already be closed
|
|
865
|
+
}
|
|
845
866
|
}
|
|
846
867
|
// Add to history
|
|
847
868
|
this.conversationHistory.push({ role: 'assistant', content: fullContent });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genesis-ai-cli",
|
|
3
|
-
"version": "14.6.
|
|
3
|
+
"version": "14.6.4",
|
|
4
4
|
"description": "Fully Autonomous AI System with RSI (Recursive Self-Improvement) - Self-funding, Self-deploying, Production Memory, A2A Protocol & Governance",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|