natureco-cli 5.15.0 → 5.16.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/package.json +1 -1
- package/src/tools/sub_agent.js +96 -0
- package/src/utils/tools.js +7 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "natureco-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.16.0",
|
|
4
4
|
"description": "OpenClaw'dan daha güvenli, daha hızlı, daha ucuz AI agent CLI. Multi-agent, self-evolving skills, audit log, maliyet optimizasyonu ve NatureCo platform-native.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"natureco": "bin/natureco.js"
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sub_agent — Spawn a sub-agent for delegated sub-tasks
|
|
3
|
+
*
|
|
4
|
+
* Creates a child agent with its own LLM call to handle a specific sub-task.
|
|
5
|
+
* Returns the sub-agent's response. Useful for parallel research, complex
|
|
6
|
+
* sub-problems, or when a focused agent is better than the main loop.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const https = require('https');
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
|
|
14
|
+
function loadConfig() {
|
|
15
|
+
try { return JSON.parse(fs.readFileSync(path.join(os.homedir(), '.natureco', 'config.json'), 'utf8')); } catch { return {}; }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isMiniMax(url) { return url && (url.includes('minimax.io') || url.includes('minimaxi.com') || url.includes('minimax.cn')); }
|
|
19
|
+
function isGemini(url) { return url && (url.includes('generativelanguage.googleapis.com') || url.includes('gemini')); }
|
|
20
|
+
|
|
21
|
+
function apiCall(providerUrl, apiKey, body) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const base = providerUrl.replace(/\/+$/, '');
|
|
24
|
+
const endpoint = isMiniMax(base)
|
|
25
|
+
? base + '/v1/text/chatcompletion_v2'
|
|
26
|
+
: isGemini(base)
|
|
27
|
+
? base + '/openai/chat/completions'
|
|
28
|
+
: base + '/chat/completions';
|
|
29
|
+
const req = https.request(endpoint, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: { 'Authorization': 'Bearer ' + apiKey, 'Content-Type': 'application/json' },
|
|
32
|
+
timeout: 120000,
|
|
33
|
+
}, (res) => {
|
|
34
|
+
let data = '';
|
|
35
|
+
res.on('data', c => data += c);
|
|
36
|
+
res.on('end', () => {
|
|
37
|
+
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
38
|
+
try { resolve(JSON.parse(data)); } catch { reject(new Error('Parse error')); }
|
|
39
|
+
} else reject(new Error('HTTP ' + res.statusCode + ': ' + data.slice(0, 300)));
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
req.on('error', reject);
|
|
43
|
+
req.on('timeout', () => { req.destroy(); reject(new Error('Timeout')); });
|
|
44
|
+
req.write(JSON.stringify(body));
|
|
45
|
+
req.end();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const name = 'sub_agent';
|
|
50
|
+
const description = 'Spawn a sub-agent to handle a specific sub-task independently. Returns the sub-agent\'s response. Use for parallel research, focused debugging, or complex sub-problems.';
|
|
51
|
+
const parameters = {
|
|
52
|
+
type: 'object',
|
|
53
|
+
properties: {
|
|
54
|
+
task: { type: 'string', description: 'The sub-task for the sub-agent to complete' },
|
|
55
|
+
context: { type: 'string', description: 'Additional context or background information' },
|
|
56
|
+
model: { type: 'string', description: 'Override model for this sub-agent (default: main config model)' },
|
|
57
|
+
temperature: { type: 'number', description: 'Temperature 0-1 (default: 0.3)' },
|
|
58
|
+
maxTokens: { type: 'number', description: 'Max tokens for response (default: 2000)' },
|
|
59
|
+
},
|
|
60
|
+
required: ['task'],
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
async function execute(params) {
|
|
64
|
+
const cfg = loadConfig();
|
|
65
|
+
const providerUrl = cfg.providerUrl;
|
|
66
|
+
const providerApiKey = cfg.providerApiKey;
|
|
67
|
+
const model = params.model || cfg.providerModel || 'default';
|
|
68
|
+
|
|
69
|
+
if (!providerUrl || !providerApiKey) {
|
|
70
|
+
return JSON.stringify({ success: false, error: 'Provider not configured. Run natureco setup first.' });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const systemContent = 'Sen bir alt-agentsin. Verilen gorevi tamamlamak icin elinden geleni yap. Kisa ve oz yanit ver.'
|
|
74
|
+
+ (params.context ? '\n\nContext:\n' + params.context : '');
|
|
75
|
+
|
|
76
|
+
const body = {
|
|
77
|
+
model,
|
|
78
|
+
messages: [
|
|
79
|
+
{ role: 'system', content: systemContent },
|
|
80
|
+
{ role: 'user', content: params.task },
|
|
81
|
+
],
|
|
82
|
+
stream: false,
|
|
83
|
+
temperature: params.temperature ?? 0.3,
|
|
84
|
+
max_tokens: params.maxTokens || 2000,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const result = await apiCall(providerUrl, providerApiKey, body);
|
|
89
|
+
const reply = result.choices?.[0]?.message?.content || '';
|
|
90
|
+
return JSON.stringify({ success: true, response: reply, model });
|
|
91
|
+
} catch (e) {
|
|
92
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = { name, description, parameters, execute };
|
package/src/utils/tools.js
CHANGED
|
@@ -68,6 +68,7 @@ const EMOJI_MAP = {
|
|
|
68
68
|
google_meet: '📹',
|
|
69
69
|
// Orchestrator
|
|
70
70
|
workflow: '⚙️',
|
|
71
|
+
social_open: '🔗', youtube_ac: '🎬', memory_provider: '🗄️',
|
|
71
72
|
};
|
|
72
73
|
|
|
73
74
|
// ── Toolset grouping ─────────────────────────────────────────────────────
|
|
@@ -122,6 +123,8 @@ const TOOLSET_MAP = {
|
|
|
122
123
|
async_delegation: 'agent', blueprint: 'planning', workflow: 'orchestrator',
|
|
123
124
|
spotify: 'media', homeassistant: 'iot', microsoft_graph: 'office',
|
|
124
125
|
computer_use: 'automation', google_meet: 'communication',
|
|
126
|
+
social_open: 'communication', youtube_ac: 'media',
|
|
127
|
+
sub_agent: 'agent', memory_provider: 'memory',
|
|
125
128
|
};
|
|
126
129
|
|
|
127
130
|
// ── check_fn'ler (tool availability kontrolleri) ────────────────────────
|
|
@@ -227,16 +230,17 @@ function loadToolDefinitions() {
|
|
|
227
230
|
}
|
|
228
231
|
|
|
229
232
|
const ALIAS_MAP = {
|
|
230
|
-
'brave_search': '
|
|
231
|
-
'google_search': '
|
|
233
|
+
'brave_search': 'duckduckgo_search', 'brave-web-search': 'duckduckgo_search',
|
|
234
|
+
'google_search': 'duckduckgo_search', 'web_search': 'duckduckgo_search',
|
|
232
235
|
'browse': 'browser', 'shell': 'bash', 'bash_command': 'bash',
|
|
233
236
|
'execute_command': 'bash', 'run_command': 'bash',
|
|
237
|
+
'http': 'http_request',
|
|
234
238
|
};
|
|
235
239
|
|
|
236
240
|
const BLOCKED_NAMES = new Set([
|
|
237
241
|
'brave_search', 'brave-web-search', 'google_search', 'web_search',
|
|
238
242
|
'browse', 'open', 'search', 'shell', 'bash_command', 'execute_command',
|
|
239
|
-
'run_command', 'sql', 'query', 'lookup',
|
|
243
|
+
'run_command', 'sql', 'query', 'lookup', 'http',
|
|
240
244
|
]);
|
|
241
245
|
|
|
242
246
|
// ── check_fn TTL cache (Hermes-style, ~30s) ────────────────────────────
|