natureco-cli 2.23.29 β 2.23.31
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 +94 -11
- package/bin/natureco.js +495 -94
- package/package.json +1 -1
- package/src/commands/acp.js +39 -0
- package/src/commands/admin-rpc.js +302 -0
- package/src/commands/agent.js +280 -0
- package/src/commands/agents.js +114 -30
- package/src/commands/approvals.js +214 -0
- package/src/commands/backup.js +124 -0
- package/src/commands/bonjour.js +167 -0
- package/src/commands/browser.js +815 -0
- package/src/commands/capability.js +237 -0
- package/src/commands/channels.js +422 -267
- package/src/commands/chat.js +5 -8
- package/src/commands/clawbot.js +19 -0
- package/src/commands/clickclack.js +130 -0
- package/src/commands/code.js +3 -2
- package/src/commands/commitments.js +148 -0
- package/src/commands/completion.js +84 -0
- package/src/commands/config.js +219 -30
- package/src/commands/configure.js +110 -0
- package/src/commands/crestodian.js +92 -0
- package/src/commands/cron.js +239 -19
- package/src/commands/daemon.js +90 -0
- package/src/commands/dashboard.js +47 -374
- package/src/commands/device-pair.js +248 -0
- package/src/commands/devices.js +137 -0
- package/src/commands/directory.js +179 -0
- package/src/commands/dns.js +196 -0
- package/src/commands/docs.js +136 -0
- package/src/commands/doctor.js +143 -492
- package/src/commands/exec-policy.js +80 -0
- package/src/commands/gateway-server.js +1155 -24
- package/src/commands/gateway.js +492 -249
- package/src/commands/health.js +148 -0
- package/src/commands/help.js +24 -25
- package/src/commands/hooks.js +141 -87
- package/src/commands/imessage.js +128 -14
- package/src/commands/infer.js +1474 -0
- package/src/commands/irc.js +64 -15
- package/src/commands/logs.js +122 -99
- package/src/commands/mattermost.js +114 -12
- package/src/commands/mcp.js +121 -309
- package/src/commands/memory-cmd.js +134 -1
- package/src/commands/memory.js +128 -0
- package/src/commands/message.js +720 -134
- package/src/commands/migrate.js +213 -2
- package/src/commands/models.js +39 -1
- package/src/commands/node.js +98 -0
- package/src/commands/nodes.js +362 -0
- package/src/commands/oc-path.js +200 -0
- package/src/commands/onboard.js +129 -0
- package/src/commands/open-prose.js +67 -0
- package/src/commands/pairing.js +108 -107
- package/src/commands/path.js +206 -0
- package/src/commands/plugins.js +35 -1
- package/src/commands/policy.js +176 -0
- package/src/commands/proxy.js +306 -0
- package/src/commands/qr.js +70 -0
- package/src/commands/reset.js +101 -94
- package/src/commands/sandbox.js +125 -0
- package/src/commands/secrets.js +201 -0
- package/src/commands/sessions.js +110 -51
- package/src/commands/setup.js +102 -543
- package/src/commands/signal.js +447 -18
- package/src/commands/skills.js +67 -1
- package/src/commands/sms.js +123 -19
- package/src/commands/status.js +101 -127
- package/src/commands/system.js +53 -0
- package/src/commands/tasks.js +208 -100
- package/src/commands/terminal.js +139 -0
- package/src/commands/thread-ownership.js +157 -0
- package/src/commands/transcripts.js +95 -0
- package/src/commands/tui.js +41 -0
- package/src/commands/uninstall.js +73 -92
- package/src/commands/update.js +146 -91
- package/src/commands/voice.js +82 -0
- package/src/commands/vydra.js +98 -0
- package/src/commands/webhooks.js +58 -66
- package/src/commands/wiki.js +783 -0
- package/src/commands/workboard.js +207 -0
- package/src/tools/audio_understanding.js +154 -0
- package/src/tools/browser.js +112 -0
- package/src/tools/canvas.js +104 -0
- package/src/tools/document_extract.js +84 -0
- package/src/tools/duckduckgo.js +54 -0
- package/src/tools/exa_search.js +66 -0
- package/src/tools/firecrawl.js +104 -0
- package/src/tools/image_generation.js +99 -0
- package/src/tools/llm_task.js +118 -0
- package/src/tools/media_understanding.js +128 -0
- package/src/tools/music_generation.js +113 -0
- package/src/tools/parallel_search.js +77 -0
- package/src/tools/phone_control.js +80 -0
- package/src/tools/phone_control_enhanced.js +184 -0
- package/src/tools/searxng.js +61 -0
- package/src/tools/speech_to_text.js +135 -0
- package/src/tools/text_to_speech.js +105 -0
- package/src/tools/thread_ownership.js +88 -0
- package/src/tools/video_generation.js +72 -0
- package/src/tools/web_readability.js +104 -0
- package/src/utils/agents-md.js +85 -0
- package/src/utils/api.js +39 -40
- package/src/utils/format.js +144 -0
- package/src/utils/headless.js +2 -1
- package/src/utils/memory.js +200 -0
- package/src/utils/parallel-tools.js +106 -0
- package/src/utils/sub-agent.js +148 -0
- package/src/utils/token-budget.js +304 -0
- package/src/utils/tool-runner.js +7 -5
- package/src/utils/web-fetch.js +107 -0
package/package.json
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
|
|
3
|
+
function acp(args) {
|
|
4
|
+
const [action, ...params] = args || [];
|
|
5
|
+
|
|
6
|
+
if (!action || action === 'status') return cmdStatus();
|
|
7
|
+
if (action === 'info') return cmdInfo();
|
|
8
|
+
|
|
9
|
+
console.log(chalk.red(`\n Unknown acp action: ${action}\n`));
|
|
10
|
+
console.log(chalk.gray(' Usage: natureco acp <action>'));
|
|
11
|
+
console.log(chalk.gray(' Actions: status, info\n'));
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function cmdStatus() {
|
|
16
|
+
console.log(chalk.cyan('\n ACP (Agent Communication Protocol) Status\n'));
|
|
17
|
+
console.log(chalk.gray(' ' + 'β'.repeat(48)));
|
|
18
|
+
console.log(` ${chalk.white('Endpoint:')} ${chalk.green('http://127.0.0.1:3847/acp')}`);
|
|
19
|
+
console.log(` ${chalk.white('Status:')} ${chalk.gray('Stub β no real implementation')}`);
|
|
20
|
+
console.log('');
|
|
21
|
+
console.log(chalk.gray(' Available endpoints:'));
|
|
22
|
+
console.log(chalk.gray(' GET /acp β Protocol root'));
|
|
23
|
+
console.log(chalk.gray(' GET /acp/health β Health check'));
|
|
24
|
+
console.log(chalk.gray(' POST /acp/message β Send agent message'));
|
|
25
|
+
console.log(chalk.gray(' GET /acp/agents β List agents'));
|
|
26
|
+
console.log('');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function cmdInfo() {
|
|
30
|
+
console.log(chalk.cyan('\n ACP Protocol Info\n'));
|
|
31
|
+
console.log(chalk.gray(' ' + 'β'.repeat(48)));
|
|
32
|
+
console.log(` ${chalk.white('Protocol:')} ${chalk.cyan('Agent Communication Protocol')}`);
|
|
33
|
+
console.log(` ${chalk.white('Version:')} ${chalk.cyan('1.0.0')}`);
|
|
34
|
+
console.log(` ${chalk.white('Port:')} ${chalk.cyan('3847')}`);
|
|
35
|
+
console.log(` ${chalk.white('Transport:')} ${chalk.cyan('HTTP/JSON')}`);
|
|
36
|
+
console.log('');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = acp;
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const http = require('http');
|
|
3
|
+
const { getConfig } = require('../utils/config');
|
|
4
|
+
|
|
5
|
+
const ALLOWED_METHODS = [
|
|
6
|
+
'health', 'status',
|
|
7
|
+
'config.get', 'config.set',
|
|
8
|
+
'channels.status', 'channels.start', 'channels.stop',
|
|
9
|
+
'agents.list',
|
|
10
|
+
'logs.tail',
|
|
11
|
+
'cron.list', 'cron.status',
|
|
12
|
+
'tasks.list',
|
|
13
|
+
'plugins.list'
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
let serverInstance = null;
|
|
17
|
+
|
|
18
|
+
function adminRpc(args) {
|
|
19
|
+
const [action, ...params] = args || [];
|
|
20
|
+
|
|
21
|
+
if (!action || action === 'status') return statusAdmin();
|
|
22
|
+
if (action === 'start') return startAdmin(params[0]);
|
|
23
|
+
if (action === 'stop') return stopAdmin();
|
|
24
|
+
if (action === 'call') return callMethod(params[0], params.slice(1).join(' '));
|
|
25
|
+
if (action === 'methods') return listMethods();
|
|
26
|
+
|
|
27
|
+
console.log(chalk.red(`\n β Bilinmeyen komut: ${action}\n`));
|
|
28
|
+
console.log(chalk.gray(' KullanΔ±m: natureco admin-rpc [status|start|stop|call|methods]\n'));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function statusAdmin() {
|
|
33
|
+
const running = serverInstance !== null;
|
|
34
|
+
console.log(chalk.cyan('\n π₯οΈ Admin HTTP RPC\n'));
|
|
35
|
+
console.log(chalk.gray(' ' + 'β'.repeat(48)));
|
|
36
|
+
console.log(` ${chalk.white('Server:')} ${running ? chalk.green(`http://localhost:${serverInstance?.port || 3847}`) : chalk.red('Durduruldu')}`);
|
|
37
|
+
console.log(` ${chalk.white('Methods:')} ${ALLOWED_METHODS.length}`);
|
|
38
|
+
console.log(chalk.gray('\n Commands:'));
|
|
39
|
+
console.log(chalk.cyan(' start [port]') + chalk.gray(' Start RPC server (default: 3847)'));
|
|
40
|
+
console.log(chalk.cyan(' stop') + chalk.gray(' Stop RPC server'));
|
|
41
|
+
console.log(chalk.cyan(' call <method>') + chalk.gray(' Call RPC method'));
|
|
42
|
+
console.log(chalk.cyan(' methods') + chalk.gray(' List methods'));
|
|
43
|
+
console.log();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function listMethods() {
|
|
47
|
+
console.log(chalk.cyan('\n π Admin RPC Methods\n'));
|
|
48
|
+
console.log(chalk.gray(' ' + 'β'.repeat(48)));
|
|
49
|
+
for (const m of ALLOWED_METHODS) {
|
|
50
|
+
console.log(` ${chalk.white(m)}`);
|
|
51
|
+
}
|
|
52
|
+
console.log();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function callMethod(method, jsonParams) {
|
|
56
|
+
if (!method) {
|
|
57
|
+
console.log(chalk.red('\n β Method adΔ± gerekli\n'));
|
|
58
|
+
console.log(chalk.cyan(' natureco admin-rpc call health\n'));
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!ALLOWED_METHODS.includes(method)) {
|
|
63
|
+
console.log(chalk.red(`\n β Desteklenmeyen method: ${method}\n`));
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let params = {};
|
|
68
|
+
if (jsonParams) {
|
|
69
|
+
try { params = JSON.parse(jsonParams); }
|
|
70
|
+
catch { console.log(chalk.red('\n β GeΓ§ersiz JSON\n')); process.exit(1); }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
console.log(chalk.cyan(`\n π‘ Calling: ${method}\n`));
|
|
74
|
+
|
|
75
|
+
if (method === 'health') {
|
|
76
|
+
console.log(chalk.green(' β
System healthy'));
|
|
77
|
+
console.log(chalk.gray(` Node: ${process.version}`));
|
|
78
|
+
console.log(chalk.gray(` Platform: ${process.platform}`));
|
|
79
|
+
console.log(chalk.gray(` Memory: ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)}MB\n`));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (method === 'status') {
|
|
84
|
+
const config = getConfig();
|
|
85
|
+
console.log(chalk.green(' β
Status\n'));
|
|
86
|
+
console.log(chalk.gray(` Gateway: ${config.gatewayUrl || 'not configured'}`));
|
|
87
|
+
console.log(chalk.gray(` Provider: ${config.provider || 'not set'}`));
|
|
88
|
+
console.log(chalk.gray(` Model: ${config.model || 'not set'}\n`));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (method === 'plugins.list') {
|
|
93
|
+
const { loadTools } = require('../utils/tool-runner');
|
|
94
|
+
const tools = loadTools();
|
|
95
|
+
console.log(chalk.green(` π¦ ${Object.keys(tools).length} tools loaded\n`));
|
|
96
|
+
for (const [name, t] of Object.entries(tools)) {
|
|
97
|
+
console.log(` ${chalk.white('β')} ${name} ${chalk.gray('- ' + (t.description || '').substring(0, 60))}`);
|
|
98
|
+
}
|
|
99
|
+
console.log();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (method === 'config.get') {
|
|
104
|
+
const config = getConfig();
|
|
105
|
+
const key = params.key;
|
|
106
|
+
if (key) {
|
|
107
|
+
const value = key.split('.').reduce((o, k) => o?.[k], config);
|
|
108
|
+
console.log(chalk.white(` ${key}: `) + chalk.cyan(JSON.stringify(value)));
|
|
109
|
+
} else {
|
|
110
|
+
console.log(chalk.cyan(JSON.stringify(config, null, 2)));
|
|
111
|
+
}
|
|
112
|
+
console.log();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (method === 'logs.tail') {
|
|
117
|
+
const lines = params.lines || 20;
|
|
118
|
+
const { execSync } = require('child_process');
|
|
119
|
+
try {
|
|
120
|
+
const logPath = require('path').join(require('os').homedir(), '.natureco', 'logs', 'gateway.log');
|
|
121
|
+
const output = execSync(`tail -${lines} "${logPath}"`, { encoding: 'utf8', maxBuffer: 1024 * 1024 });
|
|
122
|
+
console.log(output);
|
|
123
|
+
} catch {
|
|
124
|
+
console.log(chalk.yellow(' β οΈ Log bulunamadΔ±\n'));
|
|
125
|
+
}
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (method === 'config.set') {
|
|
130
|
+
const { setConfigValue } = require('../utils/config');
|
|
131
|
+
if (!params.key) { console.log(chalk.red('\n β params.key gerekli\n')); process.exit(1); }
|
|
132
|
+
setConfigValue(params.key, params.value);
|
|
133
|
+
console.log(chalk.green(`\n β
config.${params.key} = ${JSON.stringify(params.value)}\n`));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (method === 'channels.status' || method === 'channels.start' || method === 'channels.stop') {
|
|
138
|
+
const { getAllConfig } = require('../utils/config');
|
|
139
|
+
const cfg = getAllConfig();
|
|
140
|
+
const channels = ['telegram', 'discord', 'slack', 'whatsapp'];
|
|
141
|
+
console.log(chalk.cyan(`\n π‘ Channel: ${method}\n`));
|
|
142
|
+
if (method === 'channels.status') {
|
|
143
|
+
for (const ch of channels) {
|
|
144
|
+
const token = cfg[`${ch}Token`];
|
|
145
|
+
console.log(` ${token ? chalk.green('β') : chalk.gray('β')} ${ch} ${token ? chalk.gray('(configured)') : chalk.gray('(not set)')}`);
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
const ch = params.name || 'all';
|
|
149
|
+
console.log(chalk.gray(` ${method.split('.')[1]} ${ch} (simulated)\n`));
|
|
150
|
+
}
|
|
151
|
+
console.log();
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (method === 'agents.list') {
|
|
156
|
+
const { listTasks, getTaskSummary } = require('../utils/background');
|
|
157
|
+
const tasks = listTasks({ limit: 20 });
|
|
158
|
+
const summary = getTaskSummary();
|
|
159
|
+
console.log(chalk.cyan(`\n π€ Agents (${summary.active} active, ${summary.total} total)\n`));
|
|
160
|
+
console.log(chalk.gray(' ' + 'β'.repeat(48)));
|
|
161
|
+
for (const t of tasks.slice(0, 10)) {
|
|
162
|
+
const icon = t.status === 'succeeded' ? chalk.green('β') : t.status === 'running' ? chalk.yellow('β') : chalk.gray('β');
|
|
163
|
+
console.log(` ${icon} ${chalk.white(t.message || '(no message)')}`);
|
|
164
|
+
console.log(chalk.gray(` [${t.id}] ${t.runtime} β ${t.status}`));
|
|
165
|
+
}
|
|
166
|
+
console.log();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (method === 'cron.list' || method === 'cron.status') {
|
|
171
|
+
const { getConfig } = require('../utils/config');
|
|
172
|
+
const config = getConfig();
|
|
173
|
+
const jobs = config.cronJobs || [];
|
|
174
|
+
console.log(chalk.cyan(`\n β° ${method} (${jobs.length} jobs)\n`));
|
|
175
|
+
if (jobs.length === 0) {
|
|
176
|
+
console.log(chalk.gray(' Cron job yapΔ±landΔ±rΔ±lmamΔ±Ε.\n'));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
for (const j of jobs) {
|
|
180
|
+
console.log(` ${chalk.white(j.name || '(unnamed)')} β ${chalk.gray(j.schedule || j.interval)}`);
|
|
181
|
+
}
|
|
182
|
+
console.log();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (method === 'tasks.list') {
|
|
187
|
+
const { listTasks, getTaskSummary } = require('../utils/background');
|
|
188
|
+
const tasks = listTasks({ limit: 20 });
|
|
189
|
+
const summary = getTaskSummary();
|
|
190
|
+
console.log(chalk.cyan(`\n π Tasks (${summary.active} active, ${summary.total} total)\n`));
|
|
191
|
+
for (const t of tasks.slice(0, 15)) {
|
|
192
|
+
console.log(` ${chalk.white(t.id)} β ${chalk.cyan(t.status)} β ${chalk.gray(t.message?.substring(0, 50) || '')}`);
|
|
193
|
+
}
|
|
194
|
+
console.log();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
console.log(chalk.yellow(` β οΈ Method "${method}" henΓΌz implemente edilmedi\n`));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function startAdmin(portStr) {
|
|
202
|
+
if (serverInstance) {
|
|
203
|
+
console.log(chalk.yellow('\n β οΈ Server zaten Γ§alΔ±ΕΔ±yor\n'));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const port = parseInt(portStr, 10) || 3847;
|
|
208
|
+
|
|
209
|
+
const server = http.createServer((req, res) => {
|
|
210
|
+
if (req.method !== 'POST') {
|
|
211
|
+
res.writeHead(405, { 'Allow': 'POST', 'Content-Type': 'application/json' });
|
|
212
|
+
res.end(JSON.stringify({ ok: false, error: 'Method not allowed' }));
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
let body = '';
|
|
217
|
+
req.on('data', chunk => { body += chunk; });
|
|
218
|
+
req.on('end', async () => {
|
|
219
|
+
try {
|
|
220
|
+
const rpc = JSON.parse(body);
|
|
221
|
+
if (!rpc.method || typeof rpc.method !== 'string') {
|
|
222
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
223
|
+
res.end(JSON.stringify({ ok: false, error: 'method required' }));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (!ALLOWED_METHODS.includes(rpc.method)) {
|
|
228
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
229
|
+
res.end(JSON.stringify({ ok: false, error: `Method not allowed: ${rpc.method}` }));
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const config = getConfig();
|
|
234
|
+
let payload;
|
|
235
|
+
|
|
236
|
+
if (rpc.method === 'health') {
|
|
237
|
+
payload = { status: 'ok', node: process.version, uptime: process.uptime() };
|
|
238
|
+
} else if (rpc.method === 'status') {
|
|
239
|
+
payload = { gateway: config.gatewayUrl, provider: config.provider, model: config.model };
|
|
240
|
+
} else if (rpc.method === 'config.get') {
|
|
241
|
+
const key = rpc.params?.key;
|
|
242
|
+
payload = key ? { [key]: key.split('.').reduce((o, k) => o?.[k], config) } : config;
|
|
243
|
+
} else if (rpc.method === 'plugins.list') {
|
|
244
|
+
const { loadTools } = require('../utils/tool-runner');
|
|
245
|
+
payload = { tools: Object.keys(loadTools()) };
|
|
246
|
+
} else if (rpc.method === 'config.set') {
|
|
247
|
+
const { setConfigValue } = require('../utils/config');
|
|
248
|
+
setConfigValue(rpc.params.key, rpc.params.value);
|
|
249
|
+
payload = { ok: true, key: rpc.params.key, value: rpc.params.value };
|
|
250
|
+
} else if (rpc.method === 'channels.status' || rpc.method === 'channels.start' || rpc.method === 'channels.stop') {
|
|
251
|
+
const channels = ['telegram', 'discord', 'slack', 'whatsapp'];
|
|
252
|
+
const status = {};
|
|
253
|
+
for (const ch of channels) status[ch] = !!config[`${ch}Token`];
|
|
254
|
+
payload = { action: rpc.method, channels: status };
|
|
255
|
+
} else if (rpc.method === 'agents.list' || rpc.method === 'tasks.list') {
|
|
256
|
+
const { listTasks, getTaskSummary } = require('../utils/background');
|
|
257
|
+
payload = { summary: getTaskSummary(), tasks: listTasks({ limit: 20 }) };
|
|
258
|
+
} else if (rpc.method === 'cron.list' || rpc.method === 'cron.status') {
|
|
259
|
+
payload = { jobs: config.cronJobs || [] };
|
|
260
|
+
} else {
|
|
261
|
+
payload = { message: `Method "${rpc.method}" called`, params: rpc.params };
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
265
|
+
res.end(JSON.stringify({ ok: true, id: rpc.id || 'rpc-1', payload }));
|
|
266
|
+
} catch (err) {
|
|
267
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
268
|
+
res.end(JSON.stringify({ ok: false, error: 'Invalid JSON' }));
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
serverInstance = server;
|
|
274
|
+
serverInstance.port = port;
|
|
275
|
+
|
|
276
|
+
server.listen(port, () => {
|
|
277
|
+
console.log(chalk.green(`\n β
Admin RPC server started on http://localhost:${port}\n`));
|
|
278
|
+
console.log(chalk.gray(' POST requests with JSON body:'));
|
|
279
|
+
console.log(chalk.white(' { "method": "health", "id": "req-1" }'));
|
|
280
|
+
console.log(chalk.white(' { "method": "config.get", "params": { "key": "provider" } }'));
|
|
281
|
+
console.log(chalk.gray('\n Press Ctrl+C to stop\n'));
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
server.on('error', (err) => {
|
|
285
|
+
console.log(chalk.red(`\n β Server error: ${err.message}\n`));
|
|
286
|
+
serverInstance = null;
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function stopAdmin() {
|
|
291
|
+
if (!serverInstance) {
|
|
292
|
+
console.log(chalk.yellow('\n β οΈ Server Γ§alΔ±ΕmΔ±yor\n'));
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
serverInstance.close(() => {
|
|
297
|
+
console.log(chalk.gray('\n π Admin RPC server durduruldu\n'));
|
|
298
|
+
serverInstance = null;
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
module.exports = adminRpc;
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
const BINDINGS_FILE = path.join(os.homedir(), '.natureco', 'agent-bindings.json');
|
|
7
|
+
const IDENTITIES_FILE = path.join(os.homedir(), '.natureco', 'agent-identities.json');
|
|
8
|
+
|
|
9
|
+
async function agent(args) {
|
|
10
|
+
const opts = {};
|
|
11
|
+
for (let i = 0; i < args.length; i++) {
|
|
12
|
+
if (args[i] === '--to' || args[i] === '-t') opts.to = args[++i];
|
|
13
|
+
else if (args[i] === '--message' || args[i] === '-m') opts.message = args[++i];
|
|
14
|
+
else if (args[i] === '--channel' || args[i] === '-c') opts.channel = args[++i];
|
|
15
|
+
else if (args[i] === '--deliver') opts.deliver = true;
|
|
16
|
+
else if (args[i] === '--model') opts.model = args[++i];
|
|
17
|
+
else if (args[i] === '--provider') opts.provider = args[++i];
|
|
18
|
+
else if (!opts.action) opts.action = args[i];
|
|
19
|
+
else (opts._positional = opts._positional || []).push(args[i]);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!opts.action || opts.action === 'help') return showHelp();
|
|
23
|
+
if (opts.action === 'run') return runAgent(opts);
|
|
24
|
+
if (opts.action === 'abort') return abortAgent(opts.message);
|
|
25
|
+
if (opts.action === 'tail') return tailAgent(opts.message);
|
|
26
|
+
if (opts.action === 'logs') return logsAgent(opts.message);
|
|
27
|
+
if (opts.action === 'bindings') return listBindings();
|
|
28
|
+
if (opts.action === 'bind') return bindAgent(opts);
|
|
29
|
+
if (opts.action === 'unbind') return unbindAgent(opts);
|
|
30
|
+
if (opts.action === 'set-identity') return setIdentity(opts);
|
|
31
|
+
|
|
32
|
+
console.log(chalk.red(`\n β Bilinmeyen komut: ${opts.action}\n`));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function runAgent(opts) {
|
|
37
|
+
const { getConfig } = require('../utils/config');
|
|
38
|
+
const { createTask } = require('../utils/background');
|
|
39
|
+
const { getProviderConfig } = require('../utils/api');
|
|
40
|
+
const config = getConfig();
|
|
41
|
+
const pc = getProviderConfig();
|
|
42
|
+
|
|
43
|
+
const provider = opts.provider || (pc?.url?.includes('groq') ? 'groq' : config.provider || 'openai');
|
|
44
|
+
const model = opts.model || config.providerModel || config.model || 'llama-3.3-70b-versatile';
|
|
45
|
+
const message = opts.message || 'Hello';
|
|
46
|
+
const apiKey = pc?.apiKey || config[`${provider}ApiKey`] || process.env[`${provider.toUpperCase()}_API_KEY`];
|
|
47
|
+
|
|
48
|
+
if (!apiKey) {
|
|
49
|
+
console.log(chalk.red(`\n β ${provider} API key gerekli\n`));
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const task = createTask({
|
|
54
|
+
runtime: 'cli',
|
|
55
|
+
message: message.substring(0, 80),
|
|
56
|
+
botName: opts.to || 'default',
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
console.log(chalk.cyan(`\n π€ Agent Turn [${task.id}]\n`));
|
|
60
|
+
console.log(chalk.gray(' ' + 'β'.repeat(48)));
|
|
61
|
+
console.log(` ${chalk.white('Message:')} ${message}`);
|
|
62
|
+
if (opts.to) console.log(` ${chalk.white('To:')} ${opts.to}`);
|
|
63
|
+
if (opts.channel) console.log(` ${chalk.white('Channel:')} ${opts.channel}`);
|
|
64
|
+
console.log(` ${chalk.white('Provider:')} ${provider}`);
|
|
65
|
+
console.log(` ${chalk.white('Model:')} ${model}`);
|
|
66
|
+
console.log(chalk.gray('\n Running...\n'));
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const { updateTask } = require('../utils/background');
|
|
70
|
+
updateTask(task.id, { status: 'running' });
|
|
71
|
+
|
|
72
|
+
const apiUrl = pc?.url || `https://api.${provider}.com/v1`;
|
|
73
|
+
const response = await fetch(`${apiUrl}/chat/completions`, {
|
|
74
|
+
method: 'POST',
|
|
75
|
+
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },
|
|
76
|
+
body: JSON.stringify({ model, messages: [{ role: 'user', content: message }], max_tokens: 2048 })
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
updateTask(task.id, { status: 'failed', error: `API error ${response.status}` });
|
|
81
|
+
throw new Error(`API error ${response.status}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const data = await response.json();
|
|
85
|
+
const reply = data.choices?.[0]?.message?.content || 'No response';
|
|
86
|
+
|
|
87
|
+
updateTask(task.id, { status: 'succeeded', result: reply.substring(0, 500) });
|
|
88
|
+
|
|
89
|
+
console.log(chalk.white(' Response:'));
|
|
90
|
+
console.log(chalk.gray(` ${reply.substring(0, 500)}`));
|
|
91
|
+
|
|
92
|
+
if (opts.deliver && opts.channel) {
|
|
93
|
+
console.log(chalk.gray(`\n π¨ Delivering via ${opts.channel}...`));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log();
|
|
97
|
+
} catch (err) {
|
|
98
|
+
console.log(chalk.red(` β ${err.message}\n`));
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function abortAgent(taskId) {
|
|
104
|
+
const { cancelTask, listTasks } = require('../utils/background');
|
|
105
|
+
if (taskId) {
|
|
106
|
+
const t = cancelTask(taskId);
|
|
107
|
+
if (!t) { console.log(chalk.red(`\n β Task bulunamadΔ±: ${taskId}\n`)); process.exit(1); }
|
|
108
|
+
console.log(chalk.yellow(`\n π Task iptal edildi: ${taskId}\n`));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const running = listTasks({ status: 'running' });
|
|
112
|
+
if (running.length === 0) {
|
|
113
|
+
console.log(chalk.gray('\n ΓalΔ±Εan task yok\n'));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
for (const t of running) {
|
|
117
|
+
cancelTask(t.id);
|
|
118
|
+
console.log(chalk.yellow(` π Task iptal edildi: ${t.id} β ${t.message}`));
|
|
119
|
+
}
|
|
120
|
+
console.log();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function tailAgent(taskId) {
|
|
124
|
+
const { getTask } = require('../utils/background');
|
|
125
|
+
if (!taskId) {
|
|
126
|
+
console.log(chalk.red('\n β Task ID gerekli. KullanΔ±m: natureco agent tail <id>\n'));
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
const task = getTask(taskId);
|
|
130
|
+
if (!task) { console.log(chalk.red(`\n β Task bulunamadΔ±: ${taskId}\n`)); process.exit(1); }
|
|
131
|
+
console.log(chalk.cyan(`\n π Task: ${task.id}\n`));
|
|
132
|
+
console.log(chalk.gray(' ' + 'β'.repeat(48)));
|
|
133
|
+
console.log(` ${chalk.white('Message:')} ${task.message}`);
|
|
134
|
+
console.log(` ${chalk.white('Status:')} ${statusColor(task.status)}`);
|
|
135
|
+
if (task.result) console.log(` ${chalk.white('Result:')} ${chalk.gray(task.result.substring(0, 300))}`);
|
|
136
|
+
if (task.error) console.log(` ${chalk.white('Error:')} ${chalk.red(task.error)}`);
|
|
137
|
+
if (task.createdAt) console.log(` ${chalk.white('Created:')} ${chalk.gray(task.createdAt)}`);
|
|
138
|
+
if (task.endedAt) console.log(` ${chalk.white('Ended:')} ${chalk.gray(task.endedAt)}`);
|
|
139
|
+
console.log();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function logsAgent(statusFilter) {
|
|
143
|
+
const { listTasks } = require('../utils/background');
|
|
144
|
+
const tasks = listTasks(statusFilter ? { status: statusFilter } : {});
|
|
145
|
+
console.log(chalk.cyan(`\n π Agent Logs${statusFilter ? ` (${statusFilter})` : ''}\n`));
|
|
146
|
+
console.log(chalk.gray(' ' + 'β'.repeat(48)));
|
|
147
|
+
if (tasks.length === 0) {
|
|
148
|
+
console.log(chalk.gray(' Task bulunamadΔ±.\n'));
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
for (const t of tasks.slice(0, 20)) {
|
|
152
|
+
console.log(` ${statusColor(t.status)} ${chalk.white(t.message || '(boΕ)')}`);
|
|
153
|
+
console.log(chalk.gray(` [${t.id}] ${t.createdAt?.slice(0, 16) || ''} β ${t.runtime}`));
|
|
154
|
+
}
|
|
155
|
+
console.log();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ββ bindings ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
159
|
+
function listBindings() {
|
|
160
|
+
const bindings = loadBindings();
|
|
161
|
+
const ids = loadIdentities();
|
|
162
|
+
console.log(chalk.cyan('\n Agent Bindings\n'));
|
|
163
|
+
console.log(chalk.gray(' ' + 'β'.repeat(48)));
|
|
164
|
+
const entries = Object.entries(bindings);
|
|
165
|
+
if (entries.length === 0) {
|
|
166
|
+
console.log(chalk.gray(' No agents bound to any channels.\n'));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
for (const [agentId, channels] of entries) {
|
|
170
|
+
const identity = ids[agentId];
|
|
171
|
+
console.log(` ${chalk.white(agentId)}${identity ? chalk.gray(' (' + identity + ')') : ''}`);
|
|
172
|
+
for (const ch of channels) {
|
|
173
|
+
console.log(chalk.gray(' ββ ') + chalk.cyan(ch));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
console.log('');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function loadBindings() {
|
|
180
|
+
if (!fs.existsSync(BINDINGS_FILE)) return {};
|
|
181
|
+
try { return JSON.parse(fs.readFileSync(BINDINGS_FILE, 'utf8')); } catch { return {}; }
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function saveBindings(data) {
|
|
185
|
+
const dir = path.dirname(BINDINGS_FILE);
|
|
186
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
187
|
+
fs.writeFileSync(BINDINGS_FILE, JSON.stringify(data, null, 2), 'utf8');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function bindAgent(opts) {
|
|
191
|
+
const pos = opts._positional || [];
|
|
192
|
+
const agentId = pos[0];
|
|
193
|
+
const channel = pos[1] || opts.channel;
|
|
194
|
+
if (!agentId || !channel) {
|
|
195
|
+
console.log(chalk.red('\nUsage: natureco agents bind <agentId> <channel>\n'));
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
const bindings = loadBindings();
|
|
199
|
+
if (!bindings[agentId]) bindings[agentId] = [];
|
|
200
|
+
if (!bindings[agentId].includes(channel)) bindings[agentId].push(channel);
|
|
201
|
+
saveBindings(bindings);
|
|
202
|
+
console.log(chalk.green('\nAgent "' + agentId + '" bound to ' + channel + '\n'));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function unbindAgent(opts) {
|
|
206
|
+
const pos = opts._positional || [];
|
|
207
|
+
const agentId = pos[0];
|
|
208
|
+
const channel = pos[1] || opts.channel;
|
|
209
|
+
if (!agentId || !channel) {
|
|
210
|
+
console.log(chalk.red('\nUsage: natureco agents unbind <agentId> <channel>\n'));
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
213
|
+
const bindings = loadBindings();
|
|
214
|
+
if (bindings[agentId]) {
|
|
215
|
+
bindings[agentId] = bindings[agentId].filter(c => c !== channel);
|
|
216
|
+
if (bindings[agentId].length === 0) delete bindings[agentId];
|
|
217
|
+
}
|
|
218
|
+
saveBindings(bindings);
|
|
219
|
+
console.log(chalk.green('\nAgent "' + agentId + '" unbound from ' + channel + '\n'));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ββ identities ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
223
|
+
function loadIdentities() {
|
|
224
|
+
if (!fs.existsSync(IDENTITIES_FILE)) return {};
|
|
225
|
+
try { return JSON.parse(fs.readFileSync(IDENTITIES_FILE, 'utf8')); } catch { return {}; }
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function saveIdentities(data) {
|
|
229
|
+
const dir = path.dirname(IDENTITIES_FILE);
|
|
230
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
231
|
+
fs.writeFileSync(IDENTITIES_FILE, JSON.stringify(data, null, 2), 'utf8');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function setIdentity(opts) {
|
|
235
|
+
const pos = opts._positional || [];
|
|
236
|
+
const agentId = pos[0];
|
|
237
|
+
const identity = pos.slice(1).join(' ') || opts.message;
|
|
238
|
+
if (!agentId || !identity) {
|
|
239
|
+
console.log(chalk.red('\nUsage: natureco agents set-identity <agentId> <identity>\n'));
|
|
240
|
+
process.exit(1);
|
|
241
|
+
}
|
|
242
|
+
const ids = loadIdentities();
|
|
243
|
+
ids[agentId] = identity;
|
|
244
|
+
saveIdentities(ids);
|
|
245
|
+
console.log(chalk.green('\nIdentity set for agent "' + agentId + '": ' + identity + '\n'));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function statusColor(s) {
|
|
249
|
+
const m = { succeeded: chalk.green('β'), failed: chalk.red('β'), running: chalk.yellow('β'), queued: chalk.cyan('β'), cancelled: chalk.gray('β'), timed_out: chalk.red('β '), lost: chalk.magenta('?') };
|
|
250
|
+
return m[s] || chalk.gray('β');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function showHelp() {
|
|
254
|
+
console.log(chalk.cyan('\n π€ Agent\n'));
|
|
255
|
+
console.log(chalk.gray(' Run, manage, and monitor agent tasks.\n'));
|
|
256
|
+
console.log(chalk.gray(' Usage: natureco agent <action> [options]'));
|
|
257
|
+
console.log(chalk.gray('\n Actions:'));
|
|
258
|
+
console.log(chalk.cyan(' run') + chalk.gray(' Run an agent turn'));
|
|
259
|
+
console.log(chalk.cyan(' abort [id]') + chalk.gray(' Cancel a running task'));
|
|
260
|
+
console.log(chalk.cyan(' tail <id>') + chalk.gray(' Show task details'));
|
|
261
|
+
console.log(chalk.cyan(' logs [status]') + chalk.gray(' List recent tasks'));
|
|
262
|
+
console.log(chalk.cyan(' bindings') + chalk.gray(' List agent bindings'));
|
|
263
|
+
console.log(chalk.cyan(' bind <id> <ch>') + chalk.gray(' Bind agent to channel'));
|
|
264
|
+
console.log(chalk.cyan(' unbind <id> <ch>') + chalk.gray(' Unbind agent from channel'));
|
|
265
|
+
console.log(chalk.cyan(' set-identity <id> <persona>') + chalk.gray(' Set agent identity'));
|
|
266
|
+
console.log(chalk.gray('\n Options for run:'));
|
|
267
|
+
console.log(chalk.cyan(' --message, -m <text>') + chalk.gray(' Message to send'));
|
|
268
|
+
console.log(chalk.cyan(' --to, -t <target>') + chalk.gray(' Target channel/contact'));
|
|
269
|
+
console.log(chalk.cyan(' --channel, -c <name>') + chalk.gray(' Channel to use'));
|
|
270
|
+
console.log(chalk.cyan(' --deliver') + chalk.gray(' Deliver reply via channel'));
|
|
271
|
+
console.log(chalk.cyan(' --model <model>') + chalk.gray(' Model override'));
|
|
272
|
+
console.log(chalk.cyan(' --provider <name>') + chalk.gray(' Provider override'));
|
|
273
|
+
console.log(chalk.gray('\n Examples:'));
|
|
274
|
+
console.log(chalk.gray(' natureco agent run --message "Merhaba"'));
|
|
275
|
+
console.log(chalk.gray(' natureco agent abort'));
|
|
276
|
+
console.log(chalk.gray(' natureco agent tail <id>'));
|
|
277
|
+
console.log(chalk.gray(' natureco agent logs running\n'));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
module.exports = agent;
|